服务调用日志
📋 概述
使用云开发的资源(HTTP 访问服务、云函数、数据库、云存储)时,会自动产生对应的服务调用日志,供开发者在云开发控制台进行检索和分析。通过服务调用日志,您可以:
- 🔍 追踪请求链路 - 完整记录服务调用的全链路信息
- 📊 性能分析 - 监控各服务的响应时间和性能表现
- 🐛 问题排查 - 快速定位错误和异常问题
- 📈 业务洞察 - 分析用户行为和系统使用情况
📝 日志信息
通过 SDK 或者 HTTP 访问服务使用云开发的资源时,会产生一条服务调用日志。每条服务调用日志包含以下核心信息:
信息类别 | 说明 | 用途 |
---|---|---|
📊 日志元数据 | traceId、spanId、childOf | 链路追踪和关联分析 |
🎯 调用服务&事件 | service、event | 识别服务类型和操作类型 |
🗂️ 资源信息 | function、file_path 等 | 定位具体访问的资源 |
👤 调用者信息 | invoker、source、ua、ip | 识别请求来源和用户 |
⏰ 时间信息 | startTime、timeCost | 性能分析和时序追踪 |
❌ 错误信息 | errorCode、errorMsg | 问题诊断和错误分析 |
📊 日志元数据
日志元数据是实现分布式链路追踪的核心,包含以下字段:
字段 | 说明 | 示例值 |
---|---|---|
traceId | 全链路唯一标识符 | 8f431b7e-bfcc-423e-99d8-cda72471ff49 |
spanId | 当前调用的唯一标识符 | bbe75687-fffb-6cb8 |
childOf | 父级调用的 spanId | abc12345-defg-6789 |
🔗 链路追踪原理
在一次完整的服务调用中,可能访问多个云开发资源,产生多条服务调用日志:
- 🆔 相同 traceId:同一次请求的所有日志共享相同的 traceId
- 🏷️ 不同 spanId:每个服务调用都有唯一的 spanId
- 🔗 childOf 关联:记录调用的父子关系,构建完整调用链
场景:通过 SDK 调用云函数 A,云函数 A 调用云函数 B
SDK --> 云函数 A --> 云函数 B
日志记录:
- 日志 A:
traceId: abc123
,spanId: span001
,childOf: null
- 日志 B:
traceId: abc123
,spanId: span002
,childOf: span001
通过 traceId 可以查询到完整调用链,通过 childOf 可以还原调用关系。
🎯 调用服务&事件
日志中使用 service
和 event
来标记每次服务调用的服务类型和具体操作:
服务类型 | Service 值 | Event 事件动作 | 说明 |
---|---|---|---|
🔧 云函数 | function | callFunction | 函数调用执行 |
📁 云存储 | storage | upload 、delete 、download 、getTempFileURL | 文件操作 |
🗄️ 数据库 | database | add 、remove 、update 、get 、count 、aggregate | CRUD 和聚合操作 |
🌐 云托管 | app | GET 、POST 、PUT 、DELETE 、PATCH | HTTP 请求方法 |
📋 常见事件类型详解
云存储事件:
upload
- 文件上传delete
- 文件删除download
- 文件下载getTempFileURL
- 获取临时访问链接
数据库事件:
add
- 新增记录remove
- 删除记录update
- 更新记录get
- 查询记录count
- 统计数量aggregate
- 聚合查询
云托管事件:
- HTTP 方法对应具体的 API 调用类型
🗂️ 资源信息
不同的资源类型通过不同的字段来标识具体访问的资源:
资源类型 | 字段名 | 数据类型 | 说明 | 示例 |
---|---|---|---|---|
🔧 云函数 | function | String | 函数名称 | "login" , "sendEmail" |
📁 云存储 | file_path | Array | 文件路径列表 | ["/images/avatar.jpg"] |
🗄️ 数据库 | collectionName | Array | 集合名称列表 | ["users", "orders"] |
🌐 HTTP 服务 | httpPath | String | 请求路径(不含查询参数) | "/api/user/profile" |
📝 字段说明
file_path 数组格式:
- 单文件操作:
["/path/to/file.jpg"]
- 批量操作:
["/file1.jpg", "/file2.png", "/file3.pdf"]
- 批量获取临时链接时会包含多个文件路径
collectionName 数组格式:
- 单表操作:
["users"]
- 聚合查询:
["users", "orders", "products"]
- 跨集合操作时会包含多个集合名
httpPath 格式:
- 原始请求:
GET /api/user/profile?id=123&type=full
- 记录路径:
"/api/user/profile"
(自动去除查询参数)
👤 调用者信息
服务调用日志详细记录了请求的来源信息,便于安全审计和问题排查:
字段名 | 说明 | 可能值 | 用途 |
---|---|---|---|
invoker | 调用者身份标识 | admin 、uid:user123 、anonymous | 用户身份识别 |
source | 请求来源渠道 | web-sdk 、node-sdk 、http 、schedule | 来源渠道分析 |
ua | 客户端 User-Agent | 浏览器/SDK 版本信息 | 客户端环境分析 |
invokerIp | 请求来源 IP 地址 | 192.168.1.100 、10.0.0.1 | 地理位置和安全分析 |
🔍 字段详解
invoker 调用者类型:
admin
- 管理员调用(控制台操作)uid:xxxxx
- 已认证用户调用anonymous
- 匿名用户调用- 空值 - 系统内部调用
source 来源渠道:
web-sdk
- Web 端 SDK 调用node-sdk
- Node.js SDK 调用admin-sdk
- 管理端 SDK 调用http
- 直接 HTTP API 调用schedule
- 定时触发器调用trigger
- 数据库触发器调用
ua 信息示例:
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
CloudBase-JS-SDK/1.5.0
CloudBase-Node-SDK/2.8.1
⏰ 时间信息
时间信息用于性能分析和调用时序追踪:
字段名 | 说明 | 格式 | 示例 |
---|---|---|---|
startTime | 服务调用开始时间 | ISO 8601 时间戳 | 2023-12-01T10:30:45.123Z |
timeCost | 调用耗时(毫秒) | 数值 | 150 (表示 150ms) |
📊 性能分析应用
通过时间信息可以进行:
- ⚡ 性能监控:识别慢查询和性能瓶颈
- 📈 趋势分析:统计平均响应时间变化
- 🚨 异常检测:发现响应时间异常的请求
- 🎯 优化指导:为性能优化提供数据支撑
❌ 错误信息
错误信息帮助快速定位和诊断问题:
字段名 | 说明 | 示例 |
---|---|---|
errorCode | 标准错误码 | INVALID_PARAM 、PERMISSION_DENIED |
errorMsg | 详细错误描述 | "参数 userId 不能为空" 、"数据库连接超时" |
🔧 常见错误码
错误码 | 说明 | 解决方案 |
---|---|---|
INVALID_PARAM | 参数错误 | 检查请求参数格式和必填项 |
PERMISSION_DENIED | 权限不足 | 检查用户权限和安全规则 |
RESOURCE_NOT_FOUND | 资源不存在 | 确认资源路径和名称正确 |
QUOTA_EXCEEDED | 配额超限 | 检查资源使用量和配额限制 |
NETWORK_ERROR | 网络错误 | 检查网络连接和服务状态 |
🎯 典型使用场景
🔍 场景一:用户访问报错排查
检索日志方法详情请参见 检索日志。
假如用户 A 某次访问云开发的资源报错,那么怎样定位错误原因呢?
- 通过 invoker:A and errorCode:* 来检索此用户最新的访问出错的服务调用日志;
- 检索到服务调用日志后,根据访问时间查阅到日志的 traceId, 通过 traceId:\${traceId} 来检索此次服务调用的所有服务调用日志,根据日志中的调用信息、资源信息、错误信息来分析出错的原因。
- 点击”全链路日志“按钮前往全链路日志页面查看调用链关系。在调用页,可以点击查看函数执行中的日志
🌐 场景二:云托管服务调用场景
用户调用云托管 A 服务的接口 1,云托管 A 接口 1 中再次调用云托管 A 服务的接口 2 时,希望将请求关联上同一个 traceid,则需要业务侧进行配合改造。
/json
接口中调用/trace
接口,headers 里透传请求头中的x-cloudbase-trace
字段/trace
接口中,解开x-cloudbase-trace
,得到traceId
,在日志中输出,并可以在后续的日志搜索时,通过
以 nodejs koa 框架代码为例,云托管 A 中 /json
接口中调用另外一个/trace
接口
router.get("/json", async (ctx, next) => {
const res = await axios.get(
"https://test-2gbynbtb9996d4d0-1252395194.ap-shanghai.service.tcloudbase.com/node-capp/trace",
{
headers: {
"x-cloudbase-trace": ctx.req.headers["x-cloudbase-trace"]
}
}
);
ctx.body = res.data;
});
router.get("/trace", async (ctx, next) => {
// 从base64转为utf8编码,数据格式为 ${traceId},${spanId},${on | off}
// 例子:OGY0MzFiN2ViZmNjNDIzZTk5ZDhjZGE3MjQ3MWZmNDksYmJlNzU2ODdmZmZiNmNiOCxvbg 解开后为 8f431b7ebfcc423e99d8cda72471ff49,bbe75687fffb6cb8,on
const traceStr = Buffer.from(ctx.req.headers["x-cloudbase-trace"], "base64").toString("utf-8");
const [traceId] = traceStr.split(",");
// 解出后,可以在日志中打印该字段,方便关联上日志
console.log(`${traceId}: traceId log start`);
ctx.body = {
traceStr,
traceId
};
console.log(`${traceId}: traceId end`);
});
注:如果是云函数中调用云托管,x-cloudbase-trace
则是透传云函数环境变量中的 TCB_TRACELOG
。