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.