mirror of
https://github.com/actix/actix-extras.git
synced 2025-07-02 20:54:31 +02:00
Adopt OpenTelemetry's semantic convention (#15)
* Add http.route. * Align all fields with OpenTelemetry's semantic conventions. * Add span kind. * Emit event for errors. Add OTEL status code. * Create otel.status_code field as empty. * Fix errors. * Add (feature-gated) support for OpenTelemetry span propagation. * Capture the trace id as an attribute on the span. * Change message. * Log the newly-generated trace id if there is no parent context. * Define a root_span macro as a stepping stone to allow crate users to add their own fields to the root span. * Add comments. * mut is no longer necessary. * Allow users to customise generation of the root span. Split recording fields on span end from emission of log record. Make log record on error optional via feature flag. * Provide constructor + default implementation. * Explode into multiple modules. Fix various paths/private imports in root_span. * Rename module to root_span_macro. * Add a new extractor to retrieve the root span. * Document crate. * Docs! * Add section on OTEL. * Mention actix-web-opentelemetry. * Add OpenTelemetry example. * Improve readme. * Add custom root span example. Co-authored-by: LukeMathWalker <contact@palmieri.com>
This commit is contained in:
17
examples/opentelemetry/Cargo.toml
Normal file
17
examples/opentelemetry/Cargo.toml
Normal file
@ -0,0 +1,17 @@
|
||||
[package]
|
||||
name = "otel"
|
||||
version = "0.1.0"
|
||||
authors = ["Luca Palmieri <rust@lpalmieri.com>"]
|
||||
edition = "2018"
|
||||
|
||||
license = "MIT/Apache-2.0"
|
||||
|
||||
[dependencies]
|
||||
actix-web = "4.0.0-beta.6"
|
||||
tracing = "0.1.19"
|
||||
opentelemetry = { version = "0.13", features = ["rt-tokio-current-thread"] }
|
||||
opentelemetry-jaeger = { version = "0.12", features = ["tokio"] }
|
||||
tracing-opentelemetry = { version = "0.12" }
|
||||
tracing-subscriber = { version = "0.2.12", features = ["registry", "env-filter"] }
|
||||
tracing-bunyan-formatter = "0.1.6"
|
||||
tracing-actix-web = { path = "../.." }
|
33
examples/opentelemetry/README.md
Normal file
33
examples/opentelemetry/README.md
Normal file
@ -0,0 +1,33 @@
|
||||
# OpenTelemetry integration
|
||||
|
||||
## Prerequisites
|
||||
|
||||
To execute this example you need a running Jaeger instance.
|
||||
You can launch one using Docker:
|
||||
|
||||
```bash
|
||||
docker run -d -p6831:6831/udp -p6832:6832/udp -p16686:16686 jaegertracing/all-in-one:latest
|
||||
```
|
||||
|
||||
## Running
|
||||
|
||||
You can launch this example with
|
||||
|
||||
```bash
|
||||
cargo run
|
||||
```
|
||||
|
||||
An `actix-web` application will be listening on port `8080`.
|
||||
You can fire requests to it with:
|
||||
|
||||
```bash
|
||||
curl -v http://localhost:8080/hello
|
||||
```
|
||||
```text
|
||||
Hello world!
|
||||
```
|
||||
|
||||
## Traces
|
||||
|
||||
You can look at the exported traces in your browser by visiting [http://localhost:16686](http://localhost:16686).
|
||||
Spans will be also printed to the console in JSON format, as structured log records.
|
60
examples/opentelemetry/src/main.rs
Normal file
60
examples/opentelemetry/src/main.rs
Normal file
@ -0,0 +1,60 @@
|
||||
use actix_web::{web, App, HttpServer};
|
||||
use opentelemetry::{
|
||||
global, runtime::TokioCurrentThread, sdk::propagation::TraceContextPropagator,
|
||||
};
|
||||
use std::io;
|
||||
use tracing_actix_web::TracingLogger;
|
||||
use tracing_bunyan_formatter::{BunyanFormattingLayer, JsonStorageLayer};
|
||||
use tracing_subscriber::layer::SubscriberExt;
|
||||
use tracing_subscriber::{EnvFilter, Registry};
|
||||
|
||||
async fn hello() -> &'static str {
|
||||
"Hello world!"
|
||||
}
|
||||
|
||||
fn init_telemetry() {
|
||||
let app_name = "tracing-actix-web-demo";
|
||||
|
||||
// Start a new Jaeger trace pipeline.
|
||||
// Spans are exported in batch - recommended setup for a production application.
|
||||
global::set_text_map_propagator(TraceContextPropagator::new());
|
||||
let tracer = opentelemetry_jaeger::new_pipeline()
|
||||
.with_service_name(app_name)
|
||||
.install_batch(TokioCurrentThread)
|
||||
.expect("Failed to install OpenTelemetry tracer.");
|
||||
|
||||
// Filter based on level - trace, debug, info, warn, error
|
||||
// Tunable via `RUST_LOG` env variable
|
||||
let env_filter = EnvFilter::try_from_default_env().unwrap_or(EnvFilter::new("info"));
|
||||
// Create a `tracing` layer using the Jaeger tracer
|
||||
let telemetry = tracing_opentelemetry::layer().with_tracer(tracer);
|
||||
// Create a `tracing` layer to emit spans as structured logs to stdout
|
||||
let formatting_layer = BunyanFormattingLayer::new(app_name.into(), std::io::stdout);
|
||||
// Combined them all together in a `tracing` subscriber
|
||||
let subscriber = Registry::default()
|
||||
.with(env_filter)
|
||||
.with(telemetry)
|
||||
.with(JsonStorageLayer)
|
||||
.with(formatting_layer);
|
||||
tracing::subscriber::set_global_default(subscriber)
|
||||
.expect("Failed to install `tracing` subscriber.")
|
||||
}
|
||||
|
||||
#[actix_web::main]
|
||||
async fn main() -> io::Result<()> {
|
||||
init_telemetry();
|
||||
|
||||
HttpServer::new(move || {
|
||||
App::new()
|
||||
.wrap(TracingLogger::default())
|
||||
.service(web::resource("/hello").to(hello))
|
||||
})
|
||||
.bind("127.0.0.1:8080")?
|
||||
.run()
|
||||
.await?;
|
||||
|
||||
// Ensure all spans have been shipped to Jaeger.
|
||||
opentelemetry::global::shutdown_tracer_provider();
|
||||
|
||||
Ok(())
|
||||
}
|
Reference in New Issue
Block a user