Manfaat Pembalakan Terstruktur vs pencatatan dasar

110

Kami sedang membangun aplikasi baru dan saya ingin memasukkan logging terstruktur. Setup ideal saya akan menjadi seperti Serilogkode C # kami, dan Bunyanuntuk JS kami. Ini akan memberi makan fluentddan kemudian bisa pergi ke sejumlah hal, saya pikir pada awalnya elasticsearch + kibana. Kami sudah memiliki database MySQL, jadi dalam jangka pendek saya lebih tertarik untuk mendapatkan pengaturan Serilog + Bunyan dan devs untuk menggunakannya dan kami dapat login ke MySQL sementara kami mengambil sedikit lebih banyak waktu membawa fluentd dan sisanya.

Namun, salah satu coders kami yang lebih berpengalaman lebih suka melakukan sesuatu seperti: log.debug("Disk quota {0} exceeded by user {1}", quota, user);menggunakan log4netdan kemudian menjalankan pernyataan pilih terhadap MySQL seperti:SELECT text FROM logs WHERE text LIKE "Disk quota";

Karena itu, pendekatan mana yang lebih baik dan / atau hal-hal apa yang perlu kita pertimbangkan ketika memilih jenis sistem logging?

DTI-Matt
sumber
Saya setuju dengan suntingan yang dibuat. Saya tidak terlalu berusaha membuktikan sesuatu kepada seseorang karena saya mencoba memahami manfaat dan perbedaan dalam pembalakan terstruktur vs. dasar. Dalam pikiranku terstruktur memberi kita lebih banyak fleksibilitas terutama dalam sumber-sumber log, dan bagaimana kita kemudian dapat menampilkan data mereka. Pada titik pemahaman saya, saya tidak dapat menjelaskan mengapa logging dasar dan pencarian MySQL lebih baik / lebih buruk daripada logging terstruktur.
DTI-Matt
2
@ Logging terstruktur DTI-Matt serilog hanyalah logging biasa, hanya memformat objek yang Anda cetak ke dalamnya - sesuatu yang dapat Anda lakukan sendiri dengan menunggang ToString dengan sangat mudah. Aspek yang lebih penting adalah konfigurasi dan pengelolaan file log, bukan satu cara memformat string di atas yang lain, yang lain adalah kinerja. Jika dev ingin menggunakan log4net (yang merupakan lib logging yang bagus), maka pilihan Anda dari serilog (yang terlihat keren) adalah salah satu dari "solusi mencari masalah".
gbjbaanb
@ DTI-Matt Dari melihat serilog itu terlihat sangat mirip dengan log4net. log4net menangani pembuatan log terstruktur pada konfigurasi. Anda tidak perlu mencari pesan log karena Anda dapat memiliki informasi tambahan yang dikonfigurasi dan ditulis ke sebuah tabel. Juga mengkonfigurasi log4net untuk fluentd tipstuff.org/2014/05/...
RubberChickenLeader
Awas ada beberapa orang bodoh yang tidak mengerti ide pertanyaan konseptual di sini. bertanya tentang arah aplikasi database dalam upaya untuk menangani kemampuan ETL mereka v. kode akan memberi Anda beberapa downvotes serius. Saya berasumsi pertanyaan Anda juga akan ada di blok memotong.
user3916597
2
@gbjbaanb Serilog bekerja dengan cara yang sama seperti log4net saat merender acara sebagai teks, tetapi jika Anda menggunakan format terstruktur untuk menyimpan log, itu akan mengaitkan properti yang disebutkan dengan argumen yang dilewati (yaitu untuk mendukung pencarian / penyaringan tanpa regex dll. ) HTH!
Nicholas Blumhardt

Jawaban:

140

Ada dua kemajuan mendasar dengan pendekatan terstruktur yang tidak dapat ditiru menggunakan log teks tanpa (kadang-kadang tingkat ekstrim) upaya tambahan.

Jenis Acara

Ketika Anda menulis dua acara dengan log4net seperti:

log.Debug("Disk quota {0} exceeded by user {1}", 100, "DTI-Matt");
log.Debug("Disk quota {0} exceeded by user {1}", 150, "nblumhardt");

Ini akan menghasilkan teks yang serupa:

Disk quota 100 exceeded by user DTI-Matt
Disk quota 150 exceeded by user nblumhardt

Tapi, sejauh menyangkut pemrosesan mesin, mereka hanya dua baris teks yang berbeda.

Anda mungkin ingin menemukan semua peristiwa "kuota disk melebihi", tetapi kasus sederhana dalam mencari acara like 'Disk quota%'akan jatuh segera setelah peristiwa lain terjadi seperti:

Disk quota 100 set for user DTI-Matt

Pencatatan teks membuang informasi yang awalnya kami miliki tentang sumber acara, dan ini harus direkonstruksi ketika membaca log biasanya dengan lebih banyak ekspresi pertandingan yang rumit.

Sebaliknya, ketika Anda menulis dua acara Serilog berikut :

log.Debug("Disk quota {Quota} exceeded by user {Username}", 100, "DTI-Matt");
log.Debug("Disk quota {Quota} exceeded by user {Username}", 150, "nblumhardt");

Ini menghasilkan output teks yang mirip dengan versi log4net, tetapi di balik layar, "Disk quota {Quota} exceeded by user {Username}" templat pesan dilakukan oleh kedua peristiwa.

Dengan sink yang sesuai, Anda nantinya dapat menulis kueri where MessageTemplate = 'Disk quota {Quota} exceeded by user {Username}'dan mendapatkan kejadian persis di mana kuota disk terlampaui.

Tidak selalu nyaman untuk menyimpan seluruh templat pesan dengan setiap peristiwa log, jadi beberapa sinking hash templat pesan menjadi EventTypenilai numerik (misalnya 0x1234abcd), atau, Anda bisa menambahkan pengaya ke pipa logging untuk melakukan ini sendiri .

Ini lebih halus daripada perbedaan berikutnya di bawah ini, tetapi yang sangat kuat ketika berhadapan dengan volume log yang besar.

Data Terstruktur

Sekali lagi mempertimbangkan dua peristiwa tentang penggunaan ruang disk, mungkin cukup mudah menggunakan log teks untuk permintaan pengguna tertentu like 'Disk quota' and like 'DTI-Matt'.

Tetapi, diagnosa produksi tidak selalu mudah. Bayangkan perlunya menemukan peristiwa di mana kuota disk melebihi di bawah 125 MB?

Dengan Serilog, ini dimungkinkan di sebagian besar sink menggunakan varian:

Quota < 125

Membangun kueri semacam ini dari ekspresi reguler adalah mungkin, tetapi proses ini menjadi cepat melelahkan dan biasanya menjadi ukuran upaya terakhir.

Sekarang tambahkan ke ini jenis acara:

Quota < 125 and EventType = 0x1234abcd

Anda mulai melihat di sini bagaimana kemampuan ini bergabung dengan cara yang langsung untuk membuat debugging produksi dengan log terasa seperti aktivitas pengembangan kelas satu.

Satu manfaat lebih lanjut, mungkin tidak semudah itu dicegah, tetapi begitu debugging produksi telah dihapus dari tanah peretasan regex, pengembang mulai menilai log lebih banyak dan lebih berhati-hati dan mempertimbangkan ketika menulisnya. Log yang lebih baik -> aplikasi berkualitas lebih baik -> lebih banyak kebahagiaan di sekitar.

Nicholas Blumhardt
sumber
4
Saya suka jawaban ini. ditulis dengan sangat baik dan untuk beberapa alasan saya tidak bisa menjelaskan, membuat saya tetap di ujung kursi saya.
jokab
16

Saat Anda mengumpulkan log untuk diproses, baik itu untuk parsing ke dalam beberapa database dan / atau mencari melalui log yang diproses nanti, menggunakan logging terstruktur membuat beberapa proses lebih mudah / lebih efisien. Parser dapat mengambil keuntungan dari struktur yang diketahui ( mis. JSON, XML, ASN.1, apa pun) dan menggunakan mesin state untuk parsing, sebagai lawan dari ekspresi reguler (yang bisa mahal secara komputasi (relatif) untuk dikompilasi dan dieksekusi). Memilah teks bentuk bebas, seperti yang disarankan oleh rekan kerja Anda, cenderung mengandalkan ekspresi reguler, dan bergantung pada teks yang tidak berubah . Ini dapat membuat parsing teks bentuk bebas agak rapuh ( yaitu parsing digabungkan dengan teks yang tepat dalam kode).

Pertimbangkan juga kasus pencarian / pencarian, misalnya :

SELECT text FROM logs WHERE text LIKE "Disk quota";

LIKEketentuan membutuhkan perbandingan dengan setiap textnilai baris; sekali lagi, ini relatif mahal secara komputasi, khususnya ketika wildcard digunakan:

SELECT text FROM logs WHERE text LIKE "Disk %";

Dengan logging terstruktur, pesan log terkait kesalahan disk Anda mungkin terlihat seperti ini di JSON:

{ "level": "DEBUG", "user": "username", "error_type": "disk", "text": "Disk quota ... exceeded by user ..." }

Bidang-bidang struktur semacam ini dapat memetakan dengan cukup mudah untuk misalnya nama kolom tabel SQL, yang berarti pencarian dapat lebih spesifik / granular:

SELECT user, text FROM logs WHERE error_type = "disk";

Anda dapat menempatkan indeks pada kolom yang nilainya sering Anda cari / cari, selama Anda tidak menggunakan LIKEklausa untuk nilai kolom tersebut . Semakin Anda dapat memecah pesan log Anda ke dalam kategori tertentu, semakin banyak target Anda dapat membuat pencarian Anda. Misalnya, selain error_typebidang / kolom pada contoh di atas, Anda bisa membuat genap "error_category": "disk", "error_type": "quota"atau semacamnya.

Semakin banyak struktur yang Anda miliki dalam pesan log Anda, sistem yang lebih Anda parsing / mencari (seperti fluentd, elasticsearch, kibana) dapat mengambil keuntungan dari struktur itu, dan melakukan tugas-tugas mereka dengan kecepatan yang lebih besar dan kurang CPU / memori.

Semoga ini membantu!

Castaglia
sumber
1
+1 Ingin menambahkan bahwa ini bukan hanya tentang kecepatan dan efisiensi. Relevansi hasil pencarian akan jauh lebih tinggi ketika menggunakan logging terstruktur dan karenanya "query terstruktur". Tanpa itu mencari kata-kata yang muncul dalam konteks yang berbeda akan memberi Anda banyak hits yang tidak relevan.
Marjan Venema
1
+1 dari saya juga, saya pikir ini berhasil. Menambahkan formulasi yang sedikit berbeda di bawah ini, untuk memperluas kasus tipe acara juga.
Nicholas Blumhardt
8

Anda tidak akan menemukan banyak manfaat dari pendataan terstruktur ketika aplikasi Anda membuat beberapa ratus pesan log per hari. Anda pasti akan ketika Anda memiliki beberapa ratus pesan log per detik yang datang dari berbagai aplikasi yang digunakan.

Terkait, pengaturan di mana pesan log berakhir di Tumpukan ELK juga sesuai untuk skala di mana logging ke SQL menjadi hambatan.

Saya telah melihat pengaturan "logging dasar dan pencarian" dengan SQL select .. likedan regexps didorong ke batas di mana ia berantakan - ada positif palsu, kelalaian, kode filter mengerikan dengan bug knwon yang sulit dipertahankan dan tidak ada yang mau menyentuh, pesan log baru yang tidak mengikuti asumsi filter, keengganan untuk menyentuh pernyataan logging dalam kode jangan sampai mereka melanggar laporan, dll.

Jadi beberapa paket perangkat lunak muncul untuk mengatasi masalah ini dengan cara yang lebih baik. Ada Serilog, saya mendengar bahwa tim NLog sedang melihatnya , dan kami menulis StructuredLogging.Jsonuntuk Nlog , saya juga melihat bahwa abstraksi core logging ASP.Net yang baru "memungkinkan penyedia logging untuk mengimplementasikan ... logging terstruktur".

Contoh dengan StructuredLogging. Anda login ke logger NLog seperti ini:

logger.ExtendedError("Order send failed", new { OrderId = 1234, RestaurantId = 4567 } );

Data terstruktur ini menuju ke kibana. Nilai 1234disimpan di OrderIdbidang entri log. Anda kemudian dapat mencari menggunakan sintaks kibana query untuk misalnya semua entri log di mana @LogType:nlog AND Level:Error AND OrderId:1234.

Messagedan OrderIdsekarang hanya bidang yang dapat dicari untuk pencocokan tepat atau tidak tepat seperti yang Anda butuhkan, atau digabungkan untuk penghitungan. Ini kuat dan fleksibel.

Dari praktik terbaik StructuredLogging :

Pesan yang dicatat harus sama setiap kali. Ini harus berupa string konstan, bukan string yang diformat untuk berisi nilai data seperti id atau kuantitas. Maka mudah untuk mencari.

Pesan yang dicatat harus berbeda yaitu tidak sama dengan pesan yang dihasilkan oleh pernyataan log yang tidak terkait. Maka mencarinya tidak cocok dengan hal-hal yang tidak terkait juga.

Anthony
sumber