美文网首页
Java日志技术(上)

Java日志技术(上)

作者: 山巅自相见 | 来源:发表于2021-09-15 17:43 被阅读0次

    日志文件

    日志文件是用于记录系统操作时间的文件集合,可分为事件日志和消息日志。具有处理历史数据、诊断问题的追踪以及理解系统的活动等重要作用。
    在计算机中,日志文件是记录在操作系统或其他软件运行中发生的事件或在通信软件的不同用户之间的消息的文件。记录是保持日志的行为。在最简单的情况下,消息被写入单个日志文件。
    如多操作系统、软件框架和程序包括日志系统。广泛使用的日志记录标准是在因特网工程任务组(IETF)RFC5424中定义的syslog。syslog标准使专用的标准化子系统能够生成、过滤、记录和分析日志消息。

    调试日志

    软件开发中,我们京城需要去调试程序,做一些信息、状态的输出便于我们查询程序的运行情况。为了让我们能够更加灵活和方便的控制这些调试的信息,所有我们需要专业的日志技术。Java中寻找bug会需要重现。条是也就是debug可以在程序运行中暂停程序运行,可以查看程序在运行中的情况。日志主要是为了更方便的去重现问题。

    系统日志

    系统日志是记录系统中硬件、软件和系统问题的信息,同时还可以建时系统中发生的事件。用户可以通过它来检查错误发生的原因,或者寻找受到攻击时攻击者留下的痕迹。系统日志包括系统日志、应用程序日志和安全日志。
    系统日志的价值
    系统日志策略可以在故障刚刚发生时就像你发送警告信息,系统日志帮助你在最短的时间内发现问题。
    系统日志是一种非常关键的组件,因为系统日志可以让你充分了解自己的环境,这种系统日志信息对于决定故

    Java日志框架

    问题:

    1. 控制日志输出的内容和格式
    2. 控制日志输出的位置
    3. 日志优化:异步日志,日志文件的归档和压缩
    4. 日志系统的维护
    5. 面向接口开发--日志的门面

    为什么要用日志框架

    因为软件系统发展到今天已经很复杂了,特别是服务器端软件,涉及到的知识、内容、问题太多。在某些方面使用别人成熟的框架,就相当于让别人帮你完成一些基础工作,你只需要集中精力完成系统的业务逻辑设计。而且框架一般都是成熟、稳健的,它可以处理系统很多细节问题,比如: 事务处理、安全性、数据流控制等问题。还有框架一般都经过很多人使用,所以结构很好,所以扩展性也很好,而且它是不断升级的,你可以直接享受别人升级代码带来的好处。

    现有的日志框架

    JUL(java util logging)、logback、log4j、log4j2
    JCL(Jakarta Commons Logging)、slf4j(Simple Logging Facade for Java)
    日志门面
    JCL、slf4j
    日志实现
    JUL、logback、log4j、log4j2

    JUL学习

    JUL全称Java util Logging是Java原生的日志框架,使用时不需要另外引用第三方类库,相对其他日志使用方便,学习简单,能够在小型应用中灵活使用。

    JUL入门

    架构介绍

    • Loggers:被称为记录器,应用程序通过获取Logger对象,调用其API来发布日志信息。Logger通常时应用程序访问日志系统的入口程序。
    • Appenders:也被称为Handlers,每个Logger都会关联一组Handlers在此是一个抽象,其具体的实现决定了日志记录的位置可以是控制台、文件、网络上的其他日志服务或操作系统日志等。
    • Layouts:也被称为Formatters,它负责对日志文件中的数据进行转换和格式化。Layouts决定了在一条日志记录中最终形式。
    • Level:每条日志消息都有一个关联的日志级别。该级别粗略知道了日志消息的重要性和紧迫,我可以将Level和Loggers,Appenders做关联以便于我们过滤消息。
    • Filter:根据需要指定那些信息会被记录,那些信息会被放过。
      总结一下就是:
      用户使用Logger来进行日志记录,Logger持有若干个Handler,日志的输出操作是由Handler完成的。在Handler在输出日志前,会经过Filter的过滤,判断哪些日志级别过滤放行哪些拦截,Handler会将日志内容输出到指定位置(日志文件、控制台等)。Handler在输出日志时会使用Layout,将输出内容进行排版。

    入门案例

    import org.junit.Test;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    
    public class JULTest {
      @Test
      public void testOne() {
        // 获取日志记录器对象
        Logger logger = Logger.getLogger("com.itcast.JULTest");
        // 日志输出记录
        logger.info("hello info");
        // 通过方法进行日志输出
        logger.log(Level.INFO, "hello log");
        // 通过占位符 方法输出变量值
        String name = "itcast";
        Integer age = 13;
        logger.log(Level.INFO, "用户信息:{0}, {1}", new Object[]{name, age});
      }
    }
    /*
    * 输出信息:
    九月 15, 2021 3:41:06 下午 com.itcast.JULTest testOne
    信息: hello info
    九月 15, 2021 3:41:06 下午 com.itcast.JULTest testOne
    信息: hello log
    九月 15, 2021 3:41:06 下午 com.itcast.JULTest testOne
    信息: 用户信息:itcast, 13*/
    

    日志的级别

    import org.junit.Test;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    
    // 日志的级别
    @Test
    public void testTwo() {
      // 获取日志记录器对象
      Logger logger = Logger.getLogger("com.itcast.JULTest");
      // 日志输出记录
      logger.log(Level.SEVERE, "SEVERE");
      logger.log(Level.WARNING, "WARNING");
      logger.log(Level.INFO, "INFO"); // JUL默认日志级别
      logger.log(Level.CONFIG, "CONFIG");
      logger.log(Level.FINE, "FINE");
      logger.log(Level.FINER, "FINER");
      logger.log(Level.FINEST, "FINEST");
    }
    /*输出结果
    * 九月 15, 2021 4:15:55 下午 com.itcast.JULTest testTwo
    严重: SEVERE
    九月 15, 2021 4:15:55 下午 com.itcast.JULTest testTwo
    警告: WARNING
    九月 15, 2021 4:15:55 下午 com.itcast.JULTest testTwo
    信息: INFO*/
    
    // 自定义日志级别
    @Test
    public void testThree() throws IOException {
      // 获取日志输出记录器
      Logger logger = Logger.getLogger("com.itcast.JULTest");
      // 关闭系统默认配置
      logger.setUseParentHandlers(false);
      // 自定义日志级别
      // 创建ConsoleHandler 控制台输出
      ConsoleHandler consoleHandler = new ConsoleHandler();
      // 创建简单格式转换对象
      SimpleFormatter simpleFormatter = new SimpleFormatter();
      // 进行关联
      consoleHandler.setFormatter(simpleFormatter);
      logger.addHandler(consoleHandler);
      // 配置日志具体级别
      logger.setLevel(Level.ALL);
      consoleHandler.setLevel(Level.ALL);
      // 场景FileHandler 文件输出
      FileHandler fileHandler = new FileHandler("d://jul.log");
      // 进行关联
      fileHandler.setFormatter(simpleFormatter);
      logger.addHandler(fileHandler);
      // 日志输出记录
      logger.log(Level.SEVERE, "SEVERE");
      logger.log(Level.WARNING, "WARNING");
      logger.log(Level.INFO, "INFO");
      logger.log(Level.CONFIG, "CONFIG");
      logger.log(Level.FINE, "FINE");
      logger.log(Level.FINER, "FINER");
      logger.log(Level.FINEST, "FINEST");
    }
    /**
    * 九月 15, 2021 4:30:48 下午 com.itcast.JULTest testThree
    * 严重: SEVERE
    * 九月 15, 2021 4:30:48 下午 com.itcast.JULTest testThree
    * 警告: WARNING
    * 九月 15, 2021 4:30:48 下午 com.itcast.JULTest testThree
    * 信息: INFO
    * 九月 15, 2021 4:30:48 下午 com.itcast.JULTest testThree
    * 配置: CONFIG
    * 九月 15, 2021 4:30:48 下午 com.itcast.JULTest testThree
    * 详细: FINE
    * 九月 15, 2021 4:30:48 下午 com.itcast.JULTest testThree
    * 较详细: FINER
    * 九月 15, 2021 4:30:48 下午 com.itcast.JULTest testThree
    * 非常详细: FINEST
    */
    

    Logger之间的父子关系

    @Test
    public void TestFour() {
      Logger logger = Logger.getLogger("com.itcast.JULTest");
      Logger com = Logger.getLogger("com");
      System.out.println(logger.getParent() == com);
      System.out.println("com Parent:" + com.getParent() + ",name:" + com.getParent().getName());
      // 关闭默认配置
      com.setUseParentHandlers(false);
      // 设置com日志级别
      // 创建ConsoleHandler 控制台输出
      ConsoleHandler consoleHandler = new ConsoleHandler();
      // 创建简单格式转换对象
      SimpleFormatter simpleFormatter = new SimpleFormatter();
      // 进行关联
      consoleHandler.setFormatter(simpleFormatter);
      com.addHandler(consoleHandler);
      // 配置日志的具体级别
      com.setLevel(Level.ALL);
      consoleHandler.setLevel(Level.ALL);
      // 日志输出记录
      // logger的默认级别是INFO 但是继承的子类级别是ALL 所以logger的级别是ALL
      logger.log(Level.SEVERE, "SEVERE");
      logger.log(Level.WARNING, "WARNING");
      logger.log(Level.INFO, "INFO");
      logger.log(Level.CONFIG, "CONFIG");
      logger.log(Level.FINE, "FINE");
      logger.log(Level.FINER, "FINER");
      logger.log(Level.FINEST, "FINEST");
    }
    /**
    * true
    * com Parent:java.util.logging.LogManager$RootLogger@57855c9a,name:
    * 九月 15, 2021 5:15:46 下午 com.itcast.JULTest TestFour
    * 严重: SEVERE
    * 九月 15, 2021 5:15:46 下午 com.itcast.JULTest TestFour
    * 警告: WARNING
    * 九月 15, 2021 5:15:46 下午 com.itcast.JULTest TestFour
    * 信息: INFO
    * 九月 15, 2021 5:15:47 下午 com.itcast.JULTest TestFour
    * 配置: CONFIG
    * 九月 15, 2021 5:15:47 下午 com.itcast.JULTest TestFour
    * 详细: FINE
    * 九月 15, 2021 5:15:47 下午 com.itcast.JULTest TestFour
    * 较详细: FINER
    * 九月 15, 2021 5:15:47 下午 com.itcast.JULTest TestFour
    * 非常详细: FINEST
    */
    

    LOG4J学习

    Log4j是Apache下的一款开源的日志框架,通过在项目中使用Log4j,我们可以控制日志信息输出到控制台、文件、甚至是数据库中。我么可以控制每一条日志的输出格式,通过定义日志的输出级别,可以更灵活的控制日志的输出过程。方便项目的调试。

    Log4j入门

    1. 建立maven工程
    2. 添加依赖
    <dependencies>
      <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.13.2</version>
      </dependency>
      <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.17</version>
      </dependency>
    </dependencies>
    

    代码块:

    import org.apache.log4j.BasicConfigurator;
    import org.apache.log4j.Logger;
    import org.junit.Test;
    
    @Test
    public void testIne() {
      // 初始化配置信息
      BasicConfigurator.configure();
      // 获取日志记录器
      Logger logger = Logger.getLogger(log4jTest.class);
      // 日志输出记录
      // 严重错误 一般会造成系统崩溃并终止运行
      logger.fatal("FATAL");
      // 错误信息 不会影响系统运行
      logger.error("ERROR");
      // 警告信息 可能会发生的问题
      logger.warn("WARN");
      // 运行信息 数据连接、网络连接、IO操作等等
      logger.info("INFO");
      // 调试信息 一般在开发中使用 记录程序变量、参数传递信息等等 log4j默认日志级别
      logger.debug("DEBUG");
      // 追踪信息 记录程序所有的流程信息
      logger.trace("TRACE");
    }
    

    运行结果

    0 [main] FATAL com.itcast.log4jTest  - FATAL
    1 [main] ERROR com.itcast.log4jTest  - ERROR
    1 [main] WARN com.itcast.log4jTest  - WARN
    1 [main] INFO com.itcast.log4jTest  - INFO
    1 [main] DEBUG com.itcast.log4jTest  - DEBUG
    

    Log4j组件

    Log4j主要由Loggers(日志记录器)、Appenders(输出端)和Layout(日志格式化器)组成。其中Loggers控制日志的输出级别于日志是否输出;Appenders直嘀咕日志的输出方式(输出到控制台、文件等);Layout控制日志信息的输出格式。
    代码

    @Test
    public void testIne() {
      // 开启log4j内置日志记录
      LogLog.setInternalDebugging(true);
      // 获取日志记录器
      Logger logger = Logger.getLogger(log4jTest.class);
      // 日志输出记录
      // 严重错误 一般会造成系统崩溃并终止运行
      logger.fatal("FATAL");
      // 错误信息 不会影响系统运行
      logger.error("ERROR");
      // 警告信息 可能会发生的问题
      logger.warn("WARN");
      // 运行信息 数据连接、网络连接、IO操作等等
      logger.info("INFO");
      // 调试信息 一般在开发中使用 记录程序变量、参数传递信息等等
      // log4j默认日志级别
      logger.debug("DEBUG");
      // 追踪信息 记录程序所有的流程信息
      logger.trace("TRACE");
    }
    

    输出结果

    log4j: Trying to find [log4j.xml] using context classloader sun.misc.Launcher$AppClassLoader@18b4aac2.
    log4j: Trying to find [log4j.xml] using sun.misc.Launcher$AppClassLoader@18b4aac2 class loader.
    log4j: Trying to find [log4j.xml] using ClassLoader.getSystemResource().
    log4j: Trying to find [log4j.properties] using context classloader sun.misc.Launcher$AppClassLoader@18b4aac2.
    log4j: Using URL [file:/D:/idea%20project/Log/Log4j/target/classes/log4j.properties] for automatic log4j configuration.
    log4j: Reading configuration from URL file:/D:/idea%20project/Log/Log4j/target/classes/log4j.properties
    log4j: Parsing for [root] with value=[trace, console].
    log4j: Level token is [trace].
    log4j: Category root set to TRACE
    log4j: Parsing appender named "console".
    log4j: Parsing layout options for "console".
    log4j: End of parsing for "console".
    log4j: Parsed "console" options.
    log4j: Finished configuring.
    FATAL - FATAL
    ERROR - ERROR
    WARN - WARN
    INFO - INFO
    DEBUG - DEBUG
    TRACE - TRACE
    

    Loggers

    日志记录器。负责收集处理日志记录,时录得命名就是类“XX”的full quailiedname(类的全限定名),Logger的名字大小写敏感,其命名有继承机制:例如:name为org.apache.commons的logger会继承name为org.apache的logger。
    Log4j中有一个特殊的logger叫做“root”,它是所有logger的根,也就意味着其他所有的logger都会直接或者间接地继承自root,root logger可以用Logger.getRootLogger()方法获取。
    但是,自Log4j1.2版以来,Logger类已经取代了Category类。对于熟悉早期版本的log4j的人来说,Logger类可以被视为Category类的别名

    Appenders

    Appender用来指定日志输出到哪个地方,可以同时指定日志的输出目的地。Log4j常用的输出目的地有以下几种:

    输出端类型 作用
    ConsoleAppender 将日志输出到控制台
    FileAppender 将日志输出到文件中
    DailyRollingFileApender 将日志输出到一个日志文件,并且每天输出到一个新的文件
    RollingFileAppender 将日志信息输出到一个日志文件,并且指定文件的尺寸,当文件大小达到指定尺寸时,会自动把文件改名,同时产生一个新的文件
    JDBCAppender 把日志信息保存到数据库中

    Layouts

    布局其Layouts用于控制日志输出内容的格式,让我们可以使用各种需要的格式输出日志。Log4j常用的Layouts

    格式化器类型 作用
    HTMLLayouts 格式化日志输出为HTML表格形式
    SimpleLayout 简单的日志输出格式化,打印的日志格式为(info-message)
    PatternLayout 最强大的格式化期,可以根据自定义格式输出日志,如果没有指定转换格式,就是默认的转换格式

    Layout的格式

    在log4j.properties配置文件中,我们定义了日志输出级别与输出端,在输出端中分别配置日志的输出格式

    log4j采用类似于c语言的printf函数的打印格式化日志信息,具体的占位符及其含义如下:
    %m 输出代码中指定的日志信息
    %p 输出优先级,及DEBUG、INFO等
    %n 换行符(Windows平台的换行符为"\n",Unix平台为"\n")
    %r 输出自应用启动到输出改log信息耗费的毫秒数
    %c 输出打印语句所属的类的全名
    %t 输出产生该日志的线程全名
    %d 输出服务器当前时间,默认为ISO8601,也可以指定格式,如:%d{yyyy年MM月dd日 HH:mm:ss}
    %l 输出日志时间发生的位置,包括类名、线程、及在代码中的行数。如:Test.main(Test.java:10)
    %F 输出日志消息产生时所在的新建名称
    %L 输出代码中的行号
    %% 输出一个"%"字符
    可以在%与字符之间加上修饰符来控制最小宽度、最大宽度和文本的对齐方式。如:
    %5c 输出category名称,最小宽度是5,category<5,默认的情况下右对齐
    %-5c 输出category名称,最小宽度是5,category<5,“-”号指定左对齐,会有空格
    %.5c 输出category名称,最小宽度是5,category>5,就会将左边多出的字符截掉,<5不会有空格
    %20.30c category名称<20补空格,并且右对齐,>30字符,就从左边较远的字符截掉

    4.4Appender的输出

    控制台,文件,数据库

    指定日志的输出级别与输出端

    控制台输出日志,代码块

    @Test
    public void testIne() {
      // 开启Log4j内置日志记录
      LogLog.setInternalDebugging(true);
      // 获取日志记录器
      Logger logger = Logger.getLogger(log4jTest.class);
      // 日志输出记录
      // 严重错误 一般会造成系统崩溃并终止运行
      logger.fatal("FATAL");
      // 错误信息 不会影响系统运行
      logger.error("ERROR");
      // 警告信息 可能会发生的问题
      logger.warn("WARN");
      // 运行信息 数据连接、网络连接、IO操作等等
      logger.info("INFO");
      // 调试信息 一般在开发中使用 记录程序变量、参数传递信息等等
      // log4j默认日志级别
      logger.debug("DEBUG");
      // 追踪信息 记录程序所有的流程信息
      logger.trace("TRACE");
    }
    

    log4j.properties

    # 指定RootLogger顶级父元素默认配置信息
    # 之地不过日志级别=trace,使用的appender为console
    log4j.rootLogger = trace, console
    # 指定控制台日志输出的appender
    log4j.appender.console = org.apache.log4j.ConsoleAppender
    # 指定消息格式layout
    log4j.appender.console.layout = org.apache.log4j.PatternLayout
    # 指定消息格式的内容
    log4j.appender.console.layout.conversionPattern = [%p]%r %l %d{yyyy-MM-dd HH:mm:ss.SSS} %m%n
    

    输出结果

    log4j: Trying to find [log4j.xml] using context classloader sun.misc.Launcher$AppClassLoader@18b4aac2.
    log4j: Trying to find [log4j.xml] using sun.misc.Launcher$AppClassLoader@18b4aac2 class loader.
    log4j: Trying to find [log4j.xml] using ClassLoader.getSystemResource().
    log4j: Trying to find [log4j.properties] using context classloader sun.misc.Launcher$AppClassLoader@18b4aac2.
    log4j: Using URL [file:/D:/idea%20project/Log/Log4j/target/classes/log4j.properties] for automatic log4j configuration.
    log4j: Reading configuration from URL file:/D:/idea%20project/Log/Log4j/target/classes/log4j.properties
    log4j: Parsing for [root] with value=[trace, console].
    log4j: Level token is [trace].
    log4j: Category root set to TRACE
    log4j: Parsing appender named "console".
    log4j: Parsing layout options for "console".
    log4j: Setting property [conversionPattern] to [[%p]%r %l %d{yyyy-MM-dd HH:mm:ss.SSS} %m%n].
    log4j: End of parsing for "console".
    log4j: Parsed "console" options.
    log4j: Finished configuring.
    [FATAL]0 com.itcast.log4jTest.testIne(log4jTest.java:16) 2021-09-17 11:35:57.040 FATAL
    [ERROR]3 com.itcast.log4jTest.testIne(log4jTest.java:18) 2021-09-17 11:35:57.043 ERROR
    [WARN]3 com.itcast.log4jTest.testIne(log4jTest.java:20) 2021-09-17 11:35:57.043 WARN
    [INFO]3 com.itcast.log4jTest.testIne(log4jTest.java:22) 2021-09-17 11:35:57.043 INFO
    [DEBUG]3 com.itcast.log4jTest.testIne(log4jTest.java:25) 2021-09-17 11:35:57.043 DEBUG
    [TRACE]3 com.itcast.log4jTest.testIne(log4jTest.java:27) 2021-09-17 11:35:57.043 TRACE
    

    下载到本地日志文件,log4j.properties

    # 指定RootLogger顶级父元素默认配置信息
    # 之地不过日志级别=trace,使用的appender为console
    log4j.rootLogger = trace, console, file, rollingFile
    # 指定控制台日志输出的appender
    log4j.appender.console = org.apache.log4j.ConsoleAppender
    # 指定消息格式layout
    log4j.appender.console.layout = org.apache.log4j.PatternLayout
    # 指定消息格式的内容
    log4j.appender.console.layout.conversionPattern = [%p]%r %l %d{yyyy-MM-dd HH:mm:ss.SSS} %m%n
    # 指定控制台日志输出的appender
    log4j.appender.file = org.apache.log4j.FileAppender
    # 指定消息格式layout
    log4j.appender.file.layout = org.apache.log4j.PatternLayout
    # 指定消息格式的内容
    log4j.appender.file.layout.conversionPattern = [%p]%r %l %d{yyyy-MM-dd HH:mm:ss.SSS} %m%n
    # 指定日志文件保存路径
    log4j.appender.file.file = d://log4j.log
    # 指定日志文件的字符集
    log4j.appender.file.encoding = UTF-8
    # 指定控制台日志输出的appender
    log4j.appender.rollingFile = org.apache.log4j.RollingFileAppender
    # 指定消息格式layout
    log4j.appender.rollingFile.layout = org.apache.log4j.PatternLayout
    # 指定消息格式的内容
    log4j.appender.rollingFile.layout.conversionPattern = [%p]%r %l %d{yyyy-MM-dd HH:mm:ss.SSS} %m%n
    # 指定日志文件保存路径
    log4j.appender.rollingFile.file = d://log4j.log
    # 指定日志文件的字符集
    log4j.appender.rollingFile.encoding = UTF-8
    # 指定日志文件内容的大小
    log4j.appender.rollingFile.maxFileSize = 1MB
    # 指定日志文件的数量
    log4j.appender.rollingFile.maxBackupIndex = 3
    

    添加到数据库,代码块同上,log4j.properties

    # 指定RootLogger顶级父元素默认配置信息
    # 之地不过日志级别=trace,使用的appender为logDB
    log4j.rootLogger = trace, logDB
    #mysql
    log4j.appender.logDB = org.apache.log4j.jdbc.JDBCAppender
    log4j.appender.logDB.layout = org.apache.log4j.PatternLayout
    log4j.appender.logDB.Driver = com.mysql.jdbc.Driver
    log4j.appender.logDB.URL = jdbc:mysql://localhost:3306/test
    log4j.appender.logDB.User = root
    log4j.appender.logDB.Password = root
    log4j.appender.logDB.Sql = INSERT INTO log (project_name, create_date, level, category, file_name, thread_name, line, all_category, message) values ('itcast', '%d{yyyy-MM-dd HH:mm:ss}', '%p', '%c', '%F', '%t', '%L', '%l', 'm')
    

    运行结果


    Log4j自定义logger

    代码块

    import org.apache.log4j.Logger;
    import org.apache.log4j.helpers.LogLog;
    import org.junit.Test;
    
    public class log4jTest {
      @Test
      public void testIne() {
      // 开启Log4j内置日志记录
      LogLog.setInternalDebugging(true);
      // 获取日志记录器
      Logger logger = Logger.getLogger(log4jTest.class);
      // 日志输出记录
      // 严重错误 一般会造成系统崩溃并终止运行
      logger.fatal("FATAL log4jTest");
      // 错误信息 不会影响系统运行
      logger.error("ERROR log4jTest");
      // 警告信息 可能会发生的问题
      logger.warn("WARN log4jTest");
      // 运行信息 数据连接、网络连接、IO操作等等
      logger.info("INFO log4jTest");
      // 调试信息 一般在开发中使用 记录程序变量、参数传递信息等等
      // log4j默认日志级别
      logger.debug("DEBUG log4jTest");
      // 追踪信息 记录程序所有的流程信息
      logger.trace("TRACE log4jTest");
      // 再次创建日志记录器
      Logger logger1 = Logger.getLogger(Logger.class);
      logger1.fatal("FATAL Logger");
      logger1.error("ERROR Logger");
      logger1.warn("WARN Logger");
    }
    

    log4j.properties

    # 指定RootLogger顶级父元素默认配置信息
    # 之地不过日志级别=trace 使用的appender为logDB
    log4j.rootLogger = trace, console
    #自定义logger对象设置
    # 本地的日志级别为info appender为下载到本地
    log4j.logger.com.itcast = info, file
    # apache的日志级别为error
    log4j.logger.org.apache = error
    # 指定控制台日志输出的appender
    log4j.appender.console = org.apache.log4j.ConsoleAppender
    # 指定消息格式layout
    log4j.appender.console.layout = org.apache.log4j.PatternLayout
    # 指定消息格式的内容
    log4j.appender.console.layout.conversionPattern = [%p]%r %l %d{yyyy-MM-dd HH:mm:ss.SSS} %m%n
    # 指定控制台日志输出的appender
    log4j.appender.file = org.apache.log4j.FileAppender
    # 指定消息格式layout
    log4j.appender.file.layout = org.apache.log4j.PatternLayout
    # 指定消息格式的内容
    log4j.appender.file.layout.conversionPattern = [%p]%r %l %d{yyyy-MM-dd HH:mm:ss.SSS} %m%n
    # 指定日志文件保存路径
    log4j.appender.file.file = d://log4j.log
    # 指定日志文件的字符集
    log4j.appender.file.encoding = UTF-8
    # 指定控制台日志输出的appender
    log4j.appender.rollingFile = org.apache.log4j.RollingFileAppender
    # 指定消息格式layout
    log4j.appender.rollingFile.layout = org.apache.log4j.PatternLayout
    # 指定消息格式的内容
    log4j.appender.rollingFile.layout.conversionPattern = [%p]%r %l %d{yyyy-MM-dd HH:mm:ss.SSS} %m%n
    # 指定日志文件保存路径
    log4j.appender.rollingFile.file = d://log4j.log
    # 指定日志文件的字符集
    log4j.appender.rollingFile.encoding = UTF-8
    # 指定日志文件内容的大小
    log4j.appender.rollingFile.maxFileSize = 1MB
    # 指定日志文件的数量
    log4j.appender.rollingFile.maxBackupIndex = 3
    #mysql
    log4j.appender.logDB = org.apache.log4j.jdbc.JDBCAppender
    log4j.appender.logDB.layout = org.apache.log4j.PatternLayout
    log4j.appender.logDB.Driver = com.mysql.jdbc.Driver
    log4j.appender.logDB.URL = jdbc:mysql://localhost:3306/test
    log4j.appender.logDB.User = root
    log4j.appender.logDB.Password = root
    log4j.appender.logDB.Sql = INSERT INTO log (project_name, create_date, level, category, file_name, thread_name, line, all_category, message) values ('itcast',\
      '%d{yyyy-MM-dd HH:mm:ss}', '%p', '%c', '%F', '%t', '%L', '%l', 'm')
    

    运行结果

    log4j: Trying to find [log4j.xml] using context classloader sun.misc.Launcher$AppClassLoader@18b4aac2.
    log4j: Trying to find [log4j.xml] using sun.misc.Launcher$AppClassLoader@18b4aac2 class loader.
    log4j: Trying to find [log4j.xml] using ClassLoader.getSystemResource().
    log4j: Trying to find [log4j.properties] using context classloader sun.misc.Launcher$AppClassLoader@18b4aac2.
    log4j: Using URL [file:/D:/idea%20project/Log/Log4j/target/classes/log4j.properties] for automatic log4j configuration.
    log4j: Reading configuration from URL file:/D:/idea%20project/Log/Log4j/target/classes/log4j.properties
    log4j: Parsing for [root] with value=[trace, console].
    log4j: Level token is [trace].
    log4j: Category root set to TRACE
    log4j: Parsing appender named "console".
    log4j: Parsing layout options for "console".
    log4j: Setting property [conversionPattern] to [[%p]%r %l %d{yyyy-MM-dd HH:mm:ss.SSS} %m%n].
    log4j: End of parsing for "console".
    log4j: Parsed "console" options.
    log4j: Parsing for [com.itcast] with value=[info, file].
    log4j: Level token is [info].
    log4j: Category com.itcast set to INFO
    log4j: Parsing appender named "file".
    log4j: Parsing layout options for "file".
    log4j: Setting property [conversionPattern] to [[%p]%r %l %d{yyyy-MM-dd HH:mm:ss.SSS} %m%n].
    log4j: End of parsing for "file".
    log4j: Setting property [file] to [d://log4j.log].
    log4j: Setting property [encoding] to [UTF-8].
    log4j: setFile called: d://log4j.log, true
    log4j: setFile ended
    log4j: Parsed "file" options.
    log4j: Handling log4j.additivity.com.itcast=[null]
    log4j: Parsing for [org.apache] with value=[error].
    log4j: Level token is [error].
    log4j: Category org.apache set to ERROR
    log4j: Handling log4j.additivity.org.apache=[null]
    log4j: Finished configuring.
    [FATAL]0 com.itcast.log4jTest.testIne(log4jTest.java:16) 2021-09-17 16:14:16.200 FATAL log4jTest
    [ERROR]3 com.itcast.log4jTest.testIne(log4jTest.java:18) 2021-09-17 16:14:16.203 ERROR log4jTest
    [WARN]3 com.itcast.log4jTest.testIne(log4jTest.java:20) 2021-09-17 16:14:16.203 WARN log4jTest
    [INFO]3 com.itcast.log4jTest.testIne(log4jTest.java:22) 2021-09-17 16:14:16.203 INFO log4jTest
    [FATAL]3 com.itcast.log4jTest.testIne(log4jTest.java:30) 2021-09-17 16:14:16.203 FATAL Logger
    [ERROR]3 com.itcast.log4jTest.testIne(log4jTest.java:31) 2021-09-17 16:14:16.203 ERROR Logger
    

    可见运行结果在控制台打印的log4jTest级别是从fatal-info,而Logger只有fatal和error,这是根据配置文件里的
    #自定义logger对象设置
    # 本地的日志级别为info appender为下载到本地
    log4j.logger.com.itcast = info, file
    # apache的日志级别为error
    log4j.logger.org.apache = error
    

    以及代码块中的

      // 创建日志记录器
      Logger logger = Logger.getLogger(log4jTest.class);
      // 再次创建日志记录器
      Logger logger1 = Logger.getLogger(Logger.class);
    

    JCL入门

    全称为Jakarta Commons Logging,是Apache提供的一个通用日志API。
    它是为“所有的Java日志实现”提供一个统一的接口,它自身也提供一个日志的实现,但是功能非常弱(SimpleLog)。所以一般不会单独使用它。它允许开发人员使用不腰痛的具体实现工具:Log4j,jdk自带的日志(JUL)
    JCL有两个基本的抽象类:Log(基本记录器)和LogFactory(负责创建Log实例)。

    JCL基本抽象类
    我们为什么要使用日志门面:
    1. 面向接口开发,不再依赖具体的实现类,减少代码的耦合
    2. 项目通过导入不同的实现类,可以灵活的切换日志框架
    3. tongyiAPI,方便开发者学习和使用
    4. 统一配置便于项目日志的管理

    JCL原理

    1. 通过LogFactory动态加载Log是实现类


      Java日志技术_LogFactory动态加载Log
    2. 日志门面支持的日志实现数组
    private static final String[] classesToDiscover = new String[]{"org.apache.commons.logging.impl.Log4JLogger",
        "org.apache.commons.logging.impl.Jdk14Logger", "org.apache.commons.logging.impl.Jdk13LumberjackLogger",
        "org.apache.commons.logging.impl.SimpleLog"};
    
    1. 获取具体的日志实现
    for (int i = 0; i < classesToDiscover.length && result == null; ++i) {
      result = this.createLogFromClass(classesToDiscover[i], logCategory, true);
    }
    

    相关文章

      网友评论

          本文标题:Java日志技术(上)

          本文链接:https://www.haomeiwen.com/subject/jjncgltx.html