zoukankan      html  css  js  c++  java
  • Web基础之日志

    Web基础之日志

      日志在企业开发中有着不可或缺的作用,它可以用以记录用户操作、系统运行状态和错误信息。日志记录的好坏直接关系到系统出现问题时定位的速度。
      最开始的日志一般使用log4j,后来sun公司心有不甘,在jdk 1.4中加入了一个叫java.util.logging的日志包,简称jul。两种日志的api肯定是不同的,此时日志就出现了混乱。log4j的作者Ceki Gülcü就写了一个叫Jakarta Commons Logging的接口,简称jcl,来共同管理log4j和jul,并且jcl中提供了一个日志实现simplelog。接着又改良了下log4j,写出了logback。再后来Ceki Gülcü觉得jcl不好用(的确用问题),然后写了一个新的接口slf4j,来共同管理这些日志系统。接着呢Ceki Gülcü又觉得logj4性能不够了,又写了一个log4j2,。真是专注日志100年啊。

      所以他们之间的关系是这样的:

    logs

      其中slf4j并不提供日志实现,而是使用外观模式创建了一个接口,来统一这些日志的api。

      这也是为什么阿里规范上强制使用slf4j的原因:

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

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

    slf4j + log4j / log4j2

      认识了之后接下来就是使用了,首先在maven中导入依赖:

    <!-- log4j依赖,好像不更新了,我看版本还是12年的 -->
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.17</version>
    </dependency>
    <!-- slf4j的依赖 -->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.28</version>
    </dependency>
    <!-- 告诉slf4j使用log4j,也就是绑定 -->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>1.7.28</version>
        <scope>test</scope>
    </dependency>
    

      如果使用log4j2的话这么配:

    <!-- log4j2的核心 -->
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-core</artifactId>
        <version>2.12.1</version>
    </dependency>
    <!-- log4j2的api -->
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-api</artifactId>
        <version>2.12.1</version>
    </dependency>
    <!-- slf4j绑定log4j2 -->
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-slf4j-impl</artifactId>
        <version>2.12.1</version>
    </dependency>
    <!-- slf4j的依赖 -->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.28</version>
    </dependency>
    

      这里我将使用log4j2的xml和properties两种方式来简单配置。


      在resources目录下创建log4j2.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="WARN">
        <!-- 输出源的配置:日志输出的目的地 -->
        <Appenders>
            <!--
                Console标签;指定这是一个控制台输出源。
                    name:名称,需要在被引用才会生效
                    target: 控制台字体的颜色
                            SYSTEM_ERR:红色字体
                            SYSTEM_OUT:黑色字体
                    PatternLayout:布局,输出到控制台日志的格式。
            -->
            <Console name="myConsole" target="SYSTEM_ERR">
                <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %5level %logger{36} - %msg%n"/>
            </Console>
    
            <!-- 文件输出源
                fileName:指定保存日志的文件的名字和位置。
                        一般写绝对路径。
            -->
            <File name="myFile" fileName="D://demo.log">
                <PatternLayout>
                    <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
                </PatternLayout>
            </File>
    
            <!--
                多文件输出源:
                    fileName:实时记录日志的文件名和位置
                    filePattern : 文件封存的位置和格式
             -->
            <RollingFile name="rollingFile" fileName="D://demo2.log" filePattern="D://logs/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz">
                <PatternLayout>
                    <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
                </PatternLayout>
                <!-- 多文件拆分的规则 -->
                <Policies>
                    <!-- 基于时间的  此处interval属性值的单位是由filePattern属性中文件名时间精确的单位 决定的。 -->
                    <TimeBasedTriggeringPolicy interval="1" />
                    <!-- 基于文件大小的 -->
                    <SizeBasedTriggeringPolicy size="512 MB"/>
                </Policies>
            </RollingFile>
    
        </Appenders>
        <Loggers>
            <!-- 配置日志输出的级别的
                将当前级别以及比当前级别高的消息进行输出。
            -->
            <Root level="trace">
                <AppenderRef ref="myConsole"/>
                <!-- 可以同时多种方式输出日志 -->
                <AppenderRef ref="MyFile"/>
                <AppenderRef ref="RollingFile"/>
    
            </Root>
        </Loggers>
    </Configuration>
    

      log4j使用properties方式:

    # 配置输出源的   log4j.appender.输出源名=输出源的实现类
    # 属性的配置  log4j.appender.输出源名.属性名=属性值
    log4j.appender.a=org.apache.log4j.ConsoleAppender
    log4j.appender.a.Target=System.out
    log4j.appender.a.layout=org.apache.log4j.PatternLayout
    log4j.appender.a.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss,SSS} [%t] [%c]-[%p] %m%n
    
    log4j.appender.file=org.apache.log4j.FileAppender
    log4j.appender.file.File=D:/mylog.log
    log4j.appender.file.layout=org.apache.log4j.PatternLayout
    log4j.appender.file.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss,SSS} [%t] [%c]-[%p] %m%n
    
    ### log4j.rootLogger=输出级别,输出源1,输出源2....
    log4j.rootLogger=debug,a,file
    

    log4j2的properties(参考):

    status = warn
    name = MyApp
     
    appender.console.type = Console
    appender.console.name = consoleLogDemo
    appender.console.filter.threshold.type = ThresholdFilter
    appender.console.filter.threshold.level = debug
    appender.console.layout.type = PatternLayout
    appender.console.layout.pattern = %m%n
    appender.console.target = System_out
     
    appender.rolling.type = File
    appender.rolling.name = fileLogDemo
    appender.rolling.filter.threshold.type = ThresholdFilter
    appender.rolling.filter.threshold.level = error
    appender.rolling.layout.type = PatternLayout
    appender.rolling.layout.pattern = %d-%m%n
    appender.rolling.append = true
    appender.rolling.fileName = e:\propertiesTest.log
     
    rootLogger.level = debug
    rootLogger.appenderRef.consolelogdemo.ref = consoleLogDemo
    rootLogger.appenderRef.filelogdemo.ref = fileLogDemo
    

    输出格式参数为:

    %p:输出日志信息的优先级,即DEBUG,INFO,WARN,ERROR,FATAL
    %d:输出日志时间点的日期或时间,默认格式为ISO8601,可以指定格式如:%d{yyyy/MM/dd HH:mm:ss,SSS}
    %r:输出自应用程序启动到输出该log信息耗费的毫秒数
    %t:输出产生该日志事件的线程名
    %l:输出日志事件的发生位置,相当于%c.%M(%F:%L)的组合,包括类全名、方法、文件名以及在代码中的行数
    %c:输出日志信息所属的类目,通常就是类全名
    %M:输出产生日志信息的方法名
    %F:输出日志消息产生时所在的文件名
    %L:输出代码中的行号
    %m:输出代码中指定的具体日志信息
    %n:输出一个回车换行符,Windows平台为"rn",Unix平台为"n"
    %x:输出和当前线程相关联的NDC(嵌套诊断环境)
    %%:输出一个"%"字符
    

      这是几种常用的配置,如果觉得不够的话可以查看官方文档

      顺便这里推荐个讲的很详细的博客

    打日志

    在log4j2中可以这么用:

    public class MyApp {
        private static final Logger logger = LoggerFactory.getLogger(MyApp.class);
    
        public static void main(String[] args) {
            logger.warn("Hello, {}","slf4j");
        }
    }
    

    使用{}作为占位符,性能要比log4j直接字符串拼接性能好(毕竟字符串拼接的底层原理是创建StringBuilder)


    至于一大堆jar包的关系如下:

    slf4j
    关于log4j2的如下:

    log4j2

    参考关于slf4j log4j log4j2的jar包配合使用的那些事

  • 相关阅读:
    git命令将本地代码提交到github
    Git打Tag相关操作
    数值格式化,每隔三位加一个逗号
    git常用命令
    webpack4配置
    Vue系列——在vue项目中使用echarts
    利用n 升级工具升级Node.js版本及在mac环境下的坑
    vue中图片返回404时,显示默认的图片
    C# NAudio 录制声音和显示波形图
    C# NAudio 变声
  • 原文地址:https://www.cnblogs.com/lixin-link/p/11405843.html
Copyright © 2011-2022 走看看