EdgeOne Makers 日志分析
上一篇讲了可观测性的整体概念,这篇聚焦到日志分析这个具体能力。线上出了问题,日志是最直接的排查依据。代码里打印的 console.log、请求的状态码、耗时信息,全都记录在日志里。EdgeOne Makers 的日志分析让你在控制台就能搜索、过滤、查看每一次函数调用的详细日志,不用再 SSH 到服务器上翻文件。
日志系统介绍
EdgeOne Makers 的日志分两个层次:
| 层次 | 说明 | 来源 |
|---|---|---|
| 平台日志 | 自动采集,包括请求信息、状态码、耗时等 | 平台自动记录 |
| 应用日志 | 你在代码里用 console.log 打印的内容 | 开发者代码 |
两类日志在控制台统一展示,不需要分开查看。
日志保留策略
| 计划 | 日志保留时长 |
|---|---|
| 免费版 | 基础日志保留 |
| 企业版 | 更长的保留时长,支持 183 天 |
日志有保留期限,过期的日志会自动清理。遇到线上问题要尽快排查,不要等日志被清理了才想起来查。
日志查询
进入日志分析页面
在控制台里找到你的项目,进入可观测性 -> 日志分析页面。页面分为两部分: 上方的过滤条件区和下方的日志列表区。
基础过滤
最简单的查询方式是设置过滤条件:
| 过滤条件 | 说明 | 示例 |
|---|---|---|
| 时间范围 | 选择查看哪个时段的日志 | 最近 15 分钟 / 自定义 |
| 状态码 | 只看特定状态码的请求 | 只看 500 错误 |
| 请求路径 | 只看某个路径的请求 | /api/users |
| HTTP 方法 | 只看特定方法的请求 | 只看 POST 请求 |
关键词搜索
如果过滤条件不够精确,可以用关键词搜索。在搜索框里输入关键词,系统会在日志内容中匹配。
搜索示例:
搜索特定用户: "user_12345"
搜索特定错误: "TypeError"
搜索特定接口: "/api/submit"
搜索特定内容: "timeout exceeded"
组合查询
实际排查问题时,通常要组合多个条件。比如:
场景: 排查今天下午 2 点到 3 点之间 /api/submit 接口的 500 错误
过滤条件设置:
时间范围: 14:00 - 15:00
状态码: 500
请求路径: /api/submit
搜索关键词: "database"
这样一搜,就能精确定位到跟数据库相关的错误日志。
日志内容详解
每一条日志包含丰富的信息,下面拆解一条典型的日志记录:
请求日志示例:
时间: 2026-08-18 14:23:45.123
方法: POST
路径: /api/submit
状态码: 200
耗时: 234ms
客户端IP: 120.34.56.78
请求头: Content-Type: application/json
请求体: {"name": "test", "email": "test@example.com"}
响应体: {"success": true, "id": "abc123"}
应用日志:
[14:23:45.100] 收到提交请求 name=test
[14:23:45.120] 数据写入成功 id=abc123
[14:23:45.123] 响应已发送 status=200
各字段含义
| 字段 | 说明 | 排查价值 |
|---|---|---|
| 时间 | 请求处理的精确时间戳,毫秒级 | 确定问题发生的时间点 |
| 方法 | HTTP 请求方法 | 区分不同类型的请求 |
| 路径 | 请求的 URL 路径 | 定位到具体的接口 |
| 状态码 | HTTP 响应状态码 | 快速判断请求是否成功 |
| 耗时 | 从收到请求到发出响应的总时间 | 发现性能瓶颈 |
| 客户端IP | 发起请求的用户 IP | 判断是个别用户还是全局问题 |
| 请求体 | POST/PUT 请求发送的数据 | 确认入参是否正确 |
| 响应体 | 返回给客户端的数据 | 确认出参是否正确 |
| 应用日志 | console.log 打印的内容 | 了解代码内部的执行细节 |
错误追踪
常见错误类型
线上常见错误和排查思路:
| 错误类型 | 状态码 | 常见原因 | 排查方向 |
|---|---|---|---|
| 路径不存在 | 404 | URL 拼错了或路由没注册 | 检查路由配置和请求路径 |
| 参数错误 | 400 | 请求参数格式不对 | 检查请求体和应用日志 |
| 未授权 | 401 | Token 过期或缺失 | 检查认证逻辑 |
| 权限不足 | 403 | 用户没有权限访问 | 检查权限校验逻辑 |
| 服务内部错误 | 500 | 代码报错、数据库连接失败 | 看应用日志里的错误堆栈 |
| 超时 | 504 | 处理时间超过限制 | 看链路追踪,找慢步骤 |
错误日志排查实战
场景: 用户反馈提交表单时报 500 错误。
第一步,在日志分析页面设置过滤:
状态码: 500
时间范围: 最近 1 小时
第二步,找到错误日志,查看详细信息:
错误日志:
时间: 2026-08-18 15:32:10.456
方法: POST
路径: /api/submit
状态码: 500
耗时: 5023ms
应用日志:
[15:32:05.430] 收到提交请求 name=test
[15:32:05.435] 开始写入数据库
[15:32:10.450] 数据库连接超时 Error: connect ETIMEDOUT
[15:32:10.456] 响应已发送 status=500
第三步,根据日志定位问题。日志显示数据库连接超时,说明问题不在你的代码逻辑,而是数据库连接出了问题。可能是数据库负载高,可能是连接数满了,也可能是网络波动。
第四步,根据原因采取措施。如果是连接数满了,考虑用连接池。如果是网络波动,加重试机制。如果是数据库本身的问题,排查数据库端的性能。
高频错误监控
除了手动查日志,还可以通过指标分析监控错误率趋势。正常情况下错误率接近 0,如果错误率持续升高,就说明系统存在潜在问题需要处理。
建议设置告警阈值:
| 指标 | 告警阈值 | 处理方式 |
|---|---|---|
| 5xx 错误率 | 超过 1% | 立即排查 |
| 4xx 错误率 | 超过 5% | 检查是否有异常请求 |
| 平均响应时间 | 超过 2 秒 | 排查性能瓶颈 |
| 单接口错误数 | 超过 10 次/小时 | 检查对应接口代码 |
日志最佳实践
打印有意义的日志
日志不是打得越多越好,关键是要有意义。
// 不好的日志: 信息太少,排查时没啥用
console.log("请求进来了");
console.log("处理完成");
// 不好的日志: 信息太多,淹没关键内容
console.log("请求详情:", JSON.stringify(request, null, 2));
// 好的日志: 关键信息都有,排查时一目了然
console.log("收到请求", {
method: request.method,
path: request.url,
userId: request.headers.get('x-user-id')
});
console.log("处理完成", {
status: 200,
duration: Date.now() - startTime,
dataSize: responseBody.length
});
// 错误日志要包含上下文
console.error("数据库写入失败", {
error: err.message,
table: 'users',
operation: 'insert',
data: { name: userData.name }
});
日志格式建议
| 建议 | 说明 |
|---|---|
| 包含时间戳 | console.log 自动带时间,但自定义场景要注意 |
| 包含请求标识 | 给每个请求生成唯一 ID,方便串联同一次请求的多条日志 |
| 区分日志级别 | 用 console.log 记录正常信息,console.error 记录错误 |
| 结构化输出 | 用对象格式打印,比拼接字符串更易读 |
| 不要打印敏感信息 | 密码、Token、身份证号等不要出现在日志里 |
请求 ID 串联日志
一个请求可能触发多条日志,用请求 ID 把它们串起来:
// 在函数入口生成请求 ID
export default function onRequestPost(context) {
const requestId = crypto.randomUUID();
const startTime = Date.now();
console.log("请求开始", { requestId, path: context.request.url });
try {
// 业务逻辑
const result = await processData(context);
console.log("请求完成", {
requestId,
duration: Date.now() - startTime,
status: 200
});
return Response.json(result);
} catch (err) {
console.error("请求失败", {
requestId,
duration: Date.now() - startTime,
error: err.message
});
return new Response("Internal Error", { status: 500 });
}
}
这样在日志里搜索某个 requestId,就能找到这个请求从开始到结束的所有日志,排查问题时非常高效。
日志分析与指标分析的关系
可观测性概览那篇讲了指标、日志、链路追踪三层能力。日志分析和指标分析的关系是:
| 维度 | 指标分析 | 日志分析 |
|---|---|---|
| 作用 | 发现问题 | 定位问题 |
| 数据粒度 | 聚合统计 | 逐条记录 |
| 查看方式 | 图表、仪表盘 | 列表、搜索 |
| 典型问题 | “错误率是不是升高了?” | “具体是哪条请求报错了?” |
| 使用顺序 | 先看指标发现异常 | 再看日志确认原因 |
两者配合使用,先看指标发现”有问题”,再看日志搞清楚”什么问题”。
速查卡片
| 要点 | 说明 |
|---|---|
| 日志两类 | 平台自动采集的请求日志 + 开发者打印的应用日志 |
| 过滤方式 | 时间范围、状态码、请求路径、HTTP 方法、关键词搜索 |
| 日志关键字段 | 时间、方法、路径、状态码、耗时、客户端 IP、请求体、响应体 |
| 错误排查思路 | 过滤 5xx 错误 -> 查看日志详情 -> 根据应用日志定位原因 |
| 日志打印原则 | 包含关键上下文,结构化输出,不打印敏感信息 |
| 请求 ID | 给每个请求生成唯一 ID,串联同一次请求的多条日志 |
| 与指标的关系 | 指标发现问题,日志定位问题,先指标后日志 |
| 告警阈值 | 5xx 超 1%、平均响应超 2 秒就要排查 |