随笔 - 22, 文章 - 0, 评论 - 1, 引用 - 0
数据加载中……

logback_doc_manual_03_configuration

-------------------------------------------------------
与spring的配置:
貌似官网上没有介绍,但是作者在github上建立了一个扩展项目用于logback与spring结合。
目前最新版本是0.1.2,很多maven公开库里已经有了。
maven配置:
<dependency>  
     <groupId>org.logback-extensions</groupId>  
     <artifactId>logback-ext-spring</artifactId>  
     <version>0.1.2</version>  
</dependency>
web.xml配置日志框架启动监听器:
<!-- logback配置文件 -->
<context-param>
     <param-name>logbackConfigLocation</param-name>
     <param-value>/WEB-INF/classes/logback.xml</param-value>
</context-param>
<!-- logback加载监听器 -->
<listener>
     <listener-class>
          ch.qos.logback.ext.spring.web.LogbackConfigListener
     </listener-class>
</listener>
-------------------------------------------------------
logback中的配置:
可以用java程序配置,也可以用xml或者groovy脚本配置。
使用 http://logback.qos.ch/translator/ 可以把log4j的配置自动转换过来。
logback内部查找配置的过程:
     1,在classpath查找“logback.groovy”
     2,在classpath查找“logback-test.xml”
     3,在classpath查找“logback.xml”
     4,使用自身的BasicConfigurator做基本配置,所有日志被输出到控制台。
     —— 一般把“logback-test.xml”放到maven的测试路径,把“logback.xml”放到maven的正式路径,前者优先级更高。
logback的状态,加载配置文件的过程:
     代码打印:
          LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
          StatusPrinter.print(lc);
     配置文件形式打印:
          <configuration debug="true">
            ... 
          </configuration>
     也可以通过设置StatusListener来监听logback的启动和打印状态——在生产环境挺有用,因为配置文件路径挺深。
通过在系统变量里加入"logback.configurationFile"指定logback配置文件路径:
     java -Dlogback.configurationFile=/path/to/config.xml chapters.configuration.MyApp1
设置自动扫描和遇到变更时重新加载配置文件(不指定周期的话默认每1分钟):
     <configuration scan="true" scanPeriod="30 seconds"> 
       ... 
     </configuration> 
     每当N个(logback会自动调节)日志请求,logback会检查一下扫描周期是否已经到达,如到达再检查配置文件。
通过web访问状态信息:
在web.xml配置:
     <servlet>
         <servlet-name>ViewStatusMessages</servlet-name>
         <servlet-class>ch.qos.logback.classic.ViewStatusMessagesServlet</servlet-class>
      </servlet>
      <servlet-mapping>
         <servlet-name>ViewStatusMessages</servlet-name>
         <url-pattern>/lbClassicStatus</url-pattern>
      </servlet-mapping>
然后访问:http://host/yourWebapp/lbClassicStatus
注册控制台状态监听器:
     java代码方式:
          LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory(); 
          StatusManager statusManager = lc.getStatusManager();
          OnConsoleStatusListener onConsoleListener = new OnConsoleStatusListener();
          statusManager.add(onConsoleListener);
     用配置文件方式:
          <configuration>
            <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />  
            ...
          </configuration>
     系统变量方式:
          java -Dlogback.statusListenerClass=ch.qos.logback.core.status.OnConsoleStatusListener
停止logback:
     java代码方式:
          LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
          loggerContext.stop();
     web应用:
          ServletContextListener.contextDestroyed()会自动调用上面的stop方法。
-------------------------------------------------------
配置文件格式:
     最外层是<configuration>元素,里面有<appender><logger><root>元素
<logger>元素:
     level属性可以这些值:TRACE, DEBUG, INFO, WARN, ERROR, ALL, OFF,也可以明确指定继承:INHERITED或者NULL
     包含若干<appender-ref>元素,指定appender的名字。
从DEBUG改为INFO级别:
<configuration>
  <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>
  <logger name="chapters.configuration" level="INFO"/>
  <!-- Strictly speaking, the level attribute is not necessary since -->
  <!-- the level of the root level is set to DEBUG by default.       -->
  <root level="DEBUG">          
    <appender-ref ref="STDOUT" />
  </root>  
</configuration>
-------------------------------------------------------
配置Appender:
     name和class属性
     内嵌0个或1个layout元素,0个或多个encoder元素,0个或多个filter元素。还可以内嵌任意数量的appdenter类的属性(例如自定义的appender类)。
     layout元素应该内嵌具体的layout类,但是默认就是PatternLayoutEncoder。
Appender的累加性:
     logger会记录在所有绑定在它自身的appender,同时也会记录在该logger祖先的appender上,所以有可能重复记录!
配置Logger Context(可以用在“多个项目写入同一个日志文件”这种情况):
<configuration>
  <contextName>myAppName</contextName>
  ...
</configuration>
-------------------------------------------------------
变量替换:
<configuration>
  <property name="USER_HOME" value="/home/sebastien" />
  <appender name="FILE" class="ch.qos.logback.core.FileAppender">
    <file>${USER_HOME}/myApp.log</file>
    ...
  </appender>
   ...
</configuration>
——上面的变量定义在系统属性里也可以:java -DUSER_HOME="/home/sebastien" MyApp2
变量也可以定义在文件里:
<configuration>
  <property file="src/main/java/chapters/configuration/variables1.properties" />
  <appender name="FILE" class="ch.qos.logback.core.FileAppender">
     <file>${USER_HOME}/myApp.log</file>
     ...
   </appender>
   ...
</configuration>
——对应路径的文件里应该加入“USER_HOME=/home/sebastien”
(这路径挺诡异啊,是maven的结构,那打包后岂不是不能用了?)
像这样引用classpath的还靠谱些:
<property resource="resource1.properties" />
变量可以指定作用域:local,context,system
变量可以相互引用:
     USER_HOME=/home/sebastien
     fileName=myApp.log
     destination=${USER_HOME}/${fileName}
命名引用:如果"userid"会被替换为"alice",那么"${${userid}.password}"会被替换为"alice.password"对应的值。
变量可以指定默认值:${aName:-golden}  ——这就指定了默认值golden
变量的默认值也可以引用变量: "${id:-${userid}}
预置变量:HOSTNAME,CONTEXT_NAME
可以通过timestamp元素定义一个当前的日期和时间的动态元素。
可以自己继承PropertyDefiner实现动态生成属性,现在内置了2个动态属性生成器:
     FileExistsPropertyDefiner     如果指定路径文件存在,则将指定属性设为“true”,反之亦然
     ResourceExistsPropertyDefiner     如果指定资源存在,则将指定属性设为“true”,反之亦然
条件语句:
   <!-- if-then form -->
   <if condition="some conditional expression">
    <then>
      ...
    </then>
  </if>
  <!-- if-then-else form -->
  <if condition="some conditional expression">
    <then>
      ...
    </then>
    <else>
      ...
    </else>    
  </if>
判断条件只支持context变量和system变量,用property()或者p()来引用——如果没有设定对应变量,这两个方法会返回空串(而不是null)
isDefine()和isNull()分别判断变量是否设置和变量是否为空。
     <if condition='property("HOSTNAME").contains("torino")'>
     ...
     </if>
可以从JNDI读取变量值(作用域为local)。也可以将从JNDI读取的变量存入另一个不同作用域的变量。
     <configuration>
       <insertFromJNDI env-entry-name="java:comp/env/appName" as="appName" />
       ...
     </configuration>
-------------------------------------------------------
文件包含(可以使用相对路径。当前路径已经在当前项目中定义,所以没必要与配置文件路径关联):
<configuration>
  <include file="src/main/java/chapters/configuration/includedConfig.xml"/>
  ...
</configuration>     
被包含的文件必须用<include>标签包裹:
<included>
  <appender name="includedConsole" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>"%d - %m%n"</pattern>
    </encoder>
  </appender>
</included>
还可以关联资源(例如classpath下的某个文件):
     <include resource="includedConfig.xml"/>
还可以关联URL:
     <include url="http://some.host.com/includedConfig.xml"/>
可以指定此次文件包含为“可选的”:
     <include optional="true" ..../>
-------------------------------------------------------
LoggerContextListener
其中一个实现LevelChangePropagator会监听日志环境的合适的生命周期,并把日志级别的变化传播给JUL,这样JUL关闭的日志不会再传递给slf4j,用这种方式对性能冲击较小,适合jul-to-slf4j的桥接包。

posted on 2014-07-13 18:56 王星游 阅读(1263) 评论(0)  编辑  收藏 所属分类: java


只有注册用户登录后才能发表评论。


网站导航: