Hey guys, I am adding tracing (via opentelemetry and jaeger) to my actix server. However, I want the tracing to be configurable at compile time, in case someone does not want the feature at all.
I am able to kinda separate it via something like this:
#[cfg(feature = "tracing")]
#[get("/healthz")]
async fn healthz(data: web::Data<AppState>) -> HttpResponse {
let tracer = global::tracer("healthz");
tracer.in_span("index", |ctx| async move {
ctx.span().set_attribute(Key::new("parameter").i64(10));
let mut rc = data.redis_connection.clone();
let () = match redis::cmd("PING").query_async::<redis::aio::MultiplexedConnection, ()>(&mut rc).await {
Ok(_) => {
return HttpResponse::build(StatusCode::OK).append_header(header::ContentType::plaintext()).body("OK");
},
Err(_) => {
return HttpResponse::build(StatusCode::INTERNAL_SERVER_ERROR).append_header(header::ContentType::plaintext()).body("OOF");
}
};
}).await
}
#[cfg(not(feature = "tracing"))]
#[get("/healthz")]
async fn healthz(data: web::Data<AppState>) -> HttpResponse {
let mut rc = data.redis_connection.clone();
let () = match redis::cmd("PING").query_async::<redis::aio::MultiplexedConnection, ()>(&mut rc).await {
Ok(_) => {
return HttpResponse::build(StatusCode::OK).append_header(header::ContentType::plaintext()).body("OK");
},
Err(_) => {
return HttpResponse::build(StatusCode::INTERNAL_SERVER_ERROR).append_header(header::ContentType::plaintext()).body("OOF");
}
};
}
I was wondering, since basically only the initialization of global tracer and the closure are the differences, is there some cleaner way to achieve this? One approach I can think of is take out the actual handler into its own function, and then just call that, but still have two separately defined handlers, based on config. E.g.:
#[cfg(feature = "tracing")]
#[get("/healthz")]
async fn healthz(data: web::Data<AppState>) -> HttpResponse {
let tracer = global::tracer("healthz");
tracer.in_span("index", |ctx| async move {
ctx.span().set_attribute(Key::new("parameter").i64(10));
return healthz_handler(data).await;
}).await
}
#[cfg(not(feature = "tracing"))]
#[get("/healthz")]
async fn healthz(data: web::Data<AppState>) -> HttpResponse {
return healthz_handler(data).await;
}
async fn healthz_handler(data: web::Data<AppState>) -> HttpResponse {
let mut rc = data.redis_connection.clone();
let () = match redis::cmd("PING").query_async::<redis::aio::MultiplexedConnection, ()>(&mut rc).await {
Ok(_) => {
return HttpResponse::build(StatusCode::OK).append_header(header::ContentType::plaintext()).body("OK");
},
Err(_) => {
return HttpResponse::build(StatusCode::INTERNAL_SERVER_ERROR).append_header(header::ContentType::plaintext()).body("OOF");
}
};
}
Thanks for any feedback.
Link to code in repo: kiryuu/src/main.rs at e0d16eba69acc96e805b6ddd86f11cfbcbb2f738 · ckcr4lyf/kiryuu · GitHub