Kodeloka
  1. Kodeloka
  2. Kelas OpenTelemetry
  3. Materi

2 · Collector · Modul 3 dari 8

OpenTelemetry Collector

Lapis perantara yang menerima, mengolah, dan meneruskan telemetri — dan kenapa hampir selalu layak dipasang.

Kenapa Tidak Mengirim Langsung ke Backend

Tanpa Collector
  aplikasi → backend
  · setiap perubahan tujuan menuntut penerapan ulang aplikasi
  · setiap aplikasi menahan buffer dan menangani percobaan ulang sendiri
  · penyuntingan data sensitif tersebar di banyak basis kode

Dengan Collector
  aplikasi → collector → satu atau banyak backend
  · tujuan diubah lewat konfigurasi, tanpa menyentuh aplikasi
  · buffer, percobaan ulang, dan pembatasan terpusat
  · penyuntingan dan pengayaan dilakukan di satu tempat

Struktur Konfigurasi

receivers:
  otlp:
    protocols:
      grpc: { endpoint: 0.0.0.0:4317 }
      http: { endpoint: 0.0.0.0:4318 }

processors:
  memory_limiter:
    check_interval: 1s
    limit_mib: 1500
    spike_limit_mib: 300

  batch:
    timeout: 5s
    send_batch_size: 8192

  resource:
    attributes:
      - key: deployment.environment
        value: produksi
        action: upsert

exporters:
  otlp/tempo:
    endpoint: tempo:4317
    tls: { insecure: true }
  prometheus:
    endpoint: 0.0.0.0:8889

service:
  pipelines:
    traces:
      receivers:  [otlp]
      processors: [memory_limiter, resource, batch]
      exporters:  [otlp/tempo]
    metrics:
      receivers:  [otlp]
      processors: [memory_limiter, batch]
      exporters:  [prometheus]
🚫 Urutan prosesor menentukan perilaku, dan salah urut merusaknya

memory_limiter harus berada paling depan — kalau tidak, data sudah terlanjur menumpuk di prosesor sebelumnya sebelum batas memori sempat diperiksa, dan Collector tetap kehabisan memori. Sebaliknya batch harus paling belakang supaya prosesor lain bekerja pada data yang belum dikelompokkan. Untuk pengambilan sampel berbasis ekor, tail_sampling harus mendahului batch.

Menyunting Data Sensitif

processors:
  attributes/sunting:
    actions:
      - key: http.request.header.authorization
        action: delete
      - key: pengguna.surel
        action: hash
      - key: db.query.text
        action: delete

  redaction:
    allow_all_keys: false
    allowed_keys: [http.request.method, url.path, service.name]
    blocked_values: ["4[0-9]{12}(?:[0-9]{3})?"]

Dua Pola Penerapan

Agen — satu Collector per host atau sebagai sidecar
  + latensi rendah, aplikasi cukup mengirim ke localhost
  + dapat menambahkan metadata host dan pod
  − banyak instans untuk dikelola

Gateway — kelompok Collector terpusat di belakang penyeimbang beban
  + tempat ideal untuk sampling ekor dan kebijakan terpusat
  + jumlah koneksi ke backend jauh lebih sedikit
  − titik kegagalan tambahan bila tidak diberi redundansi

Umum dipakai bersama: aplikasi → agen → gateway → backend
⚠️ Sampling berbasis ekor menuntut semua span satu trace tiba di instans yang sama

Keputusan sampling ekor diambil setelah trace lengkap, sehingga seluruh span dengan trace_id sama harus dikumpulkan pada satu Collector. Bila gateway diberi penyeimbang beban round robin biasa, span satu trace tersebar ke beberapa instans dan setiap instans hanya melihat sebagian — keputusannya menjadi salah dan trace terpotong. Gunakan loadbalancing exporter yang merutekan berdasarkan trace_id.

Menjaga Collector Tetap Sehat

extensions:
  health_check: { endpoint: 0.0.0.0:13133 }
  pprof:        { endpoint: 0.0.0.0:1777 }
  zpages:       { endpoint: 0.0.0.0:55679 }

service:
  extensions: [health_check, pprof, zpages]
  telemetry:
    metrics:
      level: detailed
    logs:
      level: info

Metrik yang wajib dipantau:

otelcol_receiver_refused_spans        ditolak — biasanya batas memori
otelcol_exporter_send_failed_spans    gagal terkirim ke backend
otelcol_exporter_queue_size           antrean menumpuk
otelcol_processor_dropped_spans       span dibuang
🚫 Collector yang tumbang membuat kebutaan total tanpa peringatan

Ketika Collector mati, aplikasi tetap berjalan normal — telemetri hanya berhenti mengalir. Tanpa peringatan khusus pada Collector itu sendiri, tim baru menyadarinya saat membutuhkan data untuk menyelidiki insiden dan menemukan grafik kosong. Pantau Collector dengan sistem yang tidak bergantung pada Collector tersebut.

Transformasi dengan OTTL

processors:
  transform:
    trace_statements:
      - context: span
        statements:
          - set(status.code, STATUS_CODE_ERROR)
            where attributes["http.response.status_code"] >= 500
          - delete_key(attributes, "http.request.header.cookie")
          - replace_pattern(name, "/pesanan/[0-9]+", "/pesanan/{id}")

Baris terakhir menyelamatkan situasi yang sering terjadi: layanan lama yang menaruh ID pada nama span dapat diperbaiki di Collector tanpa menunggu perubahan kode diterapkan.