Observability — the ability to understand a system's internal state from its external outputs. Three pillars: **metrics** (numbers over time — CPU, QPS), **logs** (events — errors, audit trail), **traces** (request path across distributed services). Difference from monitoring: monitoring = knowing known unknowns (CPU high). Observability = exploring unknown unknowns (new bug type).
Below: details, example, related terms, FAQ.
Free online tool — HTTP header checker: instant results, no signup.
// OpenTelemetry instrumented code
const tracer = trace.getTracer('my-app');
const span = tracer.startSpan('db-query');
try {
await db.query('SELECT ...')
} finally {
span.end(); // exports trace to Jaeger/Tempo
}Metrics are quantitative measurements that provide insights into the performance and health of a system. In the realm of observability, metrics play a crucial role as they allow teams to track the state of various components over time. Metrics can be categorized into two types: counter and gauge.
A counter is a cumulative metric that only increases, such as the number of requests served by a server. In contrast, a gauge can go up and down, such as the current CPU usage.
Examples of key metrics include:
To effectively leverage metrics, organizations often utilize tools like Prometheus or Grafana for collection and visualization. For instance, to monitor CPU usage with Prometheus, you can use the following configuration in your prometheus.yml file:
scrape_configs:
- job_name: 'node'
static_configs:
- targets: ['localhost:9100']This configuration allows Prometheus to scrape metrics from the Node Exporter, which collects system-level metrics such as CPU utilization. By analyzing these metrics, teams can quickly identify performance bottlenecks and make data-driven decisions.
Logs are an essential component of observability, providing detailed records of events that occur within a system. They are invaluable for troubleshooting and understanding the behavior of applications in real-time. Unlike metrics, which provide a high-level overview, logs offer granular detail that can help in diagnosing issues.
Logs typically contain timestamps, severity levels (e.g., info, warning, error), and contextual information about the event. This information can help teams trace the source of problems and understand the context in which they occurred.
Common log types include:
To implement effective logging, developers often use logging frameworks like Log4j for Java applications or winston for Node.js. For instance, a basic configuration in a Node.js application using winston might look like this:
const winston = require('winston');
const logger = winston.createLogger({
level: 'info',
format: winston.format.json(),
transports: [
new winston.transports.File({ filename: 'combined.log' }),
new winston.transports.Console()
]
});This setup allows logging to both a file and the console, ensuring that all events are captured for later analysis. By leveraging logs effectively, organizations can gain deeper insights into their systems and respond to incidents more swiftly.
Traces are a vital aspect of observability, particularly in distributed systems where requests traverse multiple services. Tracing allows teams to visualize the path a request takes through various components, helping to identify latency issues and bottlenecks. By capturing traces, organizations can gain insights into how different services interact and how delays accumulate across the system.
A key concept in tracing is distributed tracing, which involves tracking requests as they propagate through multiple services. This is especially important in microservices architectures, where a single user request may involve several services communicating with one another.
Common tracing tools include:
To implement distributed tracing, you can use OpenTracing with Jaeger. Below is an example of a basic setup in a Node.js application:
const { initTracer } = require('jaeger-client');
const options = {
serviceName: 'my-service',
};
const tracer = initTracer(options, {});
const span = tracer.startSpan('my-operation');
span.finish();This code initializes a Jaeger tracer for the service and creates a span representing an operation. By instrumenting your application with tracing, you can better understand request flows and pinpoint areas for optimization, ultimately enhancing the overall performance and reliability of your system.
Monitoring = alerts on predetermined conditions. Observability = ad-hoc investigation via exploration. Overlap is big but observability goes deeper.
Minimum: metrics + logs. Traces — when you have microservices/distributed. In a monolith start with the first two.
Small team: Datadog (SaaS, all-in-one) or Grafana Cloud (cheaper). Self-host: Prometheus + Loki + Tempo + Grafana (LGTM).
Free plan — 10 monitors, checks every 5 min, no card required. Upgrade for 1-minute interval and multi-region monitoring.