> ## Documentation Index
> Fetch the complete documentation index at: https://docs.arupa.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# 日志记录

> 通过内核统一的日志记录器写入服务诊断信息。

服务应当通过内核提供的日志记录能力来写入诊断信息。这样服务的日志记录就会进入与内核消息相同的结构化日志流中，无论该服务是以 WASM 还是 gRPC 方式运行。`static` 服务没有运行中的代码，永远不会发出自己的日志记录。

服务的日志记录边界只接受一个级别和一条消息。服务不能选择输出格式、配置全局日志级别，也不能自行写入 `component` 和 `from` 字段。

## 日志级别

请使用能够描述该消息运维含义的级别：

| 级别      | 适用场景                |
| ------- | ------------------- |
| `debug` | 在排查行为时有用的诊断细节。      |
| `info`  | 正常的生命周期事件和有意义的状态变化。 |
| `warn`  | 可恢复的问题或需要关注的状况。     |
| `error` | 失败的操作，或阻止预期工作完成的状况。 |

内核会使用全局的 `[Log].Level` 设置来过滤服务的日志记录。例如，当内核以 `info` 级别运行时，服务的 `debug` 记录不会被输出。关于全局的格式、级别和输出行为，请参阅[日志配置](../kernel/config-logging)。

请谨慎使用 `info`，只记录运维人员在正常运行期间需要了解的事件。当内核已经为某项活动提供了访问日志或传输日志时，不要为其中每一个内部步骤或请求都再发出一条信息性记录。

## 日志中的服务身份

内核会为每条服务日志记录添加以下字段：

```text theme={null}
component=service from=<service-name>
```

`from` 是已注册的服务身份。对于 gRPC 服务，内核从已通过身份验证的 host 回调中推导出该值；对于 WASM 服务，该值来自内核建立的服务上下文。服务无法用任意的来源名称替换该值。

JSON 和文本输出中使用的是同一个身份标识。例如，一条 JSON 记录可能是这样的：

```json theme={null}
{
  "level": "INFO",
  "msg": "service initialized",
  "component": "service",
  "from": "my-service"
}
```

## 消息与结构化上下文

当前的服务日志契约只携带日志级别和一条消息字符串，不为服务记录提供任意的键值属性映射。请保持消息简洁，并在需要理解该事件时加入稳定的上下文信息：

```text theme={null}
cache refresh completed: items=24 source=remote
```

请不要在消息中包含密码、令牌、请求体、密钥值或其他敏感数据。日志会被集中收集到内核，并可能在服务进程之外被采集。

## 调试用的源码位置

当内核使用 `Level = "debug"` 时，其日志记录器会为记录添加 `source` 字段。这是内核 host 层中的日志调用位置，有助于诊断 host 边界的问题，但它并不是服务自身源代码中可靠的文件和行号位置。

请使用消息中的上下文来标识您正在诊断的服务操作，不要把调试用的 `source` 字段当作服务的调用栈。

## 记录失败

日志记录不应替代错误处理。当某项操作失败时，应返回或传播一个错误；当该失败需要让运维人员看到时，再额外添加一条日志记录。请包含足够的上下文以识别该操作，同时不要暴露其输入数据。

当服务可以通过回退方案继续运行时使用 `warn`；当操作失败、服务无法提供预期结果时使用 `error`；对于那些在 `info` 级别会显得过于嘈杂的成功诊断路径，使用 `debug`。

内核为 `wasm` 和 `grpc` 服务提供相同的日志记录行为。您服务中的日志记录代码应当使用为所选运行时生成的 host 绑定，而不是直接写入某种特定于运行时的输出流。
