Rumah  >  Artikel  >  hujung hadapan web  >  Ajar anda langkah demi langkah cara mencetak log pautan penuh dalam nod dengan elegan

Ajar anda langkah demi langkah cara mencetak log pautan penuh dalam nod dengan elegan

青灯夜游
青灯夜游ke hadapan
2022-03-07 20:05:102660semak imbas

Bagaimanakah nod mencetak log pautan penuh dengan elegan? Artikel berikut akan memperkenalkan kepada anda cara mencetak log pautan penuh dengan elegan dalam nod Saya harap ia akan membantu anda!

Ajar anda langkah demi langkah cara mencetak log pautan penuh dalam nod dengan elegan

Apabila pengguna melaporkan masalah: Apabila ralat berlaku apabila menggunakan fungsi dalam talian tertentu, bagaimanakah kita boleh mengesannya dengan cepat dan tepat? Bagaimana untuk mengesan pengoptimuman dengan berkesan apabila antara muka permintaan tertentu mengembalikan data dengan perlahan?

1. Prinsip dan Amalan

Seperti yang kita semua tahu, apabila permintaan datang, log berikut mungkin akan dihasilkan:

1 : Log akses pengguna

2. Pengecualian: Log pengecualian kod

3. SQL: log pertanyaan sql

4 >Bagaimana untuk menjejaki Semua log yang dihasilkan oleh satu permintaan?

Pendekatan umum ialah menggunakan requestId sebagai pengecam unik,

dan kemudian tulis middleware untuk menyuntik requestId ke dalam konteks Apabila pengelogan diperlukan, keluarkannya daripada konteks dan cetak.

Dalam perkhidmatan pihak ketiga dan log SQL, requestId juga perlu dihantar ke dalam fungsi yang sepadan untuk mencetak Pemindahan lapisan demi lapisan ini benar-benar terlalu menyusahkan dan kodnya agak mengganggu.

Matlamat kami adalah untuk mengurangkan gangguan kod, menyuntiknya sekali dan menjejakinya secara automatik.

Selepas penyelidikan, async_hooks boleh menjejaki kitaran hayat kelakuan tak segerak Dalam setiap sumber tak segerak (setiap permintaan ialah sumber tak segerak), ia mempunyai 2 ID, masing-masing asyncId (ID kitaran hayat semasa. sumber tak segerak), trigerAsyncId (ID sumber tak segerak induk).

async_hooks menyediakan cangkuk kitaran hayat berikut untuk memantau sumber tak segerak:

Jika kami membuat pemetaan, setiap asyncId memetakan ke storan dan requestId yang sepadan disimpan dalam storan, maka requestId boleh diperolehi dengan mudah.

Kebetulan perpustakaan cls-hooked telah dikapsulkan berdasarkan async_hooks Ia mengekalkan salinan data dalam sumber tak segerak yang sama dan menyimpannya dalam bentuk pasangan nilai kunci. (Nota: async_hooked perlu digunakan dalam nod versi yang lebih tinggi>=8.2.1) Sudah tentu, terdapat pelaksanaan lain dalam komuniti, seperti cls-session, node-continuation-local-storage, dsb.
asyncHook = async_hook.createHook({
  // 监听异步资源的创建
  init(asyncId,type,triggerAsyncId,resource){},
  // 异步资源回调函数开始执行之前
  before(asyncId){},
  // 异步资源回调函数开始执行后
  after(asyncId){},
  // 监听异步资源的销毁
  destroy(asyncId){}
})

Berikut ialah contoh cara saya menggunakan cls-hooked dalam projek saya:

/session.js Cipta ruang storan bernama

/logger.js Log Cetak

const createNamespace = require('cls-hooked').createNamespace 
const session = createNamespace('requestId-store') 
module.exports = session
/sequelize.js sql panggilan logger untuk mencetak log

const session = require('./session') 
module.exports = { 
info: (message) => 
{ 
const requestId = session.get('requestId')
console.log(`requestId:${requestId}`, message) 
}, 
error: (message) => 
{ 
const requestId = session.get('requestId') 
console.error(`requestId:${requestId}`, message) 
} 
}
/app.js Tetapkan requestId, tetapkan requestId untuk mengembalikan pengepala respons, cetak log akses

const logger = require("./logger") 
new Sequelize( 
logging: function (sql, costtime) { 
logger.error( `sql exe : ${sql} | costtime ${costtime} ms` ); 
} )
Mari kita lihat log apabila laluan permintaan ialah /home?a=1:

const session = require('./session') 
const logger = require('./logger') 
async function accessHandler(ctx, next) 
{ 
const requestId = ctx.header['x-request-id'] || uuid()
const params = ctx.request.body ? JSON.stringify(ctx.request.body) : JSON.stringify(ctx.request.query)
// 设置requestId session.run(() => { session.set('requestId', requestId)
logger.info(`url:${ctx.request.path};params:${params}`) next()
// 设置返回响应头
ctx.res.setHeader('X-Request-Id',requestId)
}) }
Anda boleh melihat bahawa requestId dalam log permintaan yang sama untuk keseluruhan pautan adalah sama. Jika terdapat penggera kemudian dihantar ke platform penggera, maka kami boleh mencari keseluruhan pautan yang dilaksanakan oleh permintaan ini berdasarkan requestId.

Pelajar yang berhati-hati mungkin menyedari bahawa saya juga menetapkan requestId dalam pengepala respons yang dikembalikan oleh antara muka Tujuannya adalah untuk mengetahui requestId terus daripada penyemak imbas jika permintaan didapati bertindak balas dengan perlahan atau menghadapi masalah boleh buat analisis.
访问日志:
requestId:79f422a6-6151-4bfd-93ca-3c6f892fb9ac url:/home;params:{"a":"1"}

Sql日志:
requestId:79f422a6-6151-4bfd-93ca-3c6f892fb9ac sql exe :
Executed (default): SELECT `id` FROM t_user

2. Overhed prestasi

Saya melakukan ujian tekanan secara tempatan, Ini ialah perbandingan penggunaan memori:

Kira-kira 10% lebih daripada tidak menggunakan async_hook.

Ajar anda langkah demi langkah cara mencetak log pautan penuh dalam nod dengan eleganUntuk sistem 100 peringkat QPS kami, tidak mengapa, tetapi jika ia adalah perkhidmatan konkurensi tinggi, kami mungkin perlu mempertimbangkannya dengan teliti.

ps: Jika terdapat sebarang ralat, sila nyatakan, jangan komen jika anda tidak menyukainya

Untuk lebih banyak pengetahuan berkaitan nod, sila lawati:

nodejs tutorial

!

Atas ialah kandungan terperinci Ajar anda langkah demi langkah cara mencetak log pautan penuh dalam nod dengan elegan. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:juejin.cn. Jika ada pelanggaran, sila hubungi admin@php.cn Padam