// DevOps

Observability for Small Teams: Logs, Metrics and Traces Without the Noise

How to know what your system is doing in production: the three signals, what to measure first, how to write alerts people act on, and a stack a small team can run.

Observability for Small Teams: Logs, Metrics and Traces Without the Noise

When something breaks in production, there are two questions: is it broken, and why? Monitoring answers the first. Observability is the ability to answer the second without shipping new code just to find out. For a small team the goal is not an enormous toolchain, it is enough signal to find problems quickly and few enough alerts that people still read them.

The three signals

Logs are timestamped records of events. They tell you what happened in detail.

Metrics are numbers over time: requests per second, error rate, CPU, queue length. They tell you how the system is behaving and are cheap to store and chart.

Traces follow a single request across services and show where the time went. They are the quickest way to find the slow step in a chain of calls.

Each signal answers a different question, and you need all three eventually. Start with metrics and logs, and add tracing when you have more than one service or a slow request you cannot explain.

How the pieces fit together

flowchart LR
    A["Services"] --> B["Logs"]
    A --> C["Metrics"]
    A --> D["Traces"]
    B --> E["Collector"]
    C --> E
    D --> E
    E --> F["Storage"]
    F --> G["Dashboards"]
    F --> H["Alerts"]
    G --> I["On-call"]
    H --> I
    I --> J["Fix"]

Your services emit signals, a collector receives and routes them, a storage layer keeps them, and dashboards and alerts sit on top. The important last link is a person who can act on an alert and a way to fix what they find.

Start with metrics + logs. Add traces when the questions get harder.

Start with the right metrics

Do not chart everything. Two small checklists cover most needs.

The four golden signals for any service that handles requests:

  1. Latency: how long requests take, ideally as percentiles (p50, p95, p99) and not just an average.
  2. Traffic: how many requests you receive.
  3. Errors: the rate of failed requests.
  4. Saturation: how full the system is, such as CPU, memory, connections or queue depth.

Business metrics are just as valuable: sign-ups per hour, successful payments, orders waiting. A system can look healthy to its servers while the checkout is silently broken.

Write logs you can search

Plain text lines are hard to query. Write structured logs, one JSON object per line:

Always log a request ID. It ties everything together.

{
  "time": "2026-11-05T09:14:22Z",
  "level": "error",
  "service": "checkout",
  "request_id": "b7c1f0a2",
  "user_id": 4821,
  "msg": "payment provider timeout",
  "duration_ms": 5003
}

A few rules make logs far more useful:

  • Include a request ID on every line and pass it between services, so one request can be followed end to end.
  • Log events and outcomes, not every function call.
  • Never log secrets, full card numbers, passwords or tokens. Mask personal data.
  • Use levels consistently, and keep debug logging off by default in production.

Tracing with OpenTelemetry

OpenTelemetry is the vendor-neutral standard for traces, metrics and logs. Instrumenting once means you can change the backend later without touching your code. Most frameworks have libraries that capture incoming requests, database queries and outgoing HTTP calls automatically, which gives you useful traces with little effort.

Alerts that people act on

Too many alerts is as bad as none, because people learn to ignore them. Good alerts follow a few rules:

If nobody acts on an alert, delete it.

  • Alert on symptoms, not causes. "Checkout error rate above 2 percent for 5 minutes" is a symptom a user would feel. "CPU is 85 percent" often is not.
  • Every alert needs an action. If the response is "look at it and do nothing", it should be a dashboard, not a page.
  • Link a runbook with the first three things to check.
  • Page for urgent, ticket for the rest. Wake someone only when users are affected now.
  • Review them monthly and delete the ones that never led to action.

Define a target with an SLO

A service level objective turns "it should be fast and reliable" into a number you can check. For example: "99.5 percent of requests succeed over 30 days." The gap between 100 percent and your target is your error budget. If you are well within it, you can ship faster. If you have used it up, you slow down and fix reliability.

A stack a small team can run

You can buy this as a service or run it yourself. A common open-source combination is:

Need Tool
Metrics and alert rules Prometheus
Dashboards Grafana
Logs Loki, or a hosted log service
Traces Tempo or Jaeger, fed by OpenTelemetry
Errors with stack traces Sentry
Uptime checks from outside Any external uptime monitor

Hosted platforms save time if the team is small. The important thing is that the data exists and someone looks at it.

Conclusion

Observability is not a product you buy, it is a habit of being able to ask your system questions. Start with request metrics, structured logs with a request ID, an outside uptime check and a handful of symptom-based alerts. Add tracing when the questions get harder. Anything more can wait until it earns its place.

Filed underObservabilityMonitoringDevOpsOpenTelemetry

Keep reading