logo
0
0
Login

Nginx Log to Database

这是一个将 Nginx 访问日志和错误日志实时同步到数据库的工具,支持 ClickHouse 和 DuckDB 两种数据库,通过 Rsyslog 方式接收日志。

功能特性

  • 多种日志类型: 访问日志(access log)、错误日志(error log)
  • 多种数据库支持: ClickHouse、DuckDB
  • 输入方式: Rsyslog (TCP/UDP)
  • 批量写入: 支持批量写入,提高性能
  • 自动重连: 数据库连接断开自动重连
  • 失败重试: 写入失败自动重试,并保存失败日志
  • 自动识别: 自动区分访问日志和错误日志并存储到不同的表

项目结构

. ├── main.go # 主程序入口 ├── config/ │ └── config.go # 配置管理模块 ├── models/ │ └── nginx_log.go # 数据模型定义 ├── database/ │ ├── interface.go # 数据库接口定义 │ ├── db_manager.go # ClickHouse 数据库管理 │ └── duckdb_manager.go # DuckDB 数据库管理 ├── receiver/ │ ├── interface.go # 接收器接口定义 │ └── syslog_receiver.go # Rsyslog 接收器 ├── worker/ │ └── log_worker.go # 日志处理工作线程 └── README.md

环境变量配置

创建 .env 文件,配置如下:

# 数据库类型: clickhouse 或 duckdb DATABASE_TYPE=duckdb # 输入模式: rsyslog INPUT_MODE=rsyslog # ClickHouse 配置(当 DATABASE_TYPE=clickhouse 时需要) CLICKHOUSE_ADDRESS=127.0.0.1:9000 CLICKHOUSE_DB=nginx CLICKHOUSE_USER=default CLICKHOUSE_PASS= # DuckDB 配置(当 DATABASE_TYPE=duckdb 时需要) DUCKDB_PATH=./nginx_logs.db # Syslog 配置(当 INPUT_MODE=rsyslog 时需要) SYSLOG_LISTEN_ADDR=0.0.0.0:514 # 批处理配置 BATCH_SIZE=1000 WORKER_COUNT=4 # 调试模式 DEBUG=false

编译和运行

# 下载依赖 go mod tidy # 编译 CGO_ENABLED=1 go build . # 运行 ./nglog2db

使用方式

使用 DuckDB + Rsyslog(推荐)

# 配置 .env DATABASE_TYPE=duckdb INPUT_MODE=rsyslog SYSLOG_LISTEN_ADDR=0.0.0.0:514 # 运行服务 ./nglog2db

在 rsyslog 配置文件中添加转发规则(/etc/rsyslog.d/nginx.conf):

# TCP 方式 *.* @@127.0.0.1:514 # UDP 方式 *.* @127.0.0.1:514

使用 ClickHouse + Rsyslog

# 配置 .env DATABASE_TYPE=clickhouse INPUT_MODE=rsyslog SYSLOG_LISTEN_ADDR=0.0.0.0:514 # 运行服务 ./nglog2db

失败日志

写入失败的数据会保存到以下文件中,格式为 JSON 格式,每行一条记录:

  • 访问日志失败: ./nginxnglog2db_failed.log
  • 错误日志失败: ./nginxnglog2db_error_failed.log

数据库表结构

ClickHouse 表结构

CREATE TABLE access ( time DateTime, version UInt8, remote_addr String, remote_user String, time_local String, request String, scheme String, status String, body_bytes_sent String, http_referer String, http_user_agent String, proxy_add_x_forwarded_for String, http_x_forwarded_for String, upstream_response_time String, request_time String, upstream_status String, upstream_addr String, http_host String ) ENGINE = MergeTree() ORDER BY (http_host, time);

DuckDB 表结构

DuckDB 表会自动创建,无需手动创建。表结构与 ClickHouse 相同。

Error Log 表结构

CREATE TABLE error_log ( time DateTime, level String, pid UInt32, tid UInt32, message String ) ENGINE = MergeTree() ORDER BY (time, level);

DuckDB 会自动创建对应的 error_log 表。

Nginx 日志格式

Nginx 需要配置 JSON 格式的日志输出:

Access Log 格式

log_format json_access escape=json '{' '"time":"$time_iso8601",' '"version":"1",' '"remote_addr":"$remote_addr",' '"remote_user":"$remote_user",' '"time_local":"$time_local",' '"request":"$request",' '"scheme":"$scheme",' '"status":"$status",' '"body_bytes_sent":"$body_bytes_sent",' '"http_referer":"$http_referer",' '"http_user_agent":"$http_user_agent",' '"proxy_add_x_forwarded_for":"$proxy_add_x_forwarded_for",' '"http_x_forwarded_for":"$http_x_forwarded_for",' '"upstream_response_time":"$upstream_response_time",' '"request_time":"$request_time",' '"upstream_status":"$upstream_status",' '"upstream_addr":"$upstream_addr",' '"http_host":"$host"' '}'; access_log /var/log/nginx/access.log json_access; # 或者使用 syslog access_log syslog:server=127.0.0.1:514 json_access;

Error Log 格式

Nginx 的 error_log 使用默认文本格式即可,程序会自动解析:

# 默认文本格式(推荐) error_log /var/log/nginx/error.log; # 或使用 syslog error_log syslog:server=127.0.0.1:514;

Error Log 文本格式示例:

2024/01/01 12:00:00 [error] 12345#67890: *123 connection timed out, client: 192.168.1.100, server: example.com, request: "GET /api/test HTTP/1.1", host: "www.example.com"

程序会自动解析以下字段:

  • 时间:2024/01/01 12:00:00
  • 级别:error, warn, notice, info, debug, crit, alert, emerg
  • PID#TID:进程和线程 ID(如 12345#67890
  • Message:完整的错误消息

可选:JSON 格式(需自定义)

如果你通过 rsyslog 或其他方式转换为 JSON 格式,也支持:

{ "time": "2024-01-01T12:00:00+08:00", "level": "error", "pid": 12345, "tid": 67890, "message": "connection timed out while connecting to upstream" }

About

No description, topics, or website provided.
Language
Go100%