9 个版本
0.4.0 | 2024年8月9日 |
---|---|
0.3.2 | 2023年10月25日 |
0.2.3 | 2023年9月1日 |
0.1.0 | 2023年8月30日 |
#681 in 网页编程
137 每月下载量
在 rtz 中使用
62KB
770 行
axum-insights
通过 axum 的 tracing
实现的 Azure 应用程序洞察 导出器。
用法
此库旨在作为 axum 的层使用。它将自动对您的 axum 应用程序进行仪器化,并将遥测数据发送到 Azure 应用程序洞察。随着生态系统的成熟,将添加更多功能。
示例
以下示例是一个 "完整" 示例,这意味着它包括此库的所有可选功能。
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() {
// ...
}
致谢
此库依赖于其他维护者的个人努力,例如
测试
cargo test --features web
依赖项
~14–45MB
~719K SLoC