diff --git a/examples/logging-otlp/Cargo.toml b/examples/logging-otlp/Cargo.toml new file mode 100644 index 000000000..cb13771f5 --- /dev/null +++ b/examples/logging-otlp/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "example-logging-otlp" +version.workspace = true +edition.workspace = true +publish.workspace = true + + +[dependencies] +anyhow.workspace = true +salvo = { workspace = true, features = ["logging"] } +tokio = { workspace = true, features = ["macros"] } +tracing.workspace = true +tracing-subscriber ={ workspace = true, features = ["env-filter"] } +tracing-opentelemetry = "0.23.0" +opentelemetry = "0.22.0" +opentelemetry-otlp = { version = "0.15.0", features = ["tonic"] } +opentelemetry_sdk = { version = "0.22.1", features = ["rt-tokio"] } +tracing-appender = "0.2.3" diff --git a/examples/logging-otlp/README.md b/examples/logging-otlp/README.md new file mode 100644 index 000000000..3fd7a1b81 --- /dev/null +++ b/examples/logging-otlp/README.md @@ -0,0 +1,33 @@ +# Salvo with OpenTelemetry OTLP Example + +## open-telemetry-otlp +[otlp](https://opentelemetry.io/) High-quality, ubiquitous, and portable telemetry to enable effective observability + +This example demonstrates how to integrate the Salvo web framework with OpenTelemetry OTLP for tracing and logging, using Jaeger as the backend for visualization. + +## Prerequisites + +- Rust and Cargo installed on your system. +- Docker installed for running Jaeger. + +## Running Jaeger with Docker + +Before running the application, you need to start Jaeger using Docker. This will set up Jaeger's UI and OTLP collector to receive telemetry data. + +```bash +docker run -d -p 16686:16686 -p 4317:4317 -e COLLECTOR_OTLP_ENABLED=true jaegertracing/all-in-one:latest +``` + + +## Running the Application +Build and run the application: +Access the example endpoint: +```bash +curl http://localhost:5800/ +You should see "Hello World" as the response. Traces for requests made to this endpoint will be sent to Jaeger. +``` +## Viewing Traces +Open Jaeger UI in a web browser: +http://localhost:16686 +Navigate to the Jaeger UI to view the traces and detailed telemetry data generated by interacting with the Salvo application. + diff --git a/examples/logging-otlp/src/main.rs b/examples/logging-otlp/src/main.rs new file mode 100644 index 000000000..4081ffd87 --- /dev/null +++ b/examples/logging-otlp/src/main.rs @@ -0,0 +1,76 @@ +use anyhow::Result; +use opentelemetry::KeyValue; +use opentelemetry_otlp::WithExportConfig; +use opentelemetry_sdk::{ + runtime, + trace::{self, RandomIdGenerator, Tracer}, + Resource, +}; +use salvo::logging::Logger; +use salvo::prelude::*; +use tracing::{debug, info, instrument, level_filters::LevelFilter, warn}; +use tracing_subscriber::{ + fmt::{self, format::FmtSpan}, + layer::SubscriberExt, + util::SubscriberInitExt, + Layer, +}; + +#[instrument(fields(http.uri = req.uri().path(), http.method = req.method().as_str()))] +#[handler] +async fn hello(req: &mut Request) -> &'static str { + "Hello World" +} + +#[tokio::main] +async fn main() -> Result<()> { + // console layer for tracing-subscriber + let console = fmt::Layer::new() + .with_span_events(FmtSpan::CLOSE) + .pretty() + .with_filter(LevelFilter::DEBUG); + + // file appender layer for tracing-subscriber + let file_appender = tracing_appender::rolling::daily("./logs", "salvo.log"); + let (non_blocking, _guard) = tracing_appender::non_blocking(file_appender); + let file = fmt::Layer::new() + .with_writer(non_blocking) + .pretty() + .with_filter(LevelFilter::INFO); + + // opentelemetry tracing layer for tracing-subscriber + let tracer = init_tracer()?; + let opentelemetry = tracing_opentelemetry::layer().with_tracer(tracer); + + tracing_subscriber::registry() + .with(console) + .with(file) + .with(opentelemetry) + .init(); + + let router = Router::new().get(hello); + let service = Service::new(router).hoop(Logger::new()); + + let acceptor = TcpListener::new("0.0.0.0:5800").bind().await; + Server::new(acceptor).serve(service).await; + Ok(()) +} + +fn init_tracer() -> anyhow::Result { + let tracer = opentelemetry_otlp::new_pipeline() + .tracing() + .with_exporter( + opentelemetry_otlp::new_exporter() + .tonic() + .with_endpoint("http://localhost:4317"), + ) + .with_trace_config( + trace::config() + .with_id_generator(RandomIdGenerator::default()) + .with_max_events_per_span(32) + .with_max_attributes_per_span(64) + .with_resource(Resource::new(vec![KeyValue::new("service.name", "salvo-tracing")])), + ) + .install_batch(runtime::Tokio)?; + Ok(tracer) +}