Mengekspos Metrik Aplikasi dan Metode RED
Publikasikan metrik laju, error, dan durasi dalam format Prometheus serta tentukan SLI yang bermakna.
Mengekspos Metrik Aplikasi dan Metode RED adalah pelajaran Node.js Backend Development Bootcamp gratis di CoddyKit. Ini adalah pelajaran 3 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Node.js Backend Development Bootcamp, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Node.js Backend Development Bootcamp mencakup 4 pelajaran total.
Bagian dari pelajaran ini belum diterjemahkan dan ditampilkan dalam bahasa Inggris.
Why Metrics Matter
Logs tell you what happened in a single request. Metrics tell you how your whole service is behaving right now and over time. They are cheap to store, aggregate well, and power dashboards and alerts.
A metric is a numeric measurement sampled over time. In a Node.js backend you typically export metrics in Prometheus text format over an HTTP endpoint (conventionally /metrics). Prometheus scrapes that endpoint every few seconds and stores the time series.
- Counter — only goes up (total requests, total errors).
- Gauge — goes up and down (active connections, queue depth).
- Histogram — buckets observations (request durations) to compute quantiles.
The Prometheus Text Format
Before wiring up libraries, it helps to see what the /metrics endpoint actually returns. Each line is metric_name{label="value"} number. The # HELP and # TYPE comment lines describe each metric.
Labels let one metric name carry many dimensions (per route, per status code). Below is a tiny generator that builds this exposition format by hand so you can see exactly what Prometheus parses.
function renderMetrics(samples) {
const lines = [
'# HELP http_requests_total Total HTTP requests',
'# TYPE http_requests_total counter',
];
for (const s of samples) {
const labels = Object.entries(s.labels)
.map(([k, v]) => k + '="' + v + '"')
.join(',');
lines.push('http_requests_total{' + labels + '} ' + s.value);
}
return lines.join('\n');
}
const out = renderMetrics([
{ labels: { method: 'GET', route: '/users', status: '200' }, value: 1024 },
{ labels: { method: 'GET', route: '/users', status: '500' }, value: 7 },
]);
console.log(out);Introducing the RED Method
The RED method is a focused recipe for monitoring request-driven services. For every service you track three signals:
- R — Rate: requests per second the service is handling.
- E — Errors: rate of failed requests (typically HTTP 5xx, sometimes 4xx).
- D — Duration: distribution of how long requests take (latency).
RED is the request-side complement to USE (Utilization, Saturation, Errors) which targets resources like CPU and disk. For an HTTP API, RED maps almost perfectly onto user-facing experience: throughput, failure rate, and latency.
The elegant part: all three derive from instrumenting just one thing — the request lifecycle.
Installing prom-client
In Node.js the de-facto library is prom-client. It manages a registry of metrics and renders them in Prometheus format. It also ships default metrics (event loop lag, heap usage, GC) that you enable with one call.
Create a single shared registry so every part of your app registers into the same place.
const client = require('prom-client');
const register = new client.Registry();
register.setDefaultLabels({ app: 'orders-api' });
// Node.js runtime metrics: event loop lag, heap, GC, fd count...
client.collectDefaultMetrics({ register });
module.exports = { client, register };R — A Counter for Request Rate
Rate is not stored directly. You store a monotonic counter of total requests, and Prometheus computes the per-second rate at query time with rate(http_requests_total[1m]).
Give the counter labels for method, route, and status_code. Crucially, use the route template (/users/:id) and not the raw URL (/users/42) — otherwise every id becomes a new time series and your cardinality explodes.
const client = require('prom-client');
const httpRequestsTotal = new client.Counter({
name: 'http_requests_total',
help: 'Total number of HTTP requests',
labelNames: ['method', 'route', 'status_code'],
});
// On each finished request:
httpRequestsTotal.inc({
method: 'GET',
route: '/users/:id', // template, NOT /users/42
status_code: '200',
});D — A Histogram for Duration
Duration needs a histogram so you can compute percentiles (p50, p95, p99). A histogram counts observations into predefined buckets (upper bounds in seconds). Choose buckets that span your expected latency range.
A histogram automatically exposes three series per label set: _bucket, _sum, and _count. From _sum and _count you also get the average; from _bucket you estimate quantiles with histogram_quantile().
const client = require('prom-client');
const httpRequestDuration = new client.Histogram({
name: 'http_request_duration_seconds',
help: 'HTTP request duration in seconds',
labelNames: ['method', 'route', 'status_code'],
// Tuned for a typical web API (5ms .. 5s)
buckets: [0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5],
});
// Observe a completed request that took 0.137s
httpRequestDuration.observe(
{ method: 'GET', route: '/users/:id', status_code: '200' },
0.137
);One Middleware to Capture R, E, and D
The whole point of RED is that a single piece of instrumentation feeds all three signals. An Express-style middleware starts a timer, lets the request run, then on res.finish records the count and duration with the status code as a label.
Errors need no separate metric — they are just the counter filtered by status_code=~"5.." at query time. This is framework code (Express), so treat it as a reference pattern rather than a standalone program.
function metricsMiddleware(req, res, next) {
const end = httpRequestDuration.startTimer({ method: req.method });
res.on('finish', () => {
// req.route?.path gives the template, e.g. '/users/:id'
const route = (req.route && req.route.path) || req.path;
const labels = {
method: req.method,
route,
status_code: String(res.statusCode),
};
httpRequestsTotal.inc(labels);
end(labels); // stops timer and records duration with these labels
});
next();
}
app.use(metricsMiddleware);Exposing the /metrics Endpoint
Prometheus pulls metrics, so you must expose them over HTTP. Add a GET /metrics route that returns register.metrics() with the correct content type. This is the endpoint you list as a scrape target in prometheus.yml.
Keep this endpoint internal (bind to a private interface or protect it) — it can leak operational detail and is a tempting DoS target.
const { register } = require('./metrics');
app.get('/metrics', async (req, res) => {
res.set('Content-Type', register.contentType);
res.end(await register.metrics());
});
// prometheus.yml scrape config:
// scrape_configs:
// - job_name: 'orders-api'
// scrape_interval: 15s
// static_configs:
// - targets: ['orders-api:3000']Querying RED with PromQL
Once data is flowing, you express each RED signal as a PromQL query for dashboards and alerts:
- Rate:
sum(rate(http_requests_total[5m])) by (route) - Errors (ratio):
sum(rate(http_requests_total{status_code=~"5.."}[5m])) / sum(rate(http_requests_total[5m])) - Duration (p95):
histogram_quantile(0.95, sum(rate(http_request_duration_seconds_bucket[5m])) by (le))
Note the error ratio is a fraction of total requests, not a raw count. An error rate of 0.02 means 2% of requests failed — far more meaningful than "40 errors" with no denominator.
From Metrics to SLIs and SLOs
A Service Level Indicator (SLI) is a precisely defined measure of service health, usually expressed as good events / valid events. RED metrics are exactly the raw material for SLIs:
- Availability SLI: non-5xx responses / total responses.
- Latency SLI: requests faster than 300ms / total requests.
A Service Level Objective (SLO) is a target for an SLI over a window, e.g. "99.9% of requests succeed over 30 days." The complement of the SLO is your error budget (0.1%), which tells you how much failure you can tolerate before you must stop shipping features and fix reliability.
Computing a Latency SLI From Buckets
A latency SLI like "fraction of requests under 300ms" comes straight from histogram bucket counts: take the cumulative count in the le="0.3" bucket and divide by the total count. Here is a standalone simulation of that computation over two scrape samples.
// Cumulative bucket counts from a histogram, le = upper bound (seconds)
const sample = {
total: 10000,
buckets: {
'0.1': 6000,
'0.3': 9700, // 9700 requests finished within 300ms
'1.0': 9990,
'+Inf': 10000,
},
};
function latencySLI(s, thresholdLabel) {
const good = s.buckets[thresholdLabel];
return good / s.total;
}
const sli = latencySLI(sample, '0.3');
console.log('Latency SLI (<300ms): ' + (sli * 100).toFixed(2) + '%');
console.log('Meets 99% SLO? ' + (sli >= 0.99));Quick Check
Test your understanding of cardinality and the RED method.
Recap
You can now expose meaningful application metrics in Prometheus format and reason about them with the RED method.
- Counter, Gauge, Histogram are the core metric types;
prom-clientmanages a registry and renders the exposition format. - RED = Rate, Errors, Duration — all three fall out of instrumenting the request lifecycle once, in a single middleware.
- Rate comes from a counter via
rate(); Errors are that counter filtered bystatus_code=~"5.."; Duration comes from a histogram viahistogram_quantile(). - Always label by route template, never raw URLs, to control cardinality.
- Expose metrics at
/metricsand let Prometheus scrape it; keep the endpoint internal. - Turn RED metrics into SLIs (good/valid events), set SLOs, and track your error budget.
Pertanyaan yang Sering Diajukan
Apakah pelajaran “Mengekspos Metrik Aplikasi dan Metode RED” gratis?
Ya — teks lengkap “Mengekspos Metrik Aplikasi dan Metode RED” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Node.js Backend Development Bootcamp, upgrade ke CoddyKit PRO. Kursus Node.js Backend Development Bootcamp mencakup 4 pelajaran total.
Apa yang akan aku pelajari di “Mengekspos Metrik Aplikasi dan Metode RED”?
Publikasikan metrik laju, error, dan durasi dalam format Prometheus serta tentukan SLI yang bermakna. Kamu berlatih Node.js Backend Development Bootcamp dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.
Apakah aku perlu pengalaman untuk memulai Node.js Backend Development Bootcamp?
Tidak diperlukan pengalaman sebelumnya. Node.js Backend Development Bootcamp di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 3 dari 4.
Berapa lama pelajaran “Mengekspos Metrik Aplikasi dan Metode RED” memakan waktu?
Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.
Bisakah aku menulis dan menjalankan kode dalam pelajaran Node.js Backend Development Bootcamp ini?
Ya. Setiap pelajaran Node.js Backend Development Bootcamp menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.
Semua pelajaran dalam kursus ini
- Logging Terstruktur dengan ID Korelasi
- Pelacakan Terdistribusi dengan Span OpenTelemetry
- Mengekspos Metrik Aplikasi dan Metode RED
- Propagasi Konteks dengan AsyncLocalStorage