Add observability using the tracing crate
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
15
src/main.rs
15
src/main.rs
@@ -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
36
src/observability.rs
Normal 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");
|
||||
}
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user