Tugas pertama yang paling sering dihadapi oleh pengembang yang mulai memprogram dalam JavaScript adalah cara mencatat peristiwa dalam log konsol menggunakan metode 
console.log . Dalam mencari informasi tentang debugging kode JavaScript, Anda akan menemukan ratusan artikel blog, serta instruksi tentang StackOverflow, yang memberi tahu Anda untuk "sekadar" menampilkan data ke konsol melalui metode 
console.log . Ini adalah praktik yang umum sehingga saya harus memperkenalkan aturan untuk kontrol kualitas kode, seperti 
no-console , agar tidak meninggalkan entri log acak dalam kode produksi. Tetapi bagaimana jika Anda perlu secara khusus mendaftarkan suatu acara untuk memberikan informasi tambahan?
Artikel ini membahas berbagai situasi di mana Anda perlu memelihara log; Ini menunjukkan perbedaan antara metode 
console.log dan 
console.error di Node.js dan menunjukkan cara meneruskan fungsi logging ke pustaka tanpa membebani konsol pengguna. 

Fondasi teoretis untuk bekerja dengan Node.js
Metode 
console.log dan 
console.error dapat digunakan di browser dan di Node.js. Namun, ketika menggunakan Node.js, ada satu hal penting yang perlu diingat. Jika Anda membuat kode berikut di Node.js menggunakan file bernama 
index.js ,

dan kemudian jalankan di terminal menggunakan 
node index.js , maka hasil dari eksekusi perintah akan terletak satu di atas yang lain:

Terlepas dari kenyataan bahwa mereka tampak serupa, sistem memprosesnya secara berbeda. Jika Anda melihat bagian operasi 
console di 
dokumentasi Node.js , ternyata 
console.log mencetak hasilnya melalui 
stdout , dan 
console.error mencetak melalui 
stderr .
Setiap proses dapat bekerja dengan tiga aliran ( 
stream ) secara default: 
stdin , 
stdout dan 
stderr . Aliran 
stdin memproses input untuk suatu proses, misalnya, klik tombol atau keluaran diarahkan (lebih lanjut tentang ini di bawah). Aliran output 
stdout standar adalah untuk menghasilkan data aplikasi. Akhirnya, aliran kesalahan 
stderr standar dirancang untuk menampilkan pesan kesalahan. Jika Anda perlu mencari tahu untuk apa 
stderr dan kapan menggunakannya, baca 
artikel ini .
Singkatnya, ini dapat digunakan untuk menggunakan pengalihan ( 
> ) dan operator pipa ( 
| ) untuk bekerja dengan kesalahan dan informasi diagnostik secara terpisah dari hasil aktual aplikasi. Jika operator 
> memungkinkan Anda untuk mengarahkan output dari hasil perintah ke file, maka menggunakan operator 
2> Anda dapat mengarahkan output dari stream kesalahan 
stderr ke file. Misalnya, perintah ini mengirimkan 
Halo ke file 
hello.log , dan 
Bye bye ke file 
error.log .


Kapan saya perlu menulis acara ke log?
Sekarang kami telah meninjau aspek teknis yang mendasari penebangan, mari beralih ke berbagai skenario di mana Anda perlu mendaftarkan acara. Biasanya, skenario ini termasuk dalam salah satu dari beberapa kategori:
Artikel ini hanya membahas tiga skenario terakhir berdasarkan Node.js.
Logging untuk aplikasi server
Ada beberapa alasan untuk mencatat peristiwa yang terjadi di server. Misalnya, mencatat permintaan masuk memungkinkan Anda untuk mendapatkan statistik tentang seberapa sering pengguna menemukan 404 kesalahan, apa yang bisa menjadi alasan untuk ini, atau aplikasi klien 
User-Agent mana yang sedang digunakan. Anda juga dapat mengetahui waktu kesalahan terjadi dan penyebabnya.
Untuk bereksperimen dengan materi yang diberikan di bagian artikel ini, Anda perlu membuat katalog baru untuk proyek tersebut. Di direktori proyek, buat 
index.js untuk kode yang akan digunakan, dan jalankan perintah berikut untuk memulai proyek dan menginstal 
express :

Kami menyiapkan server dengan middleware, yang akan mendaftarkan setiap permintaan di konsol menggunakan metode 
console.log . Kami menempatkan baris berikut di file 
index.js :

Ini menggunakan 
console.log('%O', req) untuk mencatat seluruh objek dalam log. Dari sudut pandang struktur internal, metode 
console.log menggunakan 
util.forma t, yang, selain 
%O mendukung placeholder lain. Informasi tentang mereka dapat ditemukan di 
dokumentasi Node.js.Ketika menjalankan 
node index.js untuk memulai server dan beralih ke 
localhost : 3000, konsol menampilkan banyak informasi yang tidak perlu:

Jika sebaliknya menggunakan 
console.log('%s', req) agar tidak menampilkan objek sepenuhnya, Anda tidak akan mendapatkan banyak informasi:

Anda dapat menulis fungsi logging Anda sendiri, yang hanya akan menghasilkan data yang diperlukan, tetapi pertama-tama Anda harus memutuskan informasi mana yang dibutuhkan. Terlepas dari kenyataan bahwa fokusnya biasanya pada isi pesan, pada kenyataannya seringkali perlu untuk mendapatkan informasi tambahan, yang meliputi:
- timestamp - untuk mengetahui kapan peristiwa terjadi;
- nama komputer / server - jika sistem terdistribusi berjalan;
- pengidentifikasi proses - jika beberapa proses Node berjalan menggunakan, misalnya, pm2;
- message - pesan aktual dengan beberapa konten;
- stack trace - jika ada kesalahan yang dicatat;
- variabel / informasi tambahan.
Selain itu, mengingat bahwa bagaimanapun juga, semuanya adalah output ke 
stdout dan 
stderr stream, ada kebutuhan untuk menyimpan jurnal di level yang berbeda, serta mengkonfigurasi dan memfilter entri jurnal tergantung pada level.
Ini dapat dicapai dengan mendapatkan akses ke berbagai bagian 
process dan menulis beberapa baris kode dalam JavaScript. Namun, Node.js luar biasa karena sudah memiliki ekosistem 
npm dan beberapa perpustakaan yang dapat digunakan untuk tujuan ini. Ini termasuk:
- pino;
- winston;
- roarr ;
- bunyan (perpustakaan ini belum diperbarui selama dua tahun).
Pino sering disukai karena cepat dan memiliki ekosistemnya sendiri. Mari kita lihat bagaimana 
pino dapat membantu logging. Keuntungan lain dari perpustakaan ini adalah paket 
express-pino-logger , yang memungkinkan Anda untuk mendaftar permintaan.
Instal 
pino dan 
express-pino-logger :

Setelah itu, kami memperbarui file 
index.js untuk menggunakan event logger dan middleware:

Dalam fragmen ini, kami membuat sebuah instance dari event 
logger untuk 
pino dan meneruskannya ke 
express-pino-logger untuk membuat perangkat lunak logging event lintas platform baru yang dengannya Anda dapat memanggil 
app.use . Selain itu, 
console.log diganti pada 
logger.info oleh 
logger.info dan 
logger.debug ditambahkan ke rute untuk menampilkan berbagai tingkat log.
Jika Anda me-restart server dengan berulang kali mengeksekusi 
node index.js , Anda akan mendapatkan hasil yang berbeda pada output, di mana setiap baris / baris akan menjadi output dalam format JSON. Sekali lagi, buka 
localhost : 3000 untuk melihat baris baru dalam format JSON.

Di antara data dalam format JSON, Anda dapat menemukan informasi yang disebutkan sebelumnya, seperti cap waktu. Juga perhatikan bahwa pesan 
logger.debug tidak ditampilkan. Untuk membuatnya terlihat, Anda perlu mengubah level log default. Setelah membuat instance dari registrasi event logger, 
process.env.LOG_LEVEL ditetapkan. Ini berarti Anda dapat mengubah nilai atau menerima nilai 
info default. 
LOG_LEVEL=debug node index.js menjalankan 
LOG_LEVEL=debug node index.js , kami mengubah level log.
Sebelum melakukan ini, perlu untuk memecahkan masalah format output, yang tidak nyaman untuk persepsi saat ini. Langkah ini disengaja. Menurut filosofi 
pino , untuk alasan kinerja, perlu untuk mentransfer pemrosesan entri jurnal ke proses terpisah, melewati output (menggunakan operator 
| ). Prosesnya melibatkan menerjemahkan output ke dalam format yang lebih nyaman untuk persepsi manusia, atau mengunggahnya ke cloud. Tugas ini dilakukan oleh alat transfer yang disebut 
transports . Lihatlah 
dokumentasi alat 
transports dan lihat mengapa kesalahan 
pino tidak dihasilkan melalui 
stderr .
Untuk melihat versi majalah yang lebih mudah dibaca, gunakan alat 
pino-pretty . Jalankan di terminal:

Semua entri log ditransfer menggunakan 
| siap untuk 
pino-pretty , karena yang outputnya "dibersihkan", yang hanya akan berisi informasi penting yang ditampilkan dalam warna yang berbeda. Jika Anda meminta 
localhost : 3000 lagi, pesan 
debug debugging akan muncul.

Agar entri jurnal lebih mudah dibaca atau dikonversi, ada banyak alat transmisi. Mereka bahkan dapat ditampilkan menggunakan emoji menggunakan 
pino-colada . Alat-alat ini akan berguna untuk pengembangan lokal. Ketika server sedang dalam produksi, mungkin perlu untuk mentransfer data log menggunakan 
alat lain , menulisnya ke disk menggunakan 
> untuk diproses lebih lanjut, atau melakukan dua operasi pada saat yang sama menggunakan perintah tertentu, misalnya 
tee .
Dokumen ini juga berbicara tentang memutar file log, memfilter dan menulis data log ke file lain.
Penjurnalan perpustakaan
Dengan menjelajahi cara-cara untuk mengatur logging untuk aplikasi server secara efisien, Anda dapat menggunakan teknologi yang sama untuk perpustakaan Anda sendiri.
Masalahnya adalah bahwa dalam kasus perpustakaan, Anda mungkin perlu menyimpan log untuk keperluan debugging tanpa memuat aplikasi klien. Sebaliknya, klien harus dapat mengaktifkan log jika debugging diperlukan. Secara default, perpustakaan tidak boleh merekam output, memberi pengguna ini hak.
Contoh yang baik dari hal ini adalah kerangka kerja 
express . Banyak proses terjadi dalam struktur internal framework 
express , yang dapat menyebabkan minat untuk mempelajarinya lebih dalam selama debugging aplikasi. 
Dokumentasi untuk kerangka kerja menyatakan bahwa Anda dapat menambahkan 
DEBUG=express:* ke awal perintah sebagai berikut:

Jika Anda menerapkan perintah ini ke aplikasi yang ada, Anda dapat melihat banyak output tambahan yang akan membantu debugging:

Informasi ini tidak dapat dilihat kecuali log debug diaktifkan. Ada paket 
debug untuk ini. Ini dapat digunakan untuk menulis pesan di "namespace", dan jika pengguna perpustakaan menyertakan namespace ini atau wildcard yang cocok dengan itu dalam 
variabel lingkungan DEBUG mereka, pesan akan ditampilkan. Pertama, Anda perlu menginstal perpustakaan 
debug :

Buat file baru bernama 
random-id.j yang akan mensimulasikan perpustakaan dan memasukkan kode berikut ke dalamnya:

Akibatnya, logger kejadian 
debug baru akan dibuat dengan 
mylib:randomid , di mana dua pesan akan didaftarkan. Kami menggunakannya di 
index.js dari bagian sebelumnya:

Jika Anda memulai server lagi, menambahkan 
DEBUG=mylib:randomid node index.js kali ini, maka entri log debug untuk "pustaka" kami akan ditampilkan:

Jika pengguna perpustakaan ingin memasukkan informasi debug dalam entri log 
pino , mereka dapat menggunakan perpustakaan yang disebut 
pino-debug dibuat oleh perintah 
pino untuk memformat entri ini dengan benar.
Instal perpustakaan:

Sebelum menggunakan 
debug untuk pertama kali, 
pino-debug harus diinisialisasi. Cara termudah untuk melakukan ini adalah dengan menggunakan tanda 
-r atau --require untuk meminta modul sebelum menjalankan skrip. Kami me-restart server menggunakan perintah (asalkan 
pino-colada diinstal):

Akibatnya, entri log debug perpustakaan akan ditampilkan dengan cara yang sama seperti di log aplikasi:

Output Antarmuka Baris Perintah (CLI)
Kasus terakhir yang dibahas oleh artikel ini adalah masuk ke antarmuka baris perintah. Lebih disukai, log yang merekam peristiwa yang berkaitan dengan logika program disimpan terpisah dari log untuk mendaftarkan data antarmuka baris perintah. Untuk merekam peristiwa apa pun yang terkait dengan logika program, Anda perlu menggunakan pustaka tertentu, misalnya 
debug . Dalam hal ini, Anda dapat menggunakan kembali logika program tanpa dibatasi pada satu skenario menggunakan antarmuka baris perintah.
Dengan membuat antarmuka baris perintah menggunakan Node.js , Anda dapat menambahkan berbagai warna, blok nilai variabel, atau alat pemformatan untuk memberikan tampilan yang menarik secara visual kepada antarmuka. Namun, Anda perlu mengingat beberapa skenario.
Menurut salah satu dari mereka, antarmuka dapat digunakan dalam konteks sistem integrasi kontinu (CI), dalam hal ini lebih baik untuk meninggalkan pemformatan warna dan presentasi hasil yang terlalu banyak secara visual. Beberapa sistem integrasi berkelanjutan memiliki flag 
CI ditetapkan. Anda dapat memverifikasi bahwa Anda berada dalam sistem integrasi berkelanjutan menggunakan paket 
is-ci , yang mendukung beberapa sistem seperti itu.
Beberapa perpustakaan, seperti 
chalk , mendefinisikan sistem integrasi berkelanjutan dan mengganti output teks berwarna ke konsol. Mari kita lihat cara kerjanya.
Instal 
chalk dengan perintah 
install chalk npm dan buat file bernama 
cli.js Masukkan baris berikut dalam file:

Sekarang, jika Anda menjalankan skrip ini menggunakan 
node cli.js , hasilnya akan disajikan menggunakan warna yang berbeda:

Tetapi jika Anda menjalankan skrip menggunakan 
CI=true node cli.js , pemformatan warna teks akan dibatalkan:

Dalam skenario lain yang patut diingat, 
stdout berjalan dalam mode terminal, yaitu data adalah output ke terminal. Dalam hal ini, hasilnya dapat ditampilkan dengan baik menggunakan 
boxen . Kalau tidak, output kemungkinan besar akan diarahkan ke file atau di tempat lain.
Anda dapat memeriksa operasi 
stdin , 
stdout atau 
stderr stream dalam mode terminal dengan melihat atribut 
isTTY dari aliran yang sesuai. Misalnya, 
process.stdout.isTTY . 
TTY berarti "teletypewriter" dan dalam hal ini dirancang khusus untuk terminal.
Nilai dapat bervariasi untuk masing-masing dari tiga utas, tergantung pada bagaimana proses Node.js dimulai. Informasi terperinci tentang ini dapat ditemukan di 
dokumentasi Node.js, di bagian βInput / output prosesβ .
Mari kita lihat bagaimana nilai 
process.stdout.isTTY bervariasi dalam situasi yang berbeda. 
cli.js file 
cli.js untuk memeriksanya:

Sekarang jalankan 
node cli.js di terminal dan lihat kata 
true , setelah itu pesan ditampilkan dalam font berwarna:

Setelah itu, kita kembali menjalankan perintah, tetapi mengarahkan output ke file, dan kemudian melihat isinya:

Kali ini, kata 
undefined muncul di terminal, diikuti oleh pesan yang ditampilkan dalam font tidak berwarna, karena aliran 
stdout mengarahkannya keluar dari mode terminal. Di sini 
chalk menggunakan alat 
supports-color , yang dari sudut pandang struktur internal memeriksa 
isTTY aliran yang sesuai.

Alat-alat seperti 
chalk melakukan hal-hal ini sendiri. Namun, ketika mengembangkan antarmuka baris perintah, Anda harus selalu waspada terhadap situasi ketika antarmuka bekerja dalam sistem integrasi berkelanjutan atau output dialihkan. Alat-alat ini membantu Anda menggunakan antarmuka baris perintah di tingkat yang lebih tinggi. Misalnya, data di terminal dapat diatur dengan cara yang lebih terstruktur, dan jika 
isTTY tidak 
undefined , beralihlah ke cara analisis yang lebih sederhana.
Kesimpulan
Mulai menggunakan JavaScript dan memasukkan baris pertama di log konsol menggunakan 
console.log cukup sederhana. Tetapi sebelum Anda menyebarkan kode dalam produksi, Anda harus mempertimbangkan beberapa aspek menggunakan log. Artikel ini hanya pengantar berbagai metode dan solusi yang digunakan dalam mengatur log peristiwa. Itu tidak mengandung semua yang perlu Anda ketahui. Oleh karena itu, disarankan untuk memperhatikan proyek open source yang sukses dan memantau bagaimana mereka memecahkan masalah logging dan alat apa yang digunakan. Dan sekarang coba login sendiri tanpa mengeluarkan data ke konsol.
Jika Anda tahu alat lain yang layak disebut, tulislah di komentar.