問題提出:
一般在生產環境上,日誌的級別是INFO以上,但有時候程序出現問題(如SQL報錯),少量日誌不能儘快定位問題,這時候可以動態修改日誌級別到DEBUG,打印更多日誌後可以快速定位到問題。
解決方法:
- 定義動態修改日誌級別的接口:這種方法的好處是不用修改配置文件,排錯後再次調用接口把日誌級別修改回去;壞處是需要在代碼中寫死指定哪些包要修改日誌級別。示例代碼如下:
@RestController
public class LogController {
private static Logger logger = LoggerFactory.getLogger(LogController.class);
@RequestMapping(value = "logLevel/{logLevel}")
public String changeLogLevel(@PathVariable("logLevel") String logLevel) {
try {
LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
loggerContext.getLogger("org.mybatis").setLevel(Level.valueOf(logLevel));
loggerContext.getLogger("org.springframework").setLevel(Level.valueOf(logLevel));
} catch (Exception e) {
logger.error("動態修改日誌級別出錯", e);
return "fail";
}
return "success";
}
}
- 修改logback.xml配置文件:在configuration根節點配置屬性scan和scanPeriod,scan爲true時,配置文件被修改會被重新加載,scanPeriod定義了掃描文件變化的週期,默認60000毫秒,即一分鐘。這種做法的好處是不用自己寫修改日誌級別的邏輯;壞處是要手動更改配置文件,排錯完成後需改回原來的配置。示例配置如下:
<?xml version="1.0" encoding="UTF-8" ?>
<configuration scan="true" scanPeriod="60000">
<property name="LOG_HOME" value="/export/logs/cmdb/" />
<property name="APP_NAME" value="cmdb" />
<property name="LOG_FILE_EXPIRE_TIME" value="180" />
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} | ${APP_NAME} - %p | %thread | %c | line:%L - %m%n</pattern>
</encoder>
</appender>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_HOME}${APP_NAME}.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>${LOG_FILE_EXPIRE_TIME}</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} | ${APP_NAME} - %p | %thread | %c | line:%L - %m%n</pattern>
</encoder>
</appender>
<root>
<level value="INFO" />
<appender-ref ref="STDOUT" />
<appender-ref ref="FILE" />
</root>
</configuration>