web-dev-qa-db-ja.com

ログ出力の行番号とファイル名を取得します

各ログ出力の行番号とファイルを取得することは可能ですか?

例えば:

  var winston = require('winston');

  winston.log('info', 'some message!'); // this is at line 4 of myfile.js

ログファイルで、「メッセージ」がmyFile.jsの4行目から来たことを指定する必要があります。

8
Lev

ファイル名をlabelとして渡すことができ、callingModuleからファイル名を取得できます。

作成logger.jsファイルとコードのような

var winston = require('winston');
var getLabel = function (callingModule) {
    var parts = callingModule.filename.split('/');
    return parts[parts.length - 2] + '/' + parts.pop();
};

module.exports = function (callingModule) {
    return new winston.Logger({
        transports: [
            new winston.transports.Console({
                label: getLabel(callingModule),
                json: false,
                timestamp: true,
                depth:true,
                colorize:true
            })
        ]
    });
};

今ここにあなたのテストファイル

var logger = require('./logger')(module);
function test() {
    logger.info('test logger');
}
test();

テストファイルを実行すると、出力は次のようになります。

2017-07-08T07:15:20.671Z - info: [utils/test.js] test logger
10
Nitin Vavdiya

ウィンストンは、パフォーマンス上の懸念から、それを行う計画を持っていませんでした。詳細については ここをチェック してください。

https://github.com/baryon/tracer を試しましたが、良くありません。行番号が間違っている場合があります。

2
Qiulang

私はこのコードをどこかで見つけました、ええ、しかしそれは機能しています。新しいwinston.jsで使用し、任意のファイルでそれを要求します。

var winston = require('winston')
var path = require('path')
var PROJECT_ROOT = path.join(__dirname, '..')
var appRoot = require('app-root-path');


const options = {
  file: {
    level: 'info',
    filename: `${appRoot}/logs/app.log`,
    handleExceptions: true,
    json: true,
    maxsize: 5242880, // 5MB
    maxFiles: 5,
    colorize: false,
    timestamp: true
  },
  console: {
    level: 'debug',
    handleExceptions: true,
    json: true,
    colorize: true,
    timestamp: true
  }
};

var logger = new winston.Logger({
  transports: [
    new winston.transports.File(options.file),
    new winston.transports.Console(options.console)
  ],
  exitOnError: false // do not exit on handled exceptions
});

logger.stream = {
  write: function (message) {
    logger.info(message)
  }
}

// A custom logger interface that wraps winston, making it easy to instrument
// code and still possible to replace winston in the future.

module.exports.debug = module.exports.log = function () {
  logger.debug.apply(logger, formatLogArguments(arguments))
}

module.exports.info = function () {
  logger.info.apply(logger, formatLogArguments(arguments))
}

module.exports.warn = function () {
  logger.warn.apply(logger, formatLogArguments(arguments))
}

module.exports.error = function () {
  logger.error.apply(logger, formatLogArguments(arguments))
}

module.exports.stream = logger.stream

/**
 * Attempts to add file and line number info to the given log arguments.
 */
function formatLogArguments (args) {
  args = Array.prototype.slice.call(args)

  var stackInfo = getStackInfo(1)

  if (stackInfo) {
    // get file path relative to project root
    var calleeStr = '(' + stackInfo.relativePath + ':' + stackInfo.line + ')'

    if (typeof (args[0]) === 'string') {
      args[0] = calleeStr + ' ' + args[0]
    } else {
      args.unshift(calleeStr)
    }
  }

  return args
}

/**
 * Parses and returns info about the call stack at the given index.
 */
function getStackInfo (stackIndex) {
  // get call stack, and analyze it
  // get all file, method, and line numbers
  var stacklist = (new Error()).stack.split('\n').slice(3)

  // stack trace format:
  // http://code.google.com/p/v8/wiki/JavaScriptStackTraceApi
  // do not remove the regex expresses to outside of this method (due to a BUG in node.js)
  var stackReg = /at\s+(.*)\s+\((.*):(\d*):(\d*)\)/gi
  var stackReg2 = /at\s+()(.*):(\d*):(\d*)/gi

  var s = stacklist[stackIndex] || stacklist[0]
  var sp = stackReg.exec(s) || stackReg2.exec(s)

  if (sp && sp.length === 5) {
    return {
      method: sp[1],
      relativePath: path.relative(PROJECT_ROOT, sp[2]),
      line: sp[3],
      pos: sp[4],
      file: path.basename(sp[2]),
      stack: stacklist.join('\n')
    }
  }
}
1
Rupesh

私はwinston2.xを使用しています(ただし、同じソリューションはwinston 3.xでも機能します)そして それが方法です 呼び出し元のファイル名と行番号をログに記録しています:

[〜#〜]重要[〜#〜]:埋め込まれたコードコメントに注意してください!

/**
 * Use CallSite to extract filename and number
 * @returns {string} filename and line number separated by a colon
 */
const getFileNameAndLineNumber = () => {
    const oldStackTrace = Error.prepareStackTrace;
    try {
        // eslint-disable-next-line handle-callback-err
        Error.prepareStackTrace = (err, structuredStackTrace) => structuredStackTrace;
        Error.captureStackTrace(this);
        // in this example I needed to "peel" the first 10 CallSites in order to get to the caller we're looking for, hence the magic number 11
        // in your code, the number of stacks depends on the levels of abstractions you're using, which mainly depends on winston version!
        // so I advise you to put a breakpoint here and see if you need to adjust the number!
        return this.stack[11].getFileName() + ':' + this.stack[11].getLineNumber();
    } finally {
        Error.prepareStackTrace = oldStackTrace;
    }
};

そして(の簡略版)フォーマッター関数:

function humanReadableFormatter ({level, message}) {
    const filename = getFileNameAndLineNumber();
    return `[${level}] ${filename} ${message}`;
}

次に、フォーマッタを使用するようにトランスポートを宣言します。

new winston.transports.Console({
        level: 'info',
        handleExceptions: true,
        humanReadableUnhandledException: true,
        json: false,
        colorize: 'level',
        stderrLevels: ['warn', 'error', 'alert'],
        formatter: humanReadableFormatter,
    })

PrepareStackTraceの詳細については、以下をお読みください: https://v8.dev/docs/stack-trace-api#customizing-stack-traces

0
alfasin