配置log4j及时发送异常报警邮件

楔子

日志作为软件发布后,检查问题的一种技术手段,为修复bug提供了强有力的依据。而如果能够把严重的异常及时地通知到开发者,让其尽早设计预案,就能起到事半功倍的效果。

log4j作为日志界的大亨,提供了各种接口,包括把日志通过邮件服务器发送到指定邮箱。在配置log4j之前,先来看看关于邮件的几个协议。
log4j

何谓POP3/IMAP/SMTP

我们知道邮件有收有发,而这两种动作是使用不同的协议,常用的是SMTP协议发送邮件,POP3接受邮件,他们都属于TCP/IP协议簇。

  • SMTP(Simple Mail Transfer Protocol)主要用于把邮件从源地址到目的地的传输规范,通过它来控制邮件的中转方式,有了它就能保障邮件及时准确地发送到目的地。而smtp服务器就是邮件中转服务器。常用端口25(非加密)、465(ssl加密)、587(tsl/starttls加密)。
  • POP3(Post Office Protocol 3)主要用于如何连接上邮件服务器,并把邮件从服务器下载下来的规范,它是一个离线协议标准。pop3允许用户从服务器上下载邮件并存储到本地,同时删除保存在邮件服务器上的邮件。而pop3服务器则是遵循pop3协议的邮件接收服务器。常用端口110(非加密)、995(加密)。
  • IMAP(Internet Mail Access Protocol)它与pop3属于同一角色,但它改进了pop3的不足:用户可以通过浏览信件头来决定是否收取、删除和检索邮件的特定部分,还可以在服务器上创建或更改文件夹或邮箱;除了支持POP3协议的脱机操作模式外,还支持联机操作和断连接操作。常用端口143(非加密)、993(加密)。

telent smtp发送邮件

你可能需要验证你的服务器是否能够连接到smtp服务且能成功发送,写一个程序比较重量,你可以使用telnet命令方便的测试。流程如下:

telnet登陆smtp服务器 -> helo/ehlo指令表示身份 -> 用户登陆 -> mailfrom指定发送者邮箱 -> rcptto指定接收者邮箱 -> data输入邮件内容 -> “.”结束数据并发送 -> quit退出smtp服务器

这里以使用163的邮箱来演示telnet发送邮件。163邮箱为了安全,使用第三方客户端不能直接使用密码登陆,需要在“邮件中心 -> 客户端授权密码”获取授权码,使用授权码来登陆发送邮件。
163-setting.png
由于163使用安全加密,所以直接telnet其25端口,登陆验证失败,因此需要使用ssl来telnet,我使用了openssl,简略过程如下:

$ openssl s_client -host smtp.163.com -port 25 -starttls smtp
#....输出省略....
250 8BITMIME
helo testemail #表示身份
250 OK
auth login #请求登陆
334 dXNlcm5hbWU6
dGVzdGVtYWlsCg== #登录名base64
334 UGFzc3dvcmQ6
MTIzNDU2Cg== #密码base64
235 Authentication successful
mail from:<testemail@163.com> #指定发送者
250 Mail OK
rcpt to:<testemail@163.com> #指定接收者
250 Mail OK
data #输入邮件内容请求
354 End data with <CR><LF>.<CR><LF>
From:testemail@163.com #指定发送者,同上
To:testemail@163.com #指定接收者,同上
Subject:telnet #邮件标题
telnet #邮件内容
. #结束内容并发送
250 Mail OK queued as smtp11,D8CowAB3v09tLO5YKU6oBQ--.44557S3 1492004074

这其中的用户名和密码需要使用base64编码,我用的是linux系统,所以使用base64非常方便,只需要”echo abc|base64”即使用base64把ab给加密了。当然也有很多在线的base64加密供你使用。

telent pop3接收邮件

同样的,也可以telent到pop3服务器查看邮件,过程如下

telnet登陆pop3服务器 -> user指令输入非base64用户名 -> pass指令输入非base64密码 -> list指令列出邮件编号 -> retr编号可以查看邮件内容 -> quit退出pop3服务器

$ openssl s_client -connect pop.163.com:995
#....省略输出内容......
user testemail #指定登陆用户名,不需要base64
+OK core mail
pass 123987Q #指定登陆密码,不需要base64
+OK 266 message(s) [31252621 byte(s)]
list #邮件编号列表
+OK 266 31252621
1 21998
2 34006
3 16701
4 28338
5 7246
.
read:errno=0

log4j配置

log4j发送邮件,日志级别是error,如果需要设置info等需要自己重写TriggeringEventEvaluator.isTriggeringEvent。而且需要依赖JavaMail

//maven
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.7</version>
</dependency>


//gradle
compile group: 'javax.mail', name: 'mail', version: '1.4.7'

我的log4j配置如下,重点是mail的设置:

## rootLogger配置
log4j.rootLogger=DEBUG, stdout, file, mail

## 标准输出日志,主要用于console
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%l - %m%n

## 文件输出日志
log4j.appender.file=org.apache.log4j.RollingFileAppender
#文件路径,${web-root}指定web站点项目根路径
log4j.appender.file.File=${web-root}/logs/myapp.log
log4j.appender.file.MaxFileSize=5MB
log4j.appender.file.MaxBackupIndex=10
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%l - %m%n

## 邮件输出日志
log4j.appender.mail=org.apache.log4j.net.SMTPAppender
log4j.appender.mail.Threshold=INFO
#缓存文件大小,日志达到设定值时出发发送,单位为k
log4j.appender.mail.BufferSize=0
#设置smtp服务器
log4j.appender.mail.SMTPHost=smtp.163.com
#设置smtp服务器端口
#log4j.appender.mail.SMTPPort=587
#设置用户名
log4j.appender.mail.SMTPUsername=testemail@163.com
#设置密码
log4j.appender.mail.SMTPPassword=123456
#设置发送者
log4j.appender.mail.From=testemail@163.com
#设置接收者,以","隔开
log4j.appender.mail.To=testemail@163.com
#设置副本(Carbon Copy)抄送者,以","隔开
log4j.appender.mail.Cc=testemail@163.com,hwj@163.com
#设置密件(Blind Carbon Copy)抄送者,以","隔开
log4j.appender.mail.Bcc=testemail@163.com,hwj@163.com
#设置邮件标题
log4j.appender.mail.Subject=ErrorMessage
#设置日志布局
log4j.appender.mail.layout=org.apache.log4j.PatternLayout
#设置自定义格式
log4j.appender.mail.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%l - %m%n

## 关闭某些日志
log4j.logger.org.springframework=OFF
log4j.logger.com.alibaba=OFF
log4j.logger.org.apache.zookeeper=OFF
log4j.logger.org.I0Itec.zkclient=OFF

翟前锋 wechat
欢迎订阅我的微信公众号:zhaiqianfeng!