ログの記録方法--node/winston

23726 ワード

ログはプログラムの重要な構成部分であり、プログラムはオンラインでログを通じてしか実行状況を観察できないので、良いログは状況を理解し、問題を分析するのに役立ちます.
一般的に、ログ記録はrotate方式でファイルに記録され、通常のログファイルはplain textを採用します.[INFO] 11:06:12 login ok.
しかし、現在では構造化JSONに永続化する傾向があり、{"requestId":"0f111049-09f9-4f8e-9306-900652c833bf","filename":"server/middleware/koa-winston.js","line":14,"level":"info","message":"--> GET /oauth/me?token=WZbxb6O5 200","timestamp":1581954414}
大量のログを生産した後、filebeatを介してELKにプッシュして分析し、このリストはissuesで説明します.winstonの使い方を見てみると、
const winston = require('winston');
const { format } = winston;

const logger = winston.createLogger({
  format: format.combine(
    format.colorize(),
    format.simple()
  ),
  transports: [
    new winston.transports.Console()
  ]
});

logger.log('info', 'some message');
logger.info('some info');
logger.error('some error');

出力内容:
$ node app
info: some message
info: some info
error: some error

ログ呼び出し方法
logger.log('info', 'hello world');

logger.log({
  level: 'info',
  message: 'hello world'
});

// string interpolation
// format     format.splat()
logger.log('info', 'hello world, %s, %s', 'hui', 'http://nonocast.cn');

logger.log({
  level: 'info',
  message: 'hello world, %s, %s',
  splat: ['hui', 'http://nonocast.cn']

});


logger.log({
  level: 'info',
  message: 'hello world, %s',
  splat: ['hui'],
  tag: 'rx'
});

logger.log({
  level: 'info',
  message: 'hello world',
  user: {
    name: 'hui',
    homepage: 'http://nonocast.cn'
  }
});

注意:
  • splatはstring interpolationに対応し、文字列フォーマットを実現する.
  • level: error: 0, warn: 1, info: 2, http: 3, verbose: 4, debug: 5, silly: 6.

  • The info parameter provided to a given format represents a single log message. The object itself is mutable. Every info must have at least the level and message properties.
    format
    formatはinfo処理のchainで、middlewareに似ています.
    new winston.transports.File({
      filename: 'app.log',
      format: format.combine(
        format(info => {
          info.message = strip(info.message);
          return info;
        })(),
        format.json()
      )
    })
    

    transport
    Transportは記録チャネルを表しており、これは比較的理解しやすい.
    container
    winson.loggersというcontainerは複数のloggerを管理します.例えばcategoryはサービスに、web controllerにあげます.
    winston.loggers.add('category1', { format: ..., transports: ... });
    winston.loggers.add('category2', { format: ..., transports: ... });
    
    let logger = winson.loggers.get('category2');
    

    error
    format.errors({ stack: true })
    

    そしてinfo(new Error(...))がstackを出力すると
    出力されたstackコンテンツは、
    {“level”:“info”,“message”:“Yo, it’s on fire”,“stack”:“Error: Yo, it’s on fire at Object. (/Users/nonocast/Desktop/hello-winston/app.js:34:20) at Module._compile (internal/modules/cjs/loader.js:701:30) at Object.Module._extensions…js (internal/modules/cjs/loader.js:712:10) at Module.load (internal/modules/cjs/loader.js:600:32) at tryModuleLoad (internal/modules/cjs/loader.js:539:12) at Function.Module._load (internal/modules/cjs/loader.js:531:3) at Function.Module.runMain (internal/modules/cjs/loader.js:754:12) at startup (internal/bootstrap/node.js:283:19) at bootstrapNodeJSCore (internal/bootstrap/node.js:622:3)”}
    query
    ログでレコードをクエリーすることができます.これはできます.
    const options = {
      from: moment().subtract(1, 'hours').unix(),
      until: moment().unix(),
      limit: 10,
      start: 0,
      order: 'desc',
      fields: ['message']
    };
    
    //
    // Find items logged between today and yesterday.
    //
    logger.query(options, function (err, results) {
      if (err) {
        /* TODO: handle me */
        throw err;
      }
    
      console.log(results);
    });
    

    Koa統合
    まずkoa-loggerを見てみましょう
    const logger = require('koa-logger');
    app.use(logger());
    

    1つのリクエストは2つ出力されますが、情報量が少なすぎて、
      GET / 200 9ms 12b
    

    loggerはブロックできます
      .use(logger((str, args) => {
        // redirect koa logger to other output pipe
        // default is process.stdout(by console.log function)
    
    }));
    
  • Param str is output string with ANSI Color, and you can get pure text with other modules like strip-ansi. 色付き文字列.
  • Param args is a array by [format, method, url, status, time, length]

  • koa-logger連注釈157行全体で、彼がどのように要求をブロックしたかを簡単に見てみましょう.
  • middleware先行log要求
  • は、次いでawait next()がすべてのmiddlewareが終了した後に終了log
  • を記録することに等しい.
    koa-requestidと組み合わせてkoa-winstonのmiddlewareを書きました
    const chalk = require('chalk');
    
    module.exports = (logger) => {
      return async function (ctx, next) {
        let child = logger.child({ requestId: ctx.state.id });
    
        ctx.logger = child;
    
        ctx.logger.info(`${chalk.gray(')} ${chalk.bold(ctx.method)} ${chalk.gray(ctx.originalUrl)}`);
    
        try {
          await next()
        } catch (err) {
          ctx.logger.warn(err);
          throw err
        }
    
        ctx.logger.info(`${chalk.gray('-->')} ${chalk.bold(ctx.method)} ${chalk.gray(ctx.originalUrl)}`);
      }
    }