最近在做項目的時候用到logback作為項目日志,而拋棄了log4j。具體為什么用logback,我總結了以下幾點:
1.log4j和logback的創作者是同一個人,logback是log4j的升級版,是對log4j核心的一個封裝。
2.性能提升,在某些特定場景上執行速度提升10倍以上,同時初始化內存更小
3.擴展文檔,豐富的並且詳細的文檔和不斷的更新,可在官網上查看
4.Filters(過濾器),過濾器的使用又是logback的一大特色,在使用log4j的時候,當我們遇到問題時,我們需要降低日志等級,但這時又會有大量的日志輸出。但logback可以根據用戶設定不同的日志級別,比如一個用戶的日志級別時debug,其他的用戶可以時error,這里要了解MDCFilter
5.日志自動清除和日志自動壓縮,自動清除通過設置TimeBasedRollingPolicy 或者 SizeAndTimeBasedFNATP的 maxHistory 屬性,自動壓縮RollingFileAppender可以在回滾操作中,自動壓縮歸檔日志文件,回滾是異步的
6.自動載入配置文件,Logback-classic可以在配置文件被修改后,自動重新載入
上面做的是理論的介紹,現在我們就通過具體的實例來使用logback框架
1.配置maven依賴
ch.qos.logback
logback-core
1.1.5
ch.qos.logback
logback-classic
1.1.5
org.logback-extensions
logback-ext-spring
0.1.3
ch.qos.logback
logback-classic
org.slf4j
slf4j-api
1.7.5
org.slf4j
slf4j-simple
1.7.5
注意事項:配置了logback的jar包后,一定不要再配置log4j的jar包,因為這樣會發生沖突,有可能導致輸出的日志文件中沒有內容,如果其他的jar包中包含的有log4j的jar包我們要exclusion,比如我們引入的shiro依賴
org.apache.shiro
shiro-core
org.slf4j
slf4j-api
1.2.2
2.配置文件
首先在web.xml中配置,用於加載logback.xml和過濾
log4jConfigLocation
classpath:logback.xml
ch.qos.logback.ext.spring.web.LogbackConfigListener
注意:一定要有listener,要不logback不生效,還有logback一定要放在rescore文件夾下,要是放在webapp下會加載不到

3.配置logback.xml
logback
%red(%d{yyyy-MM-dd HH:mm:ss}) %green([%thread]) %highlight(%-5level) %boldMagenta(%logger:%-3L) - %cyan(%msg%n)
${CONSOLE_LOG_PATH}/neoinfo.log
INFO
DENY
ACCEPT
${CONSOLE_LOG_PATTERN}
UTF-8
true
false
${CONSOLE_LOG_PATH}/neoinfo.%d.log
15
10GB
${CONSOLE_LOG_PATH}/neoinfo_error.log
ERROR
${CONSOLE_LOG_PATTERN}
UTF-8
false
false
${CONSOLE_LOG_PATH}/neoinfo_error.%d.log
15
10GB
4.配置aop類
package com.aop;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Enumeration;
import java.util.UUID;
/**鄭州婦科醫院哪家好 http://fk.zyfuke.com/
* 日志輸出
* */
@Aspect
@Component
public class LogAspect {
private static Logger log = LoggerFactory.getLogger(LogAspect.class);
@Pointcut("@annotation(org.springframework.web.bind.annotation.RequestMapping) || @annotation(org.springframework.web.bind.annotation.GetMapping) || @annotation(org.springframework.web.bind.annotation.PostMapping)")
public void webLogs() {
}
@Before("webLogs()")
public void doBefore(JoinPoint joinPoint) {
// 接收到請求,記錄請求內容
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
// 記錄下請求內容
log.info("DATE:"+new Date());
log.info("URL : " + request.getRequestURL().toString());
log.info("HTTP_METHOD : " + request.getMethod());
log.info("IP : " + request.getRemoteAddr());
log.info("CLASS_METHOD : " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
Enumeration enu = request.getParameterNames();
while (enu.hasMoreElements()) {
String name = (String) enu.nextElement();
log.info("name:{" + name + "},value:{" + request.getParameter(name) + "}");
}
}
@AfterReturning(returning = "ret", pointcut = "webLogs()")
public void doAfterReturning(JoinPoint joinPoint, Object ret) throws Throwable {
ObjectMapper mapper = new ObjectMapper();
mapper.setDateFormat(new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"));
try {
if (log.isDebugEnabled()) {
log.debug("returnValue={}", mapper.writeValueAsString(ret));
}
} catch (Exception ex) {
log.error("攔截器異常", ex);
}
}
}