9 releases
0.4.0 | Aug 9, 2024 |
---|---|
0.3.2 | Oct 25, 2023 |
0.2.3 | Sep 1, 2023 |
0.1.0 | Aug 30, 2023 |
#1566 in Web programming
Used in rtz
62KB
770 lines
axum-insights
An Azure Application Insights
exporter for axum via tracing
.
Usage
This library is meant to be used as a layer for axum. It will automatically instrument your axum application, and send telemetry to Azure Application Insights. As the ecosystem matures, more features will be added.
Example
The following example is a "complete" example, which means that it includes all of the optional features of this library.
use serde::{Serialize, Deserialize};
use axum::Router;
use axum_insights::AppInsights;
use axum_insights::AppInsightsError;
use tracing_subscriber::filter::LevelFilter;
use std::collections::HashMap;
use tracing::Instrument;
// Define some helper types for the example.
#[derive(Default, Serialize, Deserialize, Clone)]
struct WebError {
message: String,
}
impl AppInsightsError for WebError {
fn message(&self) -> Option<String> {
Some(self.message.clone())
}
fn backtrace(&self) -> Option<String> {
None
}
}
// Set up the exporter, and get the `tower::Service` layer.
let telemetry_layer = AppInsights::default()
// Accepts an optional connection string. If None, then no telemetry is sent.
.with_connection_string(None)
// Sets the service namespace and name. Default is empty.
.with_service_config("namespace", "name")
// Sets the HTTP client to use for sending telemetry. Default is reqwest async client.
.with_client(reqwest::Client::new())
// Sets whether or not live metrics are collected. Default is false.
.with_live_metrics(true)
// Sets the sample rate for telemetry. Default is 1.0.
.with_sample_rate(1.0)
// Sets the minimum level for telemetry. Default is INFO.
.with_minimum_level(LevelFilter::INFO)
// Sets the subscriber to use for telemetry. Default is a new subscriber.
.with_subscriber(tracing_subscriber::registry())
// Sets the runtime to use for telemetry. Default is Tokio.
.with_runtime(opentelemetry_sdk::runtime::Tokio)
// Sets whether or not to catch panics, and emit a trace for them. Default is false.
.with_catch_panic(true)
// Sets whether or not to make this telemetry layer a noop. Default is false.
.with_noop(true)
// Sets a function to extract extra fields from the request. Default is no extra fields.
.with_field_mapper(|parts| {
let mut map = HashMap::new();
map.insert("extra_field".to_owned(), "extra_value".to_owned());
map
})
// Sets a function to extract extra fields from a panic. Default is a default error.
.with_panic_mapper(|panic| {
(500, WebError { message: panic })
})
// Sets a function to determine the success-iness of a status. Default is (100 - 399 => true).
.with_success_filter(|status| {
status.is_success() || status.is_redirection() || status.is_informational() || status == http::StatusCode::NOT_FOUND
})
// Sets the common error type for the application, and will automatically extract information from handlers that return that error.
.with_error_type::<WebError>()
.build_and_set_global_default()
.unwrap()
.layer();
// Add the layer to your app.
// You likely will not need to specify `Router<()>` in your implementation. This is just for the example.
let app: Router<()> = Router::new()
// ...
.layer(telemetry_layer);
// Then, in a handler, you would use the `tracing` macros to emit telemetry.
use axum::response::IntoResponse;
use axum::Json;
use tracing::{Level, instrument, debug, error, info, warn, event};
// Instrument async handlers to get method-specific tracing.
#[instrument]
async fn handler(Json(body): Json<String>) -> Result<impl IntoResponse, WebError> {
// Emit events using the `tracing` macros.
debug!("Debug message");
info!("Info message");
warn!("Warn message");
error!("Error message");
event!(name: "exception", Level::ERROR, exception.message = "error message");
// Create new spans using the `tracing` macros.
let span = tracing::info_span!("DB Query");
db_query().instrument(span).await;
if body == "error" {
return Err(WebError { message: "Error".to_owned() });
}
Ok(())
}
async fn db_query() {
// ...
}
Acknowledgements
This library depends on individual efforts of other maintainers such as:
Test
cargo test --features web
Dependencies
~15–46MB
~706K SLoC