Linux计划任务与日志的管理

1、什么是计划任务

我们可以通过一些设置来让电脑定时提醒我们该做什么事了,或者我们提前设置好,告诉电脑你几点做什么几点做什么,这种我们就叫它定时任务。而遇到一些需要执行的事情或任务。我们也可以通过命令来告诉电脑一会临时把这个工作给做一下

在我们LINUX中,我们可以通过crontab和at这两个东西来实现这些功能的

计划任务的作用:是做一些周期性的任务,在生产中的主要用来定期备份数据

CROND:这个守护进程是为了周期性执行任务或者处理等待事件

任务调度分两种:

  1. 系统任务调度

  2. 用户任务调度

两种命令的区别

  1. 定时性的,例行。每隔一定的周期或要重复这个事情

  2. 突发性的,就是做完这个事情就没下次了,临时任务

at:处理只执行一次就结束的命令
crontab:把指定的工作或任务,比如:脚本,按照设定的周期一直循环执行下去

 

2、at计划任务的使用

基础语法

at 时间

服务

atd

开启atd服务

1691460938181

基础命令

查看当前计划执行的任务列表

atq

删除命令

atq 编号

删除所有命令

atq -a

例:删除文件夹

[root@fishman-160 kc111]# date 查看时间
20230808日 星期二 10:24:00 CST
[root@fishman-160 kc111]# at 10:27 设置临时任务
warning: commands will be executed using /bin/sh
at> rm -rf /tmp/kc111   
at> <EOT>   #ctrl +d 结束
job 5 at Tue Aug  8 10:27:00 2023
[root@fishman-160 kc111]# atq  #atq可以查看到任务
5	Tue Aug  8 10:27:00 2023 a root

特殊写法

  1. 相对时间间隔:

    • now + X minutes:在 X 分钟后执行任务。

    • now + X hours:在 X 小时后执行任务。

    • now + X days:在 X 天后执行任务。

  2. 具体时间和日期:

    • HH:MM:在当天的指定时间执行任务,例如 15:30 表示下午 3:30。

    • tomorrow HH:MM:在明天的指定时间执行任务。

    • YYYY-MM-DD HH:MM:在指定的日期和时间执行任务,例如 2023-08-05 10:00

  3. 关键词:

    • midnight:表示午夜 12:00。

    • noon:表示中午 12:00。

以下是一些示例:

at now + 1 hour  # 1小时后执行任务
at now + 2 days  # 2天后执行任务

at 15:30         # 当天下午3:30执行任务
at tomorrow noon # 明天中午执行任务
at 2023-08-05 10:00  # 在指定日期和时间执行任务

请注意,时间格式和关键词可能因操作系统和语言环境而略有不同。您可以通过 man at 命令查看 at 命令的手册页以获取更详细的信息。

 

3、crontab定时任务的使用

1、介绍

crontab 是在Unix-like操作系统中用来创建、编辑和管理定期执行任务的命令。这些任务可以是脚本、命令、程序等,在指定的时间间隔内自动运行。crontab 命令允许用户设置定时任务,无需手动执行命令。

linux任务调度的工作主要分为以下两类:

  1. 系统执行的工作:系统周期性所要执行的工作,如更新whatis数据库 updatedb数据库,日志定期切割,收集系统状态信息,/tmp定期清理

  2. 个人执行的工作:某个用户定期要做的工作,由每个用户自行设置

2、启动服务

[root@fishman-160 kc111]# systemctl status crond
 crond.service - Command Scheduler
   Loaded: loaded (/usr/lib/systemd/system/crond.service; enabled; vendor preset: enabled)
   Active: active (running) since Tue 2023-08-08 09:53:51 CST; 42min ago
 Main PID: 1292 (crond)
    Tasks: 2 (limit: 12048)
   Memory: 1.9M
   CGroup: /system.slice/crond.service
           ├─1292 /usr/sbin/crond -n
           └─1976 /usr/sbin/anacron -s

8 08 09:53:51 fishman-160 crond[1292]: (CRON) INFO (Syslog will be used instead of sendmail.)
8 08 09:53:51 fishman-160 crond[1292]: (CRON) INFO (RANDOM_DELAY will be scaled with factor 82% if used.)
8 08 09:53:51 fishman-160 crond[1292]: (CRON) INFO (running with inotify support)
8 08 10:01:01 fishman-160 CROND[1967]: (root) CMD (run-parts /etc/cron.hourly)
8 08 10:01:01 fishman-160 anacron[1976]: Anacron started on 2023-08-08
8 08 10:01:01 fishman-160 anacron[1976]: Will run job `cron.daily' in 18 min.
8 08 10:01:01 fishman-160 anacron[1976]: Will run job `cron.monthly' in 58 min.
8 08 10:01:01 fishman-160 anacron[1976]: Jobs will be executed sequentially
8 08 10:19:02 fishman-160 anacron[1976]: Job `cron.daily' started
8 08 10:19:02 fishman-160 anacron[1976]: Job `cron.daily' terminated

3、crond的命令参数

image-20230808103748073

* * * * * command_to_run
- - - - -
| | | | |
| | | | +----- 周几 (0 - 6) (Sunday=0)
| | | +------- 月份 (1 - 12)
| | +--------- 日期 (1 - 31)
| +----------- 小时 (0 - 23)
+------------- 分钟 (0 - 59)

例如,* * * * * 表示每分钟执行一次,0 3 * * * 表示每天凌晨 3 点执行一次。

查看当前用户的定时任务:

crontab -l

这将显示当前用户设置的定时任务列表。

编辑当前用户的定时任务:

crontab -e

这将在默认编辑器中打开当前用户的定时任务配置文件,您可以在其中添加、修改或删除定时任务。

删除当前用户的定时任务:

crontab -r

指定用户的定时任务

crontab -u <username>

列出指定用户的定时任务

crontab -u <username> -l

常见的特殊符号和它们的含义:

  1. *(星号):表示任意值,用于匹配所有可能的取值范围。

  2. */n:表示每隔 n 个单位执行一次。例如,*/5 表示每隔 5 个单位执行一次。

  3. -(连字符):用于指定范围。例如,1-5 表示从 1 到 5。

  4. ,(逗号):用于列举多个值。例如,1,3,5 表示 1、3 和 5。

  5. ?:在星期字段和日期字段中,表示无关值。

  6. L:在日期字段中,表示最后一天。例如,L 表示每个月的最后一天。

  7. W:在日期字段中,表示最近工作日。例如,15W 表示距离 15 号最近的工作日。

  8. #:在星期字段中,表示第几个星期。例如,2#3 表示每月的第三个星期二。

  9. @reboot:表示在系统启动时执行任务。

  10. @yearly@annually:表示每年执行一次(等同于 0 0 1 1 *)。

  11. @monthly:表示每月执行一次(等同于 0 0 1 * *)。

  12. @weekly:表示每周执行一次(等同于 0 0 * * 0)。

  13. @daily@midnight:表示每天执行一次(等同于 0 0 * * *)。

  14. @hourly:表示每小时执行一次(等同于 0 * * * *)。

4、crond的计划任务所在目录

/var/spool/cron/

系统级别的计划任务(都是可以写计划任务的地方)

/etc/crontab
/etc/cron.d/0hourly
/etc/cron.d/raid-check
/etc/cron.daily/logrotate 
/etc/cron.deny
/etc/cron.hourly/0anacron
/etc/crontab  #主配置文件

5、注意事项

清理邮件日志,重定向

xx.sh > /dev/null 2>&1

环境变量

6、示例

每天晚上21:00 重启apache
0 21 * * * /etc/init.d/apache restart
每月11022日的4 : 45重启apache。
45 4 1,10,22 * * /etc/init.d/apache restart
每月110日的4 : 45重启apache。
45 4 1-10 * * /etc/init.d/apache restart
每隔两天的上午8点到11点的第3和第15分钟执行apach
3,15 8-11 */2 * *  /etc/init.d/apach restart
晚上11点到早上7点之间,每隔一小时重启apach
0 23-7/1 * * * /etc/init.d/apach restart
周一到周五每天晚上 21:15 寄一封信给 root@panda:
15 21 * * 1-5 mailto -s 'hello' root@panda < /etc/fstab

7、练习题

案例要求:

每天2:00备份/etc/目录到/tmp/backup下面

将备份命令写入一个脚本中

每天备份文件名要求格式: 2017-08-19_etc.tar.gz

在执行计划任务时,不要输出任务信息

存放备份内容的目录要求只保留三天的数据

答案:

脚本部分

  1 #!/bin/bash
  2 current_date=$(date +%F)  #获取系统年月日并赋值给变量current_date
  3 tar -zcf "/tmp/backup/${current_date}_etc.tar.gz" /etc    # 打包压缩/etc目录到/tmp/backup目录下
  4 find /tmp/backup/*.tar.gz -mtime +3 -exec rm -rf {} \;  #搜索/tmp/backup目录内tar.gz的文件,搜索范围是3天前有过修改的文件,执行删除

crond部分

0 2 * * * /root/backup.sh > /dev/null 2>&1
#每天2点执行脚本,标准输出和标准错误合并数据流,输出到/dev/null

 

4、linux系统中的日志管理

在RHEL7中,系统日志消息由两个服务负责处理:systemd-journaldrsyslog

系统日志文件概述:/var/log目录保管由rsyslog维护的,里面存放的一些特定于系统和服务的日志文件

日志文件 用途
/var/log/message 大多数系统日志消息记录在此处。有也例外的:如与身份验证,电子邮件处理相关的定期作业任务等
/var/log/secure 安全和身份验证相关的消息和错误的日志文件
/var/log/maillog 与邮件服务器相关的消息日志文件
/var/log/cron 与定期执行任务相关的日志文件
/var/log/boot.log 与系统启动相关的消息记录
/var/log/dmesg 与系统启动相关的消息记录last

例:

查看`secure中的日志

[root@fishman-160 ~]# grep -i 'failed' /var/log/secure
Aug  8 09:56:59 fishman-160 sshd[1854]: channel 3: open failed: administratively prohibited:
Aug  8 13:47:37 fishman-160 sshd[4161]: channel 3: open failed: administratively prohibited:

5、rsyslog的日志管理

1、日志类型

类型  
auth pam 产生的日志
authpriv ssh、ftp等登录信息的验证信息
cron 时间任务相关
kern 内核
lpr 打印
mail 邮件
mark-(syslog)-rsyslog 服务内部的信息,时间标识
news 新闻组
user 用户程序产生的相关信息

rsyslog的配置目录是/etc/rsyslog.conf

1691485571901-1691485585982-4

2、日志优先级

优先级 描述
0 debug debug有调试信息的,日志信息最多
1 info 一般信息的日志,最常用
2 notice 最具有重要性的普通条件的信息
3 warning 警告级别
4 error 错误级别,阻止某个功能或者模块不能正常工作
5 crit 严重级别,阻止整个系统或者整个软件不能工作的信息
6 alert 需要立即修改的信息
7 emerg 内核崩溃等严重信息
none 什么都不记录

3、查看rsyslog的配置

[root@fishman-160 ~]# cat /etc/rsyslog.conf |grep -v ^#|grep -v ^$
module(load="imuxsock" 	  # provides support for local system logging (e.g. via logger command)
       SysSock.Use="off") # Turn off message reception via local log socket; 
			  # local messages are retrieved through imjournal now.
module(load="imjournal" 	    # provides access to the systemd journal
       UsePid="system" # PID nummber is retrieved as the ID of the process the journal entry originates from
       StateFile="imjournal.state") # File to store the position in the journal
global(workDirectory="/var/lib/rsyslog")
module(load="builtin:omfile" Template="RSYSLOG_TraditionalFileFormat")
include(file="/etc/rsyslog.d/*.conf" mode="optional")
*.info;mail.none;authpriv.none;cron.none                /var/log/messages
authpriv.*                                              /var/log/secure
mail.*                                                  -/var/log/maillog
cron.*                                                  /var/log/cron
*.emerg                                                 :omusrmsg:*
uucp,news.crit                                          /var/log/spooler
local7.*                                                /var/log/boot.log

module 日志模块

1691486174693

  • module(load-'imuxsock' SySock.Use='off),加载imuxsock模块,该模块用于支持本地系统日志记录,例如通过 logger 命令。

  • SySock.Use='off,关闭通过本地日志套接字接收消息的功能,因为本地消息现在通过 imjournal 模块检索。

  • module(load="imjournal" UsePid="system" StateFile="imjournal.state")

    load="imjournal": 加载 imjournal 模块,该模块提供对 systemd 日志的访问

    UsePid="system": 将 PID作为来自日志条目的进程的 ID 来检索。

    StateFile="imjournal.state": 指定用于存储在日志中的位置的文件.

  • imklogimmark。这些模块用于读取内核消息和提供 --MARK-- 消息功能,但在此配置中被注释掉,因此不会被加载。

  • module(load="imudp"): 加载 imudp 模块,该模块用于支持通过 UDP 协议接收远程日志。

  • input(type="imudp" port="514"): 配置 rsyslog 接收 UDP 日志的设置,监听端口号为 514。

  • module(load="imtcp"): 加载 imtcp 模块,该模块用于支持通过 TCP 协议接收远程日志。

  • input(type="imtcp" port="514"): 配置 rsyslog 接收 TCP 日志的设置,监听端口号为 514。

日志存储目录

1691548712416

kern.*代表kern的任何告警日志都存放到/dev/console

-号: 邮件的信息比较多,现将数据存储到内存,达到一定大小,全部写到硬盘.有利于减少I/O进程的开销数据存储在内存,如果关机不当数据消失

符号说明  
. 大于或者等于后面指定的日志级别
.= 等于后面指定的日志级别
.! 除了某个级别以外,记录所有的级别信息
.none 排除某个类别,如mail.none表示排除mail相关日志

 

6、日志的轮转(切割)

1、什么是日志切割

日志切割是指当应用或系统的日志文件达到设定的触发条件(如按照一定的时间周期:每天,按照大小:500MB),对其进行切割/分割处理,类似截断处理,把原本容量比较大的日志文件“劫走”转存为另外一个日志文件留存归档,这一刻之后产生的日志,继续输出到文件头被重置为0的日志文件中。

  • 变化的部分:日志文件的容量(瘦身变小),日志文件的个数(多出一份被切割下的历史日志)

  • 不变的部分:日志文件名不变

75a90f856c09ded1b3ae74e8aaeb9f15_658-1691549201560-3

此外,一段时间后,我们还需要删除时间久远的日志文件,整个过程也被俗称为日志滚动(log rotation)。

2、为什么要进行日志切割

在线应用(包括操作系统)在长期运行过程中,会产生很多过程日志记录,通常是应用程序记录的一些对系统管理员或者程序开发者有用的信息的文件,诸如正在执行什么、发生了什么错误等一系列信息。

随着日志记录的不断积累,日志文件越来越大,随着时间推移,会带来以下弊病:

  • 日志文件占用的硬盘空间越来越大

  • 日志文件太大,达到GB级别后查看内容太耗时,要追踪错误等非常不方便

1f41d3b3873abd3158b735a2f7998ca5_665

3、日志切割的思路

日志切割的基本需求

  • 应用层面

    切割过程中不影响应用的正常运行(不能停用应用来分割日志)

  • 数据层面

    不丢失日志,或者在可接受的范围内丢失极少日志

    切割过程中不影响应用继续输出记录日志(日志文件名不变)

  • 日志容量层面

    切割后新的日志文件从空文件开始重新记录(容量和文件头被重置),便于后续查询使用

  • 日志归档层面

    切割后老旧日志方便归档压缩处理(文件名加上日期后缀等)

    分割后的老旧日志可按照保存周期轮询删除

  • 管理维护层面

    自动化周期性进行,周而复始

思路1

重命名移走旧的日志文件,同时生成一个新的日志文件(文件名与切割之前保持一致)

把现有日志mv成另外一个文件,同时自动生成一个同文件名(mv之前的日志文件名)的新日志文件

日志的文件名不变但是需要确保应用可以指向新的文件句柄

新的日志文件当然从0开始写,日志文件成功瘦身!

a3c68f9793c50aa35480cb4e5725790e_667

思路2

拷贝并重命名一份现有日志文件,同时把现有容量大的日志文件内容清空

把现有日志文件cp一份为另外的文件名,同时非常快速地把现有日志文件清空

但不改变现有日志文件的文件句柄

这样日志文件的文件名和句柄都没有变化,只是内容已经被清空,也是从0开始继续写入,减肥成功!

14e0221bb416c3a9eb23ae9c8634e2b4_671

4、常见的日志切割方案

  1. 自定义脚本

    自定义脚本切割日志,核心原理是mv已有的日志文件,然后生成一个新的日志文件,结合kill -USR1 PID 来reload应用,以便应用获取新日志文件的文件句柄,日志即可输出到新的日志文件。

    注意:

    • 这里说的新日志文件的文件名没有变化,但本质上是一个全新的文件。

    • kill-USR1 PID 仅仅是reload应用配置,不会真正重启应用进程,因此不会引起应用停止运行

    脚本切割nginx日志案例:

    #/bin/bash
    
    # 定义备份目录和日志目录的路径
    bakpath='/home/nginx/logs'     # 备份目录路径
    logpath='/var/log/nginx/logs'  # 日志目录路径
    
    # 检查备份目录是否存在,如果不存在就创建
    if [ ! -d $bakpath/$(date +%Y)/$(date +%m) ]; then
       mkdir -p $bakpath/$(date +%Y)/$(date +%m)
    fi
    
    # 移动日志文件到备份目录,并修改文件名为带有时间戳的格式
    mv $logpath/access.log $bakpath/$(date +%Y)/$(date +%m)/access-$(date +%Y%m%d%H%M).log
    #给nginx发送一个信号量,让nginx重载,重新生成新的日志文件
    kill -USR1 `cat /usr/local/nginx/logs/nginx.pid`
    
    # 重新加载 Nginx 日志
    #/bin/systemctl reload nginx
  2. 应用层面结合log4j切割

    log4japache针对java应用开源的一套日志框架,java应用可以通过加载指定的jar包,结合配置文件,从应用本身规范日志输出的格式,级别等,同时可附加实现日志的切割处理。

    切割的触发条件可以是时间周期和日志大小两个维度。

    log4j一般需要开发人员的协助,最好由开发人员直接实现。

  3. 基于第三方工具切割( logrotate,cronolog

    logrotate:linux系统自带的日志处理工具,功能非常强大,可以进行日志的切割,压缩,滚动删除等处理。自身基于系统的crontab来运行,无需手动配置。

    cronolog:开源的日志处理工具,可以实现自动的按规则生成周期性的日志文件,需要单独安装后配置使用。

  4. 日志切割的对比

    对比方案 部署工作量 对应用的亲和性 功能性
    脚本 前期工作量较大 底层逻辑都需要自己逐一实现 功能完善的脚本开发量较大 一般 看脚本本身
    log4j 较小,加载jar包进行配置即可 较为强大,但不支持日志压缩
    第三方工具 较小仅仅需要配置 较好 强大
  5. 选型

    • 多用拿来主义,避免自己重复造轮子(特指自己巴拉巴拉一股脑式写脚本)

    • 优选应用层面结合log4j方案

      建议应用层面可以应用log4j的就应用log4j,结合第三方工具进行日志压缩和周期性删除处理

    • 备选(次选)开源第三方工具--logrotate

      不便于应用log4j的情况下推荐使用第三方工具,尤其是logrotate,系统自带,开箱即用--次选方案

5、logrotate的工作原理

  1. 核心原理

    操作系统为每一个进程维护了一个独立的打开文件表(fdtable),进程每新打开一个文件,表中就会增加一个条目。

    • 文件描述符是一个整数,代表fdtable中的索引位置(下标),指向具体的struct file(文件句柄/文件指针)

    • 文件句柄(文件指针)对应着文件的详细信息,存储着文件的状态信息、偏移量和文件的inode信息等。

    • 文件句柄中存储的inode信息,对应到应用进程正在写的一个具体文件

    • 每一个文件描述符会与一个打开的文件(文件句柄)相对应

    • 应用进程通过fdtable中的文件句柄(文件指针)来定位到它要写操作的文件

23e388599e00454b7d4c4c8fc256e2f6_674

总结:

  • 进程通过文件描述符来在它的文件描述符表(fdtable)中找到对应的文件句柄。

  • 而文件句柄则存储着关于文件的详细信息,包括文件状态、当前的读写位置、文件的inode信息等。

  • 一旦进程获得了文件句柄,它可以使用这个句柄来进行各种文件操作,如读取、写入、定位文件位置等。

  • 文件句柄允许进程与文件之间建立了联系,让进程可以通过文件句柄来访问文件的内容和属性。

  • 所以,进程首先找到文件句柄,然后通过文件句柄来操作文件中的数据。这个过程在操作系统内部进行,而进程则通过系统调用来触发这些操作。

注意事项

  • 文件句柄在应用程序和操作系统之间起着重要的桥梁作用。

  • 应用程序使用文件句柄来与文件系统进行交互,而不需要关心文件的具体路径。

  • 这种抽象使得应用程序可以更灵活地操作文件,而不受文件路径和文件名的变化影响。

  • 所以,当文件路径和文件名发生变化时,只有涉及到文件打开和关闭的操作,应用进程才会关心文件路径和文件名的变化。

  • 已经打开的文件句柄不会因为文件路径和文件名的变化而受到影响。

2.基础知识

  1. 文件描述符(File Descriptor):文件描述符是一个整数,用于标识和引用打开的文件或文件流。在大多数 Unix-like 操作系统中,包括 Linux,文件描述符通常是非负整数。文件描述符是在进程中维护的,用于跟踪打开的文件、套接字等资源。

  2. 文件表(File Table):文件表是操作系统内核中的数据结构,用于管理已打开文件的信息。每个进程都有一个文件表,它包含了进程打开的文件描述符与实际文件或文件流之间的映射关系。文件表中的每个条目通常包括文件描述符、文件状态标志、文件位置指针等信息。文件表的目的是跟踪进程所打开的文件,并确保不同进程之间的文件访问互相隔离。

  3. 文件句柄(File Handle):文件句柄通常是更高级别的抽象,它可以包含文件描述符以及其他有关文件的信息,例如文件的元数据、缓冲区等。文件句柄的确切定义可能因不同的编程语言、库或操作系统而异。在某些情况下,文件句柄可以扩展文件描述符,以提供更多的文件相关信息。

关系:

  • 文件描述符是进程级别的标识符,用于引用打开的文件或文件流。

  • 文件表是操作系统内核级别的数据结构,用于管理文件描述符与实际文件之间的映射。

  • 文件句柄可以包含文件描述符,它是更高级别的概念,用于提供对文件的更多信息,如元数据等。文件句柄可以帮助应用程序更轻松地操作文件。

查看文件描述符

6、logrotate方案

  1. 切割后使用新的文件句柄-----create方式

    create方式也是默认的方案,它的核心思路是重命名原日志文件,并创建新的日志文件create方案是在mv+create 执行完之后,通知应用重新在新的日志文件写入即可。

    那么如何通知应用程序重新打开日志文件,从而往新的空日志文件中写入呢?

    简单粗暴的方法是杀死进程重新打开。但是这样会影响在线业务,不可取

    于是有些程序提供了重新打开日志的接口,以Nginx为例,是通过发送USR1信号给Nginx进程来通知Nginx重新打开日志文件的。也存在一些其他方式(如IPC),前提是程序自身要支持

  2. 切割后继续使用旧的文件句柄-----copytruncate方式

    不过,有些程序并不支持create方式,压根没有提供重新打开日志的接口;而如果粗暴地重启应用程序,必然会降低可用性,为此引入了copytruncate的方案。

    这个方案的思路是把正在输出的日志拷(copy)一份出来重命名,再清空(trucate)原来的日志。从结果上看,旧的日志内容存在滚动的文件里,新的日志输出到被清空的文件里。

注意事项

以上两种方案中,能用默认的create方案就不用copytruncate,why?

  1. 数据丢失风险

  2. 耗时太久风险

7、logrotatecrond

  1. 定时任务执行

    logrotate自身已经被集成到系统定时任务中,基于CRON来运行,默认每天运行一次。

1691552512466

解释:

这段代码的目的是运行 logrotate命令来执行日志轮转操作。如果 logrotate 命令执行失败(即退出状态码不为0),它会使用 logger命令将一条警告日志写入系统日志,警告消息包含退出状态码。最后,脚本将自己的退出状态码设置为logrotate 命令的退出状态码,以便调用者可以根据这个值判断 logrotate是否成功执行。

#!/bin/sh

# 使用指定的配置文件运行 logrotate 命令
/usr/sbin/logrotate /etc/logrotate.conf

# 将上一个命令的退出状态保存在 EXITVALUE 变量中
EXITVALUE=$?

# 判断退出状态是否不等于 0(表示命令执行失败)
if [ $EXITVALUE != 0 ]; then
    # 使用 logger 命令写入警告日志信息到系统日志
    /usr/bin/logger -t logrotate "警告:退出状态 [$EXITVALUE]"   
fi

# 将脚本的退出状态设置为 logrotate 命令的退出状态
exit $EXITVALUE

问题: cron.daily究竟是在每天什么时间执行的呢?

logrotate是基于CRON运行的,所以这个时间是由CRON控制的,具体可以查询CRON的配置文件/etc/anacrontab(老版本的文件是/etc/crontab

1691560082056

  1 # /etc/anacrontab: configuration file for anacron
  2 
  3 # See anacron(8) and anacrontab(5) for details.
  4 
  5 SHELL=/bin/sh
  6 PATH=/sbin:/bin:/usr/sbin:/usr/bin
  7 MAILTO=root
  8 # the maximal random delay added to the base delay of the jobs
  9 RANDOM_DELAY=45   #随机延迟,表示最大延迟时间45分钟
 10 # the jobs will be started during the following hours only
 11 START_HOURS_RANGE=3-22  #这个是开始时间段,3点-22点
 12 
 13 #period in days   delay in minutes   job-identifier   command
 14 1       5       cron.daily              nice run-parts /etc/cron.daily
 15 7       25      cron.weekly             nice run-parts /etc/cron.weekly
 16 @monthly 45     cron.monthly            nice run-parts /etc/cron.monthly

cron.daily

  • period in days:以天为单位

  • delay in minutes:延迟数分钟,基本的延迟时间

    cron.daily中,总的延迟时间是:基本延迟+随机延迟 = 5 - (45 + 5),即5 - 50分钟。

    开始的基准时间是:3 - 22点,不出意外的话,就是3点开始

    所以cron.daily会在3:00 +(5-50)这个时间段执行

    定时执行时间,也可以通过日志和处理过的日志文件两种方式来确认。

8、logrotate执行过程

  1. Redhat系列系统缺省的cron在每天的3:00+(5,50)这个时间段唤醒触发cron.daily下定义的logrotate定时任务

  2. logrotate加载默认的配置文件/etc/logrotate.conf,定位判断需要被处理的日志文件

  3. 基于配置文件的相关参数,对匹配到的日志文件执行日志切割、压缩、转储即周期性删除处理

  4. 完成后产生过程状态记录文件 /var/lib/logrotate/logrotate.status

  5. 实战运用中,我们是先设置好logrotate的相关参数和任务,然后等待cron来唤醒定时任务触发执行。

9、logrotate的配置文件

  1. 全局默认配置

    /etc/logrotate.conf

  2. 自定义配置

    /etc/logrotate.d/

1691560886393

  1. 配置的有效性和优先级

    logrotate加载配置时,会针对/etc/logrotate.d目录下的每个自定义配置,与全局默认配置/etc/logrotate.conf进行合并渲染,如存在相同项或者冲突项,以自定义配置为准:

    相同项:

    全局配置和自定义配置中配置了相同的参数key,但value不同的情况

    冲突项:

    全局配置和自定义配置中存在的冲突项

  2. 全局配置文件

    1691561058320

  1 # see "man logrotate" for details
  2 # rotate log files weekly
  3 weekly    #每周一次
  4 
  5 # keep 4 weeks worth of backlogs
  6 rotate 4   #保留四个被切割转储后的日志文件(即备份的老日志文件)
  7 
  8 # create new (empty) log files after rotating old ones
  9 create   #rotate后,创建一个新的空文件,默认的create方式处理
 10 
 11 # use date as a suffix of the rotated file
 12 dateext   # 日志文件切割时添加日期后缀,后缀格式YYYYmmdd,切割后的文件名如xxx.log-20200202
 13 
 14 # uncomment this if you want your log files compressed
 15 #compress   #默认切割转储后的日志是不压缩的
 16 
 17 # RPM packages drop log rotation information into this directory
 18 include /etc/logrotate.d   #编程中常用的include大法,该目录下的配置文件都会被引用生效
 19 
 20 # system-specific logs may be also be configured here.
  1. 自定义配置文件

    默认配置文件中已经通过**include /etc/logrotate.d大法指明了自定义配置文件的路径,因此在这个路径下定义细化配置即可

    /etc/logrotate.d/btmp

    1691561323439

  1 # no packages own btmp -- we'll rotate it here
  2 /var/log/btmp {
  3     missingok
  4     monthly
  5     create 0660 root utmp
  6     rotate 1
  7 }
          

/etc/logrotate.d/wtmp

1691561403631

  1 # no packages own wtmp -- we'll rotate it here
  2 /var/log/wtmp {
  3     missingok
  4     monthly
  5     create 0664 root utmp
  6     minsize 1M
  7     rotate 1
  8 }

/etc/logrotate.d/httpd

1691561519612

 1 /var/log/httpd/*log {
  2     missingok
  3     notifempty
  4     sharedscripts
  5     delaycompress
  6     postrotate
  7         /bin/systemctl reload httpd.service > /dev/null 2>/dev/null || true
  8     endscript
  9 }

/etc/logrotate.d/nginx

1691561836301

/var/log/nginx/*.log       {   # 可以指定多个路径,多个路径通过空格或换行符分隔,支持正则匹配
    daily                      # 日志轮询周期,weekly,monthly,yearly
    rotate 30                  # 留存30份切割后的旧日志,以天为周期,即保存30天旧日志,超过则删除
    size +100M                 # 超过100M时分割,单位k,M,G,优先级高于daily
    compress                   # 切割后立即对老日志进行gzip压缩,也可以为nocompress
    dateext                    # 日志文件切割时添加日期后缀
    missingok                  # 如果没有日志文件也不报错
    notifempty                 # 日志为空时不进行切换,默认为ifempty
    create 640 nginx nginx     # 使用该模式创建新的空日志文件,mode,user和group参数可以省略
    sharedscripts              # 所有的文件切割之后再一次性执行下面脚本
    postrotate
        if [ -f /var/run/nginx.pid ]; then  #脚本符合shell语法和逻辑即可
            kill -USR1 `cat /var/run/nginx.pid`
        fi
    endscript

其它较为常用的配置参数:

nocopytruncate           copy日志文件后不截断不清空日志,仅仅备份用
nocreate                 不建立新的日志文件,用于仅仅只需要对应用日志进行压缩和轮询删除的场景
errors address           遇到错误时信息发送到指定的Email 地址
olddir directory         转储后的日志文件放入指定的目录,必须和当前日志文件在同一个文件系统
prerotate                在logrotate转储之前需要执行的指令,例如创建一个转储的日志目录
rotate count             指定日志文件删除之前转储的次数(个数),0指没有备份,5指保留5个备份
maxage                   以单个转储时间周期为计数单位来保留老旧日志,如每天处理,代表保留多少天的老旧
                         日志,此时与rotate count无区别
dateext                  使用当期日期-YYYYmmdd作为转储后的日志文件附加后缀,不配置则以数字1到n作为后
                         缀,n为rotate n中的配置参数
dateformat .%s           配合dateext使用,紧跟在下一行出现,定义文件切割后的文件名附加后缀,必须配合
                         dateext使用,只支持 %Y %m %d %s 这四个参数

注意事项:

logrotate本身是通过系统定时任务cron来在每天的凌晨3-4点之间某个时间点触发,至于logrotate它自己被触发后,会不会对我们指定的日志文件进行预期的切割处理,还取决于我们对logrotate执行动作的条件约束.

10、logrorate的debug功能

命令参数

选项 功能
-d, --debug 在调试模式下运行,检查配置文件的错误。
-f, --force 强制进行日志文件轮转,即使它没有达到规定的条件。
-m, --mail=command 在转储后,使用指定的命令将日志文件发送到指定邮箱。
-s, --state=statefile 使用指定的状态文件来记录日志的状态。
-v, --verbose 显示详细的转储过程,提供更多信息。

当你需要调试·logrotate的配置和行为时,可以通过以下方法来实现:

  1. 手动运行 logrotate 命令并启用调试模式:

logrotate -d /etc/logrotate.conf

这将以调试模式运行logrotate,并显示它将要执行的操作。你可以查看输出,了解 logrotate的具体行为。

  1. 查看日志文件:

logrotate 会将自身的操作日志写入系统日志文件中。你可以查看 /var/log/messages/var/log/syslog 等日志文件,以获取有关logrotate 操作的更多信息。

或者使用指定的状态文件 /var/lib/logrotate/status 来记录日志的状态。

s, --state=statefile

logrotate -s /var/lib/logrotate/status /etc/logrotate.conf
  1. 手动轮转日志文件:

如果你想测试特定的日志文件是否会被轮转,你可以手动执行 logrotate 的轮转命令,而不必等待计划任务:

logrotate -f /etc/logrotate.conf  #-f 就是force,强制执行

其中,-f 选项表示强制轮转。

  1. 在配置文件中启用调试输出:

在 logrotate 的配置文件中,你可以为每个日志文件添加 debug 选项,以启用调试输出。例如:

/var/log/nginx/*.log {
    ...
    debug
    ...
}

这将使 logrotate在轮转时输出更详细的调试信息。

  1. 配置邮件通知:

你可以设置 logrotate 在轮转日志时发送通知邮件,以便你可以监视轮转的行为和结果。在配置文件中添加如下行来启用邮件通知:

/var/log/nginx/*.log {
    ...
    postrotate
        /usr/bin/mail -s "Logrotate Status" your@email.com < /dev/null
    endscript
    ...
}

这将在每次轮转后发送邮件通知。

通过上述方法,你可以在 logrotate 的调试和配置过程中更好地了解它的行为,确保它按预期工作。不过,在进行任何更改时,请务必小心谨慎,以免影响现有的日志管理。

11、案例

通过修改date时间,查看/var/log/yum日志文件变化

配置自己的轮转文件

chattr +a /var/log/alert.log

vi /etc/logrotate.d/alter
/var/log/alert.log {
    weekly
    #每周轮替一次
    rotate 6
    #保留6个轮替曰志
    sharedscripts
    #以下命令只执行一次
    prerotate
    #在日志轮替之前执行
        /usr/bin/chattr -a /var/log/alert.log
        #在日志轮替之前取消a属性,以便让日志可以轮替
    endscript
    #脚本结朿
    sharedscripts
    postrotate
    #在日志轮替之后执行
        /usr/bin/chattr +a /var/log/alert.log
        #在日志轮替之后,重新加入a属性
    endscript
    sharedscripts
    postrotate
    /bin/kill -HUP $(/bin/cat /var/run/syslogd.pid 2>/dev/null) fi>/dev/null
    endscript
    #重启rsyslog服务,保证日志轮替正常进行
}
posted @   墨香清梦  阅读(478)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek “源神”启动!「GitHub 热点速览」
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· DeepSeek R1 简明指南:架构、训练、本地部署及硬件要求
· 2 本地部署DeepSeek模型构建本地知识库+联网搜索详细步骤
点击右上角即可分享
微信分享提示