Use log crate for cleaner, more flexible logging.

This commit is contained in:
Sergio Benitez 2016-08-24 01:30:09 -07:00
parent 43bfefc1b2
commit 868448c4b3
11 changed files with 44 additions and 53 deletions

View File

@ -5,6 +5,7 @@ authors = ["Sergio Benitez <sb@sergio.bz>"]
[dependencies] [dependencies]
term-painter = "*" term-painter = "*"
log = "*"
hyper = "*" hyper = "*"
url = "*" url = "*"
mime = "*" mime = "*"

View File

@ -5,6 +5,14 @@ extern crate term_painter;
extern crate hyper; extern crate hyper;
extern crate url; extern crate url;
extern crate mime; extern crate mime;
#[macro_use] extern crate log;
#[macro_use]
pub mod logger;
pub mod form;
pub mod request;
pub mod response;
pub mod content_type;
mod method; mod method;
mod error; mod error;
@ -14,17 +22,13 @@ mod rocket;
mod codegen; mod codegen;
mod catcher; mod catcher;
pub mod form;
pub mod request;
pub mod response;
pub mod content_type;
pub mod handler { pub mod handler {
use super::{Request, Response}; use super::{Request, Response};
pub type Handler = for<'r> fn(Request<'r>) -> Response<'r>; pub type Handler = for<'r> fn(Request<'r>) -> Response<'r>;
} }
pub use logger::RocketLogger;
pub use content_type::ContentType; pub use content_type::ContentType;
pub use codegen::{StaticRouteInfo, StaticCatchInfo}; pub use codegen::{StaticRouteInfo, StaticCatchInfo};
pub use request::Request; pub use request::Request;

View File

@ -53,7 +53,7 @@ impl Responder for File {
impl<T: Responder> Responder for Option<T> { impl<T: Responder> Responder for Option<T> {
fn respond<'a>(&mut self, res: FreshHyperResponse<'a>) -> Outcome<'a> { fn respond<'a>(&mut self, res: FreshHyperResponse<'a>) -> Outcome<'a> {
if self.is_none() { if self.is_none() {
println!("Option is none."); trace!("Option is none.");
// TODO: Should this be a 404 or 500? // TODO: Should this be a 404 or 500?
return Outcome::FailForward(res); return Outcome::FailForward(res);
} }
@ -67,7 +67,7 @@ impl<T: Responder, E: fmt::Debug> Responder for Result<T, E> {
default fn respond<'a>(&mut self, res: FreshHyperResponse<'a>) default fn respond<'a>(&mut self, res: FreshHyperResponse<'a>)
-> Outcome<'a> { -> Outcome<'a> {
if self.is_err() { if self.is_err() {
println!("Error: {:?}", self.as_ref().err().unwrap()); error_!("{:?}", self.as_ref().err().unwrap());
// TODO: Should this be a 404 or 500? // TODO: Should this be a 404 or 500?
return Outcome::FailForward(res); return Outcome::FailForward(res);
} }

View File

@ -5,6 +5,7 @@ use catcher;
use std::io::Read; use std::io::Read;
use std::collections::HashMap; use std::collections::HashMap;
use term_painter::Color::*; use term_painter::Color::*;
use term_painter::ToStyle; use term_painter::ToStyle;
@ -41,7 +42,7 @@ fn method_is_valid(method: &HyperMethod) -> bool {
impl HyperHandler for Rocket { impl HyperHandler for Rocket {
fn handle<'a, 'k>(&'a self, req: HyperRequest<'a, 'k>, fn handle<'a, 'k>(&'a self, req: HyperRequest<'a, 'k>,
mut res: FreshHyperResponse<'a>) { mut res: FreshHyperResponse<'a>) {
println!("{:?} '{}'", Green.paint(&req.method), Blue.paint(&req.uri)); info!("{:?} '{}':", Green.paint(&req.method), Blue.paint(&req.uri));
let finalize = |mut req: HyperRequest, _res: FreshHyperResponse| { let finalize = |mut req: HyperRequest, _res: FreshHyperResponse| {
let mut buf = vec![]; let mut buf = vec![];
@ -50,18 +51,17 @@ impl HyperHandler for Rocket {
}; };
if !uri_is_absolute(&req.uri) { if !uri_is_absolute(&req.uri) {
println!("{}", Red.paint("\t=> Internal failure. Bad URI.")); error_!("Internal failure. Bad URI.");
println!("{} {:?}", Yellow.paint("\t=> Debug:"), req.uri); debug_!("Debug: {}", req.uri);
return finalize(req, res); return finalize(req, res);
} }
if !method_is_valid(&req.method) { if !method_is_valid(&req.method) {
println!("{}", Yellow.paint("\t=> Internal failure. Bad method.")); error_!("Internal failure. Bad method.");
println!("{} {:?}", Yellow.paint("\t=> Debug:"), req.method); debug_!("Method: {}", req.method);
return finalize(req, res); return finalize(req, res);
} }
res.headers_mut().set(response::header::Server("rocket".to_string())); res.headers_mut().set(response::header::Server("rocket".to_string()));
self.dispatch(req, res) self.dispatch(req, res)
} }
@ -82,7 +82,7 @@ impl Rocket {
// A closure which we call when we know there is no route. // A closure which we call when we know there is no route.
let handle_not_found = |response: FreshHyperResponse| { let handle_not_found = |response: FreshHyperResponse| {
println!("{}", Red.paint("\t<= Dispatch failed. Returning 404.")); error_!("Dispatch failed. Returning 404.");
let request = Request::new(&req.headers, method, uri, None, &buf); let request = Request::new(&req.headers, method, uri, None, &buf);
let catcher = self.catchers.get(&404).unwrap(); let catcher = self.catchers.get(&404).unwrap();
@ -91,7 +91,7 @@ impl Rocket {
// No route found. Handle the not_found error and return. // No route found. Handle the not_found error and return.
if route.is_none() { if route.is_none() {
println!("{}", Red.paint("\t=> No matching routes.")); error_!("No matching routes.");
return handle_not_found(res); return handle_not_found(res);
} }
@ -100,14 +100,15 @@ impl Rocket {
let params = route.get_params(uri); let params = route.get_params(uri);
let request = Request::new(&req.headers, method, uri, Some(params), &buf); let request = Request::new(&req.headers, method, uri, Some(params), &buf);
println!("\t=> {}", Magenta.paint("Dispatching request.")); // TODO: Paint these magenta.
trace_!("Dispatching request.");
let outcome = (route.handler)(request).respond(res); let outcome = (route.handler)(request).respond(res);
// TODO: keep trying lower ranked routes before dispatching a not found // TODO: keep trying lower ranked routes before dispatching a not found
// error. // error.
println!("\t=> {} {}", White.paint("Outcome:"), outcome); info_!("{} {}", White.paint("Outcome:"), outcome);
outcome.map_forward(|res| { outcome.map_forward(|res| {
println!("{}", Red.paint("\t=> No further matching routes.")); error_!("No further matching routes.");
// TODO: Have some way to know why this was failed forward. Use that // TODO: Have some way to know why this was failed forward. Use that
// instead of always using an unchained error. // instead of always using an unchained error.
handle_not_found(res); handle_not_found(res);
@ -115,6 +116,9 @@ impl Rocket {
} }
pub fn new(address: &'static str, port: isize) -> Rocket { pub fn new(address: &'static str, port: isize) -> Rocket {
// FIXME: Allow user to override level/disable logging.
logger::init(logger::Level::Normal);
Rocket { Rocket {
address: address, address: address,
port: port, port: port,
@ -125,12 +129,12 @@ impl Rocket {
pub fn mount(&mut self, base: &'static str, routes: Vec<Route>) pub fn mount(&mut self, base: &'static str, routes: Vec<Route>)
-> &mut Self { -> &mut Self {
println!("🛰 {} '{}':", Magenta.paint("Mounting"), Blue.paint(base)); info!("🛰 {} '{}':", Magenta.paint("Mounting"), base);
for mut route in routes { for mut route in routes {
let path = format!("{}/{}", base, route.path.as_str()); let path = format!("{}/{}", base, route.path.as_str());
route.set_path(path); route.set_path(path);
println!("\t* {}", route); info_!("{}", route);
self.router.add(route); self.router.add(route);
} }
@ -138,14 +142,14 @@ impl Rocket {
} }
pub fn catch(&mut self, catchers: Vec<Catcher>) -> &mut Self { pub fn catch(&mut self, catchers: Vec<Catcher>) -> &mut Self {
println!("👾 {}:", Magenta.paint("Catchers")); info!("👾 {}:", Magenta.paint("Catchers"));
for c in catchers { for c in catchers {
if self.catchers.contains_key(&c.code) && if self.catchers.contains_key(&c.code) &&
!self.catchers.get(&c.code).unwrap().is_default() { !self.catchers.get(&c.code).unwrap().is_default() {
let msg = format!("warning: overrides {} catcher!", c.code); let msg = format!("warning: overrides {} catcher!", c.code);
println!("\t* {} ({})", c, Yellow.paint(msg.as_str())); info_!("{} ({})", c, Yellow.paint(msg.as_str()));
} else { } else {
println!("\t* {}", c); info_!("{}", c);
} }
self.catchers.insert(c.code, c); self.catchers.insert(c.code, c);
@ -156,11 +160,11 @@ impl Rocket {
pub fn launch(self) { pub fn launch(self) {
if self.router.has_collisions() { if self.router.has_collisions() {
println!("{}", Yellow.paint("Warning: route collisions detected!")); warn!("Route collisions detected!");
} }
let full_addr = format!("{}:{}", self.address, self.port); let full_addr = format!("{}:{}", self.address, self.port);
println!("🚀 {} {}...", White.paint("Rocket has launched from"), info!("🚀 {} {}...", White.paint("Rocket has launched from"),
White.bold().paint(&full_addr)); White.bold().paint(&full_addr));
let _ = HyperServer::http(full_addr.as_str()).unwrap().handle(self); let _ = HyperServer::http(full_addr.as_str()).unwrap().handle(self);
} }

View File

@ -6,8 +6,6 @@ pub use self::collider::Collider;
pub use self::uri::{URI, URIBuf}; pub use self::uri::{URI, URIBuf};
pub use self::route::Route; pub use self::route::Route;
use term_painter::ToStyle;
use term_painter::Color::*;
use std::collections::hash_map::HashMap; use std::collections::hash_map::HashMap;
use method::Method; use method::Method;
@ -40,7 +38,7 @@ impl Router {
let num_segments = path.segment_count(); let num_segments = path.segment_count();
if let Some(routes) = self.routes.get(&(method, num_segments)) { if let Some(routes) = self.routes.get(&(method, num_segments)) {
for route in routes.iter().filter(|r| r.collides_with(uri)) { for route in routes.iter().filter(|r| r.collides_with(uri)) {
println!("\t=> {} {}", Magenta.paint("Matched:"), route); info_!("Matched: {}", route);
if let Some(existing_route) = matched_route { if let Some(existing_route) = matched_route {
if route.rank > existing_route.rank { if route.rank > existing_route.rank {
matched_route = Some(route); matched_route = Some(route);
@ -61,9 +59,7 @@ impl Router {
for b_route in routes.iter().skip(i + 1) { for b_route in routes.iter().skip(i + 1) {
if a_route.collides_with(b_route) { if a_route.collides_with(b_route) {
result = true; result = true;
println!("{} {} and {} collide!", warn!("{} and {} collide!", a_route, b_route);
Yellow.bold().paint("Warning:"),
a_route, b_route);
} }
} }
} }

View File

@ -199,11 +199,11 @@ mod tests {
let actual = URI::new(path).segment_count(); let actual = URI::new(path).segment_count();
let actual_buf = URIBuf::from(path).segment_count(); let actual_buf = URIBuf::from(path).segment_count();
if actual != expected || actual_buf != expected { if actual != expected || actual_buf != expected {
println!("Count mismatch: expected {}, got {}.", expected, actual); trace_!("Count mismatch: expected {}, got {}.", expected, actual);
println!("{}", if actual != expected { "lifetime" } else { "buf" }); trace_!("{}", if actual != expected { "lifetime" } else { "buf" });
println!("Segments (for {}):", path); trace_!("Segments (for {}):", path);
for (i, segment) in URI::new(path).segments().enumerate() { for (i, segment) in URI::new(path).segments().enumerate() {
println!("\t{}: {}", i, segment); trace_!("{}: {}", i, segment);
} }
} }

View File

@ -12,8 +12,6 @@ use syntax_ext::deriving::generic::MethodDef;
use syntax_ext::deriving::generic::{StaticStruct, Substructure, TraitDef, ty}; use syntax_ext::deriving::generic::{StaticStruct, Substructure, TraitDef, ty};
use syntax_ext::deriving::generic::combine_substructure as c_s; use syntax_ext::deriving::generic::combine_substructure as c_s;
const DEBUG: bool = true;
static ONLY_STRUCTS_ERR: &'static str = "`FromForm` can only be derived for \ static ONLY_STRUCTS_ERR: &'static str = "`FromForm` can only be derived for \
structures with named fields."; structures with named fields.";
static PRIVATE_LIFETIME: &'static str = "'rocket"; static PRIVATE_LIFETIME: &'static str = "'rocket";

View File

@ -2,6 +2,7 @@
#![feature(quote, concat_idents, plugin_registrar, rustc_private)] #![feature(quote, concat_idents, plugin_registrar, rustc_private)]
#[macro_use] extern crate syntax; #[macro_use] extern crate syntax;
#[macro_use] extern crate log;
extern crate syntax_ext; extern crate syntax_ext;
extern crate rustc; extern crate rustc;
extern crate rustc_plugin; extern crate rustc_plugin;

View File

@ -206,7 +206,7 @@ impl<'a, 'c> RouteDecoratorExt for MetaItemParser<'a, 'c> {
}); });
let content_type = kv_pairs.get("content").and_then(|data| { let content_type = kv_pairs.get("content").and_then(|data| {
debug!("Found data: {:?}", content_type); debug!("Found data: {:?}", data);
if let Ok(ct) = ContentType::from_str(data.node) { if let Ok(ct) = ContentType::from_str(data.node) {
if ct.is_ext() { if ct.is_ext() {
let msg = format!("'{}' is not a known content-type", data.node); let msg = format!("'{}' is not a known content-type", data.node);

View File

@ -13,9 +13,6 @@ use syntax::parse::token::{self, str_to_ident};
use rocket::Method; use rocket::Method;
#[allow(dead_code)]
const DEBUG: bool = true;
pub fn extract_params_from_kv<'a>(parser: &MetaItemParser, pub fn extract_params_from_kv<'a>(parser: &MetaItemParser,
params: &'a KVSpanned<String>) -> Vec<Spanned<&'a str>> { params: &'a KVSpanned<String>) -> Vec<Spanned<&'a str>> {
let mut param_span = params.v_span; let mut param_span = params.v_span;
@ -100,7 +97,7 @@ fn get_form_stmt(ecx: &ExtCtxt, fn_args: &mut Vec<UserParam>,
match ::rocket::form::FromForm::from_form_string(form_string) { match ::rocket::form::FromForm::from_form_string(form_string) {
Ok(v) => v, Ok(v) => v,
Err(_) => { Err(_) => {
println!("\t=> Form failed to parse."); debug!("\t=> Form failed to parse.");
return ::rocket::Response::not_found(); return ::rocket::Response::not_found();
} }
} }
@ -182,7 +179,7 @@ pub fn route_decorator(known_method: Option<Spanned<Method>>, ecx: &mut ExtCtxt,
// TODO: Add some kind of loggin facility in Rocket // TODO: Add some kind of loggin facility in Rocket
// to get the formatting right (IE, so it idents // to get the formatting right (IE, so it idents
// correctly). // correctly).
println!("Failed to parse: {:?}", e); denig!("Failed to parse: {:?}", e);
return ::rocket::Response::forward(); return ::rocket::Response::forward();
} }
}; };

View File

@ -13,16 +13,6 @@ use syntax::ptr::P;
use std::collections::{HashSet, HashMap}; use std::collections::{HashSet, HashMap};
macro_rules! debug {
($($message:tt)*) => ({
if DEBUG {
println!("{}:{}", file!(), line!());
println!($($message)*);
println!("");
}
})
}
pub fn prepend_ident<T: ToString>(other: T, ident: &Ident) -> Ident { pub fn prepend_ident<T: ToString>(other: T, ident: &Ident) -> Ident {
let mut new_ident = other.to_string(); let mut new_ident = other.to_string();
new_ident.push_str(ident.name.to_string().as_str()); new_ident.push_str(ident.name.to_string().as_str());