Skip to content

About

Official PostHog Rust SDK

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

62 stars

Watchers

3 watching

Forks

Repository files navigation

PostHog Rust

Crates.io Documentation

The official Rust SDK for PostHog. See the main PostHog docs for more information.

SDK usage examples and code snippets live in the official documentation so they stay up to date.

Documentation

Request context

With the optional tower feature, tower::PostHogLayer reads X-PostHog-Distinct-Id and X-PostHog-Session-Id for Tower and Axum services. Header values are trimmed, stripped of control characters, and limited to 1000 characters. Missing or invalid values are omitted. No session ID is generated.

use axum::{routing::get, Router};
use posthog_rs::{tower::PostHogLayer, RequestContext};

let posthog = std::sync::Arc::new(posthog_rs::client("phc_project_key").await);
let app: Router = Router::new()
    .route("/work", get(move || {
        let posthog = posthog.clone();
        async move {
            let context = RequestContext::current().unwrap_or_default();
            posthog.capture(context.event("work_completed"));
            "ok"
        }
    }))
    .layer(PostHogLayer::new());

In an application handler, pass context.event("work_completed") to client.capture(...). It uses the context identity or the existing personless capture behavior when no identity exists. Existing events keep their explicit identity and properties. The context adds defaults, including $session_id, $request_method, and $request_path. Query strings are not captured.

Tracing headers are client-controlled analytics context. Never use them for authentication, authorization, or account lookup. Place an application-owned RequestContext in the request extensions before the PostHog layer runs to give that identity priority. After authentication in a handler, clone the current context, set .distinct_id(authenticated_id), and run the remaining work with .scope(async { ... }).await.

RequestContext::current() returns a snapshot inside a Tokio task scope. Captures, batches, immediate captures, and exceptions take their defaults before background delivery. client.evaluate_flags_with_context(&context, options) uses the context identity. An absent identity returns an empty flag result without a network request. Flag access events retain the context from evaluation, including when the result is read after the request ends.

Spawned tasks and streaming response bodies do not inherit context. Pass a context clone and use .scope(...) explicitly for work that must retain it. Request completion, errors, panics, and cancellation remove the scoped context. The middleware preserves application responses and errors and does not capture exceptions automatically.

Without Tower or an async client, construct RequestContext directly and use context.event(...), context.apply_to_event(&mut event), context.exception_options(options) with client.capture_exception_with(...), or client.evaluate_flags_with_context(&context, options). The exception helper requires error-tracking. Explicit event and exception values keep priority. Blocking applications use these explicit helpers; they have no ambient scope.

This integration adds analytics context to events. It does not add attributes to application-owned tracing or OpenTelemetry spans or install a trace provider.

Contributing

See CONTRIBUTING.md for local setup and test instructions.

Releasing

See RELEASING.md.

About

Official PostHog Rust SDK

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

62 stars

Watchers

3 watching

Forks

Releases

Packages

Used by

Contributors

Languages