【问题标题】:Firebase functions: logging with winston in stackdriver consoleFirebase 功能:在 stackdriver 控制台中使用 winston 进行日志记录
【发布时间】:2018-01-10 18:08:56
【问题描述】:

我无法让winston 记录器将日志写入stackdriver 控制台。我将我的功能部署为 google firebase 功能(使用firebase deploy)。 console logging 工作正常,但我们在项目中没有使用此类工具。

我尝试了什么:

请建议...我厌倦了实验(每次重新部署都需要时间)

【问题讨论】:

    标签: node.js google-app-engine firebase logging winston


    【解决方案1】:

    node.js winston 设置的文档是 herehere

    我在下面添加了完整的logger.js 设置。

    重要的是:

    const format = winston.format.combine(winston.format.colorize({ all: true }))
    const console = new winston.transports.Console({ format: winston.format.combine(format) })
    
    const options = this.#explicitSetup ? { projectId: appConfig.firebase.options.projectId, keyFilename: `${rootDirname}/service-account-file.json` } : {}
    const loggingWinston = new LoggingWinston(options)
    
    const transports = emulators ? [console] : [console, loggingWinston]
    
    this.#logger = winston.createLogger({
      level: this.#defaultLevel,
      transports
    })
    

    基本上,如果模拟器正在运行,则使用控制台记录器,否则使用控制台记录器和堆栈驱动程序传输。您可以通过 ping 本地主机上的函数端点(例如您创建的 /ping 端点)来检查模拟器是否正在运行。如果它不存在,则模拟器没有运行,或者这是一个生产环境。还要注意使用显式设置的能力,其中projectIdkeyFilename 被传入。

    keyFilename 的 JSON 文件可以在这里创建:

    https://cloud.google.com/docs/authentication/getting-started

    我的完整 logger.js 代码,如果有帮助,请如下:

    import winston from 'winston'
    import { LoggingWinston } from '@google-cloud/logging-winston'
    import { appConfig } from '../app-config.js'
    import { rootDirname } from './root-dirname.js'
    import { isObjectLike } from 'lodash-es'
    
    // https://cloud.google.com/logging/docs/setup/nodejs
    
    export class Logger {
    
      #logger
      #defaultLevel = 'debug'
      #explicitSetup = false
    
      constructor() {
        this.error = this.error.bind(this)
        this.warn = this.warn.bind(this)
        this.info = this.info.bind(this)
        this.debug = this.debug.bind(this)
        this.log = this.log.bind(this)
      }
    
      init(emulators) {
    
        // https://stackoverflow.com/a/64173978/1205871
        winston.addColors({
          error: 'red',
          warn: 'yellow',
          info: 'bold cyan',
          debug: 'bold green'
        })
    
        const format = winston.format.combine(winston.format.colorize({ all: true }))
        const console = new winston.transports.Console({ format: winston.format.combine(format) })
    
        const options = this.#explicitSetup ? { projectId: appConfig.firebase.options.projectId, keyFilename: `${rootDirname}/service-account-file.json` } : {}
        const loggingWinston = new LoggingWinston(options)
    
        const transports = emulators ? [console] : [console, loggingWinston]
    
        this.#logger = winston.createLogger({
          level: this.#defaultLevel,
          transports
        })
      }
    
      error(...args) {
        this.#logger.error(this.#argsToString(args))
      }
    
      warn(...args) {
        this.#logger.warn(this.#argsToString(args))
      }
    
      info(...args) {
        this.#logger.info(this.#argsToString(args))
      }
    
      debug(...args) {
        this.#logger.debug(this.#argsToString(args))
      }
    
      log(...args) {
        this.#logger[this.#defaultLevel](this.#argsToString(args))
      }
    
      #argsToString(args) {
        return args.map(arg => {
          const str = isObjectLike(arg) ? JSON.stringify(arg) : arg.toString()
          return str.trim()
        }).join(' \u2022\u2022 ')
      }
    }
    
    const blogger = new Logger()
    export const logger = blogger
    

    【讨论】:

      【解决方案2】:

      Winston 的默认控制台传输失败,因为它在可用时使用 console._stdout.write,Firebase 函数不接受。

      现在有一个Google Cloud transport package for Stackdriver 你可以试试。没用过,如果你使用的是 Winston 3,它需要节点 ^8.11.2

      【讨论】:

        【解决方案3】:

        最后我做了什么——实现了custom transport,它实际上在后台调用了console.log。这有帮助。

        const winston = require('winston');
        const util = require('util');
        const ClassicConsoleLoggerTransport = winston.transports.CustomLogger = function (options) {
            options = options || {};
            this.name = 'ClassicConsoleLoggerTransport';
            this.level = options.level || 'info';
            // Configure your storage backing as you see fit
        };
        util.inherits(ClassicConsoleLoggerTransport, winston.Transport);
        
        ClassicConsoleLoggerTransport.prototype.log = function (level, msg, meta, callback) {
            let args = [msg, '---', meta];
            switch (level) {
                case 'verbose':
                case 'debug':
                    console.log.apply(null, args);
                    break;
                case 'notice':
                case 'info':
                    console.info.apply(null, args);
                    break;
                case 'warn':
                case 'warning':
                    console.warn.apply(null, args);
                    break;
                case 'error':
                case 'crit':
                case 'alert':
                case 'emerg':
                    console.error.apply(null, args);
                    break;
                default:
                    console.log.apply(null, args);
            }
            callback(null, true);
        };
        

        【讨论】:

        • 能否在github中添加需要的文件以及如何作为gist使用?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-06-20
        • 2021-08-13
        • 2014-11-04
        • 1970-01-01
        • 1970-01-01
        • 2019-05-20
        • 2018-06-21
        相关资源
        最近更新 更多