主分支代码

This commit is contained in:
robin
2026-02-07 20:30:31 +08:00
parent 3b042d1dad
commit bc223fd1aa
65 changed files with 1969 additions and 188 deletions

308
deploy/fluent-bit/README.md Normal file
View File

@@ -0,0 +1,308 @@
# 边缘节点日志链路部署Fluent Bit + ClickHouse
与 [日志链路调整方案](../../log-pipeline-migration-plan.md) 配套的配置与部署说明。本文档为 **Fluent Bit 部署教程**,按步骤即可在边缘节点或日志采集机上跑通采集 → ClickHouse 写入。
---
## Fluent Bit 跑在哪台机器上?
**Fluent Bit 应部署在每台 EdgeNode 机器上**(与 edge-node 同机),不要部署在 EdgeAPI 机器上。
- 日志文件(`/var/log/edge/edge-node/*.log`)是 **EdgeNode** 在本机写的,只有 EdgeNode 所在机器才有这些文件。
- Fluent Bit 使用 **tail** 插件读取本机路径,因此必须运行在 **有这些日志文件的机器** 上,即每台 EdgeNode。
- EdgeAPI 机器上没有边缘节点日志,只负责查询 ClickHouse/MySQL因此不需要在 EdgeAPI 上跑 Fluent Bit。
- **多台 EdgeNode 时**:每台 EdgeNode 各跑一份 Fluent Bit各自采集本机日志并上报到同一 ClickHouse。
---
## 一、前置条件
- **边缘节点EdgeNode** 已开启本地日志落盘,日志目录默认 `/var/log/edge/edge-node`,会生成 `access.log``waf.log``error.log`JSON Lines。由环境变量 `EDGE_LOG_DIR` 控制路径。
- **ClickHouse** 已安装并可访问(单机或集群),且已创建好 `logs_ingest`见下文「五、ClickHouse 建表」)。
- 若 Fluent Bit 与 ClickHouse 不在同一台机,需保证网络可达(默认 HTTP 端口 8123
---
## 二、安装 Fluent Bit
### 2.1 Ubuntu / Debian
```bash
# 添加 Fluent Bit 官方源并安装(以 Ubuntu 22.04 为例)
curl https://raw.githubusercontent.com/fluent/fluent-bit/master/install.sh | sh
sudo apt-get install -y fluent-bit
# 或使用 TD Agent Bit 源(若需 ClickHouse 等扩展)
# 见https://docs.fluentbit.io/manual/installation/linux/ubuntu
```
### 2.2 CentOS / RHEL / Amazon Linux
```bash
# 使用官方 install 脚本
curl https://raw.githubusercontent.com/fluent/fluent-bit/master/install.sh | sh
# 或 yum/dnf 安装(以提供的仓库为准)
# sudo yum install -y fluent-bit
```
### 2.3 使用二进制包
从 [Fluent Bit 官方 Release](https://github.com/fluent/fluent-bit/releases) 下载对应架构的 tarball解压后将 `bin/fluent-bit` 放到 PATH并确保其 **Output 插件支持 ClickHouse**(部分发行版或自编译需启用 `out_clickhouse`)。
---
## 三、部署配置文件
### 3.1 放置配置
将本目录下配置文件放到同一目录,例如 `/etc/fluent-bit/``/opt/edge/fluent-bit/`
```bash
sudo mkdir -p /etc/fluent-bit
sudo cp fluent-bit.conf clickhouse-upstream.conf /etc/fluent-bit/
```
两文件需在同一目录,因 `fluent-bit.conf` 中有 `@INCLUDE clickhouse-upstream.conf`
### 3.2 修改 ClickHouse 地址(必做)
编辑 `clickhouse-upstream.conf`,按实际环境填写 ClickHouse 的 Host/Port
- **单机**:保留一个 `[NODE]`,改 `Host``Port`(默认 8123
- **集群**:复制多段 `[NODE]`,每段一个节点,例如:
```ini
[UPSTREAM]
Name ch_backends
[NODE]
Name node-01
Host 192.168.1.10
Port 8123
[NODE]
Name node-02
Host 192.168.1.11
Port 8123
```
### 3.3 ClickHouse 账号密码(有密码时必做)
不在 `clickhouse-upstream.conf` 里配置密码,而是通过 **环境变量** 传给 Fluent Bit
- `CH_USER`ClickHouse 用户名(如 `default`)。
- `CH_PASSWORD`:对应用户的密码。
在 systemd 或启动脚本中设置(见下文「四、以 systemd 方式运行」)。
### 3.4 日志路径与 parsers.conf
- **日志路径**`fluent-bit.conf` 里 INPUT 的 `Path` 已为 `/var/log/edge/edge-node/*.log`,与 EdgeNode 默认落盘路径一致;若你改了 `EDGE_LOG_DIR`,请同步改此处的 `Path`
- **Parsers_File**:主配置引用了 `parsers.conf`。若安装包自带(如 `/etc/fluent-bit/parsers.conf`),无需改动;若启动报错找不到文件,可:
- 从 Fluent Bit 官方仓库复制 [conf/parsers.conf](https://github.com/fluent/fluent-bit/blob/master/conf/parsers.conf) 到同一目录,或
- 在同一目录新建空文件 `parsers.conf`(仅当不使用任何 parser 时)。
### 3.5 数据与状态目录
Fluent Bit 会使用配置里的 `storage.path` 和 DB 路径,需保证进程有写权限:
```bash
sudo mkdir -p /var/lib/fluent-bit/storage
sudo chown -R <运行 fluent-bit 的用户>:<同组> /var/lib/fluent-bit
```
---
## 四、以 systemd 方式运行
### 4.1 使用自带服务(若安装包已提供)
若通过 apt/yum 安装,通常已有 `fluent-bit.service`。先改配置路径和环境变量:
```bash
# 编辑服务文件(路径以实际为准,如 /lib/systemd/system/fluent-bit.service
sudo systemctl edit fluent-bit --full
```
`[Service]` 中增加或修改:
- `EnvironmentFile` 指向你的环境变量文件,或直接写:
- `Environment="CH_USER=default"`
- `Environment="CH_PASSWORD=你的密码"`
- `ExecStart` 中的配置文件路径改为你的 `fluent-bit.conf`,例如:
- `ExecStart=/opt/fluent-bit/bin/fluent-bit -c /etc/fluent-bit/fluent-bit.conf`
然后:
```bash
sudo systemctl daemon-reload
sudo systemctl enable fluent-bit
sudo systemctl start fluent-bit
sudo systemctl status fluent-bit
```
### 4.2 自定义 systemd 单元(无自带服务时)
新建 `/etc/systemd/system/fluent-bit-edge.service`
```ini
[Unit]
Description=Fluent Bit - Edge Node Logs to ClickHouse
After=network.target
[Service]
Type=simple
ExecStart=/usr/bin/fluent-bit -c /etc/fluent-bit/fluent-bit.conf
Restart=always
RestartSec=5
# ClickHouse 认证(按需修改)
Environment="CH_USER=default"
Environment="CH_PASSWORD=your_clickhouse_password"
[Install]
WantedBy=multi-user.target
```
若密码含特殊字符,建议用 `EnvironmentFile=/etc/fluent-bit/fluent-bit.env`,并在该文件中写:
```bash
CH_USER=default
CH_PASSWORD=your_clickhouse_password
```
然后:
```bash
sudo systemctl daemon-reload
sudo systemctl enable fluent-bit-edge
sudo systemctl start fluent-bit-edge
sudo systemctl status fluent-bit-edge
```
### 4.3 前台调试
不依赖 systemd 时可直接前台跑(便于看日志):
```bash
export CH_USER=default
export CH_PASSWORD=your_clickhouse_password
fluent-bit -c /etc/fluent-bit/fluent-bit.conf
```
---
## 五、ClickHouse 建表
平台EdgeAPI查询的是表 `logs_ingest`,需在 ClickHouse 中先建表。库名默认为 `default`,若使用其它库,需与 EdgeAPI 的 `CLICKHOUSE_DATABASE` 一致。
在 ClickHouse 中执行(按需改库名或引擎):
```sql
CREATE TABLE IF NOT EXISTS default.logs_ingest
(
timestamp DateTime,
node_id UInt64,
cluster_id UInt64,
server_id UInt64,
host String,
ip String,
method String,
path String,
status UInt16,
bytes_in UInt64,
bytes_out UInt64,
cost_ms UInt32,
ua String,
referer String,
log_type String,
trace_id String,
firewall_policy_id UInt64 DEFAULT 0,
firewall_rule_group_id UInt64 DEFAULT 0,
firewall_rule_set_id UInt64 DEFAULT 0,
firewall_rule_id UInt64 DEFAULT 0,
request_headers String DEFAULT '',
request_body String DEFAULT '',
response_headers String DEFAULT '',
response_body String DEFAULT ''
)
ENGINE = MergeTree()
ORDER BY (timestamp, node_id, server_id, trace_id)
SETTINGS index_granularity = 8192;
```
- **log_type**`access` / `waf` / `error`;攻击日志同时看 **firewall_rule_id****firewall_policy_id** 是否大于 0与原有 MySQL 通过规则 ID 判断攻击日志一致)。
- **request_headers / response_headers**JSON 字符串;**request_body / response_body**:请求/响应体(单条建议限制长度,如 512KB
- **request_body 为空**:需在管理端为该站点/服务的「访问日志」策略中勾选「请求Body」后才会落盘默认未勾选。路径大致为站点/服务 → 访问日志 → 策略 → 记录字段 → 勾选「请求Body」。WAF 拦截且策略开启「记录请求Body」时也会记录。
- **response_body 为空**当前版本未实现proto 与节点均未支持响应体落盘),表中已预留字段,后续可扩展。
- **原有 MySQL 日志同步到 ClickHouse**:见 [mysql-to-clickhouse-migration.md](mysql-to-clickhouse-migration.md)。
若表已存在且缺少新字段,可执行:
```sql
ALTER TABLE default.logs_ingest ADD COLUMN IF NOT EXISTS firewall_policy_id UInt64 DEFAULT 0;
ALTER TABLE default.logs_ingest ADD COLUMN IF NOT EXISTS firewall_rule_group_id UInt64 DEFAULT 0;
ALTER TABLE default.logs_ingest ADD COLUMN IF NOT EXISTS firewall_rule_set_id UInt64 DEFAULT 0;
ALTER TABLE default.logs_ingest ADD COLUMN IF NOT EXISTS firewall_rule_id UInt64 DEFAULT 0;
ALTER TABLE default.logs_ingest ADD COLUMN IF NOT EXISTS request_headers String DEFAULT '';
ALTER TABLE default.logs_ingest ADD COLUMN IF NOT EXISTS request_body String DEFAULT '';
ALTER TABLE default.logs_ingest ADD COLUMN IF NOT EXISTS response_headers String DEFAULT '';
ALTER TABLE default.logs_ingest ADD COLUMN IF NOT EXISTS response_body String DEFAULT '';
```
Fluent Bit 写入时使用 `json_date_key timestamp``json_date_format epoch`,会将 JSON 中的 `timestamp`Unix 秒)转为 DateTime。
---
## 六、验证与排错
1. **看 Fluent Bit 日志**
- systemd`journalctl -u fluent-bit-edge -f`(或你的服务名)
- 前台:直接看终端输出。
2. **看 ClickHouse 是否有数据**
```sql
SELECT count() FROM default.logs_ingest;
SELECT * FROM default.logs_ingest LIMIT 5;
```
3. **常见问题**
- **连接被拒**:检查 `clickhouse-upstream.conf` 的 Host/Port、防火墙、ClickHouse 的 `listen_host`。
- **认证失败**:检查 `CH_USER`、`CH_PASSWORD` 是否与 ClickHouse 用户一致,环境变量是否被 systemd 正确加载。
- **找不到 parsers.conf**:见上文 3.4。
- **没有新数据**:确认 EdgeNode 已写日志到 `Path` 下,且 Fluent Bit 对该目录有读权限;可用 `tail -f /var/log/edge/edge-node/access.log` 观察是否有新行。
- **Node 上没有 `/var/log/edge/edge-node/access.log`**见下文「八、Node 上找不到日志文件」。
---
## 七、与其它组件的关系(简要)
| 组件 | 说明 |
|------|------|
| **EdgeNode** | 日志落盘路径由 `EDGE_LOG_DIR` 控制,默认 `/var/log/edge/edge-node`;生成 `access.log`、`waf.log`、`error.log`;支持 SIGHUP 重开句柄,可与 logrotate 的 `copytruncate` 配合。 |
| **logrotate** | 使用 `deploy/fluent-bit/logrotate.conf` 示例做轮转,避免磁盘占满。 |
| **平台EdgeAPI** | 配置 ClickHouse 只读连接(`CLICKHOUSE_HOST`、`CLICKHOUSE_PORT`、`CLICKHOUSE_USER`、`CLICKHOUSE_PASSWORD`、`CLICKHOUSE_DATABASE`);当请求带 `Day` 且已配置 ClickHouse 时,访问日志列表查询走 ClickHouse。 |
---
## 八、Node 上找不到日志文件
若在 EdgeNode 机器上执行 `tail -f /var/log/edge/edge-node/access.log` 报 **No such file or directory**,按下面检查:
1. **EdgeNode 版本**
本地日志落盘是较新功能,需使用**包含该功能的 EdgeNode 构建**(当前仓库版本在首次加载配置时会预创建目录和三个空日志文件)。
2. **预创建目录(可选)**
若进程以非 root 运行,可先手动建目录并赋权,避免无权限创建 `/var/log/edge`
```bash
sudo mkdir -p /var/log/edge/edge-node
sudo chown <运行 edge-node 的用户>:<同组> /var/log/edge/edge-node
```
3. **重启 EdgeNode**
新版本在**首次成功加载节点配置后**会调用 `EnsureInit()`,自动创建 `/var/log/edge/edge-node` 及 `access.log`、`waf.log`、`error.log`。重启一次 edge-node 后再看目录下是否已有文件。
4. **自定义路径**
若通过环境变量 `EDGE_LOG_DIR` 指定了其它目录则日志在该目录下Fluent Bit 的 `Path` 需与之一致。
以上完成即完成 Fluent Bit 的部署与验证。

View File

@@ -0,0 +1,11 @@
# ClickHouse 上游配置(单机或集群只改此文件)
# 单机:保留一个 NODE集群按需增加 NODE
# 有密码时:不在此文件配置,通过环境变量 CH_USER、CH_PASSWORD 在 fluent-bit.conf 的 OUTPUT 中生效。
[UPSTREAM]
Name ch_backends
[NODE]
Name node-01
Host 127.0.0.1
Port 8123

View File

@@ -0,0 +1,34 @@
# Fluent Bit 主配置(边缘节点日志采集 → ClickHouse
# 生产环境将 INPUT 改为 tail 采集 /var/log/edge/edge-node/*.log
[SERVICE]
Flush 5
Log_Level info
Parsers_File parsers.conf
storage.path /var/lib/fluent-bit/storage
storage.sync normal
storage.checksum off
storage.backlog.mem_limit 128MB
@INCLUDE clickhouse-upstream.conf
[INPUT]
Name tail
Path /var/log/edge/edge-node/*.log
Tag app.logs
Refresh_Interval 5
Read_from_Head false
DB /var/lib/fluent-bit/logs.db
Mem_Buf_Limit 128MB
Skip_Long_Lines On
[OUTPUT]
Name clickhouse
Match *
Upstream ch_backends
Table logs_ingest
Http_User ${CH_USER}
Http_Passwd ${CH_PASSWORD}
json_date_key timestamp
json_date_format epoch
Retry_Limit 10

View File

@@ -0,0 +1,11 @@
# logrotate 示例:边缘节点日志轮转
# 安装:放入 /etc/logrotate.d/edge-node 或 include 到主配置
/var/log/edge/edge-node/*.log {
daily
rotate 14
compress
missingok
notifempty
copytruncate
}

View File

@@ -0,0 +1,9 @@
# Fluent Bit 解析器(与主配置 Parsers_File 对应)
# 边缘节点日志为 JSON Lines使用 json 解析器即可
[PARSER]
Name json
Format json
Time_Key timestamp
Time_Format %s
Time_Keep On