如何使基于Logfile::Rotate的Perl日志轮转脚本按大小触发?
解决Logfile::Rotate不按大小触发轮转的问题
你的脚本现在每次执行都会强制生成新日志,完全忽略大小阈值,主要是两个关键问题导致的,我来帮你一一修正:
1. 参数大小写错误:size → Size
Logfile::Rotate模块的构造函数参数是大小写敏感的,用来指定轮转大小的参数是Size(首字母大写),而你写的是小写的size,模块根本识别不到这个配置,所以每次调用rotate()都会无条件执行轮转。
2. PID文件路径错误
你现在读取的是/usr/lib/systemd/system/rsyslog.service——这是systemd的单元配置文件,里面并没有进程PID!正确的rsyslog PID文件通常在/var/run/rsyslogd.pid或/var/run/rsyslog.pid(不同CentOS版本可能略有差异),读取错误的文件会导致你发送HUP信号给错误的进程(甚至根本不是进程ID),无法让rsyslog重新打开日志文件。
修改后的完整脚本
#!/usr/bin/perl use Logfile::Rotate; my $logfile = new Logfile::Rotate( File => '/var/log/remotehost/fakepath/Syslog.log', Count => 100, Gzip => '/usr/bin/gzip', Size => 1*1024*1024, # 修正为大写的Size sub { # 修正为正确的PID文件路径 my $pid_file = '/var/run/rsyslogd.pid'; open my $PID, '<', $pid_file or die "Unable to open pid file $pid_file: $!\n"; chomp(my $pid = <$PID>); close $PID; # 先验证PID是否有效,避免发送信号给不存在的进程 if (kill 0, $pid) { kill 'HUP', $pid; print "Sent HUP signal to rsyslog (PID: $pid)\n"; } else { die "Invalid rsyslog PID: $pid\n"; } } ); # 现在rotate()会自动检查日志大小,只有超过1MB才会执行轮转 $logfile->rotate(); undef $logfile;
额外说明
修改后,每次执行脚本时,Logfile::Rotate会先检查Syslog.log的大小是否超过1MB:
- 如果超过阈值:自动轮转日志,保留最多100份归档,并用gzip压缩旧日志,然后发送HUP信号让rsyslog切换到新的日志文件。
- 如果未超过阈值:
rotate()方法会直接返回,不会生成新日志。
你可以把这个脚本加入定时任务(比如用cron每分钟执行一次),这样就能实现基于大小的自动日志轮转了。
内容的提问来源于stack exchange,提问作者Santhosh S T
相关产品推荐
相关产品推荐

