18 poin oleh hongminhee 2025-06-23 | 7 komentar | Bagikan ke WhatsApp

Library vs Aplikasi: Kebutuhan logging yang pada dasarnya berbeda

  • Logging aplikasi: Konfigurasi dan pengelolaan eksplisit di lingkungan yang dikendalikan langsung oleh developer
  • Logging library: Disertakan dalam proyek orang lain sehingga perlu menghormati lingkungan pengguna dan kebebasan memilih mereka
  • Keterbatasan pendekatan yang ada: Saat logger yang berpusat pada aplikasi (winston, Pino) diterapkan ke library, muncul masalah pemaksaan
  • Dilema pembuat library: Menyediakan informasi debugging vs tidak membebani pengguna

Masalah logging library saat ini

  • Ekosistem logging yang terfragmentasi: Express memakai DEBUG=express:*, Mongoose memakai mongoose.set('debug', true) dan seterusnya, masing-masing dengan caranya sendiri
  • Dilema dependensi: Saat memakai library yang berpusat pada aplikasi seperti winston atau Pino, pengguna dipaksa menerima dependensi dan konfigurasi yang tidak diinginkan
  • Diam vs pemaksaan: Pilihan ekstrem antara sepenuhnya menyerah pada logging atau memaksakan cara logging kepada pengguna
  • Kompleksitas dependency injection: Pendekatan yang lebih canggih, tetapi menambah kompleksitas API dan beban bagi pengguna

Filosofi "library-first" dari LogTape

  • Aktivasi bersyarat: Jika logging tidak dikonfigurasi maka benar-benar tidak aktif, dan jika dikonfigurasi maka dikelola secara terintegrasi
  • Menjamin kebebasan memilih pengguna: Library tidak memaksakan cara logging, dan hanya aktif ketika pengguna menginginkannya
  • Zero dependency: Berukuran 5.3KB untuk menghilangkan risiko keamanan supply chain dan mencegah konflik versi
  • Dukungan penuh ESM/CJS: Menyelesaikan masalah rantai kompatibilitas dan mengoptimalkan bundle melalui tree shaking

Keunggulan praktis

  • Optimisasi performa: Saat nonaktif overhead nyaris nol, dan saat aktif memiliki performa output konsol yang baik
  • Pemisahan namespace: Mencegah benturan dengan kategori hierarkis berbentuk ["my-lib", "feature"]
  • Desain yang mengutamakan TypeScript: Menyediakan type safety penuh tanpa paket tipe tambahan
  • Bridging dengan sistem yang ada: Mendukung adopsi bertahap melalui adapter winston dan Pino

Pertimbangan realistis

  • Makna adapter: Mengakui kenyataan bahwa ini belum menjadi standar ekosistem, sekaligus menawarkan kompromi praktis
  • Inspirasi dari ekosistem Python: Merujuk pada kisah sukses Python yang terintegrasi lewat library standar logging
  • Pendekatan berorientasi masa depan: Diajukan sebagai salah satu opsi untuk perbaikan bertahap ekosistem library

7 komentar

 
sunrabbit 2025-06-25

Saya agak kurang paham bagaimana bisa dianggap tidak berjalan saat belum dikonfigurasi.
Saat memanggil getLogger, logger-nya sudah dibuat dan jika menjalankan debug juga tetap berfungsi.

Dari kode yang saya lihat, ini hanya membuatnya tampak seperti tidak berfungsi,
dan juga tidak menunda operasi string,
jadi saya agak kurang paham apa bedanya dengan library lain yang hanya tidak mencetak log ketika level log diatur.

 
hongminhee 2025-06-25

Eh, log tetap muncul meski configure()/configureSync() tidak dipanggil? Munculnya di mana? Apakah tampil di konsol?

 
sunrabbit 2025-06-26

Ah, yang saya maksud dengan “berfungsi” di sini bukan berarti log disimpan ke console atau file, melainkan apakah fungsi tersebut dieksekusi sehingga benar-benar menimbulkan overhead.

Sepertinya memang mudah menimbulkan salah paham.

 
sunrabbit 2025-06-26

Tentu saja, jika melihat bahwa overhead utama logger adalah system call, kita memang tidak bisa bilang overhead-nya tidak ada.
Namun, apakah itu bisa dibilang sebagai pembeda dibanding logger lain? Rasanya tidak, karena logger lain juga bekerja dengan cara yang sama.

 
hongminhee 2025-06-26

Aha, jadi maksud Anda begitu. Pertama-tama, ketika menjalankan benchmark dengan acuan null output, sepertinya bisa dibilang hampir tidak ada overhead. Namun, yang saya anggap lebih penting daripada overhead performa adalah apakah perilaku default-nya no-op atau tidak. Dari sudut pandang penulis library, meskipun log dicetak di dalam library, akan merepotkan jika aplikasi yang menggunakan library tersebut tiba-tiba menampilkan log ke konsol atau file sesuka hati saat dijalankan.

 
sunrabbit 2025-06-26

Aha, ternyata ini SHOW GN.
Belakangan ekosistem sering memilih bentuk logger yang diinjeksikan dari luar, jadi sepertinya itu juga alasan saya kurang bisa berempati.
Kalau tidak dikonfigurasi, tentu saja tidak akan bekerja.
Meski begitu, karena ini juga merupakan antarmuka logger yang belum ada di ekosistem tersebut sampai sekarang, dan tingkat kebebasannya tinggi, rasanya ini lebih baik.

Untuk patokan benchmark yang Anda berikan, karena yang dikeluarkan adalah null output dengan mengecualikan system call,
saya rasa pada bagian ini hasilnya memang bisa sangat berbeda tergantung bentuk logger internalnya.

Di bagian ini, selisihnya sampai tiga kali lipat dibanding Pino ya. Wah.


FYI: Tambahan, bentuk logger yang diinjeksikan dari luar seperti yang saya sebutkan sebelumnya juga bisa dicek dengan mudah hanya dengan melihat OpenAI Node SDK, karena itu juga memakai bentuk yang menerima logger dari luar lalu mengeluarkan output.