将任何后端的结构化日志发送到 Axiom,用 APL(类 SQL 语言)检索,免费层保留 30 天。Sentry 负责捕获异常,Axiom 负责记录你打印的其他一切。
数据集是日志的落地桶。进入 Dashboard → Datasets → New dataset,按服务命名:api-prod、web-prod、worker-prod。每个服务独立数据集,查询成本更低,且可按服务分别配置保留策略。
不要把所有日志都塞进一个 logs 数据集——等你积累到一千万条事件时就会后悔。
Settings → API tokens → New API token。权限范围:应用侧只需选 Ingest(写入)。如果需要从仪表盘查询,另外单独创建一个 Query(查询)令牌。
添加到 .env:
AXIOM_TOKEN=xaat-…
AXIOM_DATASET=api-prod
AXIOM_ORG_ID=your-org-id # under Settings → Organization
安装 SDK:
npm install @axiomhq/js
接入方式——推荐搭配 pino,这样你的业务代码不与 Axiom 强绑定:
import pino from "pino";
import { AxiomJSTransport } from "@axiomhq/pino";
import { Axiom } from "@axiomhq/js";
const axiom = new Axiom({ token: process.env.AXIOM_TOKEN });
const logger = pino(
{ level: "info" },
new AxiomJSTransport({
axiom,
dataset: process.env.AXIOM_DATASET,
}),
);
// Usage
logger.info({ userId: user.id, action: "signup" }, "user signed up");
logger.error({ err, requestId: req.id }, "stripe webhook failed");
该传输层每 1 秒或 1 MB 批量上传一次,单条日志的额外开销几乎为零。崩溃安全:关机时调用同步的 flushSync() 可确保尾部日志不丢失。
官方文档:从 Node.js 发送数据。
这些平台不需要 SDK——直接安装集成插件即可,原生日志引流,无需改代码。
console.log 和请求日志自动流入你的数据集。APL = Axiom Processing Language,形似 SQL,专为时序数据优化。打开 Datasets → api-prod → Query:
// Last hour of errors
['api-prod']
| where _time > ago(1h) and level == "error"
| project _time, msg, requestId, userId
// Top 10 endpoints by error rate
['api-prod']
| where _time > ago(24h)
| summarize errors=countif(level == "error"), total=count() by route
| extend errorRate = round(100.0 * errors / total, 2)
| top 10 by errorRate
// Drill into one user's session
['api-prod']
| where userId == "u_abc123" and _time > ago(7d)
| order by _time asc
将常用查询保存为星标查询(显示在侧边栏),将高价值查询转为 Monitor(监控告警,见下一步)。
APL 参考文档:axiom.co/docs/apl/introduction。
logger.info("user signed up"))只会生成一个 msg 字段。应先传对象:logger.info({ userId }, "user signed up"),字段才会变成可查询的列。redact: ["req.headers.authorization", "*.email", "*.password"]。flushInterval 降低到 500ms,或使用仪表盘的 Live 模式(每 2 秒轮询一次)。_time 字段。如果主机时钟偏差数小时,日志会出现在错误的时间桶中。请运行 chrony 或 timesyncd 进行时钟同步。定价页面:axiom.co/pricing。