Services
Register each deployable as a service, get its DSN, and read per-service activity, exceptions and last seen times.
A service is one deployable inside a project: an API, a queue worker, a web front end. Each service has its own DSN, and everything that DSN sends is stored under that service. This page is for whoever sets up a project or rotates its keys.
Open it from Settings, then Services under Project, at /o/:org/projects/:project.
The services table
One row per live service, sorted by name.
| Column | What it shows |
|---|---|
| Service | Display name and a runtime badge, with the telemetry name underneath |
| Activity | Sparkline of events per bucket over the selected range |
| Events | Spans plus log records received in the selected range |
| Exceptions | Exception occurrences reported in the selected range |
| Last seen | When the service last sent a span in this environment |
| Key | uh_live_… with the last four characters of the active key, or Revoked |
Events, Exceptions and the sparkline follow the time range and environment in the top bar, see scope controls. Last seen ignores the range on purpose: it answers "when did this service last report here", so a service that went quiet a week ago still shows a date while you look at the last hour.
The list of services is the same in every environment. Only the numbers change.
The runtime badge reads telemetry.sdk.language and the SDK name from the resource of the service's latest entry spans in the past 7 days, for example Python · OpenTelemetry or Node.js · AdonisJS agent. A service that sent no spans in that time has no badge.
Add a service
New service asks for two fields.
- Name is the display name, up to 80 characters. You can rename it later from the row menu.
- Telemetry name matches the OpenTelemetry
service.name. It must start with a letter or digit, use only letters, digits,.,_and-, be at most 120 characters, and be unique among live services in the project. It cannot change later.
Creating the service issues a key and shows the DSN once:
UNHANDLED_DSN=https://[email protected]/0b4f6c2e-8a1d-4c3e-9f7a-1234567890abCopy it now. Afterwards only the last four characters are visible. The dialog also holds a stack picker: choose AdonisJS, a Node.js framework, Python, Go, Ruby, PHP, Java, .NET or any OpenTelemetry SDK, and it shows the install and config steps with the DSN already filled in. The Unhandled SDKs read it from UNHANDLED_DSN; OpenTelemetry SDKs get the endpoint and the three headers split out of it. See Install for your stack, or the browser SDK for websites.
One DSN, every environment
A DSN carries the API key and the service id. It does not carry the environment. Your SDK adds x-unhandled-env with production, staging or development, so you deploy the same DSN to all three and switch environments with the PRD, STG and DEV controls. A request with any other value is rejected with 400.
Identity comes from the key
Ingest resolves the service from the key and the x-unhandled-service-id header. It then overwrites service.name with the service's telemetry name. If an app sends service.name=shop-api with the key of the worker service, the data lands under worker. This keeps a misconfigured OTEL_SERVICE_NAME from scattering one service's data across names.
A key that exists but belongs to another service is refused with 403. A missing, unknown or revoked key is refused with 401.
Key and service actions
Every member can open Setup instructions from the row menu. It shows the same stack picker with the key hidden after its last four characters; admins also get a Rotate key button there. The other actions are for organization admins.
- Rename changes the display name. The telemetry name, DSN and stored data stay as they are.
- Rotate key revokes the current key and shows a new DSN once. Deploy the new DSN to every environment of the service right away. Postgres tells the ingest receiver about the revoked key, and it rejects the old key within seconds. If the receiver is not listening for changes, it rechecks cached keys every 60 seconds by default. While Postgres is down, it keeps accepting keys it already knows for up to 15 minutes by default.
- Revoke key revokes the key without issuing a new one. Telemetry sent with it is rejected until you rotate.
- Delete removes the service from every environment and revokes its key. Collected history is kept.
Answering "is the worker still reporting?"
- Pick the environment the worker runs in.
- Find its row and read Last seen. A date far in the past means it stopped sending.
- If Last seen is recent but Events is low, open Logs or Traces with only that service selected to see what it does send.
- If the key shows Revoked, rotate it and redeploy the new DSN.
Not available yet: services detected from telemetry without being registered, per-service origin restrictions for browser ingestion, and key last-used times. Every sender needs a registered service and its DSN.