Sending OpenTelemetry data

SnagSpy speaks OTLP over HTTP. If your application already emits OpenTelemetry, you change an endpoint and a header rather than adopting an SDK, and the same instrumentation keeps working if you later send it somewhere else.

The endpoints

Three OTLP routes accept data, on the ingest host rather than the dashboard API. They take the standard OTLP/HTTP payloads, so a collector exporter or a language SDK needs no adapter.

The split matters operationally: ingest is the only service on the write path, so it can be scaled, rate-limited and restarted without touching the dashboard.

OTLP/HTTP endpoints
POST https://ingest.snagspy.com/v1/traces
POST https://ingest.snagspy.com/v1/logs
POST https://ingest.snagspy.com/v1/metrics

Authentication is a DSN, not a session

Every ingest route authenticates with a project DSN. It is not a user session and it carries no dashboard permissions — a leaked DSN can write telemetry to one project and read nothing at all.

That is deliberate. An ingest key travels to every machine running your application, including a developer laptop and a CI runner, and a credential in that many places should be able to do as little as possible.

The header must be the standard `Authorization` header, scheme `Bearer`. It may carry the whole DSN or just the public key inside it — the part before the `@` — because ingest resolves the project from that key either way, so there is nothing to extract before you paste. Ingest reads that one header and nothing else; a custom header name is rejected exactly like a missing one, with no distinction between the two in the response.

Collector configuration
exporters:
  otlphttp:
    endpoint: https://ingest.snagspy.com
    headers:
      Authorization: Bearer ${SNAGSPY_DSN}

Running beside what you already have

Nothing here asks you to switch. A collector pipeline can name more than one exporter and sends every batch to each of them, so SnagSpy is added under its own name beside the exporter you already run. The destination you have today keeps receiving exactly what it received before.

That is the honest way to evaluate a second backend: both see the same traffic for as long as the comparison takes, and removing either one is the same one-line change as adding it. Put the same list on the `logs` and `metrics` pipelines to compare those signals too.

Two exporters on one pipeline
exporters:
  otlphttp/existing:
    endpoint: https://otlp.your-current-backend.example
  otlphttp/snagspy:
    endpoint: https://ingest.snagspy.com
    headers:
      Authorization: Bearer ${SNAGSPY_DSN}

service:
  pipelines:
    traces:
      receivers: [otlp]
      exporters: [otlphttp/existing, otlphttp/snagspy]

A span carrying an exception becomes an issue

This is the part that differs from a general-purpose OTLP backend. Traces are stored as traces, but a span carrying an exception is also grouped into an issue — the same unit the dashboard, alerting and root-cause analysis all work on.

So you do not instrument errors separately from traces. If your spans already record exceptions the way the OpenTelemetry specification describes, the errors arrive with them and are grouped without further configuration.

Rate limits, and what happens above an allowance

Ingest is rate-limited per minute, separately from your plan allowance. The default is 600 requests per minute for a project and 30,000 events per minute for an organisation. These are a stability control on the write path, not a billing device.

Your plan allowance behaves differently and the difference is worth being precise about: going over it does not stop your telemetry. Usage is metered, the overage is reported once per period, and the write path keeps accepting data. Dropping your errors at the moment you are most likely to be over — during an incident — is the most damaging thing an error monitor could do to you.

Defaults
INGEST_REQUESTS_PER_MINUTE = 600      # per project
INGEST_EVENTS_PER_MINUTE   = 30000    # per organisation

Leaving is the same amount of work as arriving

Because the ingest path is standard OTLP, moving to another vendor means changing the endpoint back. There is no proprietary wire format to unpick and no instrumentation to rewrite.

That is stated plainly because it is a reason to adopt this rather than a risk to hide. A vendor whose retention depends on how hard it is to leave has a reason not to fix the thing that made you consider leaving.

← Documentation