Crate axum_insights

source ·
Expand description


An Azure Application Insights exporter for axum via tracing.


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> {
    fn backtrace(&self) -> Option<String> {
// 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.
    // 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.
    // Sets whether or not live metrics are collected.  Default is false.
    // Sets the sample rate for telemetry.  Default is 1.0.
    // Sets the minimum level for telemetry.  Default is INFO.
    // Sets the subscriber to use for telemetry.  Default is a new subscriber.
    // Sets the runtime to use for telemetry.  Default is Tokio.
    // Sets whether or not to catch panics, and emit a trace for them.  Default is false.
    // Sets whether or not to make this telemetry layer a noop.  Default is false.
    // 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());
    // 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.
// 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()
    // ...
// 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.
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");
    if body == "error" {
        return Err(WebError { message: "Error".to_owned() });
async fn db_query() {
    // ...


  • Re-exports of the dependencies of this crate.



  • A trait that extracts relevant information from a global error type.