Posting ini terinspirasi oleh topik
Go Forum yang diluncurkan oleh Nate Finch. Posting ini difokuskan pada Go, tetapi jika Anda melewati ini, saya pikir ide-ide yang disajikan di sini dapat diterapkan secara luas.
Kenapa tidak ada cinta?
Paket log di Go tidak memiliki level untuk log, Anda dapat secara manual menambahkan DEBUG, INFO, WARN, dan ERROR sendiri. Juga, tipe logger di Go tidak memiliki kemampuan untuk mengaktifkan atau menonaktifkan level ini secara terpisah untuk paket yang dipilih. Sebagai perbandingan, mari kita lihat beberapa penggantian dari pengembang pihak ketiga.

Google
glog memiliki level:
- Info
- Peringatan
- Kesalahan
- Fatal (mengakhiri program)
Mari kita lihat perpustakaan lain,
loggo , dikembangkan untuk Juju, level tersedia di dalamnya:
- Jejak
- Debug
- Info
- Peringatan
- Kesalahan
- Sangat penting
Loggo juga memiliki kemampuan untuk mengatur tingkat rincian log untuk paket yang diinginkan secara individual.
Berikut adalah dua contoh, jelas dibuat di bawah pengaruh perpustakaan lain untuk masuk dalam bahasa lain.
Bahkan, asal mereka dapat ditelusuri kembali ke syslog (3), bahkan mungkin lebih awal. Dan saya pikir mereka salah.
Saya ingin mengambil posisi kontroversial. Saya pikir semua pustaka log buruk karena mereka menawarkan terlalu banyak fitur; serangkaian fitur menakjubkan yang mengejutkan programmer tepat pada saat ketika ia harus berpikir jernih tentang bagaimana berkomunikasi dengan pembaca dari masa depan, dengan siapa yang akan melihat majalah ini.
Saya berpendapat bahwa paket log yang sukses membutuhkan fitur yang jauh lebih sedikit dan, tentu saja, lebih sedikit level.
Mari kita bicara tentang peringatan (PERINGATAN)
Mari kita mulai dengan yang paling sederhana. Tidak ada yang membutuhkan level PERINGATAN log (peringatan).
Tidak ada yang membaca peringatan, karena menurut definisi tidak ada hal buruk yang terjadi. Mungkin ada sesuatu yang salah di masa depan, tetapi kedengarannya seperti orang lain, bukan masalah saya.
Selain itu, jika Anda menggunakan semacam multi-level logging, mengapa Anda perlu mengatur level PERINGATAN? Anda akan mengatur level ke INFO atau ERROR. Mengatur level PERINGATAN berarti Anda mungkin melaporkan kesalahan di tingkat PERINGATAN.
Kecualikan tingkat peringatan - ini adalah pesan informasi, atau kesalahan.
Mari kita bicara tentang tingkat kesalahan fatal
Level FATAL sebenarnya mencatat pesan, dan kemudian memanggil os.Exit (1). Pada prinsipnya, ini berarti:
- ekspresi yang ditangguhkan dalam rutinitas lain (goroutine) tidak dieksekusi;
- buffer tidak memerah;
- file dan direktori sementara tidak dihapus.
Intinya, log. Fatal kurang verbose, tetapi secara semantik setara dengan panik.
Secara umum diterima bahwa perpustakaan tidak boleh menggunakan panic1, tetapi jika memanggil log.Fatal2 memiliki efek yang sama, itu juga harus dinonaktifkan.
Asumsi bahwa masalah pembersihan ini dapat diselesaikan dengan mendaftarkan penangan shutdown di logger memberikan hubungan yang erat antara logger yang digunakan dan setiap tempat di mana operasi pembersihan terjadi. Itu juga melanggar pemisahan kepentingan.
Jangan merekam pesan dengan tingkat FATAL, lebih suka mengembalikan kesalahan ke pemanggil. Jika kesalahan mencapai main.main, maka ini adalah tempat yang tepat untuk melakukan pembersihan sebelum menutup program.
Mari kita bicara tentang kesalahan (tingkat KESALAHAN)
Penanganan kesalahan dan pencatatan terkait erat, oleh karena itu, sekilas, pencatatan tingkat kesalahan (ERROR) harus mudah dibenarkan. Saya tidak setuju.
Di Go, jika memanggil fungsi atau metode mengembalikan nilai kesalahan, maka Anda benar-benar memiliki dua opsi:
- menangani kesalahan.
- mengembalikan kesalahan ke peneleponnya. Anda dapat dengan indah membungkus kesalahan dalam pembungkusan hadiah (pembungkus), tetapi ini tidak penting untuk diskusi ini.
Jika Anda memutuskan untuk memproses kesalahan dengan menulisnya ke log, maka menurut definisi itu bukan lagi kesalahan - Anda telah memprosesnya. Tindakan mendaftarkan kesalahan itu sendiri adalah pemrosesan kesalahan, oleh karena itu, tidak lagi disarankan untuk menuliskannya ke log sebagai kesalahan.
Biarkan saya meyakinkan Anda dengan potongan kode ini:
err := somethingHard() if err != nil { log.Error("oops, something was too hard", err) return err
Anda tidak boleh mendaftarkan apa pun di tingkat kesalahan karena Anda harus menangani kesalahan atau meneruskannya ke pemanggil.
Anda perlu memahami dengan jelas, saya tidak mengatakan bahwa Anda tidak boleh menulis ke log bahwa telah terjadi perubahan status:
if err := planA(); err != nil { log.Infof("could't open the foo file, continuing with plan b: %v", err) planB() }
Namun pada kenyataannya, log.Info dan log.Error memiliki tujuan yang sama.
Saya tidak mengatakan "jangan daftar kesalahan"! Sebagai gantinya, saya mengajukan pertanyaan, apakah API sekecil mungkin untuk logging? Dan ketika datang ke kesalahan, saya percaya bahwa sebagian besar hal yang dicatat di tingkat ERROR dilakukan hanya karena mereka terkait dengan kesalahan. Bahkan, mereka hanya informatif, sehingga kami dapat menghapus logging tingkat kesalahan (ERROR) dari API kami.
Apa yang tersisa
Kami mengecualikan PERINGATAN, berpendapat bahwa tidak ada yang harus dicatat pada tingkat kesalahan (ERROR), dan menunjukkan bahwa hanya aplikasi tingkat atas yang harus memiliki semacam log. Perilaku fatal. Apa yang tersisa
Saya percaya bahwa hanya ada dua hal yang harus Anda masuki:
- hal-hal yang diperhatikan pengembang ketika mereka mengembangkan atau men-debug suatu program;
- hal-hal yang diperhatikan pengguna saat menggunakan program Anda.
Jelas, ini adalah level debugging (DEBUG) dan informasi (INFO), masing-masing.
log.Info seharusnya menulis baris ini ke output log. Seharusnya tidak mungkin untuk menonaktifkannya, karena pengguna hanya harus memberi tahu apa yang bermanfaat baginya. Jika terjadi kesalahan yang tidak dapat diproses, itu akan muncul di main.main di mana program keluar. Ketidaknyamanan kecil karena harus memasukkan awalan FATAL sebelum pesan log akhir atau menulis langsung ke os.Stderr menggunakan fmt.Fprintf bukan alasan yang cukup untuk memperluas paket dengan metode log.Fatal.
log. Debug, ini masalah yang sama sekali berbeda. Pengembang atau teknisi pendukung memerlukannya untuk mengontrol program. Selama pengembangan, ekspresi debug harus banyak tanpa beralih ke level jejak atau debug2 (Anda tahu siapa Anda). Paket logging harus mendukung kontrol granular untuk mengaktifkan atau menonaktifkan ekspresi debug, untuk paket yang diinginkan dalam paket, atau bahkan mungkin dalam lingkup yang lebih sempit.
Kesimpulan
Jika itu adalah jajak pendapat Twitter, saya akan meminta Anda untuk memilih di antara
- penebangan itu penting
- logging sulit
Tetapi kenyataannya adalah bahwa penebangan keduanya. Solusi untuk masalah ini HARUS untuk menghancurkan dan tanpa ampun mengurangi gangguan yang tidak perlu.
Apa yang kamu pikirkan Apakah itu cukup boros untuk bekerja, atau itu hanya boros?
Catatan
Beberapa perpustakaan mungkin menggunakan panik / memulihkan sebagai mekanisme aliran kontrol internal, tetapi mantra utama adalah bahwa mereka tidak boleh membiarkan operasi aliran kontrol ini bocor keluar dari batas paket.
Ironisnya, meskipun tidak memiliki tingkat output DEBUG, paket Go logging standar memiliki fitur Fatal dan Panic. Dalam paket ini, jumlah fungsi yang menyebabkan penghentian program mendadak melebihi jumlah yang tidak.
Tentang penulis
Penulis artikel ini,
Dave Cheney , adalah penulis banyak paket populer untuk Go, misalnya
github.com/pkg/errors dan
github.com/davecheney/httpstat . Anda dapat mengevaluasi sendiri otoritas dan pengalaman penulis.
Dari penerjemah
Banyak pengembang khawatir tentang pencatatan, beberapa
mendiskusikan penambahan antarmuka Logger ke pustaka Go standar untuk merampingkan pencatatan dalam pustaka dan merangsang pengembang mereka. Para lelaki bahkan menyusun proposal mereka dan
menyiapkan kertas untuk diskusi.
Ditambah refleksi presentasi.
Apakah kita perlu logger baru dan apa yang seharusnya? dari Chris Hines.
Ada beberapa implementasi gagasan
go-log Dave dan sedikit di luar topik tentang masalah tingkat ERROR dan paket
logr yang lebih rumit.