用php实现nginx日志批量切割

By zhujinliang. Filed in 软折腾  |   
标签:, , , ,
Home  

接上文:尝试使用awstats分析Nginx日志。在实现了基本的分析后,又琢磨着怎么来切割日志。

网上有不少脚本用来切割,但我发现,均只能应用于一个站或预先配置好的几个站,而且都是bash脚本的,我也看不懂。于是打算自己用php写个。

您别笑,php写shell脚本也是很舒服的。

脚本实现功能:自动扫描指定目录下的log文件,移动到对应的目录中,并按日期更名,启动awstats更新,最后tar打包日志,只保留压缩后的日志。

代码:

#!/usr/bin/php

<?php

$log_file_dir = '/home/wwwlogs/access/';

$nginx_touch_log_cmd = 'kill -USR1 `cat /usr/local/nginx/logs/nginx.pid`';
$awstats_update_cmd = '/usr/local/awstats/tools/awstats_updateall.pl now';

echo "nginx log split\n";

set_time_limit(0);

$log_files = array();

if(!is_dir($log_file_dir)) die('cannot list log files');
if($handle = opendir($log_file_dir)) {

        while($file = readdir($handle)) {
                if(substr($file, -4) == '.log') array_push($log_files, $file);
                echo "find file $file\n";
        }

}else{
        die('cannot open dir');
}

$str_date = date('Ymd', strtotime('-1 day'));
echo "file date is $str_date\n";

$log_file_count = count($log_files);
for($i=0; $i<$log_file_count; $i++){

        $filename = $log_files[$i];
        $filename = substr($filename, 0, strlen($filename) - 4);
        $target_dir = $log_file_dir . $filename . '/';

        if(!file_exists($target_dir)) mkdir($target_dir, 0777);

        $rename_from = $log_file_dir . $filename . '.log';
        $rename_to   = $target_dir . $str_date . '.log';

        $log_files[$i] = $rename_to;

        if(file_exists($rename_to) || file_exists($rename_to.'.tar.gz')) continue;

        echo "rename from: $rename_from\n";
        echo "to: $rename_to\n";

        rename($rename_from, $rename_to);

}

passthru($nginx_touch_log_cmd);

passthru($awstats_update_cmd);

for($i=0; $i<$log_file_count; $i++){

        $filename = $log_files[$i];

        if(file_exists($filename.'tar.gz')) continue;
        echo "zip file: $filename\n";
        $rc = -1;
        passthru("tar -zcf $filename.tar.gz $filename", $rc);
        if($rc == 0) unlink($filename);

}

?>

目录和文件名约定:

1. 日志文件都存放在$log_file_dir指定的目录中,并以.log作为扩展名

2. 切割后的文件存放在与日志文件同名(不含.log扩展名)的目录中,以类似20130326.log文件命名

3. tar压缩的文件名在切割后的日志文件名基础上加.tar.gz后缀

 

脚本编写中发现一个问题,我们每天切割打包的日志其实是昨天的数据,而打包动作到了第二天才执行的,故文件名应是前一天的日期。

保存脚本,加可执行权限,然后配置crontab,让其每天0点01分执行:

#awstats update
01 0 * * * root /path/to/script.php

awstats中日志文件名应写成下面的样式:

LogFile="/home/wwwlogs/access/blog.zhujinliang.com/%YYYY-24%MM-24%DD-24.log"

-24表示减去24小时,即昨天的日期。

 

预告,下一步将折腾日志报表页面,方案已想好,使用php作为cgi脚本的宿主,调用awstats的cgi接口实现报表查询,而不再采用生成静态页面的方式。同时可以通过php进行一些权限控制。

发表评论

电子邮件地址不会被公开。 必填项已用 * 标注

*