# telemetry-rust ```rust use tracing::Level::INFO; // middleware::axum is available if feature flag axum is on use telemetry_rust::{ init_tracing, middleware::axum::{OtelAxumLayer, OtelInResponseLayer}, }; #[tracing::instrument] async fn route_otel() -> impl axum::response::IntoResponse { let trace_id = telemetry_rust::tracing_opentelemetry_instrumentation_sdk::find_current_trace_id(); dbg!(&trace_id); axum::Json(serde_json::json!({ "trace-id": trace_id })) } #[tokio::main] async fn main() { init_tracing!(INFO); // ... let app = axum::Router::new() // request processed inside span .route("/otel", axum::routing::get(route_otel)) // include trace context as header into the response .layer(OtelInResponseLayer::default()) // start OpenTelemetry trace on incoming request .layer(OtelAxumLayer::default()); // ... ``` ## AWS SDK instrumentation ### `AwsInstrumented` trait ```rust let res = dynamo_client .get_item() .table_name("table_name") .index_name("my_index") .set_key(primary_key) .send() .instrument(DynamodbSpanBuilder::get_item("table_name")) .await; ``` ### Low level API Creating new span: ```rust // create new span in the current span's context using either a dedicated constructor let aws_span = DynamodbSpanBuilder::get_item("table_name").start(); // or a generic one let aws_span = AwsSpanBuilder::dynamodb("GetItem", vec!["table_name"]).start(); // optionally, provide an explicit parent context let context = Span::current().context(); let aws_span = DynamodbSpanBuilder::get_item("table_name").context(&context).start(); // or set custom span attributes let aws_span = DynamodbSpanBuilder::get_item("table_name") .attribute(KeyValue::new(semconv::AWS_DYNAMODB_INDEX_NAME, "my_index")) .attributes(vec![ KeyValue::new(semconv::AWS_DYNAMODB_LIMIT, 6), KeyValue::new(semconv::AWS_DYNAMODB_SELECT, "ALL_ATTRIBUTES"), ]) .start(); ``` Ending the span once AWS operation is complete: ```rust let res = dynamo_client .get_item() .table_name("table_name") .index_name("my_index") .set_key(primary_key) .send() .await; aws_span.end(&res); ``` Only the following AWS targets are fully supported at the moment: * DynamoDB * SNS * Firehose But a generic `AwsSpanBuilder` could be used to instrument any other AWS SDK: ```rust let s3_span = AwsSpanBuilder::client( "S3", "GetObject", vec![KeyValue::new(semconv::AWS_S3_BUCKET, "my_bucket")], ) .start(); ``` ## AWS Lambda instrumentation ```rust #[tokio::main] async fn main() -> Result<(), lambda_runtime::Error> { // Grab TracerProvider after telemetry initialisation let provider = telemetry_rust::init_tracing!(tracing::Level::WARN); // Create lambda telemetry layer let telemetry_layer = telemetry_rust::middleware::lambda::OtelLambdaLayer::new(provider); // Run lambda runtime with telemetry layer lambda_runtime::Runtime::new(tower::service_fn(handler)) .layer(telemetry_layer) .run() .await?; // Shutdown tracer provider before exiting telemetry_rust::shutdown_signal(); Ok(()) } ``` ## Publishing new version New version could be published using [cargo-release](https://github.com/crate-ci/cargo-release?tab=readme-ov-file#install): ```sh cargo release -x ```