java日志框架

日志的作用

  1. 方便定位排查系统存在的问题
  2. 了解当前系统运行状态
  3. 了解系统历史运行结果
  4. 根据消耗时间,优化系统性能
  5. 通过日志分析,了解系统的安全隐患

常用的java日志框架

  • Log4j
  • JUL
  • JCL((Java Common Logging)
  • Simplelog
  • SLF4J(Simple Logging Facade for Java)
  • logback
  • Log4j2

日志 level

共有 8 个级别,按照从低到高为:All < Trace < Debug < Info < Warn < Error < Fatal < OFF。

All:最低等级的,用于打开所有日志记录
Trace:是追踪,就是程序推进以下,就可以写个 trace 输出,因此 trace 应该会特别多,不过没关系,我们可以设置最低日志级别不让它输出
Debug:指出细粒度信息事件对调试应用程序是非常有帮助的
info:消息在粗粒度级别上突出强调应用程序的运行过程Warn:输出警告及 Warn 以下级别的日志
Error:输出错误信息日志
Fatal:输出每个严重的错误事件将会导致应用程序的退出的日志
OFF:最高等级的,用于关闭所有日志记录

Log4j的用法

  1. 引入jar包
    举例:maven项目
    <dependency>
       <groupId>log4j</groupId>
       <artifactId>log4j</artifactId>
       <version>1.2.17</version>
   </dependency>
  1. 配置log4j.properties
    配置根:
#配置根 Logger
#指定日志文件输出级别:输出 info 级别以上的日志,文件分别输出,一个是 file,一个是 error,一个是A1(A1代替控制台)
log4j.rootLogger=info,file,error,A1

通过配置配置文件的Appender可以指定日志输出到什么地方,常用的输出地有控制台,文件,数据库,远程服务器等。

配置file输出:

#定义名为 file 的输出端是每天产生一个日志文件
log4j.appender.file=org.apache.log4j.DailyRollingFileAppender
#指定日志信息的最低输出级别位 INFO,默认为 DEBUG
log4j.appender.file.Threshold=INFO
#指定当前消息输出到 jpm/log4j/log.log 文件中
log4j.appender.file.File=/log4j/log.log
#指定按天来滚动日志文件
log4j.appender.file.DatePattern=yyyy-MM-dd
#配置日志信息的格式(布局)Layout 是可以灵活地指定布局模式
log4j.appender.file.layout=org.apache.log4j.PatternLayout
#格式化日志,Log4j 采用类似 C 语言中的 printf 函数的打印格式格式化日志信息
log4j.appender.file.layout.ConversionPattern=[%d{yyyy-MM-ddHH:mm:ss}][%-5p][logStudy-%c{1}-%M(%L)]-%m%n
#指定输出信息的编码
log4j.appender.file.encoding=UTF-8

注:文件地址可使用相对路径、参数化

配置控制台输出:

#指定输出级别:本记录器为DEBUG级别
log4j.category.com.log4j.test=DEBUG
#控制台输出
log4j.appender.A1=org.apache.log4j.ConsoleAppender
#DEBUG以上级别是输出
log4j.appender.A1.Threshold=DEBUG
#编码方式
log4j.appender.A1.Encoding=UTF-8
#是否立即输出
log4j.appender.A1.ImmediateFlush=true
#使用System.err输出
log4j.appender.A1.Target=System.err
#输出格式,表达式配置
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%-d{yyyy-MM-d  HH:mm:ss, SSS}[%C]-[%p] %m%n

配置指定file输出:

#自定义输出到指定的日志文件(如saveUserLog)
log4j.logger.saveUserLog=INFO,saveUserLog
#该配置就是让 job 的日志只输出到自己指定的日志文件中,表示 Logger 不会在父 Logger 的 appender 里输出,默认为 true
log4j.additivity.saveUserLog=false
log4j.appender.saveUserLog=org.apache.log4j.DailyRollingFileAppender
log4j.appender.saveUserLog.File=/log4j/saveUserLog.log
log4j.appender.saveUserLog.DatePattern=yyyy-MM-dd
log4j.appender.saveUserLog.Append=true
log4j.appender.saveUserLog.layout=org.apache.log4j.PatternLayout
log4j.appender.saveUserLog.layout.ConversionPattern=[%d{yyyy-MM-ddHH:mm:ss}][%-5p][logStudy-%c{1}-%M(%L)]-%m%n
log4j.appender.error.encoding=UTF-8
  1. 日志用法
    举例:
import org.apache.log4j.Logger;

public class Log4jTest {
   public static void  main(String[] args){
       final Logger LOGGER = Logger.getLogger(Log4jTest.class);
       final Logger SAVEUSERLOG = Logger.getLogger("saveUserLog");

       if(LOGGER.isDebugEnabled()){
           LOGGER.info("debug");   //配置文件等级设置为all、debug时才打印
       }

       LOGGER.info("info");    //配置文件等级为all,info,debug时输出
       LOGGER.warn("warn");    //配置文件等级为all,info,warn时输出
       LOGGER.error("error");  //如在配置文件配置了error文件,则会在error文件输出,配置文件等级为all,info,warn,error时输出

       SAVEUSERLOG.info("my name is menfang.");    //仅输出在自定义的saveUserLog输出文件中
   }
}

logback的用法

  1. 引入jar包
    需要依赖三个 jar 包,分别是 slf4j-api、logback-core、logback-classic,其中 slf4j-api 并不是 Logback 的一部分,建议将 SLF4J 与 Logback 结合使用。
    举例:maven项目
   <dependency>
       <groupId>org.slf4j</groupId>
       <artifactId>slf4j-api</artifactId>
       <version>1.7.25</version>
   </dependency>

   <dependency>
       <groupId>ch.qos.logback</groupId>
       <artifactId>logback-core</artifactId>
       <version>1.2.3</version>
   </dependency>

   <dependency>
       <groupId>ch.qos.logback</groupId>
       <artifactId>logback-classic</artifactId>
       <version>1.2.3</version>
   </dependency>

   <dependency>
       <groupId>ch.qos.logback</groupId>
       <artifactId>logback-access</artifactId>
       <version>1.2.3</version>
   </dependency>
  1. 配置logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->
<!-- status 用来指定打印日志的级别 -->
<!--monitorInterval自动检测修改配置文件和重新配置本身,设置间隔秒数 -->
<configuration status="DEBUG" monitorInterval="30">
   <!-- 定义日志的根目录 -->
   <property name="LOG_HOME" value="/logs/logback" />
   <!-- 定义日志文件名称 -->
   <property name="appName" value="logTest"></property>

   <!-- 配置控制台输出 -->
   <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
       <!-- encoders are assigned the type
            ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
       <encoder>
           <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
       </encoder>
   </appender>

   <!-- 配置输出文件 -->
   <appender name="FILE" class="ch.qos.logback.core.FileAppender">
       <file>${LOG_HOME}/log.log</file> //文件目录
       <encoder>
           <pattern>%date %level [%thread] %logger{10} [%file:%line] %msg%n</pattern>
       </encoder>
   </appender>

   <!-- 滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件 -->
   <appender name="appLogAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
       <!-- 指定日志文件的名称 -->
       <file>${LOG_HOME}/${appName}.log</file>
       <!--
       当发生滚动时,决定 RollingFileAppender 的行为,涉及文件移动和重命名
       TimeBasedRollingPolicy: 最常用的滚动策略,它根据时间来制定滚动策略,既负责滚动也负责出发滚动。
       -->
       <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
           <!--
           滚动时产生的文件的存放位置及文件名称 %d{yyyy-MM-dd}:按天进行日志滚动
           %i:当文件大小超过maxFileSize时,按照i进行文件滚动
           -->
           <fileNamePattern>${LOG_HOME}/${appName}-%d{yyyy-MM-dd}-%i.log</fileNamePattern>
           <!--
           可选节点,控制保留的归档文件的最大数量,超出数量就删除旧文件。假设设置每天滚动,
           且maxHistory是365,则只保存最近365天的文件,删除之前的旧文件。注意,删除旧文件是,
           那些为了归档而创建的目录也会被删除。
           -->
           <MaxHistory>365</MaxHistory>
           <!--
           当日志文件超过maxFileSize指定的大小是,根据上面提到的%i进行日志文件滚动 注意此处配置SizeBasedTriggeringPolicy是无法实现按文件大小进行滚动的,必须配置timeBasedFileNamingAndTriggeringPolicy
           -->
           <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
               <maxFileSize>100MB</maxFileSize>
           </timeBasedFileNamingAndTriggeringPolicy>
       </rollingPolicy>
       <!--
       日志输出格式:%d表示日期时间,%thread表示线程名,%-5level:级别从左显示5个字符宽度 %logger{50} 表示logger名字最长50个字符,否则按照句点分割。 %msg:日志消息,%n是换行符
       -->
       <layout class="ch.qos.logback.classic.PatternLayout">
           <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [ %thread ] - [ %-5level ] [ %logger{50} : %line ] - %msg%n</pattern>
       </layout>
   </appender>

   <!--
   logger主要用于存放日志对象,也可以定义日志类型、级别
   name:表示匹配的logger类型前缀,也就是包的前半部分
   level:要记录的日志级别,包括 TRACE < DEBUG < INFO < WARN < ERROR
   additivity:作用在于children-logger是否使用 rootLogger配置的appender进行输出,false:表示只用当前logger的appender-ref,true:表示当前logger的appender-ref和rootLogger的appender-ref都有效
   -->
   <!-- hibernate logger -->
   <logger name="org.hibernate" level="error" />
   <!-- Spring framework logger -->
   <logger name="org.springframework" level="error" additivity="false"></logger>

   <!--
   root与logger是父子关系,没有特别定义则默认为root,任何一个类只会和一个logger对应,
   要么是定义的logger,要么是root,判断的关键在于找到这个logger,然后判断这个logger的appender和level。
   -->
   <root level="debug">
       <appender-ref ref="appLogAppender" />
   </root>

   <!-- show parameters for hibernate sql 专为 Hibernate 定制 -->
   <logger name="org.hibernate.type.descriptor.sql.BasicBinder" level="TRACE" />
   <logger name="org.hibernate.type.descriptor.sql.BasicExtractor" level="DEBUG" />
   <logger name="org.hibernate.SQL" level="DEBUG" />
   <logger name="org.hibernate.engine.QueryParameters" level="DEBUG" />
   <logger name="org.hibernate.engine.query.HQLQueryPlan" level="DEBUG" />

   <!--日志异步到数据库 -->
   <appender name="DB" class="ch.qos.logback.classic.db.DBAppender">
       <!--日志异步到数据库 -->
       <connectionSource class="ch.qos.logback.core.db.DriverManagerConnectionSource">
           <!--连接池 -->
           <dataSource class="com.mchange.v2.c3p0.ComboPooledDataSource">
               <driverClass>com.mysql.jdbc.Driver</driverClass>
               <url>jdbc:mysql://127.0.0.1:3306/databaseName</url>
               <user>root</user>
               <password>root</password>
           </dataSource>
       </connectionSource>
   </appender>
</configuration>

:logback.xml文件在target里才代表生效了,否则请检查所在位置的正确性。

  1. 日志用法
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class LogbackTest {
   public static void main(String[] args) {
       final Logger LOGGER = LoggerFactory.getLogger(LogbackTest.class);

       LOGGER.info("This is info log.");
       LOGGER.warn("This is warn log.");
       LOGGER.error("This is error log.");
       LOGGER.debug("This is debug log.");
   }
}

log4j2的用法

  1. 引入jar包
    举例:maven项目
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-api</artifactId>
        <version>2.8.2</version>
    </dependency>

    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-core</artifactId>
        <version>2.8.2</version>
    </dependency>
  1. log4j2.xml配置
<?xml version="1.0" encoding="UTF-8"?>
<!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->
<!-- status 用来指定 Log4j 本身的打印日志的级别 -->
<!--monitorInterval:Log4j 能够自动检测修改配置文件和重新配置本身,设置间隔秒数 -->
<configuration status="WARN" monitorInterval="30">
   <!--先定义所有的 Appender -->
   <appenders>
       <!--这个输出控制台的配置 -->
       <console name="Console" target="SYSTEM_OUT">
           <!--输出日志的格式 -->
           <PatternLayout
                   pattern="[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5level] %l %logger{36} - %msg%n" />
       </console>

       <!--定义输出到指定位置的文件 -->
       <File name="log" fileName="/logs/log4j2/log.log" append="true">
           <PatternLayout
                   pattern="[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5level] %l %logger{36} - %msg%n" />
       </File>

       <!-- 这个会打印出所有的 info 及以下级别的信息,每次大小超过 size,则这 size 大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档 -->
       <RollingFile name="RollingFileInfo" fileName="/logs/log4j2/info.log"
                    filePattern="/logs/log4j2/$${date:yyyy-MM}/info-%d{yyyy-MM-dd}-%i.log">
           <!--控制台只输出 level 及以上级别的信息(onMatch),其他的直接拒绝(onMismatch) -->
           <ThresholdFilter level="info" onMatch="ACCEPT"
                            onMismatch="DENY" />
           <PatternLayout
                   pattern="[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5level] %l %logger{36} - %msg%n" />
           <Policies>
               <TimeBasedTriggeringPolicy />
               <SizeBasedTriggeringPolicy size="100 MB" />
           </Policies>
           <!-- DefaultRolloverStrategy 属性如不设置,则默认为最多同一文件夹下7个文件,这里设置了 30 -->
           <DefaultRolloverStrategy max="30" />
       </RollingFile>

       <RollingFile name="RollingFileError" fileName="/logs/log4j2/error.log"
                    filePattern="/logs/log4j2/$${date:yyyy-MM}/error-%d{yyyy-MM-dd}-%i.log">
           <ThresholdFilter level="error" onMatch="ACCEPT"
                            onMismatch="DENY" />
           <PatternLayout
                   pattern="[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5level] %l %logger{36} - %msg%n" />
           <Policies>
               <TimeBasedTriggeringPolicy />
               <SizeBasedTriggeringPolicy size="100 MB" />
           </Policies>
       </RollingFile>
   </appenders>

   <!--只有定义了 logger 并引入的 Appender,才会生效 -->
   <loggers>
       <!--过滤掉 Spring 和 MyBatis 的一些无用的 DEBUG 信息 -->
       <logger name="org.springframework" level="INFO"></logger>
       <logger name="org.mybatis" level="INFO"></logger>
       <root level="INFO">
           <appender-ref ref="Console" />
           <appender-ref ref="log" />
           <appender-ref ref="RollingFileInfo" />
           <appender-ref ref="RollingFileError" />
       </root>
   </loggers>
</configuration>

注意:将配置文件放在target会输出的地方

  1. 日志用法
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class Log4j2Test {
   public static void main(String[] args) {
       final Logger LOGGER = LogManager.getLogger(LogManager.ROOT_LOGGER_NAME);

       LOGGER.info("I'm info.");
       LOGGER.debug("I'm debug.");
       LOGGER.error("I'm error.");
   }
}

JCL+Log4j用法

用 commons-logging 的 Log 接口,并由 commons-logging 在运行时决定使用哪种日志架构(如 Log4j)。现在,Apache 通用日志工具 commons-logging 和 Log4j 已经成为 Java 日志的标准工具,这个组合是比较常用的一个日志框架组合

  1. 引入jar包
    举例:maven项目
   <dependency>
       <groupId>log4j</groupId>
       <artifactId>log4j</artifactId>
       <version>1.2.17</version>
   </dependency>

   <dependency>
       <groupId>commons-logging</groupId>
       <artifactId>commons-logging</artifactId>
       <version>1.2</version>
   </dependency>
  1. 配置配置文件
    可以选择两种配置文件中的一种:common-logging.properties和log4j.properties
    举例:common-logging.properties
    org.apache.commons.logging.Log=org.apache.commons.logging.impl.Log4JLogger

举例: log4j.properties参见Log4j用法

  1. 日志用法
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class JCLAndLog4jTest {
   public static void main(String[] args) {
       final Log LOGGER = LogFactory.getLog(JCLAndLog4jTest.class);

       LOGGER.info("info1");
       LOGGER.debug("debug2");
       LOGGER.error("error3");
   }
}

SLF+Log4j用法

  1. 引用jarb
    举例:maven项目
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.25</version>
    </dependency>

    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>1.7.25</version>
    </dependency>
  1. 配置配置文件
    举例: log4j.properties参见Log4j用法

  2. 日志用法

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class SLFAndLog4jTest {
   public static void main(String[] args) {
       final Logger LOGGER = LoggerFactory.getLogger(SLFAndLog4jTest.class);
       
       LOGGER.info("info");
       LOGGER.debug("debug");
       LOGGER.error("error");
   }
}

**最后的说明:**选择日志框架优先选用SLF+Log4j
原因:

  1. 独立于任意一个日志API
  2. 使用的是绑定包的方式,简便
  3. 输出日志参数用{},简便且能避免字符串拼接节省性能空间
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值