You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Winston将NestJS日志发送至Grafana Loki失败求助

问题:NestJS通过Winston推送日志至Grafana无响应(控制台日志正常、无报错)

我尝试通过Winston日志服务将NestJS的所有日志发送到Grafana,但多次尝试均未成功。控制台能正常显示格式化后的日志,但没有任何日志发送至Grafana,也未出现报错。我试过相关社区方案,还测试了本地Docker Loki镜像(出现超时错误),都没解决问题。

想问:

  • 我哪里操作有误?
  • 是否需要搭建额外服务器,仅将Grafana用于UI和搜索功能?

我的代码实现

main.ts

const logger = new LoggerService();
const app = await NestFactory.create(AppModule, {
  logger: logger,
});
app.useLogger(logger);

logger.service.ts

import { LoggerService as LS } from '@nestjs/common';
import winston from 'winston';
const { combine, timestamp } = winston.format;
import * as Transport from 'winston-transport';
import {
  utilities as nestWinstonModuleUtilities,
  WinstonModule,
} from 'nest-winston';
import LokiTransport from 'winston-loki';

export class LoggerService implements LS {
  private logger: LS;

  constructor() {
    this.logger = WinstonModule.createLogger({
      transports: this.logTransports(),
    });
  }

  private logTransports = () => {
    const logLevel = !!process.env.LOG_LEVEL ? process.env.LOG_LEVEL : 'error';

    const format = combine(
      timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),
      nestWinstonModuleUtilities.format.nestLike(),
    );

    const logTransports: Transport[] = [
      new LokiTransport({
        host: process.env.G_URL,
        basicAuth: `${process.env.G_USER}:${process.env.G_KEY}`,
        labels: { app: process.env.G_NAME },
        json: true,
        level: logLevel,
        format: winston.format.json(),
        replaceTimestamp: true,
        timeout: 10,
        onConnectionError: (err) => console.error(err),
      }),
      new winston.transports.Console({
        format: format,
        level: logLevel,
      }),
    ];

    return logTransports;
  };

  // + other functions (toPrettyJson, log, error, etc)
}

环境变量配置(已脱敏)

G_URL="https://logs-prod-....grafana.net"
G_NAME="grafanacloud-...-logs"
G_USER="8...5"
G_KEY="glc_eyJ...ifX0="
LOG_LEVEL='debug'

解决方案排查要点

1. 修正LokiTransport的超时配置

你当前设置的timeout: 10单位是秒,这个值过小,Grafana Cloud的Loki服务跨网络请求很容易超时,建议调整为30-60秒:

new LokiTransport({
  // ...其他配置
  timeout: 30, // 调整为30秒
})

2. 补全Grafana Cloud Loki的API路径

Grafana Cloud的Loki推送端点需要完整路径/loki/api/v1/push,如果你的G_URL仅为域名,需要补充完整:

# 修改环境变量
G_URL="https://logs-prod-....grafana.net/loki/api/v1/push"

或者在代码中手动拼接:

new LokiTransport({
  host: `${process.env.G_URL}/loki/api/v1/push`,
  // ...其他配置
})

3. 验证日志级别与实际输出的匹配

确保你代码中调用的日志方法级别不低于LOG_LEVEL设置的debug。比如如果只调用了logger.error(),那没问题,但如果是logger.debug(),要确认你的LoggerService的debug方法正确实现并转发到Winston实例。

4. 开启调试日志排查细节

在初始化Winston时添加调试选项,查看底层传输的日志细节:

this.logger = WinstonModule.createLogger({
  transports: this.logTransports(),
  level: logLevel,
  debug: true, // 开启调试模式
});

同时给LokiTransport加上verbose: true配置,输出更多传输相关日志:

new LokiTransport({
  // ...其他配置
  verbose: true,
})

5. 关于Grafana Cloud架构的疑问

不需要额外搭建服务器,Grafana Cloud已经包含了Loki日志存储服务,你只需要正确配置Winston-Loki传输,将日志推送到Grafana Cloud提供的Loki端点即可,Grafana本身就是用于日志的UI查询和可视化。


内容的提问来源于stack exchange,提问作者johnykes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 06:03:38