Observability And Tracing Workflow
Purpose
Add, refine, or diagnose observability in a server-side Swift service without confusing production signals with app behavior, deployment config, or low-level networking implementation.
The practical decision is what operators need to know from logs, metrics, traces, health checks, and diagnostics when a service is slow, failing, overloaded, misconfigured, or behaving correctly. Good instrumentation should make incidents easier to understand without leaking secrets or drowning normal operation in noise.
When To Use
- Use this skill when adding or changing Swift Logging, Swift Metrics, Swift Distributed Tracing, OpenTelemetry wiring, request IDs, trace propagation, log metadata, metric labels, spans, sampling, exporter configuration, or diagnostic health signals.
- Use this skill when diagnosing missing logs, noisy logs, missing spans, broken trace propagation, misleading metrics, high-cardinality labels, privacy leaks, request-correlation gaps, or unclear production failure evidence.
- Use this skill when deciding what a Vapor or Hummingbird service should log, measure, trace, or expose for operations.
- Use this skill when a deployment, Docker, or Fly.io task needs better runtime signals but not when the deployment config itself is the primary change.
- Do not use this skill for ordinary route, middleware, model, migration, Dockerfile, Fly.io, or SwiftNIO pipeline work unless observability behavior is the reason for the change.
- Do not add external telemetry vendors, collectors, exporters, dashboards, or alerting services unless the user asked for that integration or the repo already depends on it.
Source Check
Use repo-local Swift files, checked-out dependency sources, Dash MCP or Dash HTTP for installed Swift package DocC, and then official docs or source when Dash/local coverage is missing or stale. Check one of those source-specific paths before claiming observability behavior:
Use deployment, Docker, Fly.io, persistence, auth, or SwiftNIO docs when the signal depends on process lifecycle, health checks, database queries, credentials, channel pipelines, or runtime configuration.
Planning Workflow
- Inspect project shape:
Package.swift
- logging, metrics, tracing, OpenTelemetry, or exporter dependencies
- app startup and service lifecycle
- Vapor or Hummingbird middleware and request context
- SwiftNIO handlers or async tasks that already emit signals
- deployment config, log levels, health checks, and environment variables
- tests or snapshots for observable behavior
- Identify the operational question:
- Which request failed?
- Which dependency is slow or unavailable?
- Which worker, command, or route is overloaded?
- Which deploy, config, migration, or secret changed behavior?
- Which user-visible action needs correlation without exposing private data?
- Choose the smallest useful signal:
- log for discrete events and operator-readable context
- metric for aggregate counts, gauges, durations, and rates
- trace span for causal request or job flow across async boundaries
- health/readiness signal for deploy and routing decisions
- Keep signal names and labels stable.
- Keep high-cardinality data out of metric labels.
- Keep secrets and sensitive personal data out of logs, traces, metrics, and health responses.
- Add tests or manual checks that prove instrumentation is active when the repository has a reasonable way to do so.
Logging
Use Swift Logging as the default logging API for server-side Swift packages unless the repository has already chosen another facade.
When adding logs:
- choose a level that matches operator urgency
- include concrete context such as route, command, job, dependency, record type, config key, or operation name
- include correlation IDs, request IDs, trace IDs, or user-safe account identifiers when the service already has that shape
- make error messages human-readable and specific
- avoid logging secret values, tokens, passwords, cookie contents, authorization headers, raw connection strings, private keys, or sensitive payloads
Prefer structured metadata over string concatenation when the logger supports it. Use consistent field names for the same concept across the service.
Do not add noisy per-item logs inside hot loops, request bodies, event-loop reads, or high-volume background jobs unless the log is sampled, debug-only, or explicitly needed for a short diagnostic.
Metrics
Use Swift Metrics when the service needs aggregate numeric signals.
Prefer metrics for:
- request counts and durations by stable route or operation
- job counts, durations, failures, retries, and queue depth
- database or dependency latency
- cache hits and misses
- stream sizes, active connections, or back-pressure state
- deploy, startup, migration, and health-related counts
Keep metric labels low-cardinality. Use route templates, operation names, status classes, dependency names, queue names, and fixed outcome names. Do not use raw URLs, user IDs, emails, UUIDs, tokens, request bodies, error messages, or unbounded exception strings as labels.
Tracing
Use Swift Distributed Tracing or the repository's existing tracing package when causal request flow matters.
Prefer traces for:
- request lifecycle across middleware, handlers, database calls, HTTP clients, jobs, and streaming boundaries
- propagation between services
- diagnosing latency distribution across nested operations
- connecting logs to a request, job, span, or trace ID
Keep span names stable and operation-oriented. Attach only metadata that is safe, bounded, and useful for diagnosis.
When using OpenTelemetry, distinguish:
- API-only instrumentation in libraries
- SDK/exporter setup in applications
- collector, backend, sampling, and dashboard work as deployment or operations scope
Do not add an exporter or vendor SDK just because spans are added. First check whether the application already owns telemetry export.
Vapor And Hummingbird Integration
For Vapor:
- use Vapor's logging and tracing docs for framework-owned behavior
- prefer middleware for request-wide correlation, metadata, spans, and timing
- keep route-specific logs close to the route, controller, service, or command that owns the behavior
- do not leak auth headers, session cookies, request bodies, or secrets into request logs
For Hummingbird:
- inspect the app's
Application, Router, middleware, and request context shape
- use middleware for request-wide correlation, timing, and propagation
- put per-request context values in request context only when middleware or handlers truly need them
- preserve the framework's existing logger and lifecycle conventions
Use swiftnio-workflow when instrumentation crosses into channel handlers, low-level protocol flow, event-loop latency, or back-pressure.
Health And Readiness Signals
Health signals are operational contracts.
Use liveness for "process is alive" and readiness for "service can safely receive traffic." Readiness can include dependency checks only when the deployment target expects that behavior and the check will not overload dependencies.
Do not expose internal stack traces, secret names with values, database URLs, token details, or private infrastructure addresses in health responses.
Use deployment-specific workflows for wiring health checks into Docker, Fly.io, CI, load balancers, or process managers.
Testing And Validation
Choose the smallest validation that proves the signal:
- unit test for log metadata, metric labels, span naming, or redaction helpers
- middleware or route test for request IDs, propagation, and response headers
- integration test for exporter or collector behavior only when the repo already has that surface
- local run plus logs or metrics scrape only when runtime behavior matters
- deployment logs or health-check output only when the task is operational
When diagnosis fails, report the exact logger, metric, label, span, propagation header, exporter, route, job, command, environment variable, or deployment surface involved.
Handoffs
Use vapor-server-workflow or hummingbird-server-workflow for route, middleware, command, request context, or framework lifecycle changes that are not primarily instrumentation.
Use swiftnio-workflow for event-loop, channel, pipeline, back-pressure, or protocol-level instrumentation.
Use auth-authorization-workflow when the question is whether auth context is safe to log, trace, or use as an authorization signal.
Use docker-workflow or fly-io-deployment-workflow when the work is about how logs, health checks, ports, or runtime environment reach a container or hosted platform.
Output Shape
Return:
Signal shape: loggers, metrics, spans, health routes, middleware, request context, exporters, and configuration.
Docs used: Swift Logging, Metrics, Distributed Tracing, OpenTelemetry, Vapor, Hummingbird, deployment, or SwiftNIO docs consulted.
Behavior: what is logged, counted, timed, traced, propagated, redacted, sampled, or exposed.
Command path: exact build, test, run, scrape, log, or deploy commands run or recommended.
Validation: tests, log output, metric scrape, spans, health result, or deployment evidence.
Handoffs: framework, auth, NIO, persistence, Docker, Fly.io, deployment, or operations follow-up when the task crosses this skill's boundary.
Guardrails
- Do not log secrets, tokens, authorization headers, cookies, connection strings, private keys, passwords, or sensitive request bodies.
- Do not use high-cardinality values as metric labels.
- Do not add telemetry exporters, vendors, collectors, dashboards, or alerting stacks without explicit scope or existing repo precedent.
- Do not claim observability package behavior from memory when current official docs or source can be checked.
- Do not treat a health endpoint as proof of route correctness unless the route itself was tested.
1---2name: observability-tracing-workflow3description: Plan, implement, test, and diagnose observability for server-side Swift services, including Swift Logging, Swift Metrics, Swift Distributed Tracing, OpenTelemetry handoffs, request correlation, trace propagation, structured log fields, metric naming, health signals, privacy-safe diagnostics, and Vapor or Hummingbird integration.4license: Apache-2.05---67# Observability And Tracing Workflow89## Purpose1011Add, refine, or diagnose observability in a server-side Swift service without confusing production signals with app behavior, deployment config, or low-level networking implementation.1213The practical decision is what operators need to know from logs, metrics, traces, health checks, and diagnostics when a service is slow, failing, overloaded, misconfigured, or behaving correctly. Good instrumentation should make incidents easier to understand without leaking secrets or drowning normal operation in noise.1415## When To Use1617- Use this skill when adding or changing Swift Logging, Swift Metrics, Swift Distributed Tracing, OpenTelemetry wiring, request IDs, trace propagation, log metadata, metric labels, spans, sampling, exporter configuration, or diagnostic health signals.18- Use this skill when diagnosing missing logs, noisy logs, missing spans, broken trace propagation, misleading metrics, high-cardinality labels, privacy leaks, request-correlation gaps, or unclear production failure evidence.19- Use this skill when deciding what a Vapor or Hummingbird service should log, measure, trace, or expose for operations.20- Use this skill when a deployment, Docker, or Fly.io task needs better runtime signals but not when the deployment config itself is the primary change.21- Do not use this skill for ordinary route, middleware, model, migration, Dockerfile, Fly.io, or SwiftNIO pipeline work unless observability behavior is the reason for the change.22- Do not add external telemetry vendors, collectors, exporters, dashboards, or alerting services unless the user asked for that integration or the repo already depends on it.2324## Source Check2526Use repo-local Swift files, checked-out dependency sources, Dash MCP or Dash HTTP for installed Swift package DocC, and then official docs or source when Dash/local coverage is missing or stale. Check one of those source-specific paths before claiming observability behavior:2728- [Swift Logging](https://github.com/apple/swift-log)29- [Swift Metrics](https://github.com/apple/swift-metrics)30- [Swift Distributed Tracing](https://github.com/apple/swift-distributed-tracing)31- [OpenTelemetry Swift](https://github.com/open-telemetry/opentelemetry-swift)32- [OpenTelemetry Swift documentation](https://opentelemetry.io/docs/languages/swift/)33- [Vapor logging](https://docs.vapor.codes/basics/logging/)34- [Vapor tracing](https://docs.vapor.codes/advanced/tracing/)35- [Hummingbird documentation](https://docs.hummingbird.codes/)36- [Hummingbird ecosystem](https://hummingbird.codes/ecosystem/)3738Use deployment, Docker, Fly.io, persistence, auth, or SwiftNIO docs when the signal depends on process lifecycle, health checks, database queries, credentials, channel pipelines, or runtime configuration.3940## Planning Workflow41421. Inspect project shape:43 - `Package.swift`44 - logging, metrics, tracing, OpenTelemetry, or exporter dependencies45 - app startup and service lifecycle46 - Vapor or Hummingbird middleware and request context47 - SwiftNIO handlers or async tasks that already emit signals48 - deployment config, log levels, health checks, and environment variables49 - tests or snapshots for observable behavior502. Identify the operational question:51 - Which request failed?52 - Which dependency is slow or unavailable?53 - Which worker, command, or route is overloaded?54 - Which deploy, config, migration, or secret changed behavior?55 - Which user-visible action needs correlation without exposing private data?563. Choose the smallest useful signal:57 - log for discrete events and operator-readable context58 - metric for aggregate counts, gauges, durations, and rates59 - trace span for causal request or job flow across async boundaries60 - health/readiness signal for deploy and routing decisions614. Keep signal names and labels stable.625. Keep high-cardinality data out of metric labels.636. Keep secrets and sensitive personal data out of logs, traces, metrics, and health responses.647. Add tests or manual checks that prove instrumentation is active when the repository has a reasonable way to do so.6566## Logging6768Use Swift Logging as the default logging API for server-side Swift packages unless the repository has already chosen another facade.6970When adding logs:7172- choose a level that matches operator urgency73- include concrete context such as route, command, job, dependency, record type, config key, or operation name74- include correlation IDs, request IDs, trace IDs, or user-safe account identifiers when the service already has that shape75- make error messages human-readable and specific76- avoid logging secret values, tokens, passwords, cookie contents, authorization headers, raw connection strings, private keys, or sensitive payloads7778Prefer structured metadata over string concatenation when the logger supports it. Use consistent field names for the same concept across the service.7980Do not add noisy per-item logs inside hot loops, request bodies, event-loop reads, or high-volume background jobs unless the log is sampled, debug-only, or explicitly needed for a short diagnostic.8182## Metrics8384Use Swift Metrics when the service needs aggregate numeric signals.8586Prefer metrics for:8788- request counts and durations by stable route or operation89- job counts, durations, failures, retries, and queue depth90- database or dependency latency91- cache hits and misses92- stream sizes, active connections, or back-pressure state93- deploy, startup, migration, and health-related counts9495Keep metric labels low-cardinality. Use route templates, operation names, status classes, dependency names, queue names, and fixed outcome names. Do not use raw URLs, user IDs, emails, UUIDs, tokens, request bodies, error messages, or unbounded exception strings as labels.9697## Tracing9899Use Swift Distributed Tracing or the repository's existing tracing package when causal request flow matters.100101Prefer traces for:102103- request lifecycle across middleware, handlers, database calls, HTTP clients, jobs, and streaming boundaries104- propagation between services105- diagnosing latency distribution across nested operations106- connecting logs to a request, job, span, or trace ID107108Keep span names stable and operation-oriented. Attach only metadata that is safe, bounded, and useful for diagnosis.109110When using OpenTelemetry, distinguish:111112- API-only instrumentation in libraries113- SDK/exporter setup in applications114- collector, backend, sampling, and dashboard work as deployment or operations scope115116Do not add an exporter or vendor SDK just because spans are added. First check whether the application already owns telemetry export.117118## Vapor And Hummingbird Integration119120For Vapor:121122- use Vapor's logging and tracing docs for framework-owned behavior123- prefer middleware for request-wide correlation, metadata, spans, and timing124- keep route-specific logs close to the route, controller, service, or command that owns the behavior125- do not leak auth headers, session cookies, request bodies, or secrets into request logs126127For Hummingbird:128129- inspect the app's `Application`, `Router`, middleware, and request context shape130- use middleware for request-wide correlation, timing, and propagation131- put per-request context values in request context only when middleware or handlers truly need them132- preserve the framework's existing logger and lifecycle conventions133134Use `swiftnio-workflow` when instrumentation crosses into channel handlers, low-level protocol flow, event-loop latency, or back-pressure.135136## Health And Readiness Signals137138Health signals are operational contracts.139140Use liveness for "process is alive" and readiness for "service can safely receive traffic." Readiness can include dependency checks only when the deployment target expects that behavior and the check will not overload dependencies.141142Do not expose internal stack traces, secret names with values, database URLs, token details, or private infrastructure addresses in health responses.143144Use deployment-specific workflows for wiring health checks into Docker, Fly.io, CI, load balancers, or process managers.145146## Testing And Validation147148Choose the smallest validation that proves the signal:149150- unit test for log metadata, metric labels, span naming, or redaction helpers151- middleware or route test for request IDs, propagation, and response headers152- integration test for exporter or collector behavior only when the repo already has that surface153- local run plus logs or metrics scrape only when runtime behavior matters154- deployment logs or health-check output only when the task is operational155156When diagnosis fails, report the exact logger, metric, label, span, propagation header, exporter, route, job, command, environment variable, or deployment surface involved.157158## Handoffs159160Use `vapor-server-workflow` or `hummingbird-server-workflow` for route, middleware, command, request context, or framework lifecycle changes that are not primarily instrumentation.161162Use `swiftnio-workflow` for event-loop, channel, pipeline, back-pressure, or protocol-level instrumentation.163164Use `auth-authorization-workflow` when the question is whether auth context is safe to log, trace, or use as an authorization signal.165166Use `docker-workflow` or `fly-io-deployment-workflow` when the work is about how logs, health checks, ports, or runtime environment reach a container or hosted platform.167168## Output Shape169170Return:1711721. `Signal shape`: loggers, metrics, spans, health routes, middleware, request context, exporters, and configuration.1732. `Docs used`: Swift Logging, Metrics, Distributed Tracing, OpenTelemetry, Vapor, Hummingbird, deployment, or SwiftNIO docs consulted.1743. `Behavior`: what is logged, counted, timed, traced, propagated, redacted, sampled, or exposed.1754. `Command path`: exact build, test, run, scrape, log, or deploy commands run or recommended.1765. `Validation`: tests, log output, metric scrape, spans, health result, or deployment evidence.1776. `Handoffs`: framework, auth, NIO, persistence, Docker, Fly.io, deployment, or operations follow-up when the task crosses this skill's boundary.178179## Guardrails180181- Do not log secrets, tokens, authorization headers, cookies, connection strings, private keys, passwords, or sensitive request bodies.182- Do not use high-cardinality values as metric labels.183- Do not add telemetry exporters, vendors, collectors, dashboards, or alerting stacks without explicit scope or existing repo precedent.184- Do not claim observability package behavior from memory when current official docs or source can be checked.185- Do not treat a health endpoint as proof of route correctness unless the route itself was tested.