ホームページ  >  記事  >  ウェブフロントエンド  >  ノードでフルリンクのログをエレガントに出力する方法を段階的に説明します

ノードでフルリンクのログをエレガントに出力する方法を段階的に説明します

青灯夜游
青灯夜游転載
2022-03-07 20:05:102679ブラウズ

ノードはどのようにしてリンク全体のログをエレガントに出力するのでしょうか?次の記事では、node でフルリンクのログをエレガントに出力する方法を紹介します。

ノードでフルリンクのログをエレガントに出力する方法を段階的に説明します

ユーザーが問題を報告した場合: 特定のオンライン機能の使用中にエラーが発生した場合、どのようにすれば迅速かつ正確にエラーを特定できるでしょうか?特定のリクエスト インターフェイスがデータを返すのが遅い場合に最適化を効果的に追跡するにはどうすればよいでしょうか?

1. 原則と実践

ご存知のとおり、リクエストが届くと、おそらく次のログが生成されます:

1. AceesLog : ユーザー アクセス ログ

##2. 例外: コード例外ログ

##3. SQL: SQL クエリ ログ

##4. ThirdParty: サードパーティ サービス ログ

1 つのリクエストによって生成されたすべてのログを追跡するには?

一般的なアプローチは、requestId を一意の識別子として使用することです。

次に、ミドルウェアを作成し、requestId をコンテキストに挿入します。ロギングが必要な場合は、コンテキストから出力します。

サードパーティ サービスと SQL ログでは、印刷のために requestId も対応する関数に渡す必要があります。このレイヤーごとの転送は非常に面倒で、コードも比較的煩雑です。

私たちの目標は、コードの侵入性を軽減し、コードを一度挿入すれば自動的に追跡することです。

調査後、async_hooks は非同期動作のライフ サイクルを追跡できます。各非同期リソース (各リクエストは非同期リソースです) には 2 つの ID があり、

は asyncId (現在のライフ サイクル ID)非同期リソースの)、trigerAsyncId (親非同期リソース ID)。

async_hooks は、非同期リソースを監視するための次のライフ サイクル フックを提供します。

asyncHook = async_hook.createHook({
  // 监听异步资源的创建
  init(asyncId,type,triggerAsyncId,resource){},
  // 异步资源回调函数开始执行之前
  before(asyncId){},
  // 异步资源回调函数开始执行后
  after(asyncId){},
  // 监听异步资源的销毁
  destroy(asyncId){}
})

マッピングを作成すると、各 asyncId がストレージにマッピングされ、対応する requestId がストレージに保存されます。 requestId は簡単に取得できます。

たまたま、cls フックされたライブラリは async_hooks に基づいてカプセル化されており、同じ非同期リソース内にデータのコピーを維持し、キーと値のペアの形式で保存しています。 (注: async_hooked は、node>=8.2.1 以降の上位バージョンで使用する必要があります) もちろん、コミュニティには cls-session、node-continuation-local-storage などの他の実装もあります。

以下は、cls-hooked をプロジェクトに適用した例です。

/session.js 名前付きストレージ スペースを作成します

const createNamespace = require('cls-hooked').createNamespace 
const session = createNamespace('requestId-store') 
module.exports = session

/logger.js ログを出力します

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) 
} 
}

/sequelize.js SQL はログを出力するためにロガーを呼び出します

const logger = require("./logger") 
new Sequelize( 
logging: function (sql, costtime) { 
logger.error( `sql exe : ${sql} | costtime ${costtime} ms` ); 
} )

/app.js requestId を設定し、応答ヘッダーを返す requestId を設定し、アクセス ログを出力します

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)
}) }

次を見てみましょう リクエストパスが/home?a=1の場合のログ:

访问日志:
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

全体の同じリクエストのログのrequestIdが確認できます。リンクも同じです。後でアラーム プラットフォームに送信されたアラームがある場合は、requestId に基づいて、このリクエストによって実行されたリンク全体を見つけることができます。

注意深い学生は、インターフェイスから返される応答ヘッダーにも requestId を設定していることに気づくかもしれません。目的は、特定のリクエストの応答が遅い場合や問題がある場合に、ブラウザから requestId を直接知ることです。分析を行うことができます。

#2. パフォーマンスのオーバーヘッド

ローカルでストレス テストを実施しました。これはメモリ使用量の比較です:

#async_hook を使用しない場合よりも約 10% 増加します。

レベル 100 の QPS システムには問題ありませんが、同時実行性の高いサービスの場合は、慎重に検討する必要があるかもしれません。 ノードでフルリンクのログをエレガントに出力する方法を段階的に説明します

ps: エラーがある場合は指摘してください。気に入らない場合はコメントしないでください。

ノード関連の詳細については、

nodejs を参照してください。チュートリアル###!

以上がノードでフルリンクのログをエレガントに出力する方法を段階的に説明しますの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はjuejin.cnで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。