这几天一直再弄nginx日志切割问题,从最开始采用暴力的cp方式

方案一:

## 备份日志
cp access.log backupLogs
cp error.log backupLogs

## 重命名
mv backupLogs/access.log backupLogs/access.log_$date
mv backupLogs/error.log backupLogs/error.log_$date

## 清空源文件
>./access.log
>./error.log

####如果对日志没有严格要求,用这个是没啥问题的。不能确保全是当天的日志,会有误差

由于公司数据量比较大,采用上述方式的时候,在凌晨做日志切割时,backupLogs下的日志,就会出现第二天的日志,这不要紧,可以通过sed来删除,但是当采用>./access.log和>./error.log清空日志时,就有问题了,因为上面的操作需要一定的时间,这段时间内还有一些流量进来,如果上面的操作需要1s,那么采用>./access.log和>./error.log清空日志时,会直接把今天的1s时间内的日志都清除,导致丢失日志,而我司就是对日志比较严格的,因此上面的方式并不可行。

方案二:(这种方式真是坑惨我了,不推荐)

#!/bin/bash
## 新版本,保证每天的日志不会丢失,不会出现昨天的日志
## Nginx 日志清理
logdir=/app/openresty/nginx/logs
# 备份,切割
access=access.log
# 备份,切割
error=error.log

# 创建备份文件夹
if [ ! -d ${logdir}/backupLogs ];then
        mkdir ${logdir}/backupLogs
fi

## 睡眠3分钟 确保到达第二天
sleep 3s
## 昨天
a_yesterday=`date -d "-1 day" +"%d\/%b\/%Y"`
## 今天
a_today=`date +"%d\/%b\/%Y"`
## 昨天文件时间
lastdate=`date -d "-1 day" "+%F"`
echo $today
## 进入目录
cd ${logdir}

## 将文件复制到backupLogs
cp access.log backupLogs/${access}"_"${lastdate}
## 除了昨天的数据,其他都删除
sed -i "/${a_yesterday}/!d" backupLogs/${access}"_"${lastdate}
## 删除源文件中,除了今天的数据
sed -i "/${a_today}/!d" access.log

e_yesterday=`date -d "-1 day" +"%Y\/%m\/%d"`
e_today=`date +"%Y\/%m\/%d"`
## error
cp error.log backupLogs/${error}"_"${lastdate}
## 除了昨天的数据,其他都删除
sed -i "/${e_yesterday}/!d" backupLogs/${error}"_"${lastdate}
## 删除源文件中,除了今天的数据
sed -i "/${e_today}/!d" error.log

## 进入备份目录
cd ${logdir}/backupLogs

## 压缩复制后的文件,移动到备份文件夹中
zip "access."${lastdate}".zip" ${access}"_"${lastdate}
zip "error."${lastdate}".zip" ${error}"_"${lastdate}
rm -f ${access}"_"${lastdate}
rm -f ${error}"_"${lastdate}

## 删除30天前的压缩文件
find . -maxdepth 1 -type f -mtime +30 -name "*.zip" | xargs rm -rf

sed是直接删除日志文件中的内容,会导致nginx服务没办法继续往文件中写入日志,需要重启nginx,reload还不行,必须stop。

方案三:logrotate,还没试过,不知道能不能保证日志的准确性

 

方案四:推荐

##自定义日志格式:放到http模块
    log_format nginx_log_json '{ "datetime": "$time_local", '
                                 '"remote_addr": "$remote_addr", '
                                 '"http_Cdn-Src-Ip":"$http_cdn_src_ip",'
                                 '"body_bytes_sent": "$body_bytes_sent", '
                                 '"request_time": "$request_time", '
                                  '"status": "$status", '
                                  '"request_url": "$request_uri", '
                                  '"uri":"$uri",'
                                  '"request_method": "$request_method", '
                                  '"http_referer": "$http_referer", '
                                  '"request_body":"$request_body",'
                                  '"upstream_response_time":"$upstream_response_time",'
                                  '"upstream_addr":"$upstream_addr",'
                                  '"unkown":"$proxy_add_x_forwarded_for",'
                                  '"real_upstream_addr":"$http_x_real_ip",'
                                  '"req_timestamp:"$req_time"}';



###########   Round 1   ###########
## 以下都放到server模块
## 按日期
if ($time_iso8601 ~ "(\d{4}-\d{2}-\d{2})") {
set $day $1;
}

access_log logs/access_$day.log combined/或者自定义格式(nginx_log_json);
error_log  logs/error.log;    -- error_log 不支持变量

## 按小时
if ($time_iso8601 ~ "(\d{4}-\d{2}-\d{2}T\d{2})") {
set $day $1;
}

access_log logs/access_$day.log combined/或者自定义格式(nginx_log_json);
error_log  logs/error.log;    -- error_log 不支持变量

## logs 文件夹需要有写入权限,因为需要生成新文件
chmod 777 nginx/logs




###########   Round 2   ###########
## 放到http模块
map $time_iso8601 $logdate {
    '~^(?<ymd>\d{4}-\d{2}-\d{2})' $ymd;
    default    'date-not-found';
}
## 放到server模块
access_log logs/access-$logdate.log combined/或者自定义格式(nginx_log_json);
error_log  logs/error.log;    -- error_log 不支持变量

## logs 文件夹需要有写入权限,因为需要生成新文件
chmod 777 nginx/logs

 

最后修改于 2021-05-14 06:52:19
如果觉得我的文章对你有用,请随意赞赏
扫一扫支付
上一篇