Linux下如何无需扫描全文件仅查看/监控近5分钟新增内容
仅监控Linux日志近5分钟新增内容的高效方案
针对你提到的持续增长的数据库错误日志监控需求,我整理了两个高效的方案,完全避免全量扫描大文件的资源消耗:
方案一:基于时间戳精准过滤(适合带标准时间戳的日志)
既然每条错误记录都有时间戳,我们可以直接计算出5分钟前的时间点,然后过滤出时间戳晚于该点的日志行,完全不用碰旧内容。
假设你的日志时间戳格式是YYYY-MM-DD HH:MM:SS(比如2024-05-20 14:35:22 ERROR: connection failed),可以用以下脚本实现:
# 生成5分钟前的时间字符串,格式和日志匹配 START_TIME=$(date -d "-5 minutes" +"%Y-%m-%d %H:%M:%S") # 用awk比较日志时间戳和START_TIME,输出符合条件的行 awk -v start="$START_TIME" '$1" "$2 >= start' /var/log/db_error.log
- 注意:如果你的时间戳格式不同(比如
MM/DD/YYYY HH:MM),需要调整date命令的输出格式,以及awk里的字段位置(比如如果时间戳是第3、4字段,就改成$3" "$4)。
方案二:记录文件读取偏移量(通用高效方案)
如果日志时间戳格式不固定,或者你想追求极致效率(完全跳过旧内容,只读取新增部分),可以通过记录文件的字节偏移量来实现,每次只从上次读到的位置继续读取。
这个方案还能处理日志被logrotate轮转的情况,脚本示例:
#!/bin/bash LOG_FILE="/var/log/db_error.log" OFFSET_FILE="/tmp/db_log_offset.txt" # 获取当前日志文件的inode(用于判断是否被轮转) CURRENT_INODE=$(stat -c %i "$LOG_FILE") # 初始化或读取上次的记录 if [ -f "$OFFSET_FILE" ]; then read LAST_INODE LAST_OFFSET < "$OFFSET_FILE" # 如果inode变化,说明日志被轮转,重置偏移量 if [ "$CURRENT_INODE" != "$LAST_INODE" ]; then LAST_OFFSET=0 fi else LAST_INODE=$CURRENT_INODE LAST_OFFSET=0 fi # 读取从上次偏移量之后的所有新内容 tail -c +$((LAST_OFFSET + 1)) "$LOG_FILE" # 更新inode和最新的文件大小(作为下次的偏移量) echo "$CURRENT_INODE $(stat -c %s "$LOG_FILE")" > "$OFFSET_FILE"
这个脚本会记住每次读到的文件位置,下次直接跳过所有旧内容,资源消耗极低,适合超大日志文件。
配置cron定时任务
把上面的脚本保存为db_log_monitor.sh,给它加执行权限:chmod +x db_log_monitor.sh,然后配置cron每5分钟执行一次:
- 打开crontab编辑器:
crontab -e - 添加以下一行(替换脚本路径和结果日志路径):
*/5 * * * * /home/your_user/db_log_monitor.sh >> /var/log/db_monitor_results.log 2>&1
*/5 * * * *表示每5分钟执行一次>> /var/log/db_monitor_results.log 2>&1会把监控到的错误和脚本本身的输出都保存到结果日志里,方便后续查看。
内容的提问来源于stack exchange,提问作者Adireddy
相关产品推荐
相关产品推荐

