OpenTelemetry kini menjadi proyek CNCF dengan kecepatan tertinggi kedua dengan lebih dari 24.000 kontributor dan adopsi hampir 50% di antara perusahaan cloud-native. Proyek ini lulus ke tingkat kematangan tertinggi CNCF pada 2026, mengukuhkan posisinya sebagai kerangka observabilitas standar. Proyek ini mengalami peningkatan 45% year-over-year dalam commit kode pada tahun 2024 dan peningkatan 100% dalam volume pencarian. Untuk developer NestJS yang membangun microservices, ini berarti Anda memiliki satu cara terstandarisasi untuk menginstrumentasikan aplikasi Anda dan mengirim telemetri ke backend apa pun.
Dalam sistem microservices, satu permintaan pengguna mungkin menyentuh 5-10 layanan sebelum mengembalikan respons. Ketika permintaan itu gagal atau lambat, log dari layanan individual menunjukkan apa yang terjadi di dalam setiap kotak — tetapi tidak bagaimana layanan berinteraksi. Distributed tracing menangkap perjalanan penuh: layanan mana yang dipanggil, dalam urutan apa, berapa lama setiap panggilan, dan di mana kesalahan terjadi.
Observabilitas memiliki tiga pilar: metrik (apakah sesuatu berjalan?), log (apa yang terjadi?), dan trace (mengapa lambat atau rusak?). OpenTelemetry menyediakan SDK terpadu untuk ketiganya. OpenTelemetry Collector adalah pipeline vendor-agnostik — terima telemetri dari aplikasi Anda, proses dan transformasi, dan ekspor ke backend apa pun.
OpenTelemetry Architecture in NestJS Microservices
┌─────────────────────────────────────────────────────────┐
│ User Request: POST /invoices │
│ trace_id: 4bf92f3577b34da6 (W3C Trace Context header) │
└──────────────────────────┬──────────────────────────────┘
│
┌──────────────────────────▼──────────────────────────────┐
│ API Gateway (span: gateway.route) [0ms] │
│ ├── Auth validation (span: jwt.verify) [2ms] │
│ └── Route to InvoiceService [5ms] │
└──────────────────────────┬──────────────────────────────┘
│ gRPC + trace context
┌──────────────────────────▼──────────────────────────────┐
│ Invoice Service (span: invoice.create) [12ms] │
│ ├── DB insert (span: db.postgresql) [8ms] │
│ ├── Publish Kafka event (span: kafka.send) [3ms] │
│ └── Return response │
└─────────────────────────────────────────────────────────┘
OpenTelemetry Collector Pipeline:
App (OTLP) → Collector → [batch, filter] → Grafana Tempo
→ Prometheus (metrics)
→ Loki (logs)
All backends from ONE instrumentation layerDari menginstrumentasikan layanan ERP Commsult: mulailah dengan auto-instrumentation saja — paket @opentelemetry/auto-instrumentations-node menginstrumentasikan panggilan HTTP, database, dan Redis tanpa menulis satu span pun. Setelah Anda memahami topologi trace, tambahkan custom span untuk jalur kritis bisnis Anda (misalnya, alur pembuatan invoice, rantai persetujuan multi-tingkat). Jangan instrumentasikan semuanya — terlalu banyak span menciptakan kebisingan dan biaya penyimpanan.
Pengaturan OpenTelemetry di NestJS memerlukan inisialisasi SDK sebelum aplikasi bootstrap. Buat file tracing.ts yang mengonfigurasi eksporter OTLP, menetapkan nama layanan, dan mendaftarkan auto-instrumentations Node.js. Impor file ini sebagai baris pertama di main.ts Anda sebelum panggilan bootstrap NestJS.
// tracing.ts — Initialize BEFORE main.ts bootstrap
import { NodeSDK } from '@opentelemetry/sdk-node';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
import { Resource } from '@opentelemetry/resources';
import { SEMRESATTRS_SERVICE_NAME } from '@opentelemetry/semantic-conventions';
const sdk = new NodeSDK({
resource: new Resource({ [SEMRESATTRS_SERVICE_NAME]: 'invoice-service' }),
traceExporter: new OTLPTraceExporter({ url: 'http://otel-collector:4318/v1/traces' }),
instrumentations: [
getNodeAutoInstrumentations({
'@opentelemetry/instrumentation-http': { enabled: true },
'@opentelemetry/instrumentation-pg': { enabled: true }, // PostgreSQL
'@opentelemetry/instrumentation-ioredis': { enabled: true }, // Redis
}),
],
});
sdk.start();
// main.ts — tracing.ts must be imported FIRST
import './tracing'; // ← before any other import
import { NestFactory } from '@nestjs/core';
// invoice.service.ts — Custom span for business logic
import { trace, SpanStatusCode } from '@opentelemetry/api';
@Injectable()
export class InvoiceService {
async createInvoice(dto: CreateInvoiceDto) {
const tracer = trace.getTracer('invoice-service');
return tracer.startActiveSpan('invoice.create', async (span) => {
span.setAttribute('invoice.tenant_id', dto.tenantId);
span.setAttribute('invoice.amount', dto.amount);
try {
const invoice = await this.repo.save(dto);
span.setStatus({ code: SpanStatusCode.OK });
return invoice;
} catch (err) {
span.setStatus({ code: SpanStatusCode.ERROR, message: err.message });
throw err;
} finally {
span.end();
}
});
}
}Kekuatan distributed tracing berasal dari propagasi konteks — ID trace dan ID span mengalir dari layanan ke layanan melalui header HTTP (standar W3C Trace Context). Ketika Layanan A memanggil Layanan B melalui HTTP, ia menyuntikkan konteks span saat ini ke dalam header keluar. Layanan B mengekstrak konteks dan membuat span anak di bawah trace yang sama.
Merekam 100% trace pada sistem lalu lintas tinggi itu mahal — biaya penyimpanan bertambah dengan cepat. Tetapi sampling terlalu agresif berarti melewatkan trace yang penting (kesalahan, permintaan lambat). Gunakan head-based sampling sebagai baseline (sampel 10% lalu lintas normal) dikombinasikan dengan tail-based sampling di tingkat Collector — selalu simpan trace dengan kesalahan atau latensi di atas ambang batas terlepas dari keputusan head-based.
Auto-instrumentation mencakup panggilan infrastruktur, tetapi logika bisnis Anda tidak terlihat secara otomatis. Tambahkan custom span untuk operasi bisnis kritis menggunakan API OpenTelemetry. Gunakan konvensi semantik OpenTelemetry untuk atribut span — ini adalah nama atribut terstandarisasi yang membuat trace Anda dapat dikueri di seluruh alat.
Untuk self-hosted: Grafana Tempo adalah pilihan yang lebih baik daripada Jaeger untuk deployment baru — Tempo menggunakan penyimpanan objek (S3, GCS) untuk penyimpanan trace (jauh lebih murah dari Cassandra atau Elasticsearch Jaeger) dan terintegrasi secara asli dengan dashboard Grafana. Untuk managed: Honeycomb, Datadog APM, dan Grafana Cloud semuanya menerima OTLP.
Siapkan tiga kueri peringatan: latensi P99 per layanan, tingkat kesalahan per layanan, dan jumlah trace per operasi — beri peringatan ketika salah satu melampaui ambang batas. Buat dashboard yang menampilkan perjalanan pengguna kritis Anda sebagai tampilan waterfall. Ketika insiden terjadi, mulai dengan operasi yang relevan di backend tracing Anda, temukan span yang paling lambat atau yang mengalami kesalahan, dan telusuri ke layanan yang bertanggung jawab.