spring-boot 利用 actuator 動態設定 logging 的日誌級別
阿新 • • 發佈:2019-01-03
引子
已經上線的服務通常情況下都會關閉日誌列印功能。但是一但進行排錯的時候,又必須開啟日誌輸出,而修改日誌級別的方式有多種。這裡只說明個人認為最優的方式
依賴
spring-boot、spring-boot-actuator
方式
定義一個根 endpoint
import java.util.concurrent.atomic.AtomicBoolean; import org.springframework.boot.actuate.endpoint.AbstractEndpoint; public class MyLogEndpoint extends AbstractEndpoint<Boolean> { AtomicBoolean atomicBoolean = new AtomicBoolean(); // mgrLogging 為該 endpoint 的請求子路徑: http://localhost:8080/mgrLogging public MyLogEndpoint() { super("mgrLogging", true, true); } @Override public Boolean invoke() { // 這裡我的本意是 log 開關,一個布林值。 // 每次請求 http://localhost:8080/mgrLogging 都會呼叫該 invoke 方法 // 通常情況下返回該 endpoint 的監控資訊 return atomicBoolean.getAndSet(!atomicBoolean.get()); } }
定義一個掛靠在根 endpoint 的子節點
import org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter; import org.springframework.boot.logging.LogLevel; import org.springframework.boot.logging.logback.LogbackLoggingSystem; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; public class MyLogMvcEndpoint extends EndpointMvcAdapter { String format = "change package name [%s] logging level to [%s]"; public MyLogMvcEndpoint(MyLogEndpoint delegate) { super(delegate); } // 注意該 path 不是 http://localhost:8080/{level}/{pkn} // 而是構造方法中 MyLogEndpoint 的 id 對應 path 下的請求節點。 // http://localhost:8080/mgrLogging/{level}/{pkn} @RequestMapping(value = "/{level}/{pkn}") @ResponseBody public Object changeLog(@PathVariable LogLevel level, @PathVariable("pkn") String packageName) { System.err.println(String.format(format, packageName, level)); try { // 處理日誌 level 改變邏輯,根據個人需求改變 LogbackLoggingSystem logbackLoggingSystem = new LogbackLoggingSystem(this.getClass().getClassLoader()); logbackLoggingSystem.setLogLevel(packageName, level); // 處理成功(未丟擲異常)返回 success return "success"; } catch (Exception e) { // 處理失敗返回異常資訊 return e.getMessage(); } } }
endpoint 註冊
@Configuration @ConditionalOnWebApplication public class MyLogConfiguration { @Bean @ConditionalOnMissingBean public MyLogEndpoint changeLogEndpoint() { return new MyLogEndpoint(); } @Bean @ConditionalOnBean(MyLogEndpoint.class) public MyLogMvcEndpoint changeLogMvcEndpoint(MyLogEndpoint delegate) { return new MyLogMvcEndpoint(delegate); } }
最後
org.springframework.boot.actuate.endpoint.Endpoint
該 url 不能接受請求引數,一般是返回該 endpoint 監控的資訊
org.springframework.boot.actuate.endpoint.mvc.MvcEndpoint
該 url 可接受引數,一般情況下是用來修改或查詢該 endpoint 的配置。