6 releases (breaking)

Uses new Rust 2021

0.5.0 Jul 5, 2022
0.4.1 Jul 4, 2022
0.4.0 Jun 9, 2022
0.3.1 Mar 17, 2022
0.1.1 Dec 3, 2021

#154 in Debugging

Download history 202/week @ 2022-08-18 185/week @ 2022-08-25 159/week @ 2022-09-01 264/week @ 2022-09-08 270/week @ 2022-09-15 223/week @ 2022-09-22 195/week @ 2022-09-29 230/week @ 2022-10-06 212/week @ 2022-10-13 370/week @ 2022-10-20 176/week @ 2022-10-27 244/week @ 2022-11-03 209/week @ 2022-11-10 276/week @ 2022-11-17 247/week @ 2022-11-24 265/week @ 2022-12-01

1,043 downloads per month

MIT/Apache

33KB
657 lines

prima_tracing.rs

Utilities for configuring a tracing subscriber with support for logging and opentelemetry.

Installation

Install from crates.io

prima-tracing = "0.5.*"

Cargo features

  • prima-logger-json outputs traces to standard output in JSON format
  • prima-logger-datadog extends prima-logger-json output with trace and span information allowing Datadog to connect logs and traces
  • prima-telemetry exports OpenTelemetry traces using the 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 OpenTelemetry traces locally

If you are using the prima-telemetry feature in your project, the recommended way to view exported traces on your machine is to use the Jaeger all-in-one Docker image.

You need to add the following service to your Docker Compose setup (your main container should depend on it):

  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 on your browser to search the traces.

Usage examples

Simple

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_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 prima-json-logger automatically uses the JSON format as output

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_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.

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_env(Environment::Dev)
            .with_version("1.0".to_string())
            .with_telemetry(
                "http://localhost:55681/v1/traces".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

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

RUST_LOG=info cargo run --example simple

Complex (OpenTelemetry)

Run Jaeger locally

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:

RUST_LOG=info cargo run --features=prima-telemetry --example pong

Run ping service:

RUST_LOG=info cargo run --features=prima-telemetry --example ping

Check health of ping service (which calls pong service)

curl http://localhost:8081/check

Open the browser at http://localhost:16686 to inspect the traced request

OpenTelemetry + JSON logger with Datadog correlation IDs

RUST_LOG=info cargo run --features=prima-logger-datadog,prima-telemetry --example datadog_json_logger

Custom formatter

RUST_LOG=info cargo run --features=prima-logger-json --example custom_formatter

Custom subscriber with default JSON output

RUST_LOG=info cargo run --features=prima-logger-json --example custom-subscriber

Custom subscriber with custom JSON output

RUST_LOG=info cargo run --features=prima-logger-json --example custom-json-subscriber

Dependencies

~5–14MB
~267K SLoC