日志最佳实战

日志最佳实战

1. logback

2. 开发debug,生产info , 异常error

3. 使用self4j的占位符方式输入日志。多个参数输出,参数项使用数组的形式。举例 : logger.debug("Processing trade with id: {} and symbol : {} ", id, symbol);

     此种形式在确定日志输出级别前,不会拼接字符串,注意:占位符只适用于与字符串。 // LOGGER.isDebugEnabled()

4. 访问日志和错误日志记录到不同的文件中,方便查询

5. 外部接口输入和输出处加记录日志,方便调试

6. 所有怀疑影响性能的地方加上日志记录,不要怕日志多

7. 明确日志的每一项输出

8. 异常日志输出出现异常的具体位置。log中记录内容 e:logger.info("Exception is : ",e); 可以记录异常的堆栈信息

9. 日志中包含充分的信息,日志中的时间戳要精确到毫秒。

10. ERROR:运行时异常以及预期之外的错误。

      WARN:预期之外的运行时状况,不一定是错误的情况。

      INFO:运行时产生的事件。

      DEBUG:与程序运行时的流程相关的详细信息。

11. 每个记录器对象都有一个运行时对应的严重性级别。该级别可以通过配置文件或代码的方式来进行设置。如果没有显式指定严重性级别,则会根据记录器名称的层次结构关系

      往上进行查找,直到找到一个设置了严重性级别的名称为止。比如名称为“com.myapp.web.IndexController”的记录器对象,如果没有显式指定其严重性级别,则会依次

      查找是否有为名称“com.myapp.web”、“com.myapp”和“com”指定的严重性级别。如果仍然没有找到,则使用根记录器配置的值。

12. 前一天的日志自动压缩

13. MDC和NDC来处理多用户同时访问日志信息。NDC和MDC是log4j用于存储应用程序的上下文信息(context infomation),从而便于在log中使用这些上下文信息。

      NDC采用了一个类似栈的机制来push存储上下文信息,每一个线程都独立地储存上下文信息。比如说一个servlet就可以针对每一个request创建对应的NDC,储存客户端

      地址等等信息。相关的信息使用NDC.push(message); 在log的时候将信息输出。在相应的PatternLayout中使用”%x”来输出存储的上下文信息MDC内部使用了类似map

      的机制来存储信息,相对应的方法,MDC.put(key,value);在配置PatternLayout的时候使用:%X{key}来输出对应的value

14. 日志聚合与分析

参考文章:http://www.ibm.com/developerworks/cn/java/j-lo-practicelog/   

                 http://www.cnblogs.com/zhengyun_ustc/archive/2012/12/15/logging_bp.html 

               http://www.oschina.net/translate/why-use-sl4j-over-log4j-for-logging

所需jar包: logback-classic-1.1.2.jar     logback-core-1.1.2.jar       slf4j-api-1.6.1.jar

配置文件模板:

<!-- scan: 当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true。
     scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。
             当scan为true时,此属性生效。默认的时间间隔为1分钟。 -->
<configuration scan="true" scanPeriod="2 seconds" debug="false">
  <!-- 控制台 -->
  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <!-- 日志记录内容:时间,线程,级别,类,日志信息,换行  -->
      <pattern>%d [%thread] %-5level [%c] - %msg%n </pattern>
    </encoder>
  </appender>
  <root level="INFO">
    <appender-ref ref="STDOUT" />
  </root>

  <!-- 普通日志 -->
  <appender name="normal" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>logs/normal/cmserver_normal.log</file>
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <fileNamePattern>logs/cmserver_normal.%d{yyyy-MM-dd}.log.zip</fileNamePattern>
    </rollingPolicy>

    <encoder>
      <pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level [%c] - %msg%n</pattern>
    </encoder>
  </appender>
  <logger name="normal" level="INFO" additivity="false">  
    <appender-ref ref="normal" />
  </logger> 
  
  <!-- 异常日志 -->
  <appender name="exception" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>logs/exception/cmserver_exception.log</file>
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <fileNamePattern>logs/exception/cmserver_exception.%d{yyyy-MM-dd}.log.zip</fileNamePattern>
    </rollingPolicy>
    <encoder>
      <pattern>%d [%thread] %-5level [%c] - %msg%n</pattern>
    </encoder>
  </appender>
  
  <!-- additivity属性为false,表示此loger的打印信息不再向上级传递  -->
  <logger name="exception" level="INFO" additivity="false">  
    <appender-ref ref="exception"/>  
  </logger>  
  
</configuration>

测试类:

public class LogTest {
	
    //定义一个全局的记录器,通过LoggerFactory获取
    private final static Logger logger = LoggerFactory.getLogger(LogTest.class); 
    //正常日志
    private final static Logger normalLogger = LoggerFactory.getLogger("normal");
    //异常日志
    private final static Logger exceptionLongger = LoggerFactory.getLogger("exception"); 
    
	public static void main(String[] args) {
		
		while(true){
			// 普通日志
			normalLogger.info(" LogTest : {}","This is a test !" );
			try {
				Thread.sleep(2000);
				plus();
			}catch(Exception e){
				// 异常日志
				exceptionLongger.error("error :" ,e );
				logger.error("error :" ,e );
			}
	        
		}
	}
	
	public static void plus(){
		int b = 1;
		int c = b/0;;
	}
}

  

原文地址:https://www.cnblogs.com/Jtianlin/p/4564095.html