Winston + highlight.io 日志接入实战:用 HTTP Transport 将 Node.js JSON 日志送入全栈监控平台

原创2026-09-26 18:27:151,433 阅读
文章标签:可观测性后端

Winston + highlight.io 日志接入实战:用 HTTP Transport 将 Node.js JSON 日志送入全栈监控平台

导读

本篇指南讲解如何在 Node.js 服务中使用 Winston 日志框架接入 highlight.io 的日志摄取能力:借助 Winston 内置的 Http Transport,将应用日志以 JSON 形式实时上报到 highlight.io 云端,与前端会话回放、错误监控打通,形成全栈可观测闭环。读完本文,你将掌握完整的 Winston 接入配置、请求头与路径语义、日志验证方法,并理解 highlight.io 服务端 /v1/logs/json 端点的底层实现,让日志从"本地可见"升级为"平台可查、可检索、可关联"。

1. 接入前的准备:前置依赖

在配置 Winston Transport 之前,请先确认两件事:

  1. 前端集成(可选但推荐):如果你正在为应用接入 highlight.io 前端 SDK,请先按 前端快速开始 完成初始化,并参考前后端关联映射指南,让后端日志能与前端会话正确关联。这一步不强制,但能显著提升全栈排查效率。

  2. 获取项目 ID:登录 highlight.io 控制台,在项目设置中找到你的 Project ID。它将被填入 HTTP 请求头的 x-highlight-project 字段中,用于日志归属识别。

2. 核心配置:创建 Winston HTTP Transport

Winston 自带 transports.Http,可将日志序列化后通过 HTTP 上报。highlight.io 官方 Quick Start(定义于 winston.tsx)给出了如下开箱即用的配置:

import {createLogger, format, transports} from 'winston';

const highlightTransport = new transports.Http({
    host: 'pub.highlight.run',
    path: "/v1/logs/json",
    ssl: true,
    headers: {
        'x-highlight-project': '<YOUR_PROJECT_ID>',
        'x-highlight-service': 'EXAMPLE_NODEJS_SERVICE',
    },
})

export const logger = createLogger({
    level: 'info',
    format: format.combine(
        format.json(),
        format.errors({ stack: true }),
        format.timestamp(),
        format.prettyPrint(),
    ),
    transports: [new transports.Console(), highlightTransport],
})

配置项逐项拆解

配置项 取值 含义
host pub.highlight.run highlight.io 公有云日志摄取域名,对应生产环境入口
path /v1/logs/json JSON 日志接收端点,服务端由 HandleJSONLog 处理器承载(见下文源码)
ssl true 使用 HTTPS 加密传输,生产环境必须开启
headers['x-highlight-project'] <YOUR_PROJECT_ID> 必填,标识日志归属的项目
headers['x-highlight-service'] 你的服务名 建议填写,便于按服务维度过滤日志

几点实战建议:

  • 替换占位符:将 <YOUR_PROJECT_ID> 替换为真实项目 ID,将 EXAMPLE_NODEJS_SERVICE 替换为你的服务名(如 order-service),否则日志会被归到错误的项目或显示为默认服务名。
  • 日志级别:level: 'info' 意味着 info 及以上级别(warn、error)都会进入 Transport 管道;若只关心错误,可调整为 error。
  • Format 组合:format.json() 保证日志被序列化为 JSON 载荷;format.errors({ stack: true }) 会将 Error 对象展开并附带堆栈;format.timestamp() 为每条日志注入时间戳;format.prettyPrint() 则便于本地控制台阅读。生产环境中也可按需去掉 prettyPrint 以降低本地输出噪音。
  • 双 Transport 并存:Console 与 highlightTransport 同时挂载,意味着日志"本地照常打印、远端同步上报",无需改动任何业务代码中的 logger.info/error 调用点。

3. 底层原理:/v1/logs/json 端点是如何处理日志的

配置中的 path: "/v1/logs/json" 并非虚构地址,它在 highlight.io 后端有真实实现。查看 backend/http/logging.go 中的路由注册:

func Listen(r *chi.Mux, t trace.Tracer) {
	tracer = t
	r.Route("/v1", func(r chi.Router) {
		r.Use(highlightChi.Middleware)
		r.HandleFunc("/logs/raw", HandleRawLog)
		r.HandleFunc("/logs/json", HandleJSONLog)
		r.HandleFunc("/logs/firehose", HandleFirehoseLog)
	})
}

可以看到,/v1 路由族同时暴露了三种日志摄取入口:

  • /logs/json:接收 结构化 JSON 日志(即本指南 Winston 所用的端点),支持批量数组与 NDJSON 流式体;
  • /logs/raw:接收纯文本原始日志,日志内容即请求体,级别默认记为 info(见 HandleRawLog);
  • /logs/firehose:面向 AWS Firehose 等流式管道的高吞吐入口。

HandleJSONLog 在解析请求时会读取 x-highlight-project 等头部与 project、service 查询参数,将 JSON 中的每条日志转换为内部 hlog.Log 结构,补齐 service.name 等 OpenTelemetry 语义属性后,通过 SubmitHTTPLog 交给下游(ClickHouse)存储。这正是"Winston 上报 → 服务端规范化 → 可检索存储"的完整链路。

值得注意:Winston HTTP Transport 默认会将每条日志作为独立 JSON 对象 POST 上去,而 HandleJSONLog 同样支持 NDJSON(多行 JSON)批量体。若你的应用日志吞吐量很大,可以考虑使用自定义 transport 做本地批量缓冲,减少 HTTP 请求次数(从源码结构与端点设计看,服务端已为批量场景做了支持)。

4. 验证日志是否成功上报

完成配置后,用以下方法验证链路是否打通(对应 Quick Start 中的 verifyLogs 步骤):

  1. 在业务代码中主动输出一条日志,例如 logger.info('Hello from my Node.js service');
  2. 启动服务,确认控制台正常打印(Console Transport 生效);
  3. 登录 highlight.io 控制台,进入 Logs 日志检索页面,选择对应的项目;
  4. 按服务名 EXAMPLE_NODEJS_SERVICE(或你填写的服务名)过滤,应能看到刚输出的日志记录,包含时间戳、级别与完整 JSON 载荷。

如果日志迟迟未出现,按以下顺序排查:

  • 项目 ID 是否填写正确(x-highlight-project 与查询参数 project 二选一即可,但 header 方式是 Winston 配置的标准做法);
  • 网络是否可达 pub.highlight.run(公网域名,防火墙/代理需放行 443 端口);
  • 日志级别是否低于 level: 'info' 而被过滤;
  • 查看服务端端点测试样例,确认请求格式与预期一致——仓库测试 backend/http/logging_test.go 展示了 POST /v1/logs/json 的多种合法请求体(单条 NDJSON、批量 JSON 数组、带 project/service 查询参数等),可作为对照参考。

5. 进阶:与其他日志摄取方式对比

highlight.io 不止支持 Winston,同一套平台还提供多种摄取路径,便于按场景选型:

方式 适用场景 特点
Winston HTTP Transport(本文) Node.js + Winston 栈 零额外依赖,仅用 Winston 内置能力,配置即用
Pino Transport 追求极致性能的 Node.js 服务 与 Pino 的 JSON 序列化原生契合
OTLP 协议 已采用 OpenTelemetry 的异构系统 标准协议,多语言 SDK 通用,便于与 traces/metrics 统一出口
/v1/logs/raw 原始端点 快速验证、脚本化上报 请求体即消息文本,无需构造 JSON

若你的服务已在使用 OpenTelemetry,也可直接用 OTLP 上报而跳过 Winston Transport,两种方式在 highlight.io 的 Logs 视图中统一展示。

6. 小结

本文围绕 Winston 与 highlight.io 的集成,完整覆盖了从 HTTP Transport 配置、请求头与路径语义、日志验证到底层端点实现的全部要点:

  • 用 transports.Http + pub.highlight.run + /v1/logs/json 即可完成接入,核心代码不超过 20 行;
  • x-highlight-project 与 x-highlight-service 两个请求头承担了项目归属与服务标识的关键职责;
  • 后端 backend/http/logging.go 的 /v1 路由族提供了 JSON、Raw、Firehose 三种摄取入口,测试用例(logging_test.go)可帮助你验证请求格式;
  • 完成上报后,前端会话回放、错误监控与后端日志可在同一平台统一检索,真正实现全栈可观测。

现在,替换占位符、启动服务,去 Logs 页面看看你的第一条 Winston 日志吧。

登录后查看全文
highlight