122 lines
4.0 KiB
Markdown
122 lines
4.0 KiB
Markdown
|
|
# Seq 日志集成
|
|||
|
|
|
|||
|
|
HoTime 框架内置 Seq 日志推送支持。通过在 `config.json` 填写 `seqUrl` 即可激活,
|
|||
|
|
所有框架日志(含 `fmt.Println` 等绕过 Logger 的输出)实时推送到 Seq,
|
|||
|
|
通过 Seq Web UI 实现关键词、日期范围、日志级别、结构化字段等多维度搜索。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 配置项
|
|||
|
|
|
|||
|
|
在 `config.json` 中添加:
|
|||
|
|
|
|||
|
|
```json
|
|||
|
|
"seqUrl": "http://127.0.0.1:5341",
|
|||
|
|
"seqApiKey": ""
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
| 字段 | 默认值 | 说明 |
|
|||
|
|
|---|---|---|
|
|||
|
|
| `seqUrl` | 空(不激活) | Seq 服务地址,空值时功能静默不生效 |
|
|||
|
|
| `seqApiKey` | 空 | API Key,免费单用户版留空 |
|
|||
|
|
|
|||
|
|
`instance` 字段由框架自动拼接为 `ip:port`(如 `192.168.1.10:8085`),无需手动填写,同机多进程靠端口区分,跨服务器靠 IP 区分,支持未来集群扩展。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 架构原理
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
业务代码
|
|||
|
|
│ l.Info().Msg("...") ← HoTime Logger 正常调用路径
|
|||
|
|
│ fmt.Println("...") ← 被 redirectStdout 捕获后转入同一路径
|
|||
|
|
↓
|
|||
|
|
multiWriter(hotimev1.5/log/logger.go)
|
|||
|
|
├─ ConsoleWriter → 彩色终端输出(不变)
|
|||
|
|
├─ FileWriter → 本地日志文件(按需,logFile 配置)
|
|||
|
|
└─ SeqWriter
|
|||
|
|
│ Write() 只做 channel <- bytes,O(1) 非阻塞
|
|||
|
|
↓
|
|||
|
|
channel(容量 10000)
|
|||
|
|
↓ 后台 goroutine
|
|||
|
|
批量打包(100 条 或 500ms)
|
|||
|
|
↓ HTTP POST
|
|||
|
|
Seq 服务(CLEF 格式)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**关键特性:**
|
|||
|
|
- `SeqWriter.Write()` 仅向 channel 投递字节即返回,**绝不阻塞** web 请求处理 goroutine
|
|||
|
|
- channel 满时(Seq 宕机/网络故障)新日志被丢弃并计数,主服务完全不受影响
|
|||
|
|
- HTTP POST 设 5s 超时,失败仅打印到 stderr
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 字段映射(zerolog → CLEF)
|
|||
|
|
|
|||
|
|
| zerolog 字段 | Seq CLEF 字段 | 说明 |
|
|||
|
|
|---|---|---|
|
|||
|
|
| `time` | `@t` | 时间,自动转 ISO 8601 格式 |
|
|||
|
|
| `level` | `@l` | 级别,映射为 Debug/Information/Warning/Error/Fatal |
|
|||
|
|
| `message` / `msg` | `@mt` | 消息正文 |
|
|||
|
|
| `caller` | `caller` | 调用位置,原样保留 |
|
|||
|
|
| 其余自定义字段 | 原字段名 | 原样保留,可在 Seq 中直接查询 |
|
|||
|
|
| — | `instance` | 框架自动注入,值为 `port` 配置(如 `"8085"`) |
|
|||
|
|
| — | `source` | fmt.Println 等捕获的输出标记为 `stdout` |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 单机多进程实例区分
|
|||
|
|
|
|||
|
|
框架启动时自动获取本机出口 IP,拼接为 `ip:port` 格式作为 `instance`:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
单机多进程:
|
|||
|
|
192.168.1.10:8085 ─┐
|
|||
|
|
192.168.1.10:8086 ─┼─ HTTP CLEF ──→ Seq
|
|||
|
|
192.168.1.10:8087 ─┘
|
|||
|
|
|
|||
|
|
多服务器集群:
|
|||
|
|
192.168.1.10:8085 ─┐
|
|||
|
|
192.168.1.11:8085 ─┼─ HTTP CLEF ──→ Seq(中央日志服务器)
|
|||
|
|
192.168.1.12:8085 ─┘
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Seq 中按实例筛选:
|
|||
|
|
- 单台机器所有进程:`instance like '192.168.1.10%'`
|
|||
|
|
- 精确到某个进程:`instance = '192.168.1.10:8085'`
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## stdout 全量捕获
|
|||
|
|
|
|||
|
|
框架启动时(`SetConfig()` 中)自动调用 `redirectStdout()`,
|
|||
|
|
将 `os.Stdout` 和标准 `log` 包重定向到 HoTime Logger:
|
|||
|
|
|
|||
|
|
- `fmt.Println("xxx")` → 以 `INFO` 级别、`source=stdout` 字段推送到 Seq
|
|||
|
|
- `log.Printf("xxx")` → 同上
|
|||
|
|
- 控制台仍然能看到这些输出(输出管道由 goroutine 实时转发)
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Seq 安装
|
|||
|
|
|
|||
|
|
Seq 提供 Windows MSI 安装包和 Docker 镜像,单机免费,无外部数据库依赖:
|
|||
|
|
|
|||
|
|
- Windows:[https://datalust.co/download/seq](https://datalust.co/download/seq),安装后自动注册为 Windows 服务
|
|||
|
|
- Docker:`docker run -d --restart always --name seq -p 5341:80 -e ACCEPT_EULA=Y datalust/seq`
|
|||
|
|
- 访问 `http://localhost:5341` 使用 Web UI
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 搜索语法速查
|
|||
|
|
|
|||
|
|
| 目标 | 查询语句 |
|
|||
|
|
|---|---|
|
|||
|
|
| 关键词搜索 | 直接输入,如 `支付失败` |
|
|||
|
|
| 日志级别 | `@l = 'Error'` |
|
|||
|
|
| 特定实例 | `instance = '8085'` |
|
|||
|
|
| stdout 来源 | `source = 'stdout'` |
|
|||
|
|
| 调用位置 | `caller like '%order.go%'` |
|
|||
|
|
| 组合查询 | `@l = 'Error' and instance = '8086' and @mt like '%超时%'` |
|
|||
|
|
| 日期范围 | 右上角时间选择器,支持精确到秒 |
|