美文网首页
logback设置开发环境日志级别

logback设置开发环境日志级别

作者: 多关心老人 | 来源:发表于2018-11-24 00:02 被阅读0次

    生产环境日志级别一般都是warn和error,但在开发环境中,warn级别太高了,我们可能需要debug级别来观察日志输出。这时就会改动logback.xml,然后有的小伙伴一不小心就提交到代码库了,和其他小伙伴冲突甚至上线了。
    上面说的是多环境公用同一个logback.xml的问题,当然可以用多个profile来区分开发和生产环境。如果一个模块很多人开发的话,不同的人关注不同的日志,如我关心sql日志,其他人可能关心spring日志或者业务日志、监控日志,这样还是要改本地的logback.xml。

    其实还可以通过另一种方式不改变logback.xml来实现不同开发人员对应不同的日志输出,即先读取本地配置的日志级别,读取不到就用原来的级别,本地配置的级别可以在系统环境变量中设置。logback是支持这种方式的,语法${你的环境变量:-默认值},如

    <logger name="jdbc.sqltiming" level="${logback.sql.level:-warn}" additivity="false">
            <appender-ref ref="stdout"/>
        </logger>
    

    线上配置的是warn级别,如果本地配置了logback.sql.level=debug,那么日志级别就是debug,否则就是原来的值warn。注意warn前面是:-
    配置参考:https://www.cloudesire.com/configure-logback-log-level-via-environment-variables/


    源码解析:
    在创建jdbc.sqltiming这个Logger的时候,读取level属性,在OptionHelper类中

      /**
       * See  http://logback.qos.ch/manual/configuration.html#variableSubstitution
       */
      public static String substVars(String input, PropertyContainer pc0, PropertyContainer pc1) {
        try {
          return NodeToStringTransformer.substituteVariable(input, pc0, pc1);
        } catch (ScanException e) {
          throw new IllegalArgumentException("Failed to parse input [" + input + "]", e);
        }
      }
    

    先对input语法解析成Tokenizer,${logback.sql.level:-warn}会被解析成2部分:变量logback.sql.level和默认值warn,在NodeToStringTransformer类中:

    private String lookupKey(String key) {
        String value = propertyContainer0.getProperty(key);
        if (value != null)
          return value;
    
        if (propertyContainer1 != null) {
          value = propertyContainer1.getProperty(key);
          if (value != null)
            return value;
        }
    
        value = OptionHelper.getSystemProperty(key, null);
        if (value != null)
          return value;
    
        value = OptionHelper.getEnv(key);
        if (value != null) {
          return value;
        }
    
        return null;
      }
    

    会优先在logback.xml中进行变量查找,然后在SystemProperty中查找,最后到系统环境变量中查找。
    看完代码就明白了吧,对于propertyContainer0和propertyContainer1有什么区别不太了解,Property和Env的区别见https://www.jianshu.com/p/ac99ce832d6b


    logback其他知识点

    • logger层级关系,像包名目录关系一样,上级包是下级包的父类,如com.java.lang的上级是com.java,再网上是com,再往上是root。
    • 如果当前类没有定义logger,通过Logger.get(Class)也能得到logger对象,日志等级(effectiveLevel)是自己的或者最近的上级的。
    • 每个logger都可以定义自己的appender,同时也会找上级的appender,会往自己的+所有上级的appender里写日志(即使日志等级小于上级的effectiveLevel也会写),设置additivity=false可以设置不找上级的。因此设置了additivity=false就必须要设置自己的appender。 additivity只是找appender时有用,找到了就可以写,不用管上级的level。
    • 如果你要写的日志等级低于logger对象的effectiveLevel,则不输出日志,即使你写的日志等级可能高于root logger等级也不写。
    • com和com.xxx都没设置appender,那么他们都没有appedner,都会找到root的appender,appender不累加,即com.xxx找到的也只有root appender,其上级com是没有appender的。
      public static final int OFF_INT = Integer.MAX_VALUE;
      public static final int ERROR_INT = 40000;
      public static final int WARN_INT = 30000;
      public static final int INFO_INT = 20000;
      public static final int DEBUG_INT = 10000;
      public static final int TRACE_INT = 5000;
      public static final int ALL_INT = Integer.MIN_VALUE;
    

    相关文章

      网友评论

          本文标题:logback设置开发环境日志级别

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