jenkins的日志配置

use a post initialization script

jenkins支持在启动后立即运行指定脚本(${JENKINS_HOME/init.groovy} 或 ${JENKINS_HOME}/init.groovy.d/*.groovy),脚本可以访问Jenins中的类和所有插件。可以利用这个特性来实现日志配置

1
2
3
4
5
import java.util.logging.Level
import java.util.logging.Logger

Logger.getLogger("hudson.plugins.git.GitStatus").setLevel(Level.SEVERE)
Logger.getLogger("hudson.security.csrf.CrumbFilter").setLevel(Level.SEVERE)

use java.util.logging

创建一个logging.properties文件,里面包含日志记录的配置,然后通过增加JVM选项-Djava.util.logging.config.file=<pathTo>/logging.properties 来生效配置

这种方式只支持使用了 java.util.logging 来记录日志的classes,如果某些classes使用了其他日志功能(如 org.apache.commons.logging)则不会生效

1
2
3
4
5
6
7
8
9
10
11
handlers=java.util.logging.ConsoleHandler,java.util.logging.FileHandler

java.util.logging.FileHandler.level=INFO
java.util.logging.FileHandler.formatter=java.util.logging.SimpleFormatter
java.util.logging.FileHandler.pattern=/var/log/jenkins/jenkins.log
java.util.logging.FileHandler.append=true
java.util.logging.FileHandler.limit=10000000
java.util.logging.FileHandler.count=5

java.util.logging.ConsoleHandler.level=INFO
java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter

使用linux的logrotate

logrotate是个十分有用的工具,它可以自动对日志进行截断(或轮循)、压缩以及删除旧的日志文件。

Logrotate是基于CRON来运行的,其脚本是/etc/cron.daily/logrotate。

logrotate的配置文件是/etc/logrotate.conf,通常不需要对它进行修改。日志文件的轮循设置在独立的配置文件中,它们放在/etc/logrotate.d/目录下。

/etc/logrotate.d/jenkins文件配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/var/jenkins_home/logs/jenkins.log {
daily //日志文件轮循周期。可用值为‘daily’,‘weekly’或者‘yearly’
rotate 5 //最多将存储5个归档日志。对于第六个归档,时间最久的归档将被删除
dataext //旧日志文件以创建日期命名
compress //在轮循任务完成后,已轮循的归档将使用gzip进行压缩
delaycompress //总是与compress选项一起用,delaycompress选项指示logrotate不要将最近的归档压缩,压缩将在下一次轮循周期进行。这在你或任何软件仍然需要读取最新归档时很有用。
missingok //在日志轮循期间,任何错误将被忽略,例如“文件无法找到”之类的错误
notifempty //如果日志文件为空,轮循不会进行
size 100k //当日志文件到达指定的大小时才转储,log-size能指定bytes(缺省)及KB (sizek)或MB(sizem)
create 644 root root //mode owner group 转储文件,使用指定的文件模式创建新的日志文件
postrotate //在logrotate转储之后需要执行的指令,例如重新启动 (kill -HUP) 某个服务 必须独立成行
/usr/bin/killall -HUP rsyslogd
endscript
}

值得注意的一个配置是:copytruncate

copytruncate 如果没有这个选项的话,操作方式:是将原log日志文件,移动成类似log.1的旧文件, 然后创建一个新的文件。 如果设置了,操作方式:拷贝原日志文件,并且将其变成大小为0的文件。

区别是如果进程,比如nginx 使用了一个文件写日志,没有copytruncate的话,切割日志时, 把旧日志log->log.1 ,然后创建新日志log。这时候nginx 打开的文件描述符依然时log.1,由没有信号通知nginx 要换日志描述符,所以它会继续向log.1写日志,这样就不符合我们的要求了。 因为我们想切割日志后,nginx 自动会向新的log 文件写日志,而不是旧的log.1文件

解决方法有两个:

1.向上面的nginx 切割日志配置,再postrotate里面写个脚本

postrotate
[ -s /run/nginx.pid ] && kill -USR1 cat /run/nginx.pid
endscript

这样就是发信号给nginx ,让nginx 关闭旧日志文件描述符,重新打开新的日志文件描述,并写入日志

2.使用copytruncate参数,向上面说的,配置了它以后,操作方式是把log 复制一份 成为log.1,然后清空log的内容,使大小为0,那此时log依然时原来的旧log,对进程(nginx)来说,依然打开的是原来的文件描述符,可以继续往里面写日志,而不用发送信号给nginx

copytruncate这种方式操作的时候, 拷贝和清空之间有一个时间差,可能会丢失部分日志数据。

nocopytruncate 备份日志文件不过不截断。