rtb-telemetry 0.7.5

Opt-in anonymous usage telemetry with pluggable sinks. Part of the phpboyscout Rust toolkit.
Documentation
---
title: Send events to an HTTPS endpoint
description: Configure HttpSink, authenticate it, reuse your own client, and understand what one POST per event costs.
---

# Send events to an HTTPS endpoint

`HttpSink` POSTs each event as JSON to a URL you choose. It needs the
`remote-sinks` feature.

```toml
[dependencies]
rtb-telemetry = { version = "0.7", features = ["remote-sinks"] }
```

## Configure and build it

```rust
use std::sync::Arc;
use std::time::Duration;
use rtb_telemetry::{HttpSink, HttpSinkConfig};
use secrecy::SecretString;

let config = HttpSinkConfig {
    endpoint: "https://telemetry.example.com/v1/events".parse()?,
    bearer_token: Some(SecretString::from(token)),
    timeout: Duration::from_secs(5),
    user_agent: format!("{}/{}", env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION")),
    allow_insecure_endpoint: false,
};

let sink = Arc::new(HttpSink::new(config)?);
```

`HttpSinkConfig::default()` exists, but its endpoint is the placeholder
`https://telemetry.invalid/`, so always override it. Every field's default is
listed in [Sinks](../reference/sinks.md#httpsinkconfig-fields).

## Authenticate

Set `bearer_token` and the sink sends
`Authorization: Bearer <token>`. Hold it as a `SecretString`. That is the
type the field takes, and it keeps the value out of `Debug` output and
zeroes it on drop.

If your endpoint needs a different scheme or a custom header, `HttpSink`
cannot do it. Wrap your own [custom sink](write-a-custom-sink.md) around
`reqwest` instead.

## Reuse a client you already have

```rust
let sink = HttpSink::with_client(config, my_client);
```

The injected client's own timeout and user agent win; the `timeout` and
`user_agent` fields in the config are ignored. `with_client` cannot fail,
so an endpoint-scheme problem surfaces from the first `emit` rather than
from the constructor.

## What happens with a plain-http endpoint

It is refused:

```text
HTTP telemetry sink error: endpoint scheme "http" not permitted (set allow_insecure_endpoint for tests)
```

`allow_insecure_endpoint: true` lifts that, and exists for pointing tests
at a local mock server. Shipping it enabled sends usage data, and any
bearer token, in clear text.

## Know what one POST per event costs

`emit` sends one request and awaits it. There is no batching, no queue and
no retry: a slow endpoint slows the command that recorded the event, up to
`timeout`, and a failed POST loses that event.

If the endpoint is remote and the tool is interactive, consider recording
to a [file](write-events-to-a-file.md) and shipping it separately, or
buffering in a [custom sink](write-a-custom-sink.md).

## Handle the failures

Every failure is `TelemetryError::Http`: a refused scheme, a transport
error (`error sending request for url (…)`), or a non-2xx response
(`non-2xx response: 404 Not Found`). Log and continue: a telemetry POST
failing is not a reason to fail the user's command.

## What the endpoint receives

The redacted event, plus a top-level `severity` of `"ERROR"` when
`err_msg` is set and `"INFO"` otherwise:

```json
{"name":"cmd.run","tool":"mytool","tool_version":"1.0.0","machine_id":"…","timestamp_utc":"…","attrs":{},"severity":"INFO"}
```