Add observability using the tracing crate

This commit is contained in:
2022-01-10 14:41:11 +01:00
parent cbdf35eb53
commit 067838b159
10 changed files with 364 additions and 192 deletions

View File

@@ -12,7 +12,7 @@ impl TryFrom<&taskwarrior::Task> for Task {
if cs_string.is_empty() || cs_string == "{}" {
Ok(None)
} else {
Some(serde_json::from_str(&cs_string)).transpose()
Some(serde_json::from_str(cs_string)).transpose()
}
},
)?;
@@ -39,7 +39,7 @@ impl TryFrom<&taskwarrior::Task> for Task {
pub fn export(filters: Vec<&str>) -> Result<Vec<Task>, Error> {
let tasks: Result<Vec<Task>, Error> = taskwarrior::export(filters)?
.iter()
.map(|task| Task::try_from(task))
.map(Task::try_from)
.collect();
tasks
}

View File

@@ -4,8 +4,10 @@ use serde::Deserialize;
use std::env;
use std::io::Error;
use std::net::TcpListener;
use tracing_actix_web::TracingLogger;
pub mod contextswitch;
pub mod observability;
pub mod taskwarrior;
#[derive(Deserialize)]
@@ -13,6 +15,7 @@ struct TaskQuery {
filter: String,
}
#[tracing::instrument(level = "debug", skip(task_query))]
async fn list_tasks(task_query: web::Query<TaskQuery>) -> Result<HttpResponse, Error> {
let tasks = contextswitch::export(task_query.filter.split(' ').collect())?;
@@ -27,10 +30,10 @@ async fn health_check() -> HttpResponse {
pub fn run(listener: TcpListener) -> Result<Server, std::io::Error> {
let cs_front_base_url =
env::var("CS_FRONT_BASE_URL").unwrap_or("http://localhost:8080".to_string());
env::var("CS_FRONT_BASE_URL").unwrap_or_else(|_| "http://localhost:8080".to_string());
let mut server = HttpServer::new(move || {
App::new()
.wrap(middleware::Logger::default())
.wrap(TracingLogger::default())
.wrap(middleware::Compress::default())
.wrap(
middleware::DefaultHeaders::new()

View File

@@ -1,21 +1,20 @@
extern crate dotenv;
extern crate env_logger;
extern crate listenfd;
use contextswitch_api::run;
use contextswitch_api::observability::{get_subscriber, init_subscriber};
use contextswitch_api::{run, taskwarrior};
use dotenv::dotenv;
use std::env;
use std::net::TcpListener;
pub mod taskwarrior;
#[actix_web::main]
#[tokio::main]
async fn main() -> std::io::Result<()> {
env::set_var("RUST_LOG", "actix_web=info");
env_logger::init();
let subscriber = get_subscriber("info".into());
init_subscriber(subscriber);
dotenv().ok();
let port = env::var("PORT").unwrap_or("8000".to_string());
let port = env::var("PORT").unwrap_or_else(|_| "8000".to_string());
taskwarrior::load_config(None);
let listener = TcpListener::bind(format!("0.0.0.0:{}", port)).expect("Failed to bind port");

36
src/observability.rs Normal file
View File

@@ -0,0 +1,36 @@
use tracing::Level;
use tracing::{subscriber::set_global_default, Subscriber};
use tracing_log::LogTracer;
use tracing_subscriber::{filter, fmt, fmt::format, layer::SubscriberExt, EnvFilter, Layer};
pub fn get_subscriber(env_filter_str: String) -> impl Subscriber + Send + Sync {
let fmt_layer = fmt::layer()
.event_format(format::Format::default().json())
.fmt_fields(format::JsonFields::new())
.flatten_event(true)
.with_test_writer();
let access_log_layer = fmt::layer()
.event_format(format::Format::default().json())
.fmt_fields(format::JsonFields::new())
.flatten_event(true)
.with_test_writer()
.with_span_events(format::FmtSpan::CLOSE)
.with_span_list(false)
.with_filter(
filter::Targets::new().with_target("tracing_actix_web::root_span_builder", Level::INFO),
);
let env_filter =
EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new(env_filter_str));
tracing_subscriber::registry()
.with(fmt_layer)
.with(access_log_layer)
.with(env_filter)
}
pub fn init_subscriber(subscriber: impl Subscriber + Send + Sync) {
LogTracer::init().expect("Failed to set logger");
set_global_default(subscriber).expect("Failed to set subscriber");
}

View File

@@ -49,11 +49,13 @@ pub fn load_config(task_data_location: Option<&str>) -> String {
let mut taskrc = Ini::new();
taskrc
.load(&taskrc_location)
.expect(&format!("Cannot load taskrc file {}", taskrc_location));
return taskrc.get("default", "data.location").expect(&format!(
"'data.location' must be set in taskrc file {}",
taskrc_location
));
.unwrap_or_else(|_| panic!("Cannot load taskrc file {}", taskrc_location));
return taskrc.get("default", "data.location").unwrap_or_else(|| {
panic!(
"'data.location' must be set in taskrc file {}",
taskrc_location
)
});
}
let data_location = task_data_location