Java之日志

Logger

日志中应该使用SLF4J中的API:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private static final Logger logger = LoggerFactory.getLogger(Xxx.class);

参考:http://www.importnew.com/7450.html

log4j配置及加载

配置Log4j.properties就是定义Appender以及Logger

定义Appender

Appender定义包含AppenderName、输出级别ThreadHold、输出target、日志LayOut,以及Appender的实现类

常用输出目的地: System.out/System.err/File/Mail

对应的Appender实现类:

  • org.apache.log4j.ConsoleAppender
  • org.apache.log4j.DailyRollingFileAppender
  • org.apache.log4j.net.SMTPAppender

根据实现类不通,需要配置不通的属性参数,比如DailyRollingFileAppender需配置日志文件路径及Rolling时间格式:

//定义名为DRFA的Appender
log4j.appender.DRFA=org.apache.log4j.DailyRollingFileAppender
log4j.appender.DRFA.File=${hive.log.dir}/${hive.log.file}
log4j.appender.DRFA.DatePattern=.yyyy-MM-dd

//定义名为console的Appender
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.target=System.err
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d{yy/MM/dd HH:mm:ss} [%t]: %p %c{2}: %m%n
log4j.appender.console.encoding=UTF-8

Appender的layout一般有以下几种:

  • org.apache.log4j.HTMLLayout(以HTML表格形式布局)
  • org.apache.log4j.PatternLayout(可以灵活地指定布局模式)
  • org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串)
  • org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等信息)

PatternLayout可使用log4j.appender.AppenderName.Layout.ConversionPattern定义Pattern:

log4j.appender.DRFA.layout=org.apache.log4j.PatternLayout
log4j.appender.DRFA.layout.ConversionPattern=%d{ISO8601} %-5p [%t]: %c{2} (%F:%M(%L)) - %m%n

Pattern格式化参数说明:

%c Fully class name. 输出所属的类目,通常就是所在类的全名;
%d Default is ISO8601. Custom:%d{yyy-MM-dd HH:mm:ss }, output example:2002-10-18 22:10:28
%f Class name.
%l Location and line number 输出日志事件的发生位置,及在代码中的行数;
%m Message 输出代码中指定的消息;
%n Nextline 输出一个回车换行符,Windows平台为"rn”,Unix平台为"n”;
%p Log priority 输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL;
%r Log consumed time 输出自应用启动到输出该log信息耗费的毫秒数;
%t Thread name 输出产生该日志事件的线程名;

定义Logger

定义Logger就是定义LoggerName、Logger Level以及与之关联的Appender。

rootLogger

一般首先定义rootLogger, LoggerFactory默认获取的都是rootLogger:

log4j.rootLogger=WARN,DRFA,Console,AppenderX...

一个Logger可关联多个Appender,这样就能输出到多个target。

custom Logger

有时需要将某个业务日志独立出来方便进行检索,比如监控、数据库操作日志等,此时可自定义Logger,一般LoggerName定义为类名或PackageName。

自定义Logger Level:

log4j.logger.org.apache.hadoop.hive.ql.Driver=INFO
log4j.logger.org.apache.hadoop.hive.ql.log.PerfLogger=DEBUG

自定义Logger Appender:

log4j.logger.org.apache.hadoop.hive.ql.Driver=INFO,AppenderXX

注意自定义Logger同时会继承rootLogger 的Appender,也就是日志同样会输出到rootLogger 的Appender中,这样会重复输出,因此最好禁止继承rootLogger Apperder:

log4j.additivity.logger.org.apache.hadoop.hive.ql.Driver=false

加载:

log4j配置文件名如果是log4j.properties或log4j.xml并且在classpath下则会被org.apache.log4j.LogManager自动加载,如果名称不符或不在classpath下则手动加载:

PropertyConfigurator.configure(String log4j_config_path);

也可以直接定义环境变量log4j.configuration指定log4j.properties的位置,org.apache.log4j.LogManager会从此变量定义处加载log4j配置

Ali日志规约

  1. 【强制】应用中不可直接使用日志系统(Log4j、Logback)中的API,而应依赖使用日志框架SLF4J中的API,使用门面模式的日志框架,有利于维护和各个类的日志处理方式统一。

    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    private static final Logger logger = LoggerFactory.getLogger(Abc.class);
    
  2. 【强制】日志文件推荐至少保存15天,因为有些异常具备以“周”为频次发生的特点。

  3. 【强制】应用中的扩展日志(如打点、临时监控、访问日志等)命名方式:appName_logType_logName.log。

    logType:日志类型,推荐分类有stats/desc/monitor/visit等;
    logName:日志描述。

    这种命名的好处:通过文件名就可知道日志文件属于什么应用,什么类型,什么目的,也有利于归类查找。

    正例:mppserver应用中单独监控时区转换异常,如: mppserver_monitor_timeZoneConvert.log

    说明:推荐对日志进行分类,错误日志和业务日志尽量分开存放,便于开发人员查看,也便于通过日志对系统进行及时监控。

  4. 【强制】对trace/debug/info级别的日志输出,必须使用条件输出形式或者使用占位符的方式。

    说明:logger.debug(“Processing trade with id: ” + id + ” symbol: ” + symbol);

    如果日志级别是warn,上述日志不会打印,但是会执行字符串拼接操作,如果symbol是对象,会执行toString()方法,浪费了系统资源,执行了上述操作,最终日志却没有打印。

    正例:(条件)

    if (logger.isDebugEnabled()) {
      logger.debug("Processing trade with id: " + id + " symbol: " + symbol);
    }
    

    正例:(占位符)

    logger.debug("Processing trade with id: {} symbol : {} ", id, symbol);
    
  5. 【强制】避免重复打印日志,浪费磁盘空间,务必在log4j.property中设置additivity=false。

    正例: logger name=”com.taobao.dubbo.config” additivity=”false”

  6. 【强制】异常信息应该包括两类信息:案发现场信息和异常堆栈信息。如果不处理,那么往上抛。

    正例:logger.error(各类参数或者对象toString + “_” + e.getMessage(), e);

  7. 【推荐】可以使用warn日志级别来记录用户输入参数错误的情况,避免用户投诉时,无所适从。注意日志输出的级别,error级别只记录系统逻辑出错、异常等重要的错误信息。如非必要,请不要在此场景打出error级别。

  8. 【推荐】谨慎地记录日志。生产环境禁止输出debug日志;有选择地输出info日志;如果使用warn来记录刚上线时的业务行为信息,一定要注意日志输出量的问题,避免把服务器磁盘撑爆,并记得及时删除这些观察日志。 说明:大量地输出无效日志,不利于系统性能提升,也不利于快速定位错误点。记录日志时请思考:这些日志真的有人看吗?看到这条日志你能做什么?能不能给问题排查带来好处?

猜你喜欢

转载自blog.csdn.net/jinjiating/article/details/79138989