Services: requests, errors and latency per app
Services (/telemetry/services, a tab of Telemetry) lists every service that sent requests in the range, from the traces your apps send with the Shield360 SDK or any OpenTelemetry exporter:
| Column | What it shows |
|---|---|
| Service | The app’s service.name, its environment, and how many requests it served |
| Per second | Requests per second over the range |
| Error rate | The share of requests that failed (red above 5%, amber above 1%) |
| p50 / p95 / p99 | How long half, 95% and 99% of requests took |
| Apdex | The share of requests answered within 500 ms, with those under 2 s counted as half (green from 0.94, amber from 0.85) |
| Last seen | When the service last served a request |
A request is a server span, or a root span, so a worker’s jobs count even with no incoming HTTP. Sort by any column, search by name or environment, and pick a range from 15 minutes to 24 hours. Select a service to open its app’s Performance tab.
Service map
Section titled “Service map”Select Map above the list to see who calls whom, over the last 15 minutes, hour or six hours:
- Services, left to right in the order they call each other, each with requests per second, error rate and p95 latency. The border is green, amber above 1% errors and red above 5%.
- Databases (rounded) and other hosts (dashed) the services call, on the right.
- Calls as arrows, thicker the busier, labeled with calls per second and their error rate, red when more than 5% fail.
Select a service to light its calls and the services next to it, and follow Open to its app’s Performance tab. Table lists every call with its rate, errors and p95. A call is drawn when a span of one service has a parent in another service (the SDKs carry the trace across HTTP and gRPC calls), and when a service’s client span reaches a database or a host that is not one of your services.
Services without an SDK
Section titled “Services without an SDK”With the Shield360 controller on a host or Kubernetes node, turn on Service map from host connections in the controller’s Discovery settings (or start it with SHIELD360_SERVICE_MAP=true). Every 15 seconds the controller reads the kernel’s socket tables, in each container’s own network namespace, and reports every service that listens or connects, and who connects to whom. These connections are added to the same map:
- An arrow both traces and host connections saw is drawn as usual and says Seen by: Traces and host connections in the table.
- An arrow only the host saw is dashed and labeled with the most connections open at once, not requests: the controller samples sockets and reads no payloads.
- A service only the host saw says Host only · no SDK. Select it for Set up the SDK, which opens the setup guide for its runtime (Node.js, Python, Java, .NET or Go), so its requests, errors and latency show too.
- A connection to a database port (PostgreSQL, MySQL, Redis, MongoDB, ClickHouse and others) goes to the database node traces name the same way. One to a private address no service listens on shows as that address. Internet destinations are kept as their port only (Internet :443): the address itself is never stored.
Request metrics without an SDK
Section titled “Request metrics without an SDK”Turn on Trace services without an SDK (eBPF) as well (or SHIELD360_EBPF_APM=true), and the controller points OBI (OpenTelemetry eBPF Instrumentation) at every service the map finds that listens and sends no telemetry of its own: not databases, message brokers or other infrastructure servers, at most 64 per host. Their HTTP and gRPC requests show in this list with requests per second, errors, p50/p95/p99 and Apdex, under the name the map uses, marked eBPF. Upgrade to SDK opens the setup guide for the runtime OBI saw. OBI reads request metadata (method, route, status, timing), never bodies; a service that starts sending its own telemetry is left to its SDK.
What is sent: service names, workload identity (namespace, deployment, pod, container), the executable’s name (no arguments), the ports a service listens on, and connection counts per destination. Connections that open and close between two samples are not seen. The data is kept 30 days.
An app’s Performance tab
Section titled “An app’s Performance tab”An application’s page (Protect > Agents & access > Applications & agents, then the app) has a Performance tab, with a range from 15 minutes to 7 days:
- Requests, Latency (p50, p95 and p99) and Errors over time. Table shows each chart’s numbers as a list.
- Operations: the app’s routes and jobs (
GET /orders/{id},sync-catalog), with requests per second, error rate, latency, Apdex and their share of the app’s time, the costliest first. - Database calls: each database system and statement (
postgresql,SELECT orders) with calls, errors, latency and share of time. - External calls: each host or service the app calls (
api.stripe.com), with the same numbers. - Latency distribution: the app’s requests by how long they took, in log-spaced buckets (10 ms, 16 ms, 25 ms, …), failed ones in red. It shows a slow tail or two groups of requests that p50 and p95 alone hide.
- Errors: failed spans grouped by operation, exception type and message (
TimeoutError: upstream timed outonGET /orders), with how many, when last, and a link to the latest trace. Any span with an error status counts here, not only requests. - Deploys: each
service.versionfirst seen during the range, marked with a dashed line on the Requests, Latency and Errors charts, so a slowdown or error spike lines up with the release that caused it. Setservice.version(orSHIELD360_SERVICE_VERSION) in the SDK to get them; a version already running when the range starts is not a deploy.
The SDKs trace requests, database and cache calls and outgoing HTTP with no code change: see Zero-code setup. Statements are shown without their values.
Both views need View telemetry. They read the project’s own trace data for the environment you are in.
An app’s Flags tab
Section titled “An app’s Flags tab”The app’s page also has a Flags tab: the feature flags the app evaluated in the last hour, 24 hours or 7 days. The Shield360 SDKs record the variation they served on the span that was active when the flag was evaluated (shield360.flag.<key>). Flags evaluated another way are read too, from the OpenTelemetry feature flag conventions: a feature_flag.evaluation (or older feature_flag) span event, or feature_flag.* span attributes, with feature_flag.key and feature_flag.result.variant (or the older feature_flag.variant, or the value when there is no variant name). OpenFeature’s OpenTelemetry tracing hook records these. A span that reports the same flag more than one way is counted once. For each variation you see how many spans carried it, its share, its throughput per minute over the range, and the error rate and p95 of those spans.
Each flag shows whether it is On, Off or Archived, or Not defined here when the app evaluates a flag Shield360 does not manage. Flags defined for this app that it has not evaluated yet are listed after the evaluated ones. Compare variants opens the Feature flags comparison, which reads whole traces and tests whether a difference is significant. Open in Feature flags opens the Feature flags page searched to that flag.
The tab needs View telemetry. Flag state needs permission to view feature flags; without it the tab shows evaluations only.