prima_tracing.rs
Utilities for configuring a tracing subscriber with support for logging and opentelemetry.
## Installation
Install from [crates.io](https://crates.io/crates/prima-tracing)
```toml
prima-tracing = "0.11"
```
### Cargo features
For ease of use you can use the following feature sets:
- `live` enables the feature you will most likely want in a production/staging environment
- `dev` enables the features you will most likely want in a dev environment
- `json-logger` outputs traces to standard output in JSON format
- `datadog` extends `json-logger` output
with [trace and span information](https://docs.datadoghq.com/tracing/connect_logs_and_traces/opentelemetry/) allowing
Datadog to connect logs and traces
- `traces` exports [tracing](https://lib.rs/crates/tracing) spans and events using the [opentelemetry-otlp](https://crates.io/crates/opentelemetry-otlp) exporter
- `rt-tokio-current-thread` configures the OpenTelemetry tracer to use Tokio’s current thread runtime
(e.g. `actix_web::main`). Without this feature, the Tokio multi-thread runtime is used by default.
## How to collect traces locally
If you are using the `tracing` feature in your project, the recommended way to view exported traces on your machine is to use the [Jaeger all-in-one Docker image](https://hub.docker.com/r/jaegertracing/opentelemetry-all-in-one/).
You need to add the following service to your Docker Compose setup (your main container should depend on it):
```yaml
jaeger:
image: jaegertracing/all-in-one:1.35
ports:
- 16686:16686
- 55681:55681
environment:
COLLECTOR_OTLP_ENABLED: true
COLLECTOR_OTLP_HTTP_HOST_PORT: 55681
```
You can then visit the [Jaeger web UI](http://localhost:16686/search) on your browser to search the traces.
## Usage examples
### Simple
```rust
use prima_tracing::{builder, configure_subscriber, init_subscriber, Environment};
use tracing::{info, info_span};
fn main() -> std::io::Result<()> {
let subscriber = configure_subscriber(
builder("simple")
.with_country(Country::Common)
.with_env(Environment::Dev)
.build()
);
let _guard = init_subscriber(subscriber);
let span = info_span!("MySpan");
let _guard = span.enter();
info!("Starting my awesome app");
Ok(())
}
```
### JSON output
It works like the simple example, but activating the `json-logger` automatically uses the JSON format as output
```rust
use prima_tracing::{builder, configure_subscriber, init_subscriber, Environment};
use tracing::{info, info_span};
fn main() -> std::io::Result<()> {
let subscriber = configure_subscriber(
builder("json")
.with_country(Country::Common)
.with_env(Environment::Dev)
.build()
);
let _guard = init_subscriber(subscriber);
let span = info_span!("MySpan");
let _guard = span.enter();
info!("Starting my awesome app");
Ok(())
}
```
### OpenTelemetry
You need to have an OpenTelemetry collector (such as Jaeger) running locally.
```rust
use prima_tracing::{builder, configure_subscriber, init_subscriber, Environment};
use tracing::{info, info_span};
fn main() -> std::io::Result<()> {
let subscriber = configure_subscriber(
builder("myapp")
.with_country(Country::Common)
.with_env(Environment::Dev)
.with_version("1.0".to_string())
.with_telemetry(
"http://localhost:55681".to_string(),
"myapp".to_string(),
)
.build(),
);
let _guard = init_subscriber(subscriber);
let span = info_span!("MySpan");
let _guard = span.enter();
info!("Starting my awesome app");
Ok(())
}
```
### Custom Subscriber
```rust
use prima_tracing::json;
use tracing::{info, info_span};
use tracing_log::LogTracer;
use tracing_subscriber::{layer::SubscriberExt, EnvFilter};
fn main() -> std::io::Result<()> {
let subscriber = tracing_subscriber::Registry::default()
.with(EnvFilter::from_default_env())
.with(json::storage::layer())
.with(json::formatter::layer("test".to_owned(), "dev".to_owned()));
LogTracer::init().expect("Failed to set logger");
tracing::subscriber::set_global_default(subscriber).expect("Setting default subscriber failed");
let span = info_span!("MySpan");
let _guard = span.enter();
info!("Starting my awesome app");
Ok(())
}
```
## Running examples
### Simple
```sh
RUST_LOG=info cargo run --example simple
```
### Complex (OpenTelemetry)
Run [Jaeger](https://www.jaegertracing.io) locally
```sh
docker run --rm -d -p 16686:16686 -p 55681:55681 -e COLLECTOR_OTLP_ENABLED=true -e COLLECTOR_OTLP_HTTP_HOST_PORT=55681 jaegertracing/all-in-one:1.35
```
Run pong service:
```sh
RUST_LOG=info cargo run --features=traces --example pong
```
Run ping service:
```sh
RUST_LOG=info cargo run --features=traces --example ping
```
Check health of ping service (which calls pong service)
```sh
curl http://localhost:8081/check
```
Open the browser at to inspect the traced request
#### OpenTelemetry + JSON logger with Datadog correlation IDs
```sh
RUST_LOG=info cargo run --features=datadog,traces --example datadog_json_logger
```
### Custom formatter
```sh
RUST_LOG=info cargo run --features=json-logger --example custom_formatter
```
### Custom subscriber with default JSON output
```sh
RUST_LOG=info cargo run --features=json-logger --example custom-subscriber
```
### Custom subscriber with custom JSON output
```sh
RUST_LOG=info cargo run --features=json-logger --example custom-json-subscriber
```