feat: logging support
Diff
Cargo.lock | 183 +++++++++++++++++++++++++++++++--------------------
Cargo.toml | 5 +-
src/bin/server.rs | 29 ++++----
src/core/config.rs | 2 +-
src/core/helpers.rs | 28 ++------
src/core/logger.rs | 56 ++++------------
src/core/mod.rs | 9 ++-
src/core/rejection.rs | 7 +--
src/core/result.rs | 4 +-
src/lib.rs | 1 +-
10 files changed, 171 insertions(+), 153 deletions(-)
@@ -7,15 +7,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e"
[[package]]
name = "aho-corasick"
version = "0.7.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5"
dependencies = [
"memchr",
]
[[package]]
name = "alloc-no-stdlib"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -40,6 +31,15 @@ dependencies = [
]
[[package]]
name = "ansi_term"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
dependencies = [
"winapi 0.3.9",
]
[[package]]
name = "anyhow"
version = "1.0.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -56,7 +56,7 @@ dependencies = [
"flate2",
"futures-core",
"memchr",
"pin-project-lite 0.2.0",
"pin-project-lite 0.2.1",
]
[[package]]
@@ -210,7 +210,7 @@ version = "2.33.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002"
dependencies = [
"ansi_term",
"ansi_term 0.11.0",
"atty",
"bitflags",
"strsim",
@@ -268,19 +268,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88d7ed2934d741c6b37e33e3832298e8850b53fd2d2bea03873375596c7cea4e"
[[package]]
name = "env_logger"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36"
dependencies = [
"atty",
"humantime",
"log",
"regex",
"termcolor",
]
[[package]]
name = "fake-simd"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -402,7 +389,7 @@ dependencies = [
"futures-core",
"futures-sink",
"futures-task",
"pin-project 1.0.2",
"pin-project 1.0.3",
"pin-utils",
"slab",
]
@@ -540,15 +527,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "494b4d60369511e7dea41cf646832512a94e542f68bb9c49e54518e0f468eb47"
[[package]]
name = "humantime"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f"
dependencies = [
"quick-error",
]
[[package]]
name = "hyper"
version = "0.13.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -564,7 +542,7 @@ dependencies = [
"httparse",
"httpdate",
"itoa",
"pin-project 1.0.2",
"pin-project 1.0.3",
"socket2",
"tokio",
"tower-service",
@@ -670,6 +648,15 @@ dependencies = [
]
[[package]]
name = "matchers"
version = "0.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f099785f7595cc4b4553a174ce30dd7589ef93391ff414dbb67f62392b9e0ce1"
dependencies = [
"regex-automata",
]
[[package]]
name = "matches"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -877,11 +864,11 @@ dependencies = [
[[package]]
name = "pin-project"
version = "1.0.2"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ccc2237c2c489783abd8c4c80e5450fc0e98644555b1364da68cc29aa151ca7"
checksum = "5a83804639aad6ba65345661744708855f9fbcb71176ea8d28d05aeb11d975e7"
dependencies = [
"pin-project-internal 1.0.2",
"pin-project-internal 1.0.3",
]
[[package]]
@@ -897,9 +884,9 @@ dependencies = [
[[package]]
name = "pin-project-internal"
version = "1.0.2"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8e8d2bf0b23038a4424865103a4df472855692821aab4e4f5c3312d461d9e5f"
checksum = "b7bcc46b8f73443d15bc1c5fecbb315718491fa9187fa483f0e359323cde8b3a"
dependencies = [
"proc-macro2",
"quote",
@@ -914,9 +901,9 @@ checksum = "c917123afa01924fc84bb20c4c03f004d9c38e5127e3c039bbf7f4b9c76a2f6b"
[[package]]
name = "pin-project-lite"
version = "0.2.0"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6b063f57ec186e6140e2b8b6921e5f1bd89c7356dda5b33acc5401203ca6131c"
checksum = "e36743d754ccdf9954c2e352ce2d4b106e024c814f6499c2dadff80da9a442d8"
[[package]]
name = "pin-utils"
@@ -1146,10 +1133,17 @@ version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38cf2c13ed4745de91a5eb834e11c00bcc3709e773173b2ce4c56c9fbde04b9c"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
"thread_local",
]
[[package]]
name = "regex-automata"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae1ded71d66a4a97f5e961fd0cb25a5f366a42a41570d16a763a69c092c26ae4"
dependencies = [
"byteorder",
"regex-syntax",
]
[[package]]
@@ -1240,6 +1234,15 @@ dependencies = [
]
[[package]]
name = "sharded-slab"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79c719719ee05df97490f80a45acfc99e5a30ce98a1e4fb67aee422745ae14e3"
dependencies = [
"lazy_static",
]
[[package]]
name = "signal"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1265,6 +1268,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
[[package]]
name = "smallvec"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a55ca5f3b68e41c979bf8c46a6f1da892ca4db8f94023ce0bd32407573b1ac0"
[[package]]
name = "socket2"
version = "0.3.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1280,14 +1289,13 @@ name = "static-web-server"
version = "0.0.0"
dependencies = [
"anyhow",
"chrono",
"env_logger",
"jemallocator",
"log",
"nix",
"signal",
"structopt",
"tokio",
"tracing",
"tracing-subscriber",
"warp",
]
@@ -1323,9 +1331,9 @@ dependencies = [
[[package]]
name = "syn"
version = "1.0.57"
version = "1.0.58"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4211ce9909eb971f111059df92c45640aad50a619cf55cd76476be803c4c68e6"
checksum = "cc60a3d73ea6594cd712d830cc1f0390fd71542d8c8cd24e70cc54cdfd5e05d5"
dependencies = [
"proc-macro2",
"quote",
@@ -1347,15 +1355,6 @@ dependencies = [
]
[[package]]
name = "termcolor"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4"
dependencies = [
"winapi-util",
]
[[package]]
name = "textwrap"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1475,11 +1474,23 @@ checksum = "9f47026cdc4080c07e49b37087de021820269d996f581aac150ef9e5583eefe3"
dependencies = [
"cfg-if 1.0.0",
"log",
"pin-project-lite 0.2.0",
"pin-project-lite 0.2.1",
"tracing-attributes",
"tracing-core",
]
[[package]]
name = "tracing-attributes"
version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "80e0ccfc3378da0cce270c946b676a376943f5cd16aeba64568e7939806f4ada"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "tracing-core"
version = "0.1.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1499,6 +1510,49 @@ dependencies = [
]
[[package]]
name = "tracing-log"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e0f8c7178e13481ff6765bd169b33e8d554c5d2bbede5e32c356194be02b9b9"
dependencies = [
"lazy_static",
"log",
"tracing-core",
]
[[package]]
name = "tracing-serde"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fb65ea441fbb84f9f6748fd496cf7f63ec9af5bca94dd86456978d055e8eb28b"
dependencies = [
"serde",
"tracing-core",
]
[[package]]
name = "tracing-subscriber"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1fa8f0c8f4c594e4fc9debc1990deab13238077271ba84dd853d54902ee3401"
dependencies = [
"ansi_term 0.12.1",
"chrono",
"lazy_static",
"matchers",
"regex",
"serde",
"serde_json",
"sharded-slab",
"smallvec",
"thread_local",
"tracing",
"tracing-core",
"tracing-log",
"tracing-serde",
]
[[package]]
name = "try-lock"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1705,15 +1759,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-util"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
dependencies = [
"winapi 0.3.9",
]
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -23,10 +23,9 @@ include = ["src/**/*", "Cargo.toml", "Cargo.lock"]
[dependencies]
tokio = { version = "0.2", features = ["full"] }
warp = { version = "0.2", features = ["compression"] }
log = "0.4"
chrono = "0.4"
anyhow = "1.0"
env_logger = "0.7"
tracing = "0.1"
tracing-subscriber = "0.2"
structopt = "0.3"
nix = "0.14"
signal = "0.7"
@@ -4,33 +4,36 @@
#[global_allocator]
static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc;
#[macro_use]
extern crate static_web_server;
use self::static_web_server::{core::config, core::logger, core::rejection};
use structopt::StructOpt;
use tracing::info;
use warp::Filter;
use self::static_web_server::core::*;
async fn server(opts: config::Options) {
logger::init(&opts.log_level);
async fn server(opts: config::Options) -> Result {
logger::init(&opts.log_level)?;
let filters = warp::get()
.and(warp::fs::dir(opts.root))
.with(warp::compression::gzip())
.recover(rejection::handle_rejection);
.recover(rejection::handle_rejection)
.with(warp::trace::request());
info!("listening on http://[{}]:{}", &opts.host, &opts.port);
note!("server is listening on {}:{}", &opts.host, &opts.port);
let host = opts.host.parse::<std::net::IpAddr>()?;
let host = opts
.host
.parse::<std::net::IpAddr>()
.expect("not valid IP address");
warp::serve(filters).run((host, opts.port)).await;
warp::serve(filters).run((host, opts.port)).await
Ok(())
}
#[tokio::main(max_threads = 10_000)]
async fn main() {
server(config::Options::from_args()).await
async fn main() -> Result {
server(config::Options::from_args()).await?;
Ok(())
}
@@ -1,6 +1,6 @@
use structopt::StructOpt;
#[derive(Debug, StructOpt)]
pub struct Options {
#[structopt(long, short = "s", default_value = "::", env = "SERVER_HOST")]
@@ -1,35 +1,27 @@
use std::error;
use std::path::{Path, PathBuf};
use super::Result;
pub fn get_valid_dirpath<P: AsRef<Path>>(path: P) -> Result<PathBuf, Box<dyn error::Error>>
pub fn get_valid_dirpath<P: AsRef<Path>>(path: P) -> Result<PathBuf>
where
PathBuf: From<P>,
{
match PathBuf::from(path) {
v if !v.exists() => Result::Err(From::from(format!("path \"{:?}\" was not found", &v))),
v if !v.is_dir() => {
Result::Err(From::from(format!("path \"{:?}\" is not a directory", &v)))
}
v => Result::Ok(v),
v if !v.exists() => bail!("path \"{:?}\" was not found", &v),
v if !v.is_dir() => bail!("path \"{:?}\" is not a directory", &v),
v => Ok(v),
}
}
pub fn get_dirname<P: AsRef<Path>>(path: P) -> Result<String, Box<dyn error::Error>>
pub fn get_dirname<P: AsRef<Path>>(path: P) -> Result<String>
where
PathBuf: From<P>,
{
let path = match get_valid_dirpath(path) {
Err(e) => return Result::Err(e),
Ok(v) => v,
};
let path = get_valid_dirpath(path)?;
match path.iter().last() {
Some(v) => Result::Ok(v.to_str().unwrap().to_string()),
_ => Result::Err(From::from(format!(
"directory name for path \"{:?}\" was not determined",
path,
))),
Some(v) => Ok(v.to_str().unwrap().to_string()),
_ => bail!("directory name for path \"{:?}\" was not determined", path),
}
}
@@ -1,45 +1,17 @@
use env_logger::Builder;
use log::LevelFilter;
use std::io::Write;
use tracing::Level;
use tracing_subscriber::fmt::format::FmtSpan;
pub fn init(level: &str) {
let log_level = match level {
"off" => LevelFilter::Off,
"error" => LevelFilter::Error,
"warn" => LevelFilter::Warn,
"info" => LevelFilter::Info,
"debug" => LevelFilter::Debug,
"trace" => LevelFilter::Trace,
_ => {
println!("Log level \"{}\" is not supported", level);
std::process::exit(1);
}
};
use super::Result;
Builder::new()
.filter_level(log_level)
.format(|buf, record| {
writeln!(
buf,
"{} [{}] - {}",
chrono::Local::now().format("%Y-%m-%dT%H:%M:%S"),
record.level(),
record.args()
)
})
.init();
}
#[macro_export]
macro_rules! note {
($($arg:tt)*) => ({
println!(
"{} [NOTE] - {}",
chrono::Local::now().format("%Y-%m-%dT%H:%M:%S"),
format!($($arg)*)
);
})
pub fn init(level: &str) -> Result {
let level = level.parse::<Level>()?;
match tracing_subscriber::fmt()
.with_max_level(level)
.with_span_events(FmtSpan::CLOSE)
.try_init()
{
Err(err) => Err(anyhow!(err)),
_ => Ok(()),
}
}
@@ -1,7 +1,10 @@
#[macro_use]
pub mod logger;
pub mod config;
pub mod helpers;
pub mod logger;
pub mod rejection;
pub mod signal_manager;
#[macro_use]
pub mod result;
pub use crate::core::result::*;
@@ -3,8 +3,7 @@ use std::convert::Infallible;
use warp::http::StatusCode;
use warp::{Rejection, Reply};
pub async fn handle_rejection(err: Rejection) -> Result<impl Reply, Infallible> {
let code = if err.is_not_found() {
StatusCode::NOT_FOUND
@@ -15,9 +14,9 @@ pub async fn handle_rejection(err: Rejection) -> Result<impl Reply, Infallible>
} else {
StatusCode::INTERNAL_SERVER_ERROR
};
let body = format!(
let content = format!(
"<html><head><title>{}</title></head><body><center><h1>{}</h1></center></body></html>",
code, code
);
Ok(warp::reply::with_status(warp::reply::html(body), code))
Ok(warp::reply::with_status(warp::reply::html(content), code))
}
@@ -0,0 +1,4 @@
pub type Result<T = ()> = anyhow::Result<T, anyhow::Error>;
pub use anyhow::Context;
@@ -1,3 +1,4 @@
#[macro_use]
extern crate anyhow;
pub mod core;