Log4J学习记录

CDSN的markdown解析有问题?在VS中没问题的ε=(´ο`*)))唉

Log4j视频记录

log4j的核心对象

  1. Logger 完成日志信息的处理,决定输出的层次和决定信息是否输出;日志优先级如下:
    • ALL < TRACE < DEBUG < INFO < WARN < ERROR < FATAL < OFF
  2. Appender 设置日志的去向,这里可以指定多个输出目的地(需要多个appenderNanme),基本用法:
    log4j.appender.appenderName = AppenderClass
    log4j.appender.appenderName.option1 = value1
    log4j.appender.appenderName.option2 = value2

    ConsoleAppender 控制台
    FileAppender 文件
    DailyRollingFileAppender 每天产生一个新的日志文件
    RollingFileAppender 文件达到指定大小时产生新的日志文件
    WriterAppender 日志以串流的格式发送到任意指定的地方,多用于实现自己的appender
    JdbcAppender 数据库
  1. Layout 设置日志的输出样式,基本用法如下:
    org.apache.log4j.HTMLLayout 以HTML形式布局
    org.apache.log4j.SimpleLayout 包含之日的级别和信息字串
    org.apache.log4j.TTCCLayout 包含日志的时间、执行线程、类别等信息
    org.apache.log4j.PatternLayout 指定布局模式
  1. 配置文件 log4j.properties or log4j.xml

Logger的体系结构

Logger的体系结构

  1. 在创建Logger的时候,一般使用Logger.getLogger(Class)得到一个类绑定的日志记录器,这里我们其实是使用类的全限定名为Logger起了名字;所有的Logger都是由名字的(除了rootLogger),可以将logger想象成一个表,其中主键就是每个logger的名字,并且当两个logger的名字相同时,这两个就是同一个实例
  2. Logger是层次的,也是按照名字进行区分的;通过Logger.getLogger(“cd.itcast.log”)的时候,Log4J仅仅为我们创建了cd.itcast.log这个Logger;而当我们再次使用Logget.getLogger(“cd.itcast”)的时候,Log4J才会为我们创建cd.itcast这个Logger,并且Log4J会自动的去寻找这个Logger的上下级关系,并自动的把这个新创建的Logger添加到已有的Logger结构体系中
  3. rootLogger的特性
    • rootLogger没有名字
    • rootLogger自动存在
    • rootLogger必须设置等级,默认debug
  4. log4j中的等级Level也是一种层级关系,我们不需要为每个Logger设置Level,log4j为首先查看子logger的Level或Threashold,没有则继续向父logger查询;同时Threshold的优先级 > Level的优先级;如果父logger设置了Threashold,那么子logger的Level将失效
    // 在这里,logger的Level应该是Warn
    Logger logger = Logger.getLogger("cd.itcast");
    logger.getLoggerRepository().setThreshold(Level.WARN);
    logger.setLevel(Level.DEBUG);

Appender体系结构

Appender体系结构

  1. log4j中appender的用处在于决定日志的输出位置;
  2. appender也是一种层次关系,和Level类似的,不需要为每个Logger设置Appender,子logger为自动继承父logger的appender;注意,appender具有追加性,子logger不仅会继承父logger的appender,还会继承父logger的父logger的appender,以此类推;可以通过logger实例的setAdditivity(false)指定该logger不从父logger那里继承appender
@Test
public void testLogAppender1(){
    // 这里相当于启用了rootLogger,默认lavel=debug,appender=consoleAppender layout=TTCCLayout
    BasicConfigurator.configure(); 
    // 这里相当于创建了一个名为cd的logger,Level=debug appender=consoleAppender layout=SimpleLayout
    Logger log1=Logger.getLogger("cd");
    log1.setLevel(Level.DEBUG);
    log1.addAppender(new ConsoleAppender(new SimpleLayout()));
    // 这里相当于创建了一个名为cd.itcast.log的logger,Level=debug(继承来的) appender1=consoleAppender layout1=TTCCLayout,appender2=consoleAppender layout2=SimpleLayout
    Logger log2=Logger.getLogger("cd.itcast.log");
    log2.info("log2 info");
    log2.debug("log2 debug");

    INFO - log2 info --> 这是SimpleLayout的样式
    0 [main] INFO cd.itcast.log  - log2 info  --> 这是TTCCLayout的样式
    DEBUG - log2 debug
    0 [main] DEBUG cd.itcast.log  - log2 debug
}

|Logger|addAppender|setAdditivity|有效的appender
|—|—|—|—|
root| A1 | true | A1
cd | A2 | false | A2
cd.itcast| null | true | A2
cd.itcast.log| A3 | true | A3, A2
3. log4j中每个logger可以有多个appender,该logger上的每个可以输出的日志都会分别输出到所有的appender之上

三个核心组件的配合
以loggger.debug(“xxxxxxxxx”)时,log4j内会发生如下的过程
1. 继承树上的门限Threashold检查,检查当前日志请求是否满足级别,不满足立即作废;
2. 继承树上的级别Level检查,检查当前日志请求是否满足级别,不满足立即作废;
3. 日志审核通过后,创建LoggingEvent对象,该对象中保存着与本次日志相关的所有信息
4. 将创建好的LoggingEvent对象交给Appender对象
5. 使用每个appender绑定的layout格式化信息,准备成最终需要输出的字符串
6. 使用每个关联的appender输出该string至目标位置

在log4j.properties中加入 log4j.debug=treu,将会打印log4j自身的日志信息

log4j可以定义的格式示例1
log4j可以定义的格式示例2
log4j对大小写是敏感的
1. 设置整个Logger体系的Threshold

    log4j.threshold=[LEVEL],例如
    log4j.threshold=OFF <--> Logger.getRootLogger().getLoggerRepository().setThreshold(Level.OFF);
  1. 配置appender,这里需要先为每个appender设置名称,然后通过名称引用,例如
    # 设置appender的类型
    log4j.appender.appenderName=appenderClass
    # 设置appender的属性,这里的value处理上,
    # 1. log4j可以理解简单类型的值,如 Integer、String 等,
    # 2. log4j可以理解 org.apache.log4j.LEVEL 类型的值
    log4j.appender.appenderName.propertyName1=value1

    log4j.appender.CA.target=System.err
    log4j.appender.CA.follow=true
    log4j.appender.FA.file=log1.log
    log4j.appender.FA.append=true
  1. 配置layout,layout一般都属于某一个appender,换句话说,一般不会在不同的appender之间共享相同的Layout对象,因此我们一般会为每个appender设置自己的layout
    # SimpleLayout 是预定义的layout
    log4j.appender.CA.layout=org.apache.log4j.SimpleLayout < -- > CA.setLayout(new org.apache.log4j.SimpleLayout())

    # PatternLayout提供了自定义格式的能力,需要通过 conversionPattern 进行具体指定
    log4j.appender.FA.layout=org.apache.log4j.PatternLayout
    log4j.appender.FA.layout.conversionPattern=%r [%t] %p %c %x - %m%n
  1. 配置Logger,log4j中Logger对象有两大类
    • rootLogger,格式如下:log4j.rootLogger=[LEVEL],[Appender1,Append2…AppendN]
      java
      log4j.rootLogger=INFO,console
      log4j.appender.console=org.apache.log4j.ConsoleAppender
      log4j.appender.console.layout=org.apache.log4j.SimpleLayout
      < -等价java代码- >
      Logger.getRootLogger().setLevel(Level.INFO);
      Logger.getRootLogger().addAppender(new ConsoleAppender(new SimpleLayout()))
    • 自定义Logger对象,格式如下: log4j.logger.loggerName=[LEVEL|INHERITED|NULL],[Appender1,Append2…AppendN],这里的INHERITED|NULL是等价的,都是使用默认等级,即从继承中获取
      java
      log4j.rootLogger=INFO,file
      # log4j在变量检查上,会先在系统环境变量中按照变量的名字查询值,如果没有,在在配置文件中查询变量的值,最后,使用查询到的值替换占位符即可
      dir=${user.home}
      file=log1.log
      log4j.additivity.file=true|false
      log4j.appender.file=org.apache.log4j.FileAppender
      log4j.appender.file.layout=org.apache.log4j.PatternLayout
      log4j.appender.file.layout.conversionPattern=%r [%t] %p %c %x - %m%n
      log4j.appender.file.file=${dir}/${file}

常用appender

WriterAppender
1. WriterAppender是一个基础的appender,是下述appender的父类,其可以将LoggingEvent对象交给Writer处理,是不可以通过配置文件使用的,其有两个重要的参数
* encoding,输出string的编码方式,默认采用系统编码
* immediateFlush,是否立即刷新,默认true,在大日志量时有助于提高提供性能,但会有日志丢失风险
ConsoleAppender
1. ConsoleAppender,继承了WriterAppender,也有对应的encoding和immediateFlush两个属性
2. ConsoleAppender还有target属性,指定控制台输出位置,对于java,有System.out和System.err两个
java
log4j.rootLogger=INFO,stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.SimpleLayout
log4j.appender.stdout.target=System.err

FileAppender1FileAppender2
1. fileappender继承了writerappender,多增加了FileWriter,其相关属性配置如下
* file,指定保存日志的文件全路径名
* append,true|false,决定日志以添加的方式还是覆盖的方式写入,默认true
* bufferedIO,true|false,决定是否为FileWriter增加BufferedWriter,默认false即立即写入
* buffersize,如果设置bufferIO为true,该属性决定缓冲区大小
2. RollingFileAppender,继承了FileAppender,可以在日志文件达到一定程度时开启新的日志文件,其特有参数如下
* maximumFileSize,决定日志的最大容量,超过则开新的日志文件,类型是long
* maxFileSize,决定日志最大容量,类型是String,允许使用KB/MB/GB指定文件带下
* maxBackupIndex,备份文件的最大索引号,索引号超过后则删除早期的文件
* RollingFileAppender存在的问题:
* 文件命名没有规律,并可能造成某个时间段的日志分散在多个日志文件中;根据文件名很难定位日志的时间
3. DailyRollingFileAppender,提供了按照特定时间生成日志的能力,继承了FileAppender
* datePattern,设置日志文件名的日期格式,例如 log4j.appender.appenderName.datePattern=’.’yyyy-MM-dd-HH-mm

常用Layout

PatternLayout
1. 在PatternLayout中,每个格式都是一个字符,并位于%之后,常用个格式如下,其中C/F/L/l非常消耗性能:
* c,logger的名字,后面可以附加 {num} 表示从右至左数“.”的个数
* C,logger所属的类的名字,后面可以附加 {num} 表示从右至左数“.”的个数
* d,日志输出时间,后面可以附加{format}指定个数,默认按照ISO08601样式
* F,日志所在的文件的名称
* l,输出日志所在的类的文件名称
* L,输出java代码中所在的行号
* m,输出日志的内容
* M,输出日志所在的方法名称
* n,就是换行符
* p,该日志对应的级别Level
* r,从系统启动到输出该日志间隔的时间 ms
* t,输出该日志的线程的名称
* x,输出日志的NDC信息
* X,输出日志的MDC信息
2. 日志对齐控制
格式 |左对齐 |最小长度 |最大长度
—|—|—|—|
[%c] | 无 | 不限 | 不限
[%15c] | 无 | 15 | 不限
[%-15c] |是 | 15 | 不限
[%.8c] | 无 | 不限 | 8
[%5.8c] | 无 |5 | 8
[%-5.8c] | 是 | 5 | 8

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值