You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使基于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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 03:14:51