Files
hotime/docs/Seq_日志集成.md

166 lines
6.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Seq 日志集成
HoTime 框架内置 Seq 日志推送支持。通过在 `config.json` 填写 `seqUrl` 即可激活。
**目标:用 Seq 集中检索替代翻 `logs/*.txt`**;本地 `logFile` 可并行保留。
---
## 配置项
`config.json` 中添加:
```json
"seqUrl": "http://127.0.0.1:5341",
"seqApiKey": ""
```
| 字段 | 默认值 | 说明 |
|---|---|---|
| `seqUrl` | 空(不激活) | Seq 服务地址,空值时功能静默不生效 |
| `seqApiKey` | 空 | API Key,免费单用户版留空 |
`instance` 字段由框架自动拼接为 `ip:port`(如 `192.168.1.10:8085`),无需手动填写。
激活后每个 HTTP 请求会自动:
- 生成 `request_id`12 位 hex),回写响应头 `X-Request-Id`
-`sessionId` 前 12 位作为 `sid` 写入请求级日志(脱敏,避免把登录凭据写进 Seq)
- 业务日志、SQL 日志、访问日志均携带 `sid` / `request_id`
- **控制台自动降噪**(零额外配置):业务日志(`that.Log`)控制台放宽到 **Info+**(Debug/SQL 不上控制台),访问日志(`that.WebConnectLog`)控制台保持 **Warn+**(量大不上控制台);Debug/SQL/访问日志(Info 级)仍全量进 Seq 与文件
---
## 会话追踪与 LogBind
框架在 `handler` 入口派生请求级 Logger,并浅拷贝 `Db` 将其 `Log` 指向同一 Logger,因此 **SQL 日志自动带会话字段**。字段会出现在同条日志的控制台/文件/Seq 出口上。
业务在 `SetConnectListener` 中按需绑定自定义字段(建议放在鉴权/守卫之前,这样未登录被拒的 Warning 也能带上维度字段):
```go
appIns.SetConnectListener(func(context *Context) bool {
if v := context.Session("user_id").ToCeilInt64(); v > 0 {
context.LogBind("user_id", v)
}
// 其他 session / 请求参数字段同理:有值再绑
return false
})
```
`LogBind` 后,本请求后续业务日志与 SQL 日志都会带上该字段。session 在 context 内有缓存,多次 `Session()` 只查一次库。字段名与取值由业务自行约定。
**不带会话字段的边界:**
- `fmt.Println` / stdout 捕获、panic、MySQL driver、定时任务等无请求上下文的日志
- 直接写 `that.Application.Log` 的旧代码(应改用 `that.Logger``that.LogBind` 后的请求级 Logger
---
## 控制台降噪(配了 seqUrl)
| Logger | 控制台行为 |
|---|---|
| 业务日志(`that.Log` | Info+Info / Warn / Error,含 `Display` 非 0 的 WarnDebug/SQL 不上控制台) |
| 访问日志(`that.WebConnectLog`) | Warn+(访问日志量大,Info 级不上控制台) |
| 出口 | 行为 |
|---|---|
| Seq | 按 `logLevel` 全量(Info/Debug/SQL/访问日志等) |
| 本地文件 | 与原先一致,不受控制台过滤影响 |
未配置 `seqUrl` 时控制台仍按 `logLevel` 全打。
框架不新增配置项;如需自定义某个 Logger 的控制台门槛,可在挂 Seq 后调用 `Logger.SetConsoleMinLevel(level zerolog.Level)`(仅影响该 Logger 的控制台出口,不影响 Seq/文件)。
---
## 客户端 IP 与地域
零配置。`ip` 选取优先级(跳过空值与回环 `127.0.0.1` / `::1`):
1. `EO-Connecting-IP`EdgeOne 真实建连 IP
2. `X-Forwarded-For` **从左到右第一个非回环**(反代误把 CDN 写入 `X-Real-IP` 时仍能落到客户端)
3. `X-Real-IP`(非回环)
4. `RemoteAddr`
访问日志另附 `ip_chain`:上述源头出现过的 IP 按**首次出现**顺序逗号拼接,**同一 IP 不重复**;若与 `ip` 相同则省略该字段。
请求头有 `EO-Client-IPCountry` 时,访问日志追加 `ip_country`(两位国家码);没有则不记。
---
## 架构原理
```
业务代码
│ that.Logger.Info().Msg("...") ← 请求级(含 sid/request_id
│ Db.Query → SQL 日志 ← 同一请求级 Logger
│ fmt.Println("...") ← 捕获后无 sid
multiWriterhotimev1.5/log/logger.go
├─ Console(挂 Seq 后:业务 Info+ / 访问日志 Warn+)→ 终端
├─ FileWriter → 本地文件(按需,全量)
└─ SeqWriter → Seq(全量)
│ Write() 只做 channel <- bytesO(1) 非阻塞
channel(容量 10000
↓ 后台 goroutine
批量打包(100 条 或 500ms
↓ HTTP POST(失败重试 1 次)
Seq 服务(CLEF 格式)
```
优雅停机时调用 `CloseSeq()` 冲刷残留批次,避免停机前后日志丢失。
---
## 字段映射(zerolog → CLEF
| zerolog 字段 | Seq CLEF 字段 | 说明 |
|---|---|---|
| `time` | `@t` | 毫秒精度 ISO 8601 |
| `level` | `@l` | Debug/Information/Warning/Error/Fatal |
| `message` / `msg` | `@m` | 消息正文(不用 `@mt`,避免 `{xxx}` 被当模板) |
| `caller` | `caller` | 调用位置 |
| `sid` | `sid` | sessionId 前 12 位 |
| `request_id` | `request_id` | 单次请求 id |
| `ip` | `ip` | 客户端最佳 IP |
| `ip_chain` | `ip_chain` | 多源去重链路(与 `ip` 不同时才有) |
| `ip_country` | `ip_country` | 有 `EO-Client-IPCountry` 时 |
| `ua` | `ua` | 访问日志携带,User-Agent 原文截断 200 字符(按 rune 安全截断) |
| 其余自定义字段 | 原字段名 | `LogBind` 追加的字段原样保留 |
| — | `instance` | `ip:port` |
| — | `source` | stdout / stderr / panic 等 |
---
## 搜索语法速查
| 目标 | 查询语句 |
|---|---|
| 按会话追踪 | `sid = 'abc123def456'` |
| 按单次请求 | `request_id = 'fedcba987654'` |
| 关键词 | 直接输入,如 `支付失败` |
| 日志级别 | `@l = 'Error'` |
| 特定实例 | `instance = '192.168.1.10:8085'` |
| 地域 | `ip_country = 'CN'` |
| stdout | `source = 'stdout'` |
| panic | `source = 'panic'` |
| 组合 | `@l = 'Error' and sid = 'abc123def456'` |
| 关键字组合其他条件 | `@Message like '%支付失败%' and @l = 'Warning' and instance = '192.168.1.10:8085'` |
---
## Seq 安装
- Windows[https://datalust.co/download/seq](https://datalust.co/download/seq)
- Docker`docker run -d --restart always --name seq -p 5341:80 -e ACCEPT_EULA=Y datalust/seq`
- 访问 `http://localhost:5341`
---
## 相关文档
- [QuickStart_快速上手.md](QuickStart_快速上手.md) — 其中的 `that.Log` 是业务 logs 表,与本文 Seq 推送不同
- [GracefulShutdown_优雅停机.md](GracefulShutdown_优雅停机.md)
- [文档索引](README.md)