java log

作者: 后知不觉1 | 来源:发表于2023-07-20 17:05 被阅读0次

1、java日志使用模式

  • 直接调用java日志实现
  • 门面模式调用日志

当前有众多日志选择,大部分组合是:

  • slf4j + log4j-slf4j-iml + log4j-core (2.x)
  • slf4j + slf4j-log4j2 + log4j (1.x)
  • log4j (1.x)
  • log4j-api + log4j-core
  • log4j-api + log4j-1.2-api + log4j(1.x)
  • slf4j + logback
    也有 JCL + jul组合使用但是比较少
  • common-log + log4j(1.x)
  • common-log + log4j-jcl + log4j-core
  • common-log + sample-log
    log4j说明.png
    大图http://asdu.cn/log4j-info.png

2、直接使用日志实现方式

这种方式有缺点,项目包引用带有日志输出的依赖时会导致日志输出不统一


image.png

2.1、代码实现,以log4j为例

pom.xml

                <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>1.2.17</version>
            </dependency>

log4j2.properties

status = warn

appender.console.type = Console
appender.console.name = LogToConsole
appender.console.layout.type = PatternLayout
appender.console.layout.pattern = [%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n


rootLogger.level = debug
rootLogger.appenderRef.stdout.ref = LogToConsole

java 代码

import org.apache.logging.log4j.Logger;

/**
 * Hello world!
 *
 */
public class App 
{
    private static Logger logger = Logger.getLogger(App.class);
    public static void main( String[] args )
    {
        logger.info("asdasd {}",123);
        logger.error("asdasd {}",123);
    }
}

3、通过接口调用

三个日志接口:commons-logging(JCL)、slf4j、log4j-api
常用日志实现:logging(java util logging),log4j、log4j-core、logback、simplelog

备注:通过接口调用日志可以并且保证项目中只有一个日志实现,如果依赖包中有可以将项目的日志统一输出到指定位置


image.png

4、动态查找路径

4.1、commons-logging动态查找

动态查找原理:Log 是一个接口声明。LogFactory 的内部会去装载具体的日志系统,并获得实现该Log 接口的实现类。LogFactory 内部装载日志系统的流程如下:

  • 首先,寻找org.apache.commons.logging.LogFactory 属性配置。
  • 否则,利用JDK1.3 开始提供的service 发现机制,会扫描classpah 下的META-INF/services/org.apache.commons.logging.LogFactory文件,若找到则装载里面的配置,使用里面的配置。
  • 否则,从Classpath 里寻找commons-logging.properties ,找到则根据里面的配置加载。
  • 否则,使用默认的配置:如果能找到Log4j 则默认使用log4j 实现,如果没有则使用JDK14Logger 实现,再没有则使用commons-logging 内部提供的SimpleLog 实现。

5. commons-logging常用集成demo

5.1、commons-logging与jul集成(simplelog)

pom.xml

<dependency>
  <groupId>commons-logging</groupId>
  <artifactId>commons-logging</artifactId>
  <version>1.2</version>
</dependency> 

commons-logging.properties 告诉commons-logging用哪个日志实现类

org.apache.commons.logging.Log=org.apache.commons.logging.impl.SimpleLog

simplelog.properties 告诉simplelog的日志登记等配置

org.apache.commons.logging.simplelog.defaultlog=TRACE

java代码使用

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


public class App
{

    private  static Log logger1 = LogFactory.getLog(App .class);
    public static void main( String[] args )
    {

        //使用logger输出日志
        logger1.trace("TRACE...");
        logger1.debug("DEBUG ...");
        logger1.info("INFO ...");
        logger1.error("ERROR ...");
        logger1.warn("WARN...");
    }
}
5.2、commons-logging与log4j集成

根据上面的动态查找路径,可以只有一个log4j.properties文件即可。log4j配置文件详解

log4j.properties

log4j.rootLogger=DEBUG,console,dailyFile,im
log4j.additivity.org.apache=true
# 控制台(console)
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.Threshold=DEBUG
log4j.appender.console.ImmediateFlush=true
log4j.appender.console.Target=System.err
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=[%-5p] %d(%r) --> [%t] %l: %m %x %n
# 日志文件(logFile)
log4j.appender.logFile=org.apache.log4j.FileAppender
log4j.appender.logFile.Threshold=DEBUG
log4j.appender.logFile.ImmediateFlush=true
log4j.appender.logFile.Append=true
log4j.appender.logFile.File=D:/logs/log.log4j
log4j.appender.logFile.layout=org.apache.log4j.PatternLayout
log4j.appender.logFile.layout.ConversionPattern=[%-5p] %d(%r) --> [%t] %l: %m %x %n
# 回滚文件(rollingFile)
log4j.appender.rollingFile=org.apache.log4j.RollingFileAppender
log4j.appender.rollingFile.Threshold=DEBUG
log4j.appender.rollingFile.ImmediateFlush=true
log4j.appender.rollingFile.Append=true
log4j.appender.rollingFile.File=D:/logs/log.log4j
log4j.appender.rollingFile.MaxFileSize=200KB
log4j.appender.rollingFile.MaxBackupIndex=50
log4j.appender.rollingFile.layout=org.apache.log4j.PatternLayout
log4j.appender.rollingFile.layout.ConversionPattern=[%-5p] %d(%r) --> [%t] %l: %m %x %n
# 定期回滚日志文件(dailyFile)
log4j.appender.dailyFile=org.apache.log4j.DailyRollingFileAppender
log4j.appender.dailyFile.Threshold=DEBUG
log4j.appender.dailyFile.ImmediateFlush=true
log4j.appender.dailyFile.Append=true
log4j.appender.dailyFile.File=D:/logs/log.log4j
log4j.appender.dailyFile.DatePattern='.'yyyy-MM-dd
log4j.appender.dailyFile.layout=org.apache.log4j.PatternLayout
log4j.appender.dailyFile.layout.ConversionPattern=[%-5p] %d(%r) --> [%t] %l: %m %x %n
# 应用于socket
log4j.appender.socket=org.apache.log4j.RollingFileAppender
log4j.appender.socket.RemoteHost=localhost
log4j.appender.socket.Port=5001
log4j.appender.socket.LocationInfo=true
# Set up for Log Factor 5
log4j.appender.socket.layout=org.apache.log4j.PatternLayout
log4j.appender.socket.layout.ConversionPattern=[%-5p] %d(%r) --> [%t] %l: %m %x %n
# Log Factor 5 Appender
log4j.appender.LF5_APPENDER=org.apache.log4j.lf5.LF5Appender
log4j.appender.LF5_APPENDER.MaxNumberOfRecords=2000
# 发送日志到指定邮件
log4j.appender.mail=org.apache.log4j.net.SMTPAppender
log4j.appender.mail.Threshold=FATAL
log4j.appender.mail.BufferSize=10
log4j.appender.mail.From = xxx@mail.com
log4j.appender.mail.SMTPHost=mail.com
log4j.appender.mail.Subject=Log4J Message
log4j.appender.mail.To= xxx@mail.com
log4j.appender.mail.layout=org.apache.log4j.PatternLayout
log4j.appender.mail.layout.ConversionPattern=[%-5p] %d(%r) --> [%t] %l: %m %x %n
# 应用于数据库
log4j.appender.database=org.apache.log4j.jdbc.JDBCAppender
log4j.appender.database.URL=jdbc:mysql://localhost:3306/test
log4j.appender.database.driver=com.mysql.jdbc.Driver
log4j.appender.database.user=root
log4j.appender.database.password=
log4j.appender.database.sql=INSERT INTO LOG4J (Message) VALUES('=[%-5p] %d(%r) --> [%t] %l: %m %x %n')
log4j.appender.database.layout=org.apache.log4j.PatternLayout
log4j.appender.database.layout.ConversionPattern=[%-5p] %d(%r) --> [%t] %l: %m %x %n

# 自定义Appender
log4j.appender.im = net.cybercorlin.util.logger.appender.IMAppender
log4j.appender.im.host = mail.cybercorlin.net
log4j.appender.im.username = username
log4j.appender.im.password = password
log4j.appender.im.recipient = corlin@cybercorlin.net
log4j.appender.im.layout=org.apache.log4j.PatternLayout
log4j.appender.im.layout.ConversionPattern=[%-5p] %d(%r) --> [%t] %l: %m %x %n

java代码使用

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


public class App
{

    private  static Log logger1 = LogFactory.getLog(App .class);
    public static void main( String[] args )
    {

        //使用logger输出日志
        logger1.trace("TRACE...");
        logger1.debug("DEBUG ...");
        logger1.info("INFO ...");
        logger1.error("ERROR ...");
        logger1.warn("WARN...");
    }
}
5.3、commons-logging与log4j2集成

pom.xml

<dependency>
  <groupId>org.apache.logging.log4j</groupId>
  <artifactId>log4j-jcl</artifactId>
  <version>2.17.2</version>
</dependency>

<dependency>
  <groupId>org.apache.logging.log4j</groupId>
  <artifactId>log4j-core</artifactId>
  <version>2.17.2</version>
</dependency>

<dependency>
  <groupId>commons-logging</groupId>
  <artifactId>commons-logging</artifactId>
  <version>1.2</version>
</dependency>

log4j2.properties

appender.console.type = Console
appender.console.name = LogToConsole
appender.console.layout.type = PatternLayout
appender.console.layout.pattern = [%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n


rootLogger.level = debug
rootLogger.appenderRef.stdout.ref = LogToConsole
5.4、log4j-api+ log4j-core

log4j2.xml

<?xml version="1.0" encoding="UTF-8"?>
<!--status:Log4j2内部日志的输出级别,设置为TRACE对学习Log4j2非常有用 -->
<!--monitorInterval:定时检测配置文件的修改,有变化则自动重新加载配置,时间单位为秒,最小间隔为5s -->
<Configuration status="WARN" monitorInterval="600">
    <!--properties:设置全局变量 -->
    <properties>
        <!--LOG_HOME:指定当前日志存放的目录 -->
        <property name="LOG_HOME">/app/logs</property>
        <!--FILE_NAME:指定日志文件的名称 -->
        <property name="FILE_NAME">log4j2_info</property>
    </properties>
    <!--Appenders:定义日志输出目的地,内容和格式等 -->
    <Appenders>
        <!--Console:日志输出到控制台标准输出 -->
        <Console name="Console" target="SYSTEM_OUT">
            <!--
                %d表示日期,
                %-5level 表示日志级别,另外在显示时占5个字符,不足的地方用空格补齐,
                %t 表示线程名
                %c{1.} 表示显示调用者的时候,只显示包名最后一截及方法名,前面的几段只取首字母
                比如:调用logger.info的方法是com.kittycoder.Log4j2Test.test,只显示成c.k.Log4j2Test.test
                %L 表示调用者所在代码的行号
                %msg 表示需要打印的日志信息
                %n 表示系统换行符
             -->
            <!--pattern:日期,日志级别,线程名,调用者,行号,日志信息,换行 -->
            <!--<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%t] %c{1.} [%L] : %msg%n"/>-->

            <!--日志高亮  需要设置IDEA中,点击右上角->Edit Configurations,在VM options中添加  -Dlog4j.skipJansi=false-->
            <PatternLayout charset="UTF-8"
                           pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight{%-5level}{ERROR=Bright RED, WARN=Bright Yellow, INFO=Bright Green,
                     DEBUG=Bright Cyan, TRACE=Bright White} %style{[%t]}{bright,magenta} %style{%c{1.}.%M(%L)}{cyan} : %msg%n"/>
        </Console>
        <!--RollingFile:日志输出到文件,下面的文件都使用相对路径 -->
        <!--fileName:当前日志输出的文件名称 -->
        <!--filePattern:备份日志文件名称,备份目录为logs下面以年月命名的目录,备份时使用gz格式压缩 -->
        <RollingFile name="RollingFile" fileName="${LOG_HOME}/${FILE_NAME}.log"
                     filePattern="${LOG_HOME}/${FILE_NAME}-%d{yyyy-MM-dd-HH-mm}-%i.log.gz">
            <!--pattern:日期,日志级别,线程名,调用者,行号,日志信息,换行 -->
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%t] %c{1.} [%L] : %msg%n"/>
            <!--Policies:触发策略决定何时执行备份 -->
            <Policies>
                <!--TimeBasedTriggeringPolicy:日志文件按照时间备份 -->
                <!--interval:每1天生成一个新文件,时间单位需要结合filePattern时间%d{yyyy-MM-dd} -->
                <!--同理,如果要每1小时生成一个新文件,则改成%d{yyyy-MM-ddHH} -->
                <!--modulate:对备份日志的生成时间纠偏,纠偏以0为基准进行,"0+interval"决定启动后第一次备份时间 -->
                <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
                <!--SizeBasedTriggeringPolicy:日志文件按照大小备份 -->
                <!--size:指定日志文件最大为100MB,单位可以为KB、MB或GB -->
                <SizeBasedTriggeringPolicy size="200MB"/>
            </Policies>
            <!--DefaultRolloverStrategy:翻转策略决定如何执行备份 -->
            <!--max:最多保存5个备份文件,结合时间使用后,在每个时间段内最多有5个备份,多出来的会被覆盖 -->
            <!--compressionLevel:配置日志压缩级别,范围0-9,0不压缩,1压缩速度最快,9压缩率最好,目前只对于zip压缩文件类型有效 -->
            <DefaultRolloverStrategy max="5" compressionLevel="1">
                <!--Delete:删除匹配到的过期备份文件 -->
                <!--maxDepth:由于备份文件保存在${LOG_HOME}/$${date:yyyy-MM},所以目录深度设置为2 -->
                <Delete basePath="${LOG_HOME}" maxDepth="1">
                    <!--IfFileName:匹配文件名称 -->
                    <!--glob:匹配2级目录深度下的以.log.gz结尾的备份文件 -->
                    <IfFileName glob="*/*.log.gz"/>
                    <!--IfLastModified:匹配文件修改时间 -->
                    <!--age:匹配超过180天的文件,单位D、H、M、S分别表示天、小时、分钟、秒-->
                    <IfLastModified age="7D"/>
                </Delete>
            </DefaultRolloverStrategy>
        </RollingFile>
    </Appenders>
    <!--Loggers:定义日志级别和使用的Appenders -->
    <Loggers>
        <!--name: 打印日志的类的包路径 -->
        <!--additivity: true当前的Logger打印的日志附加到Root,false仅仅打印到RollingFile -->
        <Logger name="org.apache.logging.log4j" level="ERROR" additivity="true">
            <AppenderRef ref="RollingFile"/>
        </Logger>
        <!--Root:日志默认打印到控制台 -->
        <!--level日志级别: ALL < TRACE < DEBUG < INFO < WARN < ERROR < FATAL < OFF -->
        <Root level="INFO">
            <!--输出到控制台-->
            <AppenderRef ref="Console"/>
            <!--输出到文件-->
            <AppenderRef ref="RollingFile"/>
        </Root>
    </Loggers>
</Configuration>

pom.xml

    <dependency>
                <groupId>org.apache.logging.log4j</groupId>
                <artifactId>log4j-api</artifactId>
                <version>2.17.2</version>
            </dependency>
    <dependency>
                <groupId>org.apache.logging.log4j</groupId>
                <artifactId>log4j-core</artifactId>
                <version>2.17.2</version>
            </dependency>

java

import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;


public class App
{
    private static Logger logger = LogManager.getLogger(App.class);
    public static void main( String[] args ) throws InterruptedException {
        logger.info("asd");
        logger.info("111111111111111");
        int i =0;
        while(i < 20){
            Thread.sleep(2);
            long a = System.currentTimeMillis();
            logger.info("asd");
            logger.info(String.valueOf(a));
            logger.error(String.valueOf(a));
            i++;
        }
    }
}
5.4、slf4j + logback

pom

   <dependency>
          <groupId>ch.qos.logback</groupId>
          <artifactId>logback-classic</artifactId>
          <version>1.2.3</version>
   </dependency>
   <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.25</version>
    </dependency>

logback.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">

    <property name="log.path" value="/app/logs"/>
    <property name="log_info_file" value="info"/>
    <contextName>logback</contextName>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern>
            <charset>UTF-8</charset>
        </encoder>
    </appender>
    <appender name="INFO_ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}[%L] - %msg%n</pattern>
            <charset>UTF-8</charset>
        </encoder>
        <file>${log.path}/${log_info_file}.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 每分钟生成一个滚动文件 , 生产环境请调成天-->
            <fileNamePattern>${log.path}/${log_info_file}-%d{yyyy-MM-dd-HH-mm}.%i.log</fileNamePattern>
            <!-- 每分钟生成一个滚动文件 , 生产环境请调成天-->
            <!-- <fileNamePattern>${log.path}/${log_info_file}-%d{yyyy-MM-dd}.%i.log</fileNamePattern>-->

            <!-- 限制日志总文件大小 不能写G -->
            <totalSizeCap>2048mb</totalSizeCap>
            <!-- 请修改保留个数,这个个数是跟时间相关,如果是天 就是保留7天,如果是分钟就是保留7分钟-->
            <maxHistory>7</maxHistory>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <!-- 限制单个日志文件大小 -->
                <maxFileSize>1mb</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
        <append>true</append>
    </appender>
    <root level="INFO">
<!--        <appender-ref ref="STDOUT"/>-->
        <appender-ref ref="INFO_ROLLING"/>
    </root>
</configuration>

java

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



public class App
{
    private static Logger logger = LoggerFactory.getLogger(App.class);
    public static void main( String[] args ) throws InterruptedException {
        logger.info("asd");
        logger.info("111111111111111");
        int i =0;
        while(i < 20){
            Thread.sleep(2);
            long a = System.currentTimeMillis();
            logger.info("asd");
            logger.info(String.valueOf(a));
            logger.error(String.valueOf(a));
            i++;
        }
    }
}
5.5、slf4j + log4j(1.x)

pom.xml

<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.7.25</version>
</dependency>

log4j.properties

log4j.rootLogger = debug,stdout,file


log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern =  %d{ABSOLUTE} %5p %c{1}:%L - %m%n


log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.Threshold=INFO
log4j.appender.file.File=/app/logs/log4j_test_info.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} [%5p] - %c -%F(%L) -%m%n
log4j.appender.file.MaxFileSize=1MB
log4j.appender.file.MaxBackupIndex=5

java

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



public class App
{
    private static Logger logger = LoggerFactory.getLogger(App.class);
    public static void main( String[] args ) throws InterruptedException {
        logger.info("asd");
        logger.info("111111111111111");
        int i =0;
        while(i < 20){
            Thread.sleep(2);
            long a = System.currentTimeMillis();
            logger.info("asd");
            logger.info(String.valueOf(a));
            logger.error(String.valueOf(a));
            i++;
        }
    }
}
5.6、 slf4j + log4j-slf4j-iml + log4j-core

pom.xml

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.25</version>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-slf4j-impl</artifactId>
    <version>2.17.2</version>
</dependency>
<!-- log4j2 日志实面 -->
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.17.2</version>
</dependency>

log4j2.xml 同上

java 同上

相关文章

网友评论

      本文标题:java log

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