Skip to content

Commit

Permalink
feat: migrate to tracing and add api metrics
Browse files Browse the repository at this point in the history
  • Loading branch information
zleyyij committed Aug 29, 2024
1 parent ed8df52 commit c714b1a
Show file tree
Hide file tree
Showing 9 changed files with 207 additions and 164 deletions.
224 changes: 125 additions & 99 deletions Cargo.lock

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions databases/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ phf_codegen = "0.11.2"
parsing = { path = "../parsing" }
chrono = "0.4.32"
nom = "7.1.3"
log = "0.4.20"
serde = { version = "1.0.195", features = ["derive"] }
phf = { version = "0.11.2", features = ["macros"] }
tracing = "0.1.40"

[dev-dependencies]
criterion = "0.5.1"
Expand All @@ -32,4 +32,4 @@ harness = false

[[bench]]
name = "cpu_intel"
harness = false
harness = false
2 changes: 1 addition & 1 deletion databases/src/cpu/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ mod intel_codegen;

use amd_codegen::AMD_CPUS;
use intel_codegen::INTEL_CPUS;
use log::{debug, error};
use tracing::{debug, error};
use nom::bytes::complete::{take_until, take_while};
use phf::Map;
use serde::Serialize;
Expand Down
4 changes: 2 additions & 2 deletions handlers/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ edition = "2021"
databases = { path = "../databases" }
parsing = { path = "../parsing" }
axum = "0.7.4"
log = "0.4.20"
serde = { version = "1.0.195", features = ["derive"] }
tower-http = { version = "0.5.1", features = ["cors"] }
tower-http = { version = "0.5.1", features = ["cors"] }
tracing = "0.1.40"
2 changes: 1 addition & 1 deletion handlers/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use databases::{cpu::CpuCache, usb::UsbCache, pcie::PcieCache};
use axum::extract::Query;
use axum::http::StatusCode;
use axum::{extract::State, Json};
use log::{error, warn};
use tracing::{error, warn};
use serde::{Deserialize, Serialize};


Expand Down
5 changes: 2 additions & 3 deletions parsing/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
# TODO: remove
log = "0.4.20"
nom = "7.1.3"
serde = { version = "1.0.195", features = ["derive"] }
serde_json = "1.0.111"
nohash-hasher = "0.2.0"
nohash-hasher = "0.2.0"
tracing = "0.1.40"
2 changes: 1 addition & 1 deletion parsing/src/cpu.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::collections::{HashMap, HashSet};

use log::{debug, error};
use tracing::{debug, error};
use nom::bytes::complete::{take_until, take_while};
use serde::Serialize;
mod amd;
Expand Down
6 changes: 3 additions & 3 deletions server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ handlers = { path = "../handlers" }
axum = "0.7.4"
chrono = "0.4.32"
clap = { version = "4.0", features = ["derive"] }
colored = "2.1.0"
log = "0.4.20"
tokio = { version = "1.35.1", features = ["full"] }
tower-http = { version = "0.5.1", features = ["cors"] }
tower-http = { version = "0.5.1", features = ["cors", "trace"] }
tracing = "0.1.40"
tracing-subscriber = "0.3.18"
122 changes: 70 additions & 52 deletions server/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,64 +1,64 @@
//! This module contains the code centered around the actual server binary. It relies on handlers from the `handlers` crate, which fetch data from
//! interfaces provided by the `database` crate, which rely on data parsed by the `parsing` crate.

use axum::extract::{MatchedPath, Request};
use axum::http::{header, HeaderValue, Method};
use axum::routing::post;
use axum::{routing::get, Router};
use chrono::Local;
use clap::builder::TypedValueParser;
use clap::{Parser, ValueEnum};
use colored::*;
use handlers::*;
use log::info;
use log::{Level, LevelFilter, Metadata, Record};
use clap::Parser;
use databases::cpu::CpuCache;
use databases::pcie::PcieCache;
use databases::usb::UsbCache;
use handlers::*;
use std::env;
use tower_http::cors::CorsLayer;
use tower_http::trace::TraceLayer;
use tracing::{info, info_span, Level};
use tracing_subscriber::fmt::format::FmtSpan;

/// Because the error that nom uses is rather lengthy and unintuitive, it's defined here
/// to simplify handling
// pub type NomError<'a> = nom::Err<nom::error::Error<&'a str>>;
/// https://docs.rs/log/latest/log/#implementing-a-logger
struct SimpleLogger;
// /// Because the error that nom uses is rather lengthy and unintuitive, it's defined here
// /// to simplify handling
// // pub type NomError<'a> = nom::Err<nom::error::Error<&'a str>>;
// /// https://docs.rs/log/latest/log/#implementing-a-logger
// struct SimpleLogger;

impl log::Log for SimpleLogger {
fn enabled(&self, _: &Metadata) -> bool {
// this is configured by calling log::set_max_level, and so this logging implementation logs all kinds of levels
true
}
// impl log::Log for SimpleLogger {
// fn enabled(&self, _: &Metadata) -> bool {
// // this is configured by calling log::set_max_level, and so this logging implementation logs all kinds of levels
// true
// }

fn log(&self, record: &Record) {
if self.enabled(record.metadata()) {
let level = match record.level() {
Level::Info => format!("{}", record.level()).bold().blue(),
Level::Warn => format!("{}", record.level()).bold().yellow(),
Level::Error => format!("{}", record.level()).bold().red(),
Level::Debug => format!("{}", record.level()).bold().green(),
Level::Trace => format!("{}", record.level()).bold().cyan(),
};
println!(
"({})[{}] {}",
Local::now().to_rfc2822(),
level,
record.args()
);
}
}
// fn log(&self, record: &Record) {
// if self.enabled(record.metadata()) {
// let level = match record.level() {
// Level::Info => format!("{}", record.level()).bold().blue(),
// Level::Warn => format!("{}", record.level()).bold().yellow(),
// Level::Error => format!("{}", record.level()).bold().red(),
// Level::Debug => format!("{}", record.level()).bold().green(),
// Level::Trace => format!("{}", record.level()).bold().cyan(),
// };
// println!(
// "({})[{}] {}",
// Local::now().to_rfc2822(),
// level,
// record.args()
// );
// }
// }

fn flush(&self) {}
}
// fn flush(&self) {}
// }

#[derive(ValueEnum, Clone)]
enum LoggingLevel {
Silent,
Error,
Warning,
Info,
Debug,
Trace,
}
// #[derive(ValueEnum, Clone)]
// enum LoggingLevel {
// Silent,
// Error,
// Warning,
// Info,
// Debug,
// Trace,
// }

#[derive(Parser)]
struct Args {
Expand All @@ -68,23 +68,25 @@ struct Args {
/// Level of logging verbosity
#[arg(short = 'v',
long = "verbosity",
default_value_t = LevelFilter::Info,
default_value_t = Level::INFO,
value_parser = clap::builder::PossibleValuesParser::new(["TRACE", "DEBUG", "INFO", "WARN", "ERROR", "OFF"])
.map(|s| s.to_lowercase().parse::<LevelFilter>().unwrap())
.map(|s| s.to_lowercase().parse::<Level>().unwrap())
)]
logging_level: LevelFilter,
logging_level: Level,
}

static LOGGER: SimpleLogger = SimpleLogger;
// static LOGGER: SimpleLogger = SimpleLogger;

// The production VM is heavily limited by logical cpu cores, and Tokio blocks till completion by default
#[tokio::main(flavor = "multi_thread", worker_threads = 10)]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// initialize logging
let cli_args = Args::parse();
log::set_logger(&LOGGER)
.map(|()| log::set_max_level(cli_args.logging_level))
.unwrap();
tracing_subscriber::fmt()
.with_span_events(FmtSpan::CLOSE)
.init();
// log::set_logger(&LOGGER)
// .map(|()| log::set_max_level(cli_args.logging_level))
// .unwrap();
info!("Application started");
// parse command line arguments
// create a new http router and register respective routes and handlers
Expand All @@ -100,6 +102,22 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
.allow_headers([header::ACCEPT, header::CONTENT_TYPE])
.allow_origin("*".parse::<HeaderValue>().unwrap()),
)
.layer(
TraceLayer::new_for_http().make_span_with(|request: &Request<_>| {
// Log the matched route's path (with placeholders not filled in).
// Use request.uri() or OriginalUri if you want the real path.
let matched_path = request
.extensions()
.get::<MatchedPath>()
.map(MatchedPath::as_str);
info_span!(
"http_request",
method = ?request.method(),
path=matched_path,
some_other_field = tracing::field::Empty,
)
}),
)
.with_state(AppState {
cpu_cache: CpuCache::new(),
usb_cache: UsbCache::new(),
Expand Down

0 comments on commit c714b1a

Please sign in to comment.