37 poin oleh GN⁺ 2025-12-22 | 1 komentar | Bagikan ke WhatsApp
  • Dalam sistem terdistribusi modern, pendekatan logging lama memiliki keterbatasan struktural sehingga gagal menyampaikan kebenaran
  • Log masih dirancang dengan asumsi lingkungan server tunggal ala 2005, sehingga kehilangan konteks permintaan yang melewati banyak layanan, database, dan cache
  • Pencarian string sederhana tidak memahami struktur, relasi, dan korelasi, sehingga menyulitkan penemuan akar masalah
  • Solusinya adalah menyimpan satu ‘Wide Event (atau Canonical Log Line)’ yang memuat seluruh konteks untuk setiap permintaan
  • Dengan ini, log berubah dari sekadar teks menjadi aset data yang bisa dianalisis

Masalah mendasar dalam logging

  • Log lama dibuat dengan asumsi era server monolitik, sehingga tidak mencerminkan arsitektur layanan terdistribusi modern
    • Satu permintaan bisa melewati banyak layanan, DB, cache, dan queue, tetapi log masih dicatat berdasarkan perspektif satu server
  • Dalam contoh log, satu permintaan menghasilkan 13 baris, sehingga dengan 10.000 pengguna serentak, muncul 130.000 baris per detik, namun sebagian besar tidak bermakna
  • Saat masalah terjadi, yang dibutuhkan adalah konteks, tetapi log saat ini tidak memilikinya

Batas pencarian string

  • Ketika pengguna melaporkan “pembayaran tidak berhasil”, mencari log berdasarkan email atau user_id pun sulit memberi hasil yang berguna karena tidak ada struktur yang konsisten
    • ID pengguna yang sama bisa dicatat dalam puluhan bentuk seperti user-123, user_id=user-123, {"userId":"user-123"}
  • Format log antarlayanan berbeda-beda sehingga pelacakan event yang saling terkait menjadi mustahil
  • Masalah intinya adalah log dirancang berfokus pada penulisan (write), bukan dioptimalkan untuk query

Definisi konsep inti

  • Structured Logging: cara mencatat dalam bentuk key-value (JSON) alih-alih string
  • Cardinality: jumlah nilai unik dalam sebuah field; misalnya user_id sangat tinggi
  • Dimensionality: jumlah field dalam sebuah event log; makin banyak, makin besar peluang analisis
  • Wide Event / Canonical Log Line: satu event log tunggal yang kaya konteks per permintaan
  • Sebagian besar sistem logging membatasi data berkardinalitas tinggi karena masalah biaya, padahal justru itulah yang paling berguna untuk debugging
Iklan

Batasan OpenTelemetry

  • OpenTelemetry (OTel) adalah sekumpulan protokol dan SDK yang hanya menyediakan standar untuk pengumpulan dan pengiriman data
  • Namun OTel tidak melakukan hal-hal berikut
    1. Tidak menentukan apa yang harus dicatat ke log
    2. Tidak otomatis menambahkan konteks bisnis seperti tingkat langganan atau nilai keranjang belanja
    3. Tidak mengubah cara berpikir developer tentang logging
  • Bahkan dengan library yang sama, pengalaman debugging akan sangat berbeda antara instrumentasi yang sengaja menambahkan konteks dan instrumentasi yang sekadar dasar
  • OTel hanyalah sarana pengangkutan (plumbing); apa yang dialirkan tetap harus diputuskan developer

Pendekatan Wide Event / Canonical Log Line

  • Logging harus keluar dari pendekatan berpusat pada “apa yang dilakukan kode” dan mulai mencatat “apa yang terjadi pada permintaan
  • Untuk setiap permintaan, buat satu event yang luas di tingkat layanan
    • Dapat mencakup lebih dari 50 field seperti permintaan, pengguna, pembayaran, error, dan environment
  • Contoh JSON mencakup seluruh konteks debugging seperti user_id, subscription_tier, service_version, dan error_code
  • Dengan ini, satu pencarian saja cukup untuk analisis langsung, misalnya menemukan penyebab kegagalan pembayaran pada pengguna premium

Pemanfaatan query pada Wide Event

  • Wide Event diperlakukan sebagai query data terstruktur, bukan pencarian teks sederhana
  • Debugging setingkat analisis real-time dimungkinkan dengan data berdimensi tinggi dan berkardinalitas tinggi
  • Contoh: query seperti “agregasikan tingkat kegagalan pembayaran pengguna premium selama 1 jam terakhir berdasarkan kode error” bisa dijalankan seketika
Iklan

Pola implementasi

  • Bangun event sepanjang seluruh siklus hidup permintaan, lalu keluarkan sekali saja di akhir
    • Di middleware, inisialisasi field dasar seperti request_id, timestamp, method, dan path
    • Di handler, tambahkan secara bertahap informasi pengguna, keranjang, pembayaran, dan error
  • Pada akhirnya, catat satu event JSON tunggal dengan logger.info(event)

Mengendalikan biaya dengan sampling

  • Jika mencatat lebih dari 50 field per permintaan, biaya bisa melonjak sehingga diperlukan sampling
  • Sampling acak sederhana berisiko melewatkan error
  • Strategi Tail Sampling yang diusulkan
    1. Error (seperti 500) selalu disimpan
    2. Permintaan lambat (di atas p99) selalu disimpan
    3. Pengguna VIP atau sesi dengan flag tertentu selalu disimpan
    4. Sisanya hanya diambil sampel acak 1–5%
  • Dengan ini, penghematan biaya dan pelestarian event penting bisa dicapai sekaligus

Meluruskan kesalahpahaman umum

  • Structured Logging ≠ Wide Event: format JSON saja tidak cukup; konteks adalah inti utamanya
  • Menggunakan OpenTelemetry ≠ observability lengkap: yang distandarkan hanya pengumpulan; apa yang dicatat tetap tanggung jawab developer
  • Tidak sama dengan tracing: tracing menunjukkan alur antarservice, sedangkan Wide Event memberi konteks di dalam service
  • Pemisahan bahwa log untuk debugging dan metrics untuk dashboard tidak lagi perlu — Wide Event memenuhi kedua kebutuhan itu
  • Anggapan bahwa data berkardinalitas tinggi itu mahal sudah usang; database modern seperti ClickHouse dan BigQuery dapat menanganinya secara efisien

Dampak penerapan Wide Event

  • Debugging berubah dari ekskavasi (archaeology) menjadi analitik (analytics)
  • Dari pendekatan grep pada log 50 service untuk mencari “kegagalan pembayaran pengguna”,
    menjadi analisis berbasis satu query seperti “lihat tingkat kegagalan pembayaran pengguna premium menurut kode error”
  • Hasil akhirnya, log berubah dari alat yang mengatakan kebohongan menjadi aset data yang mengatakan kebenaran

1 komentar

 
GN⁺ 2025-12-22
Komentar Hacker News
  • Tulisannya sulit dibaca dan terasa seperti dibantu AI. Meski begitu, pesannya tetap bernilai, dan akan lebih baik jika dibuat lebih ringkas
    Beberapa hal yang belakangan ini saya pikirkan adalah sebagai berikut.

    • Karena autentikasi ada di seluruh stack, saya mulai menyertakan user id di setiap baris log. Hasilnya, jadi jauh lebih mudah melihat pengalaman yang dialami pengguna secara menyeluruh
    • Mencatat error sebagai baris terpisah dari log request itu merepotkan. Memang bisa difilter lewat trace, tetapi sulit membuat kueri seperti “tunjukkan hanya error yang terkait dengan request 5xx”
    • Menambahkan konteks seperti ini saja tidak cukup, kita juga harus mengedukasi rekan kerja bahwa ada field baru. Saya sering melihat orang bersusah payah sendiri hanya karena tidak tahu
    • Jika berinvestasi pada alat tracing yang lebih baik, level debugging yang tidak mungkin dicapai dengan log biasa jadi memungkinkan. Ini semacam pengembangan dari gagasan memakai user id sebagai trace
    • Jika ada konsep request ID di codebase, itu juga bisa dipakai untuk melacak perilaku pengguna dengan lebih spesifik
    • Jika TID diwajibkan di seluruh layanan, tim mana pun bisa melacak seluruh transaksi hanya dengan satu TID
    • Komentar seperti “tercium bau AI” seperti ini tampaknya akan segera menjadi budaya yang dikritik
  • Untuk topik ini, mustahil tidak menyebut Charity Majors. Dia sudah lebih dari 10 tahun menyebarkan konsep “wide events” dan “observability”, dan membangun Honeycomb.io di atas filosofi itu.
    Sekarang pendekatan ini bisa diterapkan dengan berbagai alat. Yang penting adalah menangkap wide event menggunakan structured logs atau traces, lalu memakai tool dengan visualisasi kaya seperti deret waktu dan histogram

    • Namun, istilah “observability” itu sendiri bukan diciptakan olehnya. Konsep itu sudah dipakai di berbagai bidang sejak puluhan tahun lalu. Dia adalah praktisi berpengaruh, tetapi bukan pencipta istilahnya
    • Blognya dan kisah di balik Honeycomb adalah bacaan wajib bagi orang di industri ini. Mereka adalah salah satu tim pertama yang benar-benar memahami nilai pendekatan ini
    • Tulisan ini sangat mirip dengan gayanya, sampai saya sempat mengira di akhir akan muncul iklan Honeycomb, dan cukup terkejut ternyata tidak
    • Di ekosistem .NET, Nick Blumhardt sudah lama membahas “structured logging”, dan Seq serta Serilog mendukung hal itu
    • Kontennya bagus, tetapi tidak ada satu orang pun yang “mem-branding” istilah “observability”. Layak dihormati, tapi klaim yang berlebihan sebaiknya dihindari
  • Saya setuju dengan sebagian argumen tulisan itu, tetapi ada jebakan dalam pendekatan yang hanya menyisakan satu wide event. Jika exception atau timeout terjadi di tengah request, bisa saja tidak ada apa pun yang tersisa.
    Log bawaan framework bahasa atau log dependensi juga akan terlewat.
    Karena itu, ini lebih baik dipakai sebagai lapisan tambahan di atas log yang sudah ada. Gunakan ID pada level request/session dan agregasikan di tempat seperti ClickHouse

    • Jika masalahnya adalah visibilitas pada lapisan tengah, berarti event itu belum cukup wide. log.error(data) dan wide_event.attach(error, data) pada dasarnya sama saja
    • Log seperti “connection X:Y accepted at Z ns” dan “closed at Z ns” sangat berguna untuk debugging sistem yang lambat
    • Saya menyelesaikannya di framework PHP dengan membuat LoggerInterface. Exception ditangkap di handler global lalu disimpan ke DB dalam bentuk wide. Ada sedikit boilerplate, tetapi hasilnya sangat bagus sampai sekarang terasa sulit hidup tanpanya
  • Presentasi dan contoh interaktif-nya sangat bagus. Tetapi pada akhirnya, inti ceritanya bisa diringkas menjadi “tambahkan tag terstruktur ke log”.
    Saya merasa wide log tidak memberi manfaat yang sepadan dibanding kompleksitas dan penurunan keterbacaan yang ditimbulkannya.
    Kalau cukup dengan grep "uid=user-123" application.log, apakah memang perlu sampai menambahkan metode pengiriman pengguna juga?
    (Sebagai catatan, checkbox tidak berfungsi di browser Brave Android)

    • Jika log-nya JSON, masih bisa dicari dengan grep '"uid": "user-123"'. Opsi --context juga bisa dipakai untuk melihat baris di sekitarnya
  • Saya pernah menangani sistem di lingkungan manufaktur semikonduktor dengan ribuan peserta message bus. Log yang keluar mencapai 300~400MB per jam, tetapi grep dan tool CLI saja sudah cukup untuk mengelolanya.
    Log hanyalah deret waktu dari event, sedangkan analisis detail dilakukan dengan kueri Oracle. Log adalah alat untuk memahami hubungan sebab-akibat dari suatu kejadian

    • Log itu untuk memahami timeline, bukan untuk memuat semua data request/response. Jika terlalu banyak informasi dimasukkan, justru makin sulit dipahami.
      Log menjelaskan “kapan dan apa yang terjadi”, sedangkan “mengapa” dicari dari kombinasi kode, data, dan event
      Secara pribadi saya merasa antarmuka seperti ELK stack kurang nyaman untuk eksplorasi yang intuitif. Log penting untuk dibaca sambil diikuti secara naluriah
    • Log 400MB per jam sebenarnya tidak terlalu besar. Jadi grep sederhana pun sudah cukup untuk menanganinya
  • Saran di akhir tulisan, “log semua error, exception, dan request yang lambat”, adalah gagasan yang berbahaya.
    Misalnya, jika dependensi melambat, volume log bisa meledak 100 kali lipat.
    Dalam kondisi gangguan, layanan justru harus melakukan lebih sedikit pekerjaan agar pemulihan lebih mudah, tetapi ledakan log malah bisa memicu kegagalan berantai

    • Di Cloudflare mereka memakai adaptive sampling. Batch log dibucket-kan berdasarkan field, lalu dari tiap bucket hanya disimpan akar kuadrat atau nilai logaritmik dari jumlah log masuk.
      Makin besar volume log, rasio sampling otomatis menyesuaikan sehingga sistem tidak kelebihan beban
    • Ambang batas ajaib seperti ini berbahaya. Nilai seperti P(99) seharusnya diperbarui secara dinamis. Lebih aman jika provider OTEL mengambil nilai aktual secara berkala
    • Layanan produksi seharusnya dirancang agar pengumpulan log bisa diskalakan sesuai permintaan. Buffering di disk lokal saja pun sangat membantu
    • Jika layanannya bert traffic tinggi, cukup sampling request yang sehat dengan cara seperti trace_id mod 100 == 0
    • Jika log menjadi bottleneck, berarti desain sistemnya yang salah. Logging yang efisien bisa menangani ratusan juta event per detik
  • Dalam software modern, sulit menjelaskan sepenuhnya “apa yang terjadi” hanya dengan satu log.
    Karena itu diperlukan korelasi vertikal (Vertical correlation) dan korelasi horizontal (Horizontal correlation).
    Antar lapisan atas-bawah dalam stack harus berbagi nilai correlation yang sama, dan saat ada komunikasi antarsistem, korelasi antarpihak juga diperlukan.
    Menambahkan nilai seperti ini ke API atau protokol memang sulit, tetapi jika transaction ID sudah dirancang sejak awal, penelusuran menyeluruh jadi memungkinkan

  • Saya rasa mendaftarkan domain terpisah hanya untuk satu tulisan itu kurang berkelanjutan.
    Karena harus membayar biaya perpanjangan setiap tahun, menurut saya lebih baik memakai blog pribadi atau subdomain.
    Misalnya bentuk seperti logging-sucks.boristane.com

    • Sebenarnya domain dan tulisan ini adalah sarana promosi untuk observability SaaS milik penulis. Memang butuh akun Cloudflare, tetapi gratis, jadi terasa seperti strategi pemasaran jangka panjang. Meski begitu, tetap bermanfaat, dan saya juga punya akun CF jadi tertarik mencobanya
    • Tulisan ini sejalan dengan “Give people something to link to” dari Simon Willison
    • Ini lebih terasa seperti halaman lead generation untuk pemasaran digital daripada sebuah tulisan blog. Promosi layanannya cukup jelas
  • Terkait klaim bahwa “log adalah peninggalan era monolitik”, saya merasa log lokal masih tetap relevan.
    Fungsi aslinya memang mencatat percakapan proses lokal, dan untuk memahami situasi di server lain kita perlu transaction tracing.
    Dengan melihat log di titik yang tepat saja, kita bisa sampai ke akar masalah

    • Namun log bukan hanya untuk analisis akar penyebab semata, tetapi juga bisa memberi insight bisnis seperti siapa yang terdampak, korelasi antara performa dan input, atau dampak kerentanan keamanan.
      Log yang kaya konteks bisa digabungkan dengan engine analitik untuk membantu perbaikan produk juga
    • Ada juga tanggapan terhadap kalimat “request melewati 15 layanan dan 3 DB”, bahwa kompleksitas seperti itu seharusnya dihindari
    • Saya merasa APN/Kibana saja sudah cukup untuk analisis log
  • Saya setuju dengan pernyataan “log-lah apa yang terjadi pada request, bukan apa yang dilakukan kode”, tetapi penulis tampak kurang berpengalaman.
    Saya menyebutnya “bug parts logging”, dan menurut saya harus mencakup sinyal awal seperti jalur pemrosesan, jumlah kemunculan, dan waktu.
    Logging berbeda dari metrik atau audit. Jika logging gagal, pemrosesan tetap harus berjalan, tetapi kegagalan audit bersifat fatal.
    Seperti konsep “historian” pada sistem SCADA, kita perlu membedakan observables dan evaluatives.
    Misalnya, event rinci dari sensor bahan bakar berguna untuk diagnosis, tetapi tidak perlu untuk menjawab pertanyaan “apakah bisa sampai ke tujuan”.
    Pada akhirnya, yang penting adalah memperjelas apa yang akan diamati, dan apa yang akan dievaluasi

    • Saya mendukung “teori terpadu observability”. Log, metrik, dan audit pada dasarnya hanyalah aliran bit, dan bisa ditransformasikan tanpa kehilangan informasi.
      Cara penyimpanan, transformasi, dan query-nya bisa berbeda, tetapi titik konsumsi dan mekanismenya dapat dirancang sama.
      Dengan begitu desain sistem menjadi lebih sederhana, dan log yang disimpan jangka panjang pun bisa diproses ulang di kemudian hari