从GKE登录到Stackdriver时如何选择设置Winston传输

安德鲁·里杜特

我有一个运行在Google Kubernetes Engine的Docker容器中的Node.js应用程序。我已经建立了一个日志类,它使用Winston(v3.2.1)定义了两个传输;一个登录到控制台,另一个登录到@google-cloud/logging-winstonStackdriver (使用(v3.0.0))。

定义了两种传输方式后,一切都很好,我可以在Stackdriver中看到日志。控制台日志转到,projects/[project-id]/logs/stdout而Stackdriver日志转到projects/[project-id]/logs/winston_log

但是,我要配置记录器,以便在本地调试时,日志仅发送到控制台,而在GKE中运行时,日志仅发送到Stackdriver,如下所示:

  // Configure console logger
  private readonly consoleLogger = new winston.transports.Console({
    format: combine(
      colorize(),
      simple(),
      printf(context => {
        return `[${context.level}]${context.message}`;
      }),
    ),
  });

  // Configure Stackdriver logger
  private readonly stackdriverLogger = new LoggingWinston({
    serviceContext: {
      service: this.serviceName,
    },
  });

  // Create Winston logger
  private readonly logger = winston.createLogger({
    level: process.env.LOG_LEVEL || 'info',
    format: json(),
    defaultMeta: {
      service: this.serviceName,
    },
    // This line does not work:
    transports: [process.env.NODE_ENV === 'development' ? this.consoleLogger : this.stackdriverLogger],
  });

此处的目的是,如果NODE_ENVdevelopment,则使用控制台记录器,否则使用Stackdriver记录器。但是,将其部署到GKE时,在Stackdriver控制台日志中看到以下错误(在中没有projects/[project-id]/logs/winston_log):

[winston] Attempt to write logs with no transports { // Logged message }

当我使用时NODE_ENV=development在开发人员计算机上本地运行此代码时,我在本地控制台中看到了日志,如果设置了,NODE_ENV=production我在Stackdriver中看到了日志。

如果删除三元运算符并定义了两个传输并将其部署到GKE,则看不到上述错误,并且两种传输均正确记录了日志:

transports: [this.consoleLogger, this.stackdriverLogger],

谁能帮我正确配置此设置?

编辑

添加了完整Logger.ts的上下文文件:

import { LoggerService } from '@nestjs/common';
import * as winston from 'winston';
const { colorize, combine, json, printf, simple } = winston.format;
import { LoggingWinston } from '@google-cloud/logging-winston';
import cls from 'cls-hooked';
import { ConfigManager } from '../config';
import { TraceId } from '../middleware/traceId/constants';

export class Logger implements LoggerService {
  private readonly serviceName: string = process.env.SERVICE_NAME;

  private readonly consoleLogger = new winston.transports.Console({
    format: combine(
      colorise(),
      simple(),
      printf(context => {
        return `[${context.level}]${context.message}`;
      }),
    ),
  });

  private stackdriverLogger = new LoggingWinston({
    serviceContext: {
      service: this.serviceName,
    },
  });

  private readonly logger = winston.createLogger({
    level: process.env.LOG_LEVEL || 'info',
    format: json(),
    defaultMeta: {
      service: this.serviceName,
    },
    transports: [process.env.NODE_ENV === 'development' ? this.consoleLogger : this.stackdriverLogger]
  });

  constructor(private readonly context?: string) {}

  public verbose(message: string, context?: string) {
    const log = this.buildLog(message, context);
    this.logger.verbose(log.message, log.metadata);
  }

  public debug(message: string, context?: string) {
    const log = this.buildLog(message, context);
    this.logger.debug(log.message, log.metadata);
  }

  public log(message: string, context?: string) {
    const log = this.buildLog(message, context);
    this.logger.info(log.message, log.metadata);
  }

  public warn(message: string, context?: string) {
    const log = this.buildLog(message, context);
    this.logger.warn(log.message, log.metadata);
  }

  public error(message: string, trace?: string, context?: string) {
    const log = this.buildLog(message, context, trace);
    this.logger.error(log.message, log.metadata);
  }

  private buildLog(message: string, context?: string, trace?: string) {
    const ctx = context || this.context;
    const traceId = this.getTraceId();

    return {
      message: `[${ctx}] ${message}`,
      metadata: {
        traceId,
        source: ctx,
        stackTrace: trace,
      },
    };
  }

  private getTraceId(): string {
    const clsNamespace = cls.getNamespace(TraceId.Namespace);
    if (!clsNamespace) {
      return null;
    }
    return clsNamespace.get(TraceId.Key);
  }
}
安德鲁·里杜特

因此事实证明问题出在@google-cloud/logging-winston软件包中有一个错误导致该错误:

UnhandledPromiseRejectionWarning: FetchError: request to http://169.254.169.254/computeMetadata/v1/instance failed, reason: connect ECONNREFUSED 169.254.169.254:80

现在,此问题已在版本3.0.6中修复-参见https://github.com/googleapis/nodejs-logging-winston/issues/389#issuecomment-593727968

更新后@google-cloud/logging-winston,Winston日志记录在Stackdriver中对我来说正常工作。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

当用户单击链接时,如何传输登录信息并自动登录到另一个网站?

来自分类Dev

通过ssh登录到远程服务器时,如何更改目录并设置bash选项

来自分类Dev

如何关闭vscode设置同步(要求登录到Microsoft帐户)

来自分类Dev

登录到shell时如何打印Maildir内容的摘要?

来自分类Dev

无法登录到 google stackdriver 日志记录 django + gunicorn + nGINX?

来自分类Dev

登录到Bluemix时出错

来自分类Dev

设置loggly / winston时出错

来自分类Dev

MVC-Asp.Net身份。用户登录时如何登录到数据库

来自分类Dev

当Microsoft帐户与Windows登录相关联时,如何登录到网络共享?

来自分类Dev

使用Serilog登录到事件查看器时动态设置EventID

来自分类Dev

登录到KDE时自动打开kwallet

来自分类Dev

当OOM杀手杀死任何进程时,如何使其登录到/ var / log / messages?

来自分类Dev

如何从Excel登录到交换日历

来自分类Dev

如何配置Laravel 5.1登录到syslog?

来自分类Dev

如何登录到特定的PostgreSQL版本

来自分类Dev

如何运行并登录到容器进行调试?

来自分类Dev

如何登录到远程服务器?

来自分类Dev

如何从Erlang Shell登录到文件?

来自分类Dev

如何使用NodeJS登录到Azure AD?

来自分类Dev

如何使用Deno登录到文件

来自分类Dev

如何禁用内核登录到systemd日志?

来自分类Dev

dmesg内容如何登录到文件中?

来自分类Dev

如何登录到特定的PostgreSQL版本

来自分类Dev

如何使用systemd自动登录到桌面?

来自分类Dev

如何登录到远程服务器?

来自分类Dev

如何配置Laravel 5.1登录到syslog?

来自分类Dev

如何使用Python登录到网页?

来自分类Dev

如何使用Goutte登录到Amazon SellerCentral

来自分类Dev

如何从Windows登录到Ubuntu中的MySQL?

Related 相关文章

  1. 1

    当用户单击链接时,如何传输登录信息并自动登录到另一个网站?

  2. 2

    通过ssh登录到远程服务器时,如何更改目录并设置bash选项

  3. 3

    如何关闭vscode设置同步(要求登录到Microsoft帐户)

  4. 4

    登录到shell时如何打印Maildir内容的摘要?

  5. 5

    无法登录到 google stackdriver 日志记录 django + gunicorn + nGINX?

  6. 6

    登录到Bluemix时出错

  7. 7

    设置loggly / winston时出错

  8. 8

    MVC-Asp.Net身份。用户登录时如何登录到数据库

  9. 9

    当Microsoft帐户与Windows登录相关联时,如何登录到网络共享?

  10. 10

    使用Serilog登录到事件查看器时动态设置EventID

  11. 11

    登录到KDE时自动打开kwallet

  12. 12

    当OOM杀手杀死任何进程时,如何使其登录到/ var / log / messages?

  13. 13

    如何从Excel登录到交换日历

  14. 14

    如何配置Laravel 5.1登录到syslog?

  15. 15

    如何登录到特定的PostgreSQL版本

  16. 16

    如何运行并登录到容器进行调试?

  17. 17

    如何登录到远程服务器?

  18. 18

    如何从Erlang Shell登录到文件?

  19. 19

    如何使用NodeJS登录到Azure AD?

  20. 20

    如何使用Deno登录到文件

  21. 21

    如何禁用内核登录到systemd日志?

  22. 22

    dmesg内容如何登录到文件中?

  23. 23

    如何登录到特定的PostgreSQL版本

  24. 24

    如何使用systemd自动登录到桌面?

  25. 25

    如何登录到远程服务器?

  26. 26

    如何配置Laravel 5.1登录到syslog?

  27. 27

    如何使用Python登录到网页?

  28. 28

    如何使用Goutte登录到Amazon SellerCentral

  29. 29

    如何从Windows登录到Ubuntu中的MySQL?

热门标签

归档