最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot如何動態(tài)改變日志級別

 更新時間:2020年12月17日 09:37:55   作者:ksfzhaohui  
這篇文章主要介紹了SpringBoot如何動態(tài)改變日志級別,幫助大家更好的理解和使用springboot框架,感興趣的朋友可以了解下

前言

關于日志級別,大部分項目可能都設置為info級別,當然也可能有一些追求性能或者說包含很多敏感信息的項目直接將級別設置為warn或者error;這時候如果項目中出現一些未知異常,需要用到很詳細的日志信息,此時如果項目中沒有動態(tài)改變日志級別的機制,排查問題將很棘手。

日志系統(tǒng)

我們常用的一些日志系統(tǒng)包括:Log4j2、Logback、Java Util Logging;我們想動態(tài)改變日志的級別,前提是這些日志系統(tǒng)都支持我們直接設置日志等級,當然這些系統(tǒng)提供了很簡單的接口;

  • Log4j2
LoggerContext loggerContext = (LoggerContext) LogManager.getContext(false);
LoggerConfig loggerConfig = loggerContext.getConfiguration().getLoggers().get("root");
loggerConfig.setLevel(level);
  • Logback
LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
Logger logger = loggerContext.getLogger("root");
((ch.qos.logback.classic.Logger) logger).setLevel(level);
  • Java Util Logging
Logger logger = Logger.getLogger("root");
logger.setLevel(level);

當然除了上面直接設置日志級別的方式,也有可以動態(tài)加載配置文件的方式,同樣也可以在配置文件中動態(tài)改變日志級別,以logback為例:

LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
File externalConfigFile = new File("logback.xml");
JoranConfigurator configurator = new JoranConfigurator();
configurator.setContext(lc);
lc.reset();      
configurator.doConfigure(externalConfigFileLocation);

上面簡單介紹了一下每種日志系統(tǒng)都是如何去設置日志級別的,最關鍵的是設置完之后,可以實時生效,立馬可以看到我們想要的日志;有了這些下面其實就是通過何種方式去改變日志級別的問題了;

如何動態(tài)改變級別

如何去動態(tài)改變級別,最簡單的方式就是對外提供一個接口,給定一個日志級別作為參數實時變更;或者通過配置中心的方式;另外其實像SpringBoot這些主流的框架本身也提供了動態(tài)修改的功能;下面可以具體看一下是如何實現的,以logback為例;

自定義接口

自定義一個給定日志級別的接口,外部直接通過調用接口來改變級別:

@RequestMapping(value = "logLevel/{logLevel}")
public String changeLogLevel(@PathVariable("logLevel") String logLevel) {
  try {
    LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
    Logger logger = loggerContext.getLogger("root");
    ((ch.qos.logback.classic.Logger) logger).setLevel(Level.valueOf(logLevel));
  } catch (Exception e) {
    logger.error("changeLogLevel error", e);
    return "fail";
  }
  return "success";
}

想要改變日志級別直接請求如下地址即可,設置一個debug的級別:

http://[ip]:[port]/logLevel/debug

這種方式雖然比較簡單,但是如果節(jié)點很多的話,操作起來就很麻煩,當然也可以匯總所有節(jié)點路徑,一次操作觸發(fā)所有節(jié)點的請求;其實最好的辦法應該是類似發(fā)布訂閱的方式,發(fā)布者會給所有訂閱者都發(fā)送一個更改日志級別的通知,有新的節(jié)點只要成為訂閱者即可,這種方式其實就是現在主流的配置中心的方式。

配置中心

配置中心的目的其實就是把一些會經常變動的參數集中保存起來,某個系統(tǒng)啟動時去配置中心獲取相關的參數,同時會對這些參數進行監(jiān)聽,后面在配置中心里面改變參數的值會實時推送給相關系統(tǒng);這樣系統(tǒng)就可以在不重啟的情況下就更新了配置;
利用現有的一些中間件我們就能很快實現一個配置中心,比如Zookeeper提供了對某個Node進行監(jiān)聽的功能,MQ和Redis都有發(fā)布訂閱的功能,所以用來實時推送變更再好不過了;

  • Zookeeper方式

可以直接使用PathChildrenCache用來監(jiān)聽子節(jié)點的CHILD_ADDED,CHILD_UPDATED,CHILD_REMOVED事件;這樣如果在Zookeeper服務端對節(jié)點的值就行更新,客戶端會觸發(fā)以上三個事件:

private void watcherPath(String path) {
  PathChildrenCache cache = new PathChildrenCache(client, path, true);
  cache.start(StartMode.POST_INITIALIZED_EVENT);
  cache.getListenable().addListener(new PathChildrenCacheListener() {
    @Override
    public void childEvent(CuratorFramework client, PathChildrenCacheEvent event) throws Exception {
      switch (event.getType()) {
      case CHILD_ADDED:
        break;
      case CHILD_UPDATED:
        String logLevel = new String(event.getData().getData());
         //日志級別更新處理
        break;
      case CHILD_REMOVED:
        break;
      default:
        break;
      }
    }
  });
}
  • MQ方式

MQ一般都有Queue和Topic方式,Topic方式其實就是訂閱發(fā)布模式,所有的集群節(jié)點可以訂閱某個Topic,這樣發(fā)布端發(fā)送更新日志級別的消息,其他訂閱節(jié)點都能收到:

//日志等級Topic
private final String TOPIC = "LOGLEVEL";
 
private void watcherPaths() throws JMSException {
  Topic topic = session.createTopic(TOPIC);
  MessageConsumer consumer = session.createConsumer(topic);
  consumer.setMessageListener(new MessageListener() {
    @Override
    public void onMessage(Message message) {
      TextMessage tm = (TextMessage) message;
      String logLevel = tm.getText();
      //日志級別更新處理
    }
  });
}
  • Redis方式

Redis其實除了緩存的功能,也提供了類似MQ的發(fā)布訂閱的模式;集群節(jié)點通過訂閱一個channel,發(fā)布端通過此channel來發(fā)布消息:

private void watcherPaths() throws JMSException {
  jedis.subscribe(new JedisPubSub() {
    @Override
    public void onMessage(String channel, String message) {
       String logLevel = message;
       //日志級別更新處理
    }
  },"LOGLEVEL");
}

SpringBoot內置

SpringBoot2.0之后可以通過actuator動態(tài)調整日志級別,主要是通過暴露loggers這個endpoint來實現,具體步驟如下:

  • 需要引入actuator
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
  • 暴露loggers

在application.properties中添加如下配置:

management.endpoints.web.exposure.include=loggers
  • 查看日志級別

啟動服務可以通過:

http://[ip]:[port]/actuator/loggers

查看當前項目每個包的日志級別:

{
levels: [
  "OFF","ERROR","WARN","INFO","DEBUG","TRACE"
],
loggers: {
  ROOT: {
   configuredLevel: "INFO",
   effectiveLevel: "INFO"
  },
...
}
  • 動態(tài)修改日志級別

發(fā)送POST請求到:

http://[ip]:[port]/actuator/loggers/[包路徑]

需要在body中指定configuredLevel參數;
比如修改整個項目日志級別為error:

http://[ip]:[port]/actuator/loggers/root

關于SpringBoot內部是如何實現動態(tài)改變日志級別的,可以查看其實現核心類LoggersEndpoint:

@Endpoint(id = "loggers")
public class LoggersEndpoint {
  private final LoggingSystem loggingSystem;
  @WriteOperation
  public void configureLogLevel(@Selector String name, @Nullable LogLevel configuredLevel) {
    Assert.notNull(name, "Name must not be empty");
    this.loggingSystem.setLogLevel(name, configuredLevel);
  }
  ...
}

具體通過LoggingSystem來對日志系統(tǒng)動態(tài)改變級別,上面也介紹了主流使用的日志系統(tǒng),SpringBoot也都支持這些系統(tǒng),這是一個抽象類,具體實現類:

  • JavaLoggingSystem
  • Log4J2LoggingSystem
  • LogbackLoggingSystem
  • NoOpLoggingSystem

分別對應了幾種日志系統(tǒng),這幾個類內部其實也是調用上面介紹的方法去改變日志級別,當然SpringBoot自動會識別出當前使用的是哪個日志系統(tǒng),然后使用哪個LoggingSystem;

總結

大部分公司其實更多的還是使用配置中心的方式來動態(tài)改變日志級別,這種方式更加靈活,而且配置中心已經成為很多公司的標配組件,不光用來改變日志級別,所有有可能改變的參數都可以使用。

以上就是SpringBoot如何動態(tài)改變日志級別的詳細內容,更多關于SpringBoot 動態(tài)改變日志級別的資料請關注腳本之家其它相關文章!

相關文章

最新評論

陕西省| 堆龙德庆县| 三门县| 手机| 大冶市| 康平县| 双桥区| 水城县| 瑞昌市| 合阳县| 金川县| 龙游县| 凌海市| 桃园县| 垫江县| 土默特右旗| 南充市| 江永县| 克东县| 聂拉木县| 崇礼县| 同心县| 北海市| 金寨县| 石阡县| 南雄市| 民权县| 台中县| 团风县| 漯河市| 滦平县| 遂平县| 合川市| 尼木县| 侯马市| 龙口市| 禄劝| 阿勒泰市| 水城县| 汝南县| 手游|