log 4 jsでkoa 2ログミドルウェアを書く

6432 ワード

koaミドルウェアなので、少なくともまずkoaサービスをしなければなりません.
まずlog 4 jsについてご紹介します
log 4 jsモジュールのインストール
npm install log4js --save

appenders
はっきり言って、印刷出力ソースを設定します.
type:
「type」:「console」は、コンソール印刷であり、多くの場合、開発テストに使用されます.
「type」:「file」は、ログ出力が通常のファイルであることを示し、この構成ではログがターゲットフォルダのターゲットファイルに出力され、ファイルサイズの変化に伴って自動的にファイルが生成される.
「type」:「dateFile」は、時間分割ファイルを出力するログを表します.この構成では、ログはターゲットディレクトリに出力され、時間形式で命名されます.時間が経つにつれて、時間形式で命名されたファイルがまだ存在しない場合、自動的に新しいファイルが作成されます.
filename:ログファイルパス.
maxLogSize:type:fileモードのみ有効で、ファイルがどれだけ大きいかを示す場合に次のファイル(xxx.log.1など)を作成する単位がバイトであり、実際に設定する場合の具体的な値は業務によって決まるが、100 Mb以上は推奨されない.
pattern:type:dateFileモードのみ有効で、ファイルの時間ネーミングモードを表し、生成ファイルにpattern構成に従ってfilenameのファイルの最後に時間列を追加してファイルをネーミングします.
AlwaysIncludePattern:type:dateFileモードのみ有効です.この構成はtureです.つまり、最終的なログパスファイル名はfilename+patternです.
backups:type:fileモードのみ有効で、バックアップされたファイルの数を示し、ファイルが多すぎると最も古いファイルが削除されます.
categories
ロゴ4 js.getLogger(分類)が入っていて、次のコードをくどくど見ないでください.
簡単なlog 4 js構成
{
    appenders: {     //      
        cheese: { 
            type: 'dateFile',   //       ,     filename + pattern
            filename: 'logs/',
            pattern: 'yyyy-MM-dd.log',
            alwaysIncludePattern: true
        }
    },
    categories: {     //logger  , log4js.getLogger('default')
        default: { 
            appenders: ['cheese'],
            level: 'info' 
        } 
    }
}

 
ミドルウェアの書き込み開始
ミドルウェアディレクトリを作成し、ディレクトリの下にindex.jsファイル(エントリファイル)を作成し、access.jsファイル(クライアント情報)を再構築します.
index.js
主にapp.jsから渡されたパラメータ別にlog 4 jsを構成し、開発環境であればappendersにdev={type:[console]}を追加し、開発環境でコンソールで印刷できることを示します.またctxにいくつかのlog 4 jsを追加する方法もあります.
const log4js = require('log4js');
const clientInfo = require('./access');
// log4js     
const levels = ['trace', 'debug', 'info', 'warn', 'error', 'fatal'];
module.exports = (appender, options) => {
    // appenders
    let appenders = { 
        cheese: appender    //app.js    appender
    };

    //          appenders  dev
    if(options.env === 'development'){
        appenders.dev = {type: "console"}
    }

    // log4js  
    log4js.configure({
        appenders: appenders,
        categories: { 
            default: {      //         
                appenders: Object.keys(appenders),
                level: options.level    //app.js    level
            } 
        }
    });
    const logger = log4js.getLogger();

    return async (ctx, next) => {
        //  ctx   logger     
        let ctxLogger = {};
        levels.forEach(level => {
            ctxLogger[level] = message => {
                // clientInfo()       
                logger[level](clientInfo(ctx, message));
            }
        })
        ctx.log = ctxLogger;

        ctx.log.startTime = Date.now();

        await next();
    }
}

access.js
クライアント情報を含む出力コンテンツのフォーマット.
/**
 * @param {*} req ctx.req
 * @method      ip  
 */
function getClientIp(req){
    return req.headers['x-forwarded-for'] ||
        req.connection.remoteAddress ||
        req.socket.remoteAddress ||
        req.connection.socket.remoteAddress;
}

function isMobile(userAgent){
    //         pc 
    return /Mobile/.test(userAgent) ? 'Mobile' : 'PC';
}

module.exports = (ctx, message) => {
    let client = {
        ip: getClientIp(ctx.req),
        method: ctx.request.method,
        path: ctx.request.path,
        referer: ctx.request.headers['referer'],
        userAgent: isMobile(ctx.request.headers['user-agent']),
        responseTime: (Date.now()-ctx.log.startTime)/1000 + 's',
        message: message
    }
    //          logger  
    return JSON.stringify(client);
}

app.jsで使用
const myLog = require('koa-sam-log');

// myLog      appender       
app.use(myLog({ 
    type: 'dateFile',   //       ,     filename + pattern
    filename: 'logs/',
    pattern: 'yyyy-MM-dd.log',
    alwaysIncludePattern: true
},{
    env: app.env,      //   development            
    level: 'info'      //logger level
}));

最終ログ印刷スタイル
[2018-11-07T00:24:08.406] [INFO] default - {"ip":"::1","method":"GET","path":"/","userAgent":"PC","responseTime":"0.001s","message":"    koa-sam-log         "}

このミドルウェアはkoa-sam-logというnpmに公開されています.npm installはすぐにプロジェクトで使用できます.
npm install koa-sam-log --save

npmアドレス    githubアドレス
 
ログ解析
ログを書いた以上、その情報を分析しなければならない.
ログはすべてテキストファイルで、正則で分析することができますが、ファイルは基本的にとても大きくて、この時まずストリームでテキストの内容を読み取らなければなりませんが、readStreamには問題があります.毎回最大64 kしか読めません.テキストがどこまで読んだのか全然分かりません.私たちのログの内容は各行印刷なので、ここでreadlineを使うことができます.
コードは次のとおりです.
const fs = require('fs');
const readline = require('readline');
const readliner = readline.createInterface({
  input: fs.createReadStream('./logs/2018-11-05.log')
})

//     
let count = 0;
//       
let data = {
    INFO: 0,
    ERROR: 0,
    FATAL: 0,
    WARN: 0,
    ips: [],
    mobileUser: 0,
    pcUser: 0
}
let levelReg = /(\[INFO\]|\[ERROR\]|\[FATAL\]|\[WARN\])/;
let startTime = Date.now();

readliner.on('line', line => {
    //           
    let key = line.match(levelReg)[0].slice(1, -1);
    data[key]++;

    //       
    if(line.indexOf('"userAgent"') != -1){
        if (line.match(/userAgent\":\"(.+?)\"/)[1] === 'Mobile') {
            data.mobileUser++;
        }else{
            data.pcUser++;
        }
    }

    //   ip    
    if(line.indexOf('"ip"') != -1){
        let ip = line.match(/ip\":\"(.+?)\"/)[1];
        data.ips.push(ip);
    }
    count++;
})

readliner.on('close', () => {
    // ips    
    data.ips = Array.from(new Set(data.ips));
    console.log(data, count);
    console.log(Date.now() - startTime)     //    31104   ,  232ms
})

最後に統計したデータは大体こうです
{ INFO: 10,
  ERROR: 12,
  FATAL: 0,
  WARN: 8,
  ips: [ '::1', '::ffff:10.0.223.238' ],
  mobileUser: 13,
  pcUser: 17 
}

readlineリファレンス記事