zoukankan      html  css  js  c++  java
  • slf4j+log4j2模式的日志搭建

    前言:今天打算为大家介绍一下我们我们在项目中必须得有的一个部分——日志!是的,就是那些让我们看着头疼的东西~~~好的日志可以帮助团队成员快速发现并解决问题,用好了可以大幅度提高代码缺陷修复效率!言归正传,今天先来讲讲如何为一个项目建立日志!解决方案:(slf4j+log4j2)
    项目地址:https://github.com/ksuth/wsyq.git

    原理介绍:
    现在行业内有很多关于日志记录的jar包,我选用的slf4j可以通俗的理解为一个日志调用的接口,其本身里面是没有关于日志的具体实现,所以我选用了log4j作为它的具体实现。(这也是目前用得比较多吧~~)当然如果你觉得不好,也可以选用其他具体日志作为其实现。

    环境搭建:1.在你的maven项目中引入如下依赖:(这是我写测试时候的版本,相互之间可兼容,如需使用其他版本请确定其兼容性)

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

                    <dependency>
                        <groupId>org.apache.logging.log4j</groupId>
                        <artifactId>log4j-slf4j-impl</artifactId>
                        <version>2.9.1</version>
                      </dependency>

    2.新增log4j2.xml的配置文件:

    <?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="warn" name="MyApp" packages="">
            <Properties>
            <Property name="baseDir">/logtest</Property>
        </Properties>
      <Appenders>
               <Console name="console" target="SYSTEM_OUT">
                <PatternLayout pattern="%d %p [%c] [%M] [Line:%L] - <%m>%n"/>
            </Console>
        <RollingFile name="RollingFile" fileName="${baseDir}/logs/app.log"
                     filePattern="${baseDir}/logs/app-%d{MM-dd-yyyy}.log.gz">
          <RegexFilter regex=".*password.*" onMatch="ACCEPT" onMismatch="DENY"/>
          <PatternLayout>
            <pattern>%d %p %c{1.} [%t] %m%n</pattern>
          </PatternLayout>
          <TimeBasedTriggeringPolicy />
        </RollingFile>
      </Appenders>
      <Loggers>
              <AsyncLogger name="test.log.shuyuq" level="debug" additivity="false" includeLocation="true">
                <AppenderRef ref="RollingFile"/>
        </AsyncLogger>
        <AsyncRoot level="info">
          <AppenderRef ref="console"/>
        </AsyncRoot>
      </Loggers>
    </Configuration>

    3.包装原生日志:(这个并不是必须的,主要应用于公司对日志有特别的规范,或者业务处理中需要一些特别的记录)项目日志类:

    @Data
    public class CASLogger {
        
        /** LOGINDEVICE */
        private static final String LOGINDEVICE="loginDevice";
        /** slf4j */
        private Logger log;

        /**
         * 调用类名
         * @param name String
         */
        public CASLogger(String name) {
            log = org.slf4j.LoggerFactory.getLogger(name);

        }

        /**
         * 此处用于重写需要用的的log方法
         */


    }

    为项目日志类提供静态的调用方式:

    package util;

    import java.util.HashMap;
    import java.util.Map;

    /**
      * 功能描述: 日志添加
    * @author  shuyuq
    * @date 2018-8-17
    **************************************************/

    public class LoggerFactory {

            private static Object initLock = new Object();
            private static Map<String, CASLogger> loggerMap = new HashMap<String, CASLogger>();


            /**
             * 功能描述: 获取Logger
             * @param name String
             * @return CASLogger CASLogger
             * Date: 2018-8-17
             */
            public static CASLogger getLogger(String name) {
                    CASLogger casLogger = null;
                    synchronized(initLock) {
                            casLogger = loggerMap.get(name);
                            if (casLogger == null) {
                                    casLogger = new CASLogger(name);
                                    loggerMap.put(name, casLogger);
                            }
                    }
                    return casLogger;
            }
            
            /**
         * 功能描述: 获取Logger
         * @param clazz String
         * @return CASLogger CASLogger
         * Date: 2018-8-17
         */
        public static CASLogger getLogger(Class<?> clazz) {
            String name=clazz.getName();
            CASLogger casLogger = null;
            synchronized(initLock) {
                casLogger = loggerMap.get(name);
                if (casLogger == null) {
                    casLogger = new CASLogger(name);
                    loggerMap.put(name, casLogger);
                }
            }
            return casLogger;
        }
    }


    做到这儿整个项目的简单日志文件就已经搭建好啦~下面着重为大家介绍一下log4j2的配置文件!这也是实现其日志个性化的核心!

    配置说明:
    1.配置文件加载的优先级:
    classpath下名为 log4j-test.json 或者log4j-test.jsn文件
    classpath下名为 log4j2-test.xml
    classpath下名为 log4j.json 或者log4j.jsn文件
    classpath下名为 log4j2.xml文件


    2.简单参数介绍:
    先为大家贴上log4j的官方文档地址:https://logging.apache.org/log4j/2.x/
    如果需要实现一些特别的个性化功能可参考官方文档
    我在这儿为大家介绍一些比较常用的参数:
    Properties:这个参数主要用于为配置文件定义一些常用量,可参考上面的配置中我为其定义了一个文件写的路径
    Appenders:用于包裹Appender标签,每一个Appender为一个OutputStream
    Loggers:用于包裹Logger标签,Logger标签用于筛选路径(类比于spring的扫描路径)和指定需要使用的Appender

    3.RollingFileAppender

    在正式介绍这个之前先介绍一个概念:rollover (表示当日志满足指定条件的时候就生成一个新的文件的过程)
    RollingFileAppender是一个OutputStreamAppender,它写入fileName参数中指定的File,并根据TriggeringPolicy和RolloverPolicy滚动文件。RollingFileAppender使用RollingFileManager(扩展OutputStreamManager)来实际执行文件I / O并执行翻转。虽然无法共享来自不同配置的RolloverFileAppenders,但如果可以访问Manager,则可以使用RollingFileManagers。例如,如果Log4j位于两个共用的ClassLoader中,则servlet容器中的两个Web应用程序可以拥有自己的配置并安全地写入同一文件。
    RollingFileAppender需要TriggeringPolicy和 RolloverStrategy。触发策略确定是否应在RolloverStrategy定义如何进行翻转时执行翻转。如果未配置RolloverStrategy,则RollingFileAppender将使用DefaultRolloverStrategy。从log4j-2.5开始,可以在DefaultRolloverStrategy中配置自定义删除操作以在翻转时运行。从2.8开始,如果没有配置文件名, 则将使用DirectWriteRolloverStrategy而不是DefaultRolloverStrategy。从log4j-2.9开始,自定义POSIX文件属性查看动作 可以在DefaultRolloverStrategy中配置以在rollover中运行,如果未定义,将应用RollingFileAppender继承的POSIX文件属性视图。
    RollingFileAppender不支持文件锁定。
    关于参数的问题~~~(在官网中找到Appenders搜索RollingFileAppender可以找到对应内容
    更多参数请访问:http://logging.apache.org/log4j/2.x/manual/appenders.html#RollingFileAppender)
     参数名称  类型  说明
     append  boolean  默认为true,记录追加到文件的最后,否则就先清除以前的记录再写入
     bufferedIO  boolean  如果为true - 默认情况下,记录将写入缓冲区,当缓冲区已满时,数据将写入磁盘;如果设置了immediateFlush,则写入记录时。文件锁定不能与bufferedIO一起使用。性能测试表明,即使启用了immediateFlush,使用缓冲I / O也可以显着提高性能。
     bufferSize  int  当bufferedIO为true时,这是缓冲区大小,默认为8192字节。
     createOnDemand  boolean  appender按需创建文件。appender仅在日志事件通过所有过滤器并将其路由到此appender时创建该文件。默认为false.
     filter  Filter  过滤器,用于确定此Appender是否应该处理该事件。使用CompositeFilter可以使用多个Filter
     fileName  String  要写入的文件的名称。如果文件或其任何父目录不存在,则将创建它们。
     filePattern  String  归档日志文件的文件名模式。模式的格式取决于使用的RolloverPolicy。DefaultRolloverPolicy将同时接受与SimpleDateFormat兼容的日期/时间模式 和/或表示整数计数器的%i。该模式还支持在运行时进行插值,因此任何查找(例如DateLookup)都可以包含在模式中
     immediateFlush  boolean  设置为true时 - 默认值,每次写入后都会进行刷新。这将保证数据写入磁盘,但可能会影响性能。

    每次写入后刷新仅在将此appender与同步记录器一起使用时才有用。即使immediateFlush设置为false,异步记录器和追加器也会在一批事件结束时自动刷新。这也保证了数据被写入磁盘但效率更高

     layout  Layout 用于格式化LogEvent的布局。如果未提供布局,则将使用“%m%n”的默认图案布局。
     name  String  Appender的名字
     policy  TriggeringPolicy  用于确定是否应发生翻转的策略
     strategy  RolloverStrategy  用于确定存档文件的名称和位置的策略
     参数名称  类型  说明
     ignoreExceptions  boolean  默认值为true,导致在将事件附加到内部记录然后被忽略时遇到异常。设置为false时,异常将传播给调用者。将此Appender包装在FailoverAppender中时, 必须将此参数设置为false。
     filePermissions  String POSIX格式的文件属性权限,以便在创建文件时应用      
     fileOwner  String  文件所有者在每次创建文件时定义,出于安全原因,可能会限制更改文件的所有者,并且不允许操作IOException。如果_POSIX_CHOWN_RESTRICTED对路径有效,则只有具有等效于文件用户ID或具有适当权限的有效用户ID的进程才能更改文件的所有权。
     fileGroup  String

     文件组,用于定义创建文件的时间

  • 相关阅读:
    Eclipse正确导入第三方project
    面试的基础_01字符串反向操作
    一个简单的实现了智能虚拟女友—图灵机器人
    Notepad++去除代码行号的几种方法
    fastjson将bean转成字符串时首字母变小写问题
    2015第34周二能收发邮件但不能打开网页解决方法
    2015第34周一
    2015第33周日
    2015第33周六
    构建自己的顾问团
  • 原文地址:https://www.cnblogs.com/shuyuq/p/9627800.html
Copyright © 2011-2022 走看看