dns clickhouse改造

This commit is contained in:
robin
2026-02-10 19:30:44 +08:00
parent 4812ad5aaf
commit 1bb8140a41
47 changed files with 2815 additions and 174 deletions

View File

@@ -6,18 +6,20 @@
## Fluent Bit 跑在哪台机器上?
**Fluent Bit 应部署在每台 EdgeNode 机器上**(与 edge-node 同机),不要部署在 EdgeAPI 机器上。
**Fluent Bit 应部署在写日志文件的节点机器上**EdgeNode / EdgeDNS 同机),不要部署在 EdgeAPI 机器上。
- 日志文件(`/var/log/edge/edge-node/*.log`)是 **EdgeNode** 本机写的,只有 EdgeNode 所在机器才有这些文件
- Fluent Bit 使用 **tail** 插件读取本机路径,因此必须运行在 **有这些日志文件的机器** 上,即每台 EdgeNode
- EdgeAPI 机器上没有边缘节点日志,只负责查询 ClickHouse/MySQL因此不需要在 EdgeAPI 上跑 Fluent Bit
- **多台 EdgeNode 时**:每台 EdgeNode 各跑一份 Fluent Bit各自采集本机日志并上报到同一 ClickHouse
- HTTP 日志文件默认在 `/var/log/edge/edge-node/*.log`,由 **EdgeNode** 本机写入;若配置了公用访问日志策略的文件 `path`,节点会优先复用该 `path` 所在目录
- DNS 日志文件默认在 `/var/log/edge/edge-dns/*.log`,由 **EdgeDNS** 本机写入;若配置了公用访问日志策略的文件 `path`,节点会优先复用该 `path` 所在目录
- Fluent Bit 使用 **tail** 读取本机路径,因此必须运行在这些日志文件所在机器上
- EdgeAPI 机器主要负责查询 ClickHouse/MySQL不需要承担日志采集
- 多机部署时,每台写日志节点都跑一份 Fluent Bit上报到同一 ClickHouse 集群。
---
## 一、前置条件
- **边缘节点EdgeNode** 已开启本地日志落盘,日志目录默认 `/var/log/edge/edge-node`,会生成 `access.log``waf.log``error.log`JSON Lines由环境变量 `EDGE_LOG_DIR` 控制路径。
- **边缘节点EdgeNode** 已开启本地日志落盘,目录优先取“公用访问日志策略”的文件 `path`(取目录),为空时回退 `EDGE_LOG_DIR`,再回退默认 `/var/log/edge/edge-node`生成 `access.log``waf.log``error.log`JSON Lines
- **DNS 节点EdgeDNS** 已开启本地日志落盘,目录优先取“公用访问日志策略”的文件 `path`(取目录),为空时回退 `EDGE_DNS_LOG_DIR`,再回退默认 `/var/log/edge/edge-dns`;生成 `access.log`JSON Lines
- **ClickHouse** 已安装并可访问(单机或集群),且已创建好 `logs_ingest`见下文「五、ClickHouse 建表」)。
- 若 Fluent Bit 与 ClickHouse 不在同一台机,需保证网络可达(默认 HTTP 端口 8123
@@ -98,7 +100,10 @@ sudo cp fluent-bit.conf clickhouse-upstream.conf /etc/fluent-bit/
### 3.4 日志路径与 parsers.conf
- **日志路径**`fluent-bit.conf` INPUT 的 `Path` 已为 `/var/log/edge/edge-node/*.log`,与 EdgeNode 默认落盘路径一致;若你改了 `EDGE_LOG_DIR`,请同步改此处的 `Path`
- **日志路径**`fluent-bit.conf`已同时配置 HTTP 与 DNS 两类路径:
- HTTP`/var/log/edge/edge-node/*.log`
- DNS`/var/log/edge/edge-dns/*.log`
若你配置了公用访问日志策略的文件 `path`,或改了 `EDGE_LOG_DIR` / `EDGE_DNS_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 时)。
@@ -194,7 +199,11 @@ fluent-bit -c /etc/fluent-bit/fluent-bit.conf
## 五、ClickHouse 建表
平台EdgeAPI查询的是表 `logs_ingest`,需在 ClickHouse 中先建表。库名默认为 `default`,若使用其它库,需与 EdgeAPI 的 `CLICKHOUSE_DATABASE` 一致。
平台EdgeAPI查询两张表:
- HTTP`logs_ingest`
- DNS`dns_logs_ingest`
需在 ClickHouse 中先建表。库名默认为 `default`,若使用其它库,需与 EdgeAPI 的 `CLICKHOUSE_DATABASE` 一致。
在 ClickHouse 中执行(按需改库名或引擎):
@@ -231,6 +240,34 @@ ORDER BY (timestamp, node_id, server_id, trace_id)
SETTINGS index_granularity = 8192;
```
DNS 日志建表:
```sql
CREATE TABLE IF NOT EXISTS default.dns_logs_ingest
(
timestamp DateTime,
request_id String,
node_id UInt64,
cluster_id UInt64,
domain_id UInt64,
record_id UInt64,
remote_addr String,
question_name String,
question_type String,
record_name String,
record_type String,
record_value String,
networking String,
is_recursive UInt8,
error String,
ns_route_codes Array(String),
content_json String DEFAULT ''
)
ENGINE = MergeTree()
ORDER BY (timestamp, request_id, node_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」时也会记录。
@@ -248,6 +285,7 @@ ALTER TABLE default.logs_ingest ADD COLUMN IF NOT EXISTS request_headers String
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 '';
ALTER TABLE default.dns_logs_ingest ADD COLUMN IF NOT EXISTS content_json String DEFAULT '';
```
Fluent Bit 写入时使用 `json_date_key timestamp``json_date_format epoch`,会将 JSON 中的 `timestamp`Unix 秒)转为 DateTime。
@@ -264,13 +302,15 @@ Fluent Bit 写入时使用 `json_date_key timestamp` 和 `json_date_format epoch
```sql
SELECT count() FROM default.logs_ingest;
SELECT * FROM default.logs_ingest LIMIT 5;
SELECT count() FROM default.dns_logs_ingest;
SELECT * FROM default.dns_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` 观察是否有新行
- **没有新数据**:确认 EdgeNode/EdgeDNS 已写日志到 `Path` 下,且 Fluent Bit 对目录有读权限;可分别执行 `tail -f /var/log/edge/edge-node/access.log` 与 `tail -f /var/log/edge/edge-dns/access.log`
- **Node 上没有 `/var/log/edge/edge-node/access.log`**见下文「八、Node 上找不到日志文件」。
---
@@ -279,7 +319,8 @@ Fluent Bit 写入时使用 `json_date_key timestamp` 和 `json_date_format epoch
| 组件 | 说明 |
|------|------|
| **EdgeNode** | 日志落盘路径 `EDGE_LOG_DIR` 控制,默认 `/var/log/edge/edge-node`;生成 `access.log`、`waf.log`、`error.log`;支持 SIGHUP 重开句柄,可与 logrotate 的 `copytruncate` 配合。 |
| **EdgeNode** | 日志落盘路径优先复用公用访问日志策略文件 `path`(取目录);若为空回退 `EDGE_LOG_DIR`再回退默认 `/var/log/edge/edge-node`;生成 `access.log`、`waf.log`、`error.log`;支持 SIGHUP 重开句柄,可与 logrotate 的 `copytruncate` 配合。 |
| **EdgeDNS** | DNS 访问日志落盘路径优先复用公用访问日志策略文件 `path`(取目录);若为空回退 `EDGE_DNS_LOG_DIR`,再回退默认 `/var/log/edge/edge-dns`;生成 `access.log`JSON Lines由 Fluent Bit 采集写入 `dns_logs_ingest`。 |
| **logrotate** | 使用 `deploy/fluent-bit/logrotate.conf` 示例做轮转,避免磁盘占满。 |
| **平台EdgeAPI** | 配置 ClickHouse 只读连接(`CLICKHOUSE_HOST`、`CLICKHOUSE_PORT`、`CLICKHOUSE_USER`、`CLICKHOUSE_PASSWORD`、`CLICKHOUSE_DATABASE`);当请求带 `Day` 且已配置 ClickHouse 时,访问日志列表查询走 ClickHouse。 |
@@ -303,6 +344,6 @@ Fluent Bit 写入时使用 `json_date_key timestamp` 和 `json_date_format epoch
新版本在**首次成功加载节点配置后**会调用 `EnsureInit()`,自动创建 `/var/log/edge/edge-node` 及 `access.log`、`waf.log`、`error.log`。重启一次 edge-node 后再看目录下是否已有文件。
4. **自定义路径**
通过环境变量 `EDGE_LOG_DIR` 指定了其它目录,则日志在该目录下;Fluent Bit 的 `Path` 需与一致。
在管理端设置了公用访问日志策略的文件 `path`,节点会优先使用该目录;否则才使用 `EDGE_LOG_DIR`。Fluent Bit 的 `Path` 需与实际目录一致。
以上完成即完成 Fluent Bit 的部署与验证。

View File

@@ -0,0 +1,36 @@
# DNS 节点专用:使用 HTTP 输出写入 ClickHouse无需 out_clickhouse 插件)
# 启动前设置CH_USER、CH_PASSWORD若 ClickHouse 不在本机,请修改 Host、Port
# Read_from_Head=true首次启动会发送已有日志若只采新日志建议改为 false
[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
[INPUT]
Name tail
Path /var/log/edge/edge-dns/*.log
Tag app.dns.logs
Parser json
Refresh_Interval 5
Read_from_Head false
DB /var/lib/fluent-bit/dns-logs.db
Mem_Buf_Limit 128MB
Skip_Long_Lines On
[OUTPUT]
Name http
Match app.dns.logs
Host 127.0.0.1
Port 8123
URI /?query=INSERT%20INTO%20default.dns_logs_ingest%20FORMAT%20JSONEachRow
Format json_lines
http_user ${CH_USER}
http_passwd ${CH_PASSWORD}
json_date_key timestamp
json_date_format epoch
Retry_Limit 10

View File

@@ -1,5 +1,6 @@
# Fluent Bit 主配置(边缘节点日志采集 → ClickHouse
# 生产环境将 INPUT 改为 tail 采集 /var/log/edge/edge-node/*.log
# HTTP: /var/log/edge/edge-node/*.log
# DNS: /var/log/edge/edge-dns/*.log
[SERVICE]
Flush 5
@@ -15,16 +16,26 @@
[INPUT]
Name tail
Path /var/log/edge/edge-node/*.log
Tag app.logs
Tag app.http.logs
Refresh_Interval 5
Read_from_Head false
DB /var/lib/fluent-bit/logs.db
DB /var/lib/fluent-bit/http-logs.db
Mem_Buf_Limit 128MB
Skip_Long_Lines On
[INPUT]
Name tail
Path /var/log/edge/edge-dns/*.log
Tag app.dns.logs
Refresh_Interval 5
Read_from_Head false
DB /var/lib/fluent-bit/dns-logs.db
Mem_Buf_Limit 128MB
Skip_Long_Lines On
[OUTPUT]
Name clickhouse
Match *
Match app.http.logs
Upstream ch_backends
Table logs_ingest
Http_User ${CH_USER}
@@ -32,3 +43,14 @@
json_date_key timestamp
json_date_format epoch
Retry_Limit 10
[OUTPUT]
Name clickhouse
Match app.dns.logs
Upstream ch_backends
Table dns_logs_ingest
Http_User ${CH_USER}
Http_Passwd ${CH_PASSWORD}
json_date_key timestamp
json_date_format epoch
Retry_Limit 10

View File

@@ -9,3 +9,12 @@
notifempty
copytruncate
}
/var/log/edge/edge-dns/*.log {
daily
rotate 14
compress
missingok
notifempty
copytruncate
}