Skip to content

Service catalog

Every service that sends logs, traces or metrics to a project, discovered automatically, with its environments, versions, request stats, operations and dependencies.

Updated View as Markdown

The service catalog lists every service that sends telemetry to a project. Nothing needs to be set up: a service appears a few minutes after its first logs, traces or metrics arrive, across every environment of the project, and it leaves once all its data has aged out. The catalog is read-only. Services can’t be created, edited or deleted by hand.

Each service has an ID, an svc_ slug and a resource name like any other resource. Its request rate, error rate and latency come from the span metrics Observability generates from its traces, and its callers and callees come from the service map.

The Services list: each service's application, environments, requests per second, error rate, p95 latency, trend and when it was last seen.The Services list: each service's application, environments, requests per second, error rate, p95 latency, trend and when it was last seen.

How services are named

A service is identified by its key, built from two resource attributes:

Resource attributes Key
service.name=checkout checkout
service.name=api, service.namespace=payments payments/api
No service.name unknown_service, or <namespace>/unknown_service with a namespace
  • The key is the same value as the job label of the service’s metrics and the service label of its span metrics, so one name works in the catalog, in PromQL and in Grafana.
  • One key is one service in the whole project. The same key sent to production and staging is one service seen in two environments.
  • Keys are kept exactly as sent: they’re case-sensitive, and spaces aren’t trimmed. Checkout and checkout are two services. (Environment and application names, by contrast, are lowercased.)
  • OpenTelemetry SDKs send unknown_service:<process name> when service.name isn’t set. That’s cataloged as sent. A resource with no service.name at all is cataloged as unknown_service, which the console shows as Not set (payments/unknown_service with a namespace, shown as sent).
  • The key’s parts are split at its last /, so avoid / in service.name itself.
  • Keys starting with ezgh. are reserved for series Observability generates (such as ezgh.servicegraph). Data sent with such a key is stored, but the service isn’t cataloged.
  • A key longer than 255 bytes, or one with control characters, isn’t cataloged either, and its spans generate no span metrics. Its data is still stored.

Set service.namespace

Use service.namespace to group the services of one team or system, and to keep two services with the same service.name apart:

OTEL_RESOURCE_ATTRIBUTES="service.name=api,service.namespace=payments,ezgh.metadata.application=storefront,ezgh.metadata.environment=production"

Changing a service’s service.name or service.namespace makes it a new service. The old one stays in the catalog, marked inactive after 7 days, until its data ages out.

What the catalog shows

Everything about a service comes from its telemetry:

Field From
Environments The datasets it sent data to, with the signals (logs, traces, metrics) and when each was first and last seen
Applications The ezgh.metadata.application values it sent; unknown isn’t listed
Latest version Per environment, the most recently seen service.version
Versions Per environment, every service.version with when it was first and last seen; the newest 100 are kept
Languages telemetry.sdk.language, such as java or python
First seen, last seen Its first and latest data, on any signal and in any environment
Active Whether it sent anything in the last 7 days

A version or language longer than 128 bytes isn’t kept.

Discovery takes a few minutes: a new service, a new environment or a new version shows up about 2 to 4 minutes after its data arrives, and last-seen times are just as far behind. Request stats come from span metrics, which follow the spans by about a minute.

Services that last sent data before the service catalog was available aren’t listed, and a service’s first-seen time is never earlier than that.

In the console

Open Observability > Services.

  • The list shows each active service’s application, environments, requests per second, error rate and p95 latency over the time range, a trend, and when it was last seen, with a mark for each signal it sends. Filter by environment (or all of them) and application, find services by name, turn on Group by application, and turn on Show inactive to include services not seen for 7 days. The filters are in the URL, so a filtered list can be shared.
  • A service’s page has its key, ID, resource name, applications, languages, environments, latest version, and first and last seen, with View logs and View traces for its data. Pick an environment (the most recently seen one by default) or All environments, then a tab. Log volume and versions need one environment.
Tab Shows
Overview Requests per second, error rate and p50, p95 and p99 latency over time, with new versions marked; log volume by severity; View error traces
Operations Each span name and kind with its requests, errors and latency, ranked by its share of the time spent in the service. A row opens its traces.
Dependencies Called by and Calls: the services, databases, queues, external hosts and users it talks to, with each one’s requests, errors and p95
Versions The versions it reported in the environment, newest first
Metrics The metric names with job equal to its key: those it sends and its span metrics (marked Span metrics), each opening in Metrics
A service's Overview tab: its key, ID, resource name, applications, languages, environments and versions, then charts of requests, error rate and latency percentiles, and its log volume.A service's Overview tab: its key, ID, resource name, applications, languages, environments and versions, then charts of requests, error rate and latency percentiles, and its log volume.
  • Requests are spans of kind server and consumer: the requests and messages a service receives. A service with none, such as a worker or a scheduled job, shows No inbound requests; its Operations tab covers every span kind.
  • A service that sends no traces in the environment shows No traces: it’s listed from its logs and metrics, without request stats.
  • The stats are PromQL queries over span metrics and need obs.metrics.query. Without it, the list and pages say so once and still show the services.

Service map opens the service map for the same environment and time range.

From the CLI and the API

ezgh obs services list --project web
ezgh obs services list --environment production --stats --from 6h --project web
ezgh obs services get payments/api --project web
ezgh obs services versions payments/api --environment production --project web
ezgh obs services deps payments/api --environment production --from 24h --project web

get, versions and deps take a service’s exact key, its ID or its svc_ slug. list shows active services; --active all includes inactive ones and --active false shows only those. --stats adds requests per second, error rate and p95 latency over --from and --to. deps lists what calls the service and what it calls, from the service map. -o json prints the API’s answer. See ezgh obs services.

The services are under the project’s Observability API:

Operation Request
ListServices GET /v1/organizations/<organization ID>/projects/<project ID>/obs/services
GetService GET …/obs/services/<service ID>
ListServiceVersions GET …/obs/services/<service ID>/versions?environment=production
  • ListServices returns { "services": […], "nextCursor": …, "capReached": … }, ordered by key. Filters: q (part of the key or name, ignoring case), key (an exact key), environment, application and active (true, the default; false; or all). limit is 1 to 100 (default 20), and cursor takes nextCursor for the next page.
  • capReached is true when the project has reached its services quota.
  • A service has the common resource fields (id, slug, name, resourceName, organizationId, projectId, region, status, createdAt, updatedAt), plus key, serviceName, serviceNamespace (null without a namespace), active, firstSeenAt, lastSeenAt, applications, languages and environments. Each environment is { "environment", "datasetId", "latestVersion", "signals" }, where signals has a { "firstSeenAt", "lastSeenAt" } for each of logs, traces and metrics the service sent there.
  • GetService takes the service’s ID. To find a service by key, list with key.
  • ListServiceVersions requires environment and returns { "versions": [{ "version", "firstSeenAt", "lastSeenAt" }], "nextCursor" }, newest first.
  • An ID that isn’t one of the project’s services is 404. Viewing a service without obs.services.get on it is 403.

Request stats and dependencies are PromQL over span metrics, through the project’s Prometheus API; see Span metrics for the queries.

When services are removed

There’s no way to delete a service. It’s removed automatically once none of its data is left:

  • Each environment and signal it was seen on expires when the dataset’s retention for that signal has passed since it was last seen there. Traces count the dataset’s metrics retention too when it’s longer, because the span metrics generated from them are kept that long (13 months by default).
  • Once a day, services with nothing left are removed, together with their versions.
  • When a dataset is deleted, the service’s environment is removed with it, and a service seen only in that dataset is removed.

Until then, a service not seen for 7 days is inactive and hidden from the default list. Removing a service gives back its place in the quota.

Limits

Quota ID Name Scope Default Adjustable
obs.services.perProject Services per project Project 1,000 Yes, up to 5,000

When a project has reached its quota, new service keys aren’t cataloged: their data is still stored and their span metrics are still generated, but they aren’t listed. The list says so (capReached in the API), and the console links to the quota. A key that wasn’t cataloged is added the next time it sends data while the project is under its quota. ezgh quotas get obs.services.perProject --scope-key <project> shows the limit and usage; see Service quotas.

Access

Action Allows
obs.services.list Listing a project’s services
obs.services.get Viewing a service and its versions

ObsFullAccess, ObsReadOnlyAccess and ReadOnlyAccess include both. Request stats, operations, dependencies and the service map read span metrics, which needs obs.metrics.query on the environment’s dataset; the same three policies include it.

Trails

When the catalog adds a service, Trails records a CreateService event with eventSource obs.ezghcloud.com and additionalEventData { "autoCreated": true }. Its userIdentity is the ingest key that first sent the service’s data (type IngestKey, with the key’s ID). When that key is no longer known, the event is a ServiceEvent by obs.ezghcloud.com instead. A service that’s already cataloged, or that the quota keeps out, records nothing.

Listing and viewing services aren’t recorded, and neither are the stats. Removing services when their data ages out or their dataset is deleted isn’t recorded.

Navigation

Type to search…

↑↓ navigate↵ selectEsc close