您现在的位置是:网站首页 > 代码编程 > JAVA开发JAVA开发
【原】log4j使用之SMTPAppender教程
不忘初心 2019-05-15 围观() 评论() 点赞() 【JAVA开发】
简介:在一些场景中,对于error的感知需要非常快,需要第一时间通知到负责人,此时就需要SMTPAppender来救场了,它可以直接将日志内容当做邮件发出来,这样就算是责任人没在电脑旁边儿,也可以稍微从日志中找一下问题的原因。
在一些场景中,对于error的感知需要非常快,需要第一时间通知到负责人,此时就需要SMTPAppender来救场了,它可以直接将日志内容当做邮件发出来,这样就算是责任人没在电脑旁边儿,也可以稍微从日志中找一下问题的原因。
直接来看配置文件:log4j.properties
# 配置根logger,如果下面没有自定义logger,那么项目中的日志就都是debug级别,输出到console
log4j.rootLogger=DEBUG,console,mail
# 屏蔽框架日志,只有报错的时候才放出来,优先级高于rootLogger
log4j.logger.org.springframework=ERROR
log4j.logger.org.apache.ibatis=ERROR
log4j.logger.org.mybatis.spring=ERROR
log4j.logger.com.mchange=ERROR
# 自定义包路径中的日志等级,直接写一个level即可,appender可选择,如果没写就默认使用rootLogger中配置的console
log4j.logger.com.ssm=DEBUG
# 打印出jdbc的日志
log4j.appender.java.sql.ResultSet=DEBUG
log4j.appender.java.sql.Connection=DEBUG
log4j.appender.java.sql.Statement=DEBUG
log4j.appender.java.sql.PreparedStatement=DEBUG
# 控制台(console)
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.Threshold=DEBUG
log4j.appender.console.ImmediateFlush=true
log4j.appender.console.Target=System.out
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} [%5p] - %c - %m%n
# 发送日志到指定邮件
log4j.appender.mail=org.apache.log4j.net.SMTPAppender
#这里就需要注意了,强制只有error的才会发送邮件,所以指定了也没啥鸟用
log4j.appender.mail.Threshold=DEBUG
#缓冲区大小,默认512,单位:kb,每次发送邮件时会从缓冲区读日志
log4j.appender.mail.BufferSize=2
#开启debug模式,可以看到很多有用的信息,出错了容易查找
log4j.appender.mail.SMTPDebug=true
#配置邮件服务
log4j.appender.mail.SMTPHost=smtp.sina.com
#邮箱账号
log4j.appender.mail.SMTPUsername=xxx@sina.com
#邮箱密码
log4j.appender.mail.SMTPPassword=xxx
#发送者邮箱
log4j.appender.mail.From=xxx@sina.com
#接收者邮箱
log4j.appender.mail.To=xxx@sina.com
#邮件标题
log4j.appender.mail.Subject=Log4J Message
#选择输出方式
log4j.appender.mail.layout=org.apache.log4j.PatternLayout
#配置日志输出格式
log4j.appender.mail.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} [%5p] - %c - %m%n
我这里以新浪邮箱来做演示,与邮件发送相关的参数,大家请移步:Java发送新浪邮件图文教程
需要注意的有两点:
1、Threshold参数的配置,这里就很秀了,可能是防止日志级别配置有误,从而导致垃圾邮件干扰,所以log4j默认就只发送error级别及以上的日志邮件,就像我上面配置了debug,其实是没啥鸟用的;
2、BufferSize参数的配置,用来控制缓冲区大小;
3、新浪邮箱直接使用账号密码,其他的邮箱就需要使用SMTP授权字符;
挑重要的地方给大家看一下SMTPAppender的源码:
SMTPAppender的构造方法:
/**
The default constructor will instantiate the appender with a
{@link TriggeringEventEvaluator} that will trigger on events with
level ERROR or higher.*/
public
SMTPAppender() {
this(new DefaultEvaluator());
}
默认传入了一个DefaultEvaluator,这个是它的内部类:
class DefaultEvaluator implements TriggeringEventEvaluator {
/**
Is this <code>event</code> the e-mail triggering event?
<p>This method returns <code>true</code>, if the event level
has ERROR level or higher. Otherwise it returns
<code>false</code>. */
public
boolean isTriggeringEvent(LoggingEvent event) {
return event.getLevel().isGreaterOrEqual(Level.ERROR);
}
}
实现了TriggeringEventEvaluator,重写了isGreaterOrEqual方法,跟error级别做了一个比对:
/**
Returns <code>true</code> if this level has a higher or equal
level than the level passed as argument, <code>false</code>
otherwise.
<p>You should think twice before overriding the default
implementation of <code>isGreaterOrEqual</code> method.
*/
public
boolean isGreaterOrEqual(Priority r) {
return level >= r.level;
}
比对的值是一个Level对象:
/**
Defines the minimum set of levels recognized by the system, that is
<code>OFF</code>, <code>FATAL</code>, <code>ERROR</code>,
<code>WARN</code>, <code>INFO</code, <code>DEBUG</code> and
<code>ALL</code>.
<p>The <code>Level</code> class may be subclassed to define a larger
level set.
@author Ceki Gülcü
*/
public class Level extends Priority implements Serializable {
/**
* TRACE level integer value.
* @since 1.2.12
*/
public static final int TRACE_INT = 5000;
/**
The <code>OFF</code> has the highest possible rank and is
intended to turn off logging. */
final static public Level OFF = new Level(OFF_INT, "OFF", 0);
/**
The <code>FATAL</code> level designates very severe error
events that will presumably lead the application to abort.
*/
final static public Level FATAL = new Level(FATAL_INT, "FATAL", 0);
/**
The <code>ERROR</code> level designates error events that
might still allow the application to continue running. */
final static public Level ERROR = new Level(ERROR_INT, "ERROR", 3);
/**
The <code>WARN</code> level designates potentially harmful situations.
*/
final static public Level WARN = new Level(WARN_INT, "WARN", 4);
/**
The <code>INFO</code> level designates informational messages
that highlight the progress of the application at coarse-grained
level. */
final static public Level INFO = new Level(INFO_INT, "INFO", 6);
/**
The <code>DEBUG</code> Level designates fine-grained
informational events that are most useful to debug an
application. */
final static public Level DEBUG = new Level(DEBUG_INT, "DEBUG", 7);
/**
* The <code>TRACE</code> Level designates finer-grained
* informational events than the <code>DEBUG</code level.
* @since 1.2.12
*/
public static final Level TRACE = new Level(TRACE_INT, "TRACE", 7);
/**
The <code>ALL</code> has the lowest possible rank and is intended to
turn on all logging. */
final static public Level ALL = new Level(ALL_INT, "ALL", 7);
}
Level继承了Priority:
/**
<font color="#AA4444">Refrain from using this class directly, use
the {@link Level} class instead</font>.
@author Ceki Gülcü */
public class Priority {
transient int level;
transient String levelStr;
transient int syslogEquivalent;
public final static int OFF_INT = Integer.MAX_VALUE;
public final static int FATAL_INT = 50000;
public final static int ERROR_INT = 40000;
public final static int WARN_INT = 30000;
public final static int INFO_INT = 20000;
public final static int DEBUG_INT = 10000;
//public final static int FINE_INT = DEBUG_INT;
public final static int ALL_INT = Integer.MIN_VALUE;
}
可以看到Priority中定义的这些常量,正好是Level构造方法中传入的参数。
代码看到这里,基本上已经可以明白log4j是怎么实现这个控制的,上面的代码跳来跳去,不过最终比对的值就是Priority的level字段,而level字段在初始化Level对象的时候会被赋值成Priority中的常量,那么将isGreaterOrEqual方法中算式取出来就是:>=40000,而符合这个条件的,只有ERROR和FATAL级别。
好了,来给大家看下效果:
效果有了,不过大家注意看上图,最下面几封邮件内容中竟然还是有debug级别的日志,莫非是我噼里啪啦讲了这么多废话?
不是的,大家不要惊慌,在上面提到了BufferSize参数,这里就是因为它导致的,我配置的是2kb,所以总共会有2kb的数据在缓冲区中,从最后一个字节往回算,总共2kb大小的日志。
来张图给大家看一下:
只缓冲了错误日志上面那一行的信息,而这个参数默认是512,那如果使用默认的值,error之前的日志信息将会更多,如下图:
但是作为报错的场景来说,其实是需要更多日志的,我觉着512反而还不够,所以大家在使用的时候酌情考量!
看完文章,有任何疑问,请加入群聊一起交流!!!
很赞哦! ()
相关文章
标签云
猜你喜欢
- IntelliJ IDEA 2019.2已经可以利用补丁永久破解激活了
- IntelliJ IDEA 2019.3利用补丁永久破解激活教程
- IntelliJ IDEA高版本最灵活的永久破解激活方法(含插件激活,时长你说了算)
- Jetbrains全家桶基于ja-netfilter的最新破解激活详细图文教程
- IntelliJ IDEA 2022.1永久破解激活教程(亲测可用,持续更新)
- 分享几个正版 IntelliJ IDEA 激活码(破解码、注册码),亲测可用,持续更新
- ja-netfilter到底需不需要mymap,2021.3.2版本激活失效?
- 如何激活idea2022.1及以上版本中的插件(亲测可用)
- 【史上最全】IntelliJ IDEA最新2022.1版本安装和激活视频教学(含插件)
- IntelliJ IDEA 2022.2 版本最新2099年永久激活方法,亲测可用,也可以开启新UI了。
站点信息
- 网站程序:spring + freemarker
- 主题模板:《今夕何夕》
- 文章统计:篇文章
- 标签管理:标签云
- 微信公众号:扫描二维码,关注我们