web-dev-qa-db-ja.com

NodeJS Express-グローバル一意リクエストID

ロガーを各メソッド/関数呼び出しに渡さずに、各ログステートメントに含まれる一意のリクエストIDを定義することはできますか?

使用中のテクノロジ:NodeJS、Express、Winston

15
smokedice

編集済み

最後に、すべての作業を行うライブラリを作成しました。 https://github.com/davicente/express-logger-unique-req-id

Winstonライブラリのラッパーなので、同じように使用できます。

それがあなたを助けるかどうか私に知らせてください


いくつかのプロジェクトで同じ問題があり、この質問に対する完全な解決策を見つけることができませんでした。同じテクノロジー(ログにはNode.js、Express.js、Winston)を使用しています。いくつかのライブラリを使用してWinstonライブラリをラップすることで、これに対する解決策を見つけました。-各リクエストに対して一意の識別子を作成するためのnode-uuidすべての呼び出しでreqオブジェクトを送信せずに、異なるモジュール間でこのIDを共有するためのストレージ。

まず、リクエストごとに一意の識別子を作成して設定する必要があります。私はミドルウェアでそれをします:

var uuid = require('node-uuid');
var createNamespace = require('continuation-local-storage').createNamespace;
var myRequest = createNamespace('my request');

// Run the context for each request. Assign a unique identifier to each request
app.use(function(req, res, next) {
    myRequest.run(function() {
        myRequest.set('reqId', uuid.v1());
        next();
    });
});

その後、Winstonライブラリをラップして、コンテキストからIDを回復し、ログのメッセージに追加する必要がありました。

var winston = require('winston');
var getNamespace = require('continuation-local-storage').getNamespace;

// Wrap Winston logger to print reqId in each log
var formatMessage = function(message) {
    var myRequest = getNamespace('my request');
    message = myRequest && myRequest.get('reqId') ? message + " reqId: " + myRequest.get('reqId') : message;
    return message;
};

var logger = {
    log: function(level, message) {
        winstonLogger.log(level, formatMessage(message));
    },
    error: function(message) {
        winstonLogger.error(formatMessage(message));
    },
    warn: function(message) {
        winstonLogger.warn(formatMessage(message));
    },
    verbose: function(message) {
        winstonLogger.verbose(formatMessage(message));
    },
    info: function(message) {
        winstonLogger.info(formatMessage(message));
    },
    debug: function(message) {
        winstonLogger.debug(formatMessage(message));
    },
    silly: function(message) {
        winstonLogger.silly(formatMessage(message));
    }
};
module.exports = logger;

少し複雑だったと思いますので、投稿に書き留めております。あなたはそこからより多くの情報を得ることができます: Express.js:グローバルな一意のリクエストIDを持つログ情報– Node.js

これが問題の解決に役立つことを願っています。

9
David Vicente

この回答 には問題があります。ノードプロセスが再起動されるたびに、カウンタは0に戻ります。かなり簡単に回避できることがわかりました。 [uuid パッケージを使用して、呼び出された各リクエストに [〜#〜] uuid [〜#〜] でタグ付けするExpressミドルウェアを追加するだけです。

Uuid 2.0以前の場合

const uuid = require('uuid');
const app = express();
app.use(function (req, next) {
  req.id = uuid.v4();
  next();
});

Uuid 3.0以降の場合

const uuidv4 = require('uuid/v4');
const app = express();
app.use(function (req, next) {
  req.id = uuidv4();
  next();
});
4
milan

リクエスト処理の最初に、次のようなものを追加します(または独自のファイルに追加します)。

var makeID = (function() {
  var index = 0;
  return function() {
   return index++;
  }
})();

app.use(function(req, res, next) {
  req.id = makeID()
  next()
})

これにより、すべてのリクエストに一意の(順次)IDが付与されます。 それを使って身元を明かさないでください。内部でのみ使用してください!

Winstonにログインするときに、次のようなメタデータを入力して、メッセージの後に表示することができます(${name}=${value}の形式)。

app.use(function(req, res) {
  winston.log('info', 'Test Log Message', { id: req.id });
  res.end("Done.")
});

これがお役に立てば幸いです。

0
MayorMonty