<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %level [%thread] %class:%line >> %msg%n</pattern>
</encoder>
</appender>
<appender name="file"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>/home/usercenter/log/member-boss.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>/home/usercenter/log/member-boss.%d{yyyy-MM-dd}.log.gz
</FileNamePattern>
<!-- keep 20 days' worth of history -->
<maxHistory>20</maxHistory>
</rollingPolicy>
<encoder>
<!-- %-40(%-35logger{35}:%-4line) -->
<Pattern>[%date{yyyy-MM-dd HH:mm:ss}] [%-5level][%thread] [%logger:%line] --%mdc{client} %msg%n</Pattern>
</encoder>
</appender>
<!--cics链接日志 -->
<appender name="cicsClientLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>/home/usercenter/log/cics/cicscore.log</file>
<Encoding>UTF-8</Encoding>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>/home/usercenter/log/cics/cicscore-%d{yyyy-MM-dd}-%i.log.gz</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>10MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<encoder>
<!-- 时间 级别 线程 类路径 信息 -->
<pattern>%date %level [%thread] %logger{50} [%file : %line] %msg%n</pattern>
</encoder>
</appender>
<logger name="cicsClient" additivity="false" level="info">
<appender-ref ref="cicsClientLog" />
</logger>
<appender name="test_Log" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>/home/usercenter/log/test/Cscs.log</file>
<Encoding>UTF-8</Encoding>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<maxHistory>60</maxHistory>
<fileNamePattern>/home/usercenter/log/test/Cscs%d{yyyy-MM-dd}-%i.log.gz</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>10MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<!-- encoder 和 layout 在作用上没有本质区别。但是自0.9.19版本之后,极力推荐使用encoder。
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
</layout> -->
<encoder>
<!-- 时间 级别 线程 类路径 信息 -->
<pattern>%date %level [%thread] %logger{50} [%file : %line] %msg%n</pattern>
</encoder>
</appender>
<logger name="test" additivity="false" level="debug">
<appender-ref ref="test_Log" />
</logger>
<logger name="org.springframework" level="info" />
<logger name="jdbc.audit" level="error" />
<logger name="jdbc.connection" level="error" />
<logger name="jdbc.sqlonly" level="error" />
<logger name="jdbc.resultset" level="error" />
<logger name="jdbc.sqltiming" level="error" />
<logger name="jdbc.resultset" level="error" />
<logger name="com.testpay.its" level="info"></logger>
<root level="info">
<appender-ref ref="file" />
<!-- <appender-ref ref="stdout" /> -->
</root>
</configuration>
0.预备知识:
slf4j是一系列的日志接口,而log4j logback是具体实现了的日志框架。
logback是直接实现了slf4j的接口,是不消耗内存和计算开销的。而log4j不是对slf4j的原生实现,所以 slf4j api 在调用log4j时需要一个适配层。
配置文件---观察控制台打印信息:
可知,系统会自动扫描这三个文件,直到找到配置信息。
1.如果有指定logger,那么将在logger指令路径打印日志;否则,没有指定路径,那么将在root指定的路径打印日志。例如logger为test,由于上文中已指定路径,则在Cscs.log中打印日志,若上文中不存在test,则会将日志生成在member-boss.log中。
2.日志封装类:
import java.io.PrintWriter;
import java.io.StringWriter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class BocLogger {
private static Logger logger;
private final static String LOG_TYPE = "Boc_SYSRun_Error";
/**
* 内部私有构造器
* @param logger
*/
protected BocLogger(Logger logger){
this.logger = logger;
}
/**
* 方法说明:
* slf4j日志工厂启用(指定到输出的文件)
* @param name
* @return
*/
public static BocLogger getLogger(String name) {
logger = LoggerFactory.getLogger(name);
BocLogger BocLogger = new BocLogger(logger);
return BocLogger;
}
/**
* 方法说明:
* Debug调试信息
* @param logMessage 日志信息
* @param logType 日志类别
* @param properties 扩展属性
*/
public void debug(String logMessage, String logType, String properties) {
getLogger(logType);
logger.debug(logMessage);
}
/**
* 方法说明:
* Info输出调试信息
* @param logMessage 输出信息
* @param logType 日志类别
* @param properties 扩展属性
*/
public void info(String logMessage, String logType, String properties) {
getLogger(logType);
logger.info(logMessage);
}
/**
* 方法说明:
* ERROR 输出错误日志
* <pre> 2016-12-30升级:增加错误日志汇总输出方法printSysErrorLog</pre>
* @param logMessage 错误信息
* @param logType 日志输出文件
* @param properties 扩展属性
*/
public void error(String logMessage, String logType, String properties) {
getLogger(logType);
logger.error(logMessage);
printSysErrorLog(logType + "-" + logMessage, null);
}
/**
* 方法说明:
* 输出错误日志,仅异常信息
* <pre> 2016-12-30升级:增加错误日志汇总输出方法printSysErrorLog</pre>
* @param exception 异常信息
* @param logType 日志类别
* @param properties 扩展属性
*/
public void error(Exception exception, String logType, String properties) {
getLogger(logType);
logger.error("错误信息:",exception);
printSysErrorLog(logType + " ERROR:", exception);
}
/**
* 方法说明:
* 输出错误日志,错误信息和异常信息
* <pre> 2016-12-30升级:增加错误日志汇总输出方法printSysErrorLog</pre>
* @param logMessage 日志内容
* @param exception 异常捕捉
* @param logType 日志类别
* @param properties 扩展属性
*/
public void error(String logMessage, Exception exception, String logType,
String properties) {
getLogger(logType);
logger.error(logMessage,exception);
printSysErrorLog(logType + "-" + logMessage + " ERROR:", exception);
}
/**
* 方法说明:
* 错误日志汇总,方便生产监控和问题排查
* @param logMessage
* @param exception
*/
private void printSysErrorLog(String logMessage, Exception exception) {
getLogger(LOG_TYPE);
logger.error(logMessage,exception);
}
/**
* 错误日志异常信息堆栈输出
* @param e
* @return
*/
public static String getStackTrace(Exception e){
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);
return sw.toString();
}
3.logger缓存类:
import java.util.HashMap;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class BocLoggerFactory {
private static Logger logger;
/**
* 用于对象缓存
*/
private static Map MapbocClass = new HashMap();
/**
* 内部私有构造器
*
* @param logger
*/
private BocLoggerFactory(Logger logger) {
this.logger = logger;
}
/**
* logger集合
*
*/
public static BocLogger getLogger(final Class<?> caller) {
if (MapbocClass.containsKey(caller.getName()))
return (BocLogger) MapbocClass.get(caller.getName());
else {
Logger logger = LoggerFactory.getLogger(caller);
BocLogger bocLogger = new BocLogger(logger);
MapbocClass.put(caller.getName(), bocLogger);
return bocLogger;
}
}
}
4.测试类-打印日志:
public class Test {
//两种方式:1采用logback,2.采用slf4j,3.异常堆栈
private static final BocLogger logger = BocLoggerFactory.getLogger(StudentInfo.class);
private static final Logger log = LoggerFactory.getLogger(StudentInfo.class);
public void test() {
logger.info("info测试信息001", "test", "");
logger.debug("debug测试信息001", "test", "");
logger.error("error测试信息001", "test", "");
log.info("info测试信息002");
log.debug("debug测试信息002");
log.error("error测试信息002");
try {
int i = 0;
int a = 8/i;
} catch (Exception e) {
e.printStackTrace();
logger.error("异常堆栈1:"+BocLogger.getStackTrace(e), "test", "");
log.error("异常堆栈2:"+BocLogger.getStackTrace(e));
}
}
}
End!