【问题标题】:Nodejs Winston using async function inside 'createLogger'Nodejs Winston 在“createLogger”中使用异步函数
【发布时间】:2020-02-29 17:33:45
【问题描述】:

我正在尝试将服务器的 IP 地址放在日志的开头。我正在使用public-ip 库。问题是,我不允许在 winston 选项中使用 await getIp()

我的 logger.js 看起来像这样

const winston = require( 'winston' );
const publicIp = require( 'public-ip' );

let ip;

async function getIp() {
  if ( !ip ) {
    ip = await publicIp.v4();
  }
  return ip;
}

const logger = winston.createLogger( {
  level: process.env.NODE_ENV !== global.PRODUCTION ? 'debug' : 'info',
  defaultMeta: { service: 'user-service' },
  format: winston.format.combine(
    winston.format.timestamp( {
      format: 'YYYY-MM-DD HH:mm:ss'
    } ),
    winston.format.printf( ( info ) => `[${await getIp()}] ${info.message}` )
  ),
  transports: [
    new winston.transports.File( { filename: 'logs/error.log', level: 'error', maxsize: '20MB' } ),
    new winston.transports.File( { filename: 'logs/combined.log', maxsize: '20MB' } ),
    new winston.transports.Console( {
      format: winston.format.combine(
        winston.format.colorize()
      )
    } )
  ]
} );

module.exports = logger;

【问题讨论】:

  • 您不能在非异步函数中使用 await。为什么要等待 getIp()?您已经在 getIp() 函数中等待。
  • 哦,所以我不必再等待异步函数了?
  • 可以,不用等两次。
  • 如果我不使用await getIp(),我的PHP Storm ESLint 会在async 关键字下划线并显示:“ESLint 需要一个函数表达式。(func-style)”
  • 我不知道 ESLint。更一般地说,我可以说:getIp() 是一个异步函数。异步函数返回一个承诺。要从 Promise 中获取价值,您需要 .then 函数。所以 getIP().then( result => { console.log(result)}) 会返回你的结果。

标签: node.js asynchronous winston


【解决方案1】:

您的日志配置是同步的,因此您需要在完成某些操作(即获取您的public-ip)后提供您的日志配置。

// log.config.js
const winston = require('winston');
const publicIp = require('public-ip');

module.exports = {
    // Logger initialized async-hronously
    logger: async () => {
        let ip = await publicIp.v4();

        return winston.createLogger({
            level: process.env.NODE_ENV !== global.PRODUCTION ? 'debug' : 'info',
            defaultMeta: {service: 'user-service'},
            format: winston.format.combine(
                winston.format.timestamp({
                    format: 'YYYY-MM-DD HH:mm:ss'
                }),
                winston.format.printf((info) => `[${ip}] ${info.message}`)
            ),
            transports: [
                new winston.transports.File({filename: 'logs/error.log', level: 'error', maxsize: '20MB'}),
                new winston.transports.File({filename: 'logs/combined.log', maxsize: '20MB'}),
                new winston.transports.Console({
                    format: winston.format.combine(
                        winston.format.colorize()
                    )
                })
            ]
        })
    }
};

由于您的记录器在 format 消息中异步获取了 ip 地址,因此您的应用程序需要在正确初始化后获取实例,就像这样。

// main.js
const myLogger = require('./log.config');

async function start() {
    let logger = await myLogger.logger();

    logger.debug('Hello from my log');

    // Application can proceed with rest of the logic ...
}

// Run my app
start();

希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-17
    • 2021-08-27
    • 1970-01-01
    • 2022-01-26
    相关资源
    最近更新 更多