rsyslog 无法原生按天分表,但可通过时间模板实现日志文件按天分割,并结合 ommysql/ompgsql 模块写入数据库,再通过 cron 脚本每日建表、迁移和清理数据。

在 Linux 中,Rsyslog 本身不直接支持“按天分表”(如数据库表),但可通过日志轮转 + 文件命名规则 + 外部脚本/数据库写入实现“逻辑上按天分表”。若目标是将日志存入 MySQL/PostgreSQL 等数据库并按日期建表(例如 syslog_20240520),需结合 Rsyslog 的 ommysql/ompgsql 模块与自定义模板 + 定时建表脚本。同时用 Cron 实现归档(如压缩旧日志、迁移历史表、清理等)。
一、配置 Rsyslog 按天生成独立日志文件(基础轮转)
Rsyslog 原生支持基于时间的文件分割,无需外部工具:
- 编辑
/etc/rsyslog.conf或新建配置文件(如/etc/rsyslog.d/99-log-by-day.conf) - 启用
imfile(如需读取应用日志)或直接使用内置日志源(imuxsock,imjournal) - 定义模板,嵌入日期变量:
$template DailyFile,"/var/log/syslog-%$YEAR%%$MONTH%%$DAY%.log"
此模板使每条日志写入当天命名的文件(如/var/log/syslog-20240520.log) - 绑定模板到规则:
*.* ?DailyFile
注意:问号?表示使用模板名;确保目录/var/log/可写 - 重启服务:
sudo systemctl restart rsyslog
二、将日志写入数据库并按天建表(需 ommysql / ompgsql)
若最终目标是数据库“分表”,Rsyslog 可直连 MySQL/PostgreSQL,但需手动建表 + 动态选择表名:
- 安装模块(以 MySQL 为例):
sudo apt install rsyslog-mysql(Debian/Ubuntu) - 创建基础表结构(含日期字段):
CREATE TABLE syslog_raw (id INT AUTO_INCREMENT PRIMARY KEY, host VARCHAR(64), facility VARCHAR(16), priority VARCHAR(16), level INT, tag VARCHAR(32), datetime DATETIME, program VARCHAR(32), msg TEXT, logdate DATE); - 定义动态表名模板(MySQL 不支持运行时拼接表名,因此常用做法是:固定表名 + logdate 字段索引,再通过视图或分区表模拟分表)
- 更实用方案:用
ommysql写入统一表,再由 Cron 每日凌晨执行 SQL 创建新表 + INSERT … SELECT 转移昨日数据 + 清空原表(或加分区) - 示例插入规则(写入统一表):
action(type="ommysql" server="127.0.0.1" db="SyslogDB" uid="rsyslog" pwd="xxx" template="dbFormat")
其中dbFormat模板需包含$YEAR$MONTH$DAY字段供后续归档识别
三、用 Cron 实现自动化归档(压缩、转移、清理)
归档动作与存储方式强相关,以下是常见组合:
-
文件归档(推荐初学者):
每日凌晨 2:00 将昨日日志压缩并移入/var/log/archive/:0 2 * * * find /var/log -name "syslog-??????.log" -mtime 1 -exec gzip {} \; -exec mv {}\.gz /var/log/archive/ \; -
数据库归档(按天分表):
编写归档脚本/usr/local/bin/archive-syslog.sh:
• 用mysql -e "CREATE TABLE syslog_$(date -d 'yesterday' +\%Y\%m\%d) LIKE syslog_raw;"
• 执行INSERT INTO syslog_20240519 SELECT * FROM syslog_raw WHERE logdate = '2024-05-19';
• 删除已归档数据:DELETE FROM syslog_raw WHERE logdate = '2024-05-19';
加入 Cron:0 3 * * * /usr/local/bin/archive-syslog.sh >/dev/null 2>&1 -
保留策略:在归档脚本末尾添加清理逻辑,例如:
find /var/log/archive -name "*.log.gz" -mtime +90 -delete
或数据库中DROP TABLE IF EXISTS syslog_$(date -d '3 months ago' +\%Y\%m\%d);
四、关键注意事项与验证方法
避免踩坑,重点关注以下几点:
- Rsyslog 模板中的时间变量(
$YEAR等)默认为消息到达时间,非系统当前时间;若日志延迟,可能导致错天 —— 可用$NOW系列变量(需 v8.33+)或启用freshness机制 - 数据库写入性能敏感:高并发日志建议开启 Rsyslog 队列(
queue.type="disk")并调大缓冲 - Cron 时间依赖系统时区,确认
timedatectl status时区与业务一致 - 验证是否生效:
• 查看ls -lt /var/log/syslog-*.log是否每天新增
• 查询数据库:SELECT DISTINCT DATE(datetime) FROM syslog_raw ORDER BY 1 DESC LIMIT 5;
• 检查 Cron 日志:grep CRON /var/log/syslog











