当前位置: 首页 > 科技观察

Linux日志定时轮询过程详解

时间:2023-03-19 14:58:14 科技观察

logrotate简介对于Linux系统的安全,日志文件是一个极其重要的工具。日志文件包含有关系统中发生的事件的有用信息,通常在故障排除或系统性能分析期间使用。当日志文件不断增长时,需要定期对其进行裁剪,否则写入日志的速度和性能也会下降,不方便我们归档和查询。所以在使用logrotate的时候,logrotate是一个非常好用的工具,可以自动截断(或轮转)、压缩、删除日志上的旧日志文件。例如,您可以将logrotate设置为每30天轮换一次/var/log/foo日志文件并删除超过6个月的日志。配置完成后,logrotate的运行完全自动化,无需任何进一步的人工干预。logrotate配置文件位置Linux系统默认安装logrotate工具。它的默认配置文件是:/etc/logrotate.conf/etc/logrotate.d/logrotate.conf是主配置文件,logrotate.d是一个目录。所有文件都将主动读入/etc/logrotate.conf以执行。另外,如果在/etc/logrotate.d/文件中没有设置一些细节,文件/etc/logrotate.conf中的设置将被用作默认值。Logrotate在实际运行时会调用配置文件/etc/logrotate.conf。您可以将自定义配置文件放在/etc/logrotate.d目录中以覆盖Logrotate的默认值。常规轮转机制Logrotate基于CRON运行,其脚本为/etc/cron.daily/logrotate,日志轮转由系统自动完成。logrotate任务默认放在cron的每日定时任务cron.daily下。/etc/cron.daily/logrotate/etc/目录下还有cron.weekly/、cron.hourly/、cron.monthly/目录。[/etc]$cat/etc/cron.daily/logrotate#!/bin/sh#Cleannonexistentlogfileentriesfromstatusfilecd/var/lib/logrotatetest-estatus||touchstatushead-1status>status.cleansed's/"//g'计划任务状态|whilereadlogfiledatedo[-e"$logfile"]&&echo"\"$logfile\"$date"done>>status.cleanmvstatus.cleanstatustest-x/usr/sbin/logrotate||exit0/usr/sbin/logrotate/etc/logrotate。conf这里是实际运行的轮询命令***行/usr/sbin/logrotate/etc/logrotate.conf定义了日常执行任务的脚本cron.daily/logrotate,然后查看crontab的内容,里面设置了对应的cron.xxly执行时间[/etc]$vim/etc/crontabSHELL=/bin/shPATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin#mhdommondowusercommand17****rootcd/&&run-parts--report/etc/cron.hourly256***roottest-x/usr/sbin/anacron||(cd/&&run-parts--report/etc/cron.daily)476**7roottest-x/usr/sbin/anacron||(cd/&&run-parts--report/etc/cron.weekly)5261**roottest-x/usr/sbin/anacron||(cd/&&run-parts--report/etc/cron.monthly)可以看到只要如是在/etc/cron.daily/每天6点25分执行以下任务/etc/cron.weekly/每周日6点47分执行以下任务/etc/cron.monthly/以下任务都是每月1号6点52分执行。如果等不及cron自动执行logrotation,想强制手动切log,需要加上-f参数;但在正式执行前,最好通过Debug选项(-d参数)验证一下。调试也很重要#/usr/sbin/logrotate-f/etc/logrotate.d/nginx//切割时间未到或切割条件未达到,强制切割#/usr/sbin/logrotate-d-f/etc/logrotate.d/nginx//输出切割调试信息至此,我们知道了logrotate是如何实现logrotate自动切割日志的logrotate配置案例nginx常见的切割日志配置/data/log/nginx/*.log/data/log/nginx/*/*。log{#在比赛周切日志文件#每周切missingok#在日志轮换过程中,任何错误都将被忽略,例如“找不到文件”之类的错误rotate6#Reserve6backupscompress#compressdelaycompress#delaycompress和compress一起使用时,转储的日志文件直到下次dumpnotifempty#如果是空文件,不转储create0644www-dataymserver#modeownergroup转储文件,使用指定的文件模式创建一个新的日志文件sharedscripts#下面详细介绍prerotate#logrotatedumps之前需要执行的指令,比如修改文件的属性;必须独立if[-d/etc/logrotate.d/httpd-prerotate];then\run-parts/etc/logrotate.d/httpd-prerotate;\fi\endscriptpostrotate#logrotatedump后需要执行的指令,比如重启(kill-HUP)某个服务!必须独立执行[-s/run/nginx.pid]&&kill-USR1`cat/run/nginx.pid`endscriptsurootymserver#轮转日志时切换设置的用户/用户组执行(默认为root),如果setuser/groupdoesnothavepermissiontoallowthefiletoownedbytheownerbythecreateoption,会触发错误。}如果想配置一个每天0:00的切割任务,怎么实现呢?我们的logrotate默认每日执行时间已经写在/etc/cron.daily/目录下,这个目录下的任务执行时间上面也有提到,6:25是在/etc/crontab中定义的。之前有这样的需求,看下面的配置/data/log/owan_web/chn_download_stat/chn_app_rec.log{copytruncate#weekly注释但是会继承/etc/logrorate.conf的全局变量,还有weeklymissingokrotate10compressdelaycompresssize=1000M#的时候size达到size,开始转储notifemptycreate664www-dataymserversurootdateext//这个参数很重要!即切割后的日志文件以当前日期的格式结束,如xxx.log-20131216。如果被注释掉,则截出的按数字递增,即上面提到的xxx.log-1的格式compress//是否通过gzip压缩转储的日志文件,如xxx.log-20131216.gz;如果不需要压缩,就注释掉}然后到root的crontab配置一个0点执行的任务wwwadm@host:/etc/logrotate.d$sudocrontab-l-uroot00***/usr/sbin/logrotate/etc/logrotate.d/web_roteate-fv>/tmp/logro.log2>&1因为logrotate的切割周期是周,所以每次切割都是在上一次切割的基础上如果距离上一次有一周time,会切,但是我们设置了crontab的日切,既不会进入/etc/cron.daily/的日切,也不会进入周切。这样,您就可以***自定义您想要的切割日志时间了。logrotate参数说明compress通过gzip压缩转储的日志nocompress不进行gzip压缩处理createmodeownergroup指定轮转时创建新文件的属性,如create0777nobodynobodynocreate不创建新的日志文件delaycompress一起使用时使用compress时,转储的日志文件直到下一次转储才会被压缩。nodelaycompress覆盖delaycompress选项,同时压缩转储。missingok如果日志丢失,继续滚动到下一条日志而不报错ifempty即使日志文件为空也进行轮转。这是logrotate的默认选项。notifempty当日志文件为空时,不轮换邮件地址将转储的日志文件发送到指定的E-mail地址olddir目录将转储的日志文件放入指定目录,该目录必须与当前日志文件在同一个文件中systemnoolddir将转储的日志文件和当前的日志文件放在同一个目录下。sharedscripts运行postrotate脚本,用于在所有日志轮转后执行一次脚本。如果未配置,则脚本prerotate将在每次日志轮换后执行。logrotatedump前需要执行的指令,比如修改文件的属性等;postrotate必须独立执行。logrotatedump后需要执行的指令,比如重启Start(kill-HUP)aservice!每日必须单独一行。将转储周期指定为每天。将转储周期指定为每周一次。指定转储周期为每月。使用当前日期作为命名格式dateformat.%s与dateext一起使用,后面一行定义文件切割后的文件名,必须与dateext一起使用,只支持%Y%m%d四个参数%ssize(orminsize)log-size当日志文件达到指定大小时,将被转储。日志大小可以指定字节(默认)、KB(sizek)或MB(sizem)。当日志文件>=log-size时,将被转储存储。以下是合法格式:(其他格式的单位大小写我没试过)size=5orsize5(dumpif>=5bytes)size=100korsize100ksize=100Morsize100M一个值得注意的配置是:copytruncatecopytruncate如果没有这个选项,操作方法是将原来的日志文件移动到类似log.1的旧文件中,然后新建一个文件。如果设置,操作方法:复制原日志文件,改成大小为0的文件。不同的是,如果nginx等进程使用文件写日志,如果没有copytruncate,切割日志时,将旧日志log->log.1,然后创建新日志log。此时nginx打开的文件描述符还是log.1,没有信号通知nginx改变日志描述符,所以会继续向log.1写入日志,不符合我们的要求。因为我们要切日志,nginx会自动将日志写入新的日志文件,而不是旧的日志。1解决方法有两种:1.切日志配置到上面的nginx,然后在postrotate中写一个脚本postrotate#logrotatedump后需要执行的指令,比如重启(kill-HUP)一个服务!必须单独一行[-s/run/nginx.pid]&&kill-USR1`cat/run/nginx.pid`endscript这是给nginx发送一个信号,让nginx关闭旧的日志文件描述符,重新打开新的日志filedescription,并写入log2.使用copytruncate参数,上面说了,配置好后,操作方法是将log复制到log.1,然后清空log内容,使size为0,那么此时的日志还是原来的旧日志,对于进程(nginx)来说,还是打开原来的文件描述符,可以继续往里面写日志,而不用给nginxcopytruncate发送信号。以这种方式操作时,复制和清除之间存在时间差,可能会丢失部分日志数据。nocopytruncate备份日志文件但不截断引用《Linux下logrotate日志轮询操作梳理》