女性情感,我想去远方我想去远方的心情说说

访客

前言

关于日志级别大部分项目可能都设置为info级别当然也可能有一些追求性能或者说包含很多敏感信息的项目直接将级别设置为warn或者error这时候如果项目中出现一些未知异常需要用到很详细的日志信息此时如果项目中没有动态改变日志级别的机制排查问题将很棘手

日志系统

我们常用的一些日志系统包括

Log4j2

Logback

JavaUtilLogging

我们想动态改变日志的级别前提是这些日志系统都支持我们直接设置日志等级当然这些系统提供了很简单的接口

Log4j2

LoggerContextloggerContextLoggerContextLogManagergetContextfalseLoggerConfigloggerConfigloggerContextgetConfigurationgetLoggersgetrootloggerConfigsetLevellevel

Logback

LoggerContextloggerContextLoggerContextLoggerFactorygetILoggerFactoryLoggerloggerloggerContextgetLoggerrootchqoslogbackclassicLoggerloggersetLevellevel

JavaUtilLogging

LoggerloggerLoggergetLoggerrootloggersetLevellevel

当然除了上面直接设置日志级别的方式也有可以动态加载配置文件的方式同样也可以在配置文件中动态改变日志级别以logback为例

LoggerContextlcLoggerContextLoggerFactorygetILoggerFactoryFileexternalConfigFilenewFilelogbackxmlJoranConfiguratorconfiguratornewJoranConfiguratorconfiguratorsetContextlclcresetconfiguratordoConfigureexternalConfigFileLocation

上面简单介绍了一下每种日志系统都是如何去设置日志级别的最关键的是设置完之后可以实时生效立马可以看到我们想要的日志有了这些下面其实就是通过何种方式去改变日志级别的问题了

如何动态改变级别

如何去动态改变级别最简单的方式就是对外提供一个接口给定一个日志级别作为参数实时变更或者通过配置中心的方式另外其实像SpringBoot这些主流的框架本身也提供了动态修改的功能下面可以具体看一下是如何实现的以logback为例

自定义接口

自定义一个给定日志级别的接口外部直接通过调用接口来改变级别

RequestMappingvaluelogLevellogLevelpublicStringchangeLogLevelPathVariablelogLevelStringlogLeveltryLoggerContextloggerContextLoggerContextLoggerFactorygetILoggerFactoryLoggerloggerloggerContextgetLoggerrootchqoslogbackclassicLoggerloggersetLevelLevelvalueOflogLevelcatchExceptioneloggererrorchangeLogLevelerrorereturnfailreturnsuccess

想要改变日志级别直接请求如下地址即可设置一个debug的级别这种方式虽然比较简单但是如果节点很多的话操作起来就很麻烦当然也可以汇总所有节点路径一次操作触发所有节点的请求其实最好的办法应该是类似发布订阅的方式发布者会给所有订阅者都发送一个更改日志级别的通知有新的节点只要成为订阅者即可这种方式其实就是现在主流的配置中心的方式

配置中心

配置中心的目的其实就是把一些会经常变动的参数集中保存起来某个系统启动时去配置中心获取相关的参数同时会对这些参数进行监听后面在配置中心里面改变参数的值会实时推送给相关系统这样系统就可以在不重启的情况下就更新了配置利用现有的一些中间件我们就能很快实现一个配置中心比如Zookeeper提供了对某个Node进行监听的功能MQ和Redis都有发布订阅的功能所以用来实时推送变更再好不过了

Zookeeper方式

可以直接使用PathChildrenCache用来监听子节点的CHILDADDEDCHILDUPDATEDCHILDREMOVED事件这样如果在Zookeeper服务端对节点的值就行更新客户端会触发以上三个事件

privatevoidwatcherPathStringpathPathChildrenCachecachenewPathChildrenCacheclientpathtruecachestartStartModePOSTINITIALIZEDEVENTcachegetListenableaddListenernewPathChildrenCacheListenerOverridepublicvoidchildEventCuratorFrameworkclientPathChildrenCacheEventeventthrowsExceptionswitcheventgetTypecaseCHILDADDEDbreakcaseCHILDUPDATEDStringlogLevelnewStringeventgetDatagetData日志级别更新处理breakcaseCHILDREMOVEDbreakdefaultbreak

MQ方式

MQ一般都有Queue和Topic方式Topic方式其实就是订阅发布模式所有的集群节点可以订阅某个Topic这样发布端发送更新日志级别的消息其他订阅节点都能收到

日志等级TopicprivatefinalStringTOPICLOGLEVELprivatevoidwatcherPathsthrowsJMSExceptionTopictopicsessioncreateTopicTOPICMessageConsumerconsumersessioncreateConsumertopicconsumersetMessageListenernewMessageListenerOverridepublicvoidonMessageMessagemessageTextMessagetmTextMessagemessageStringlogLeveltmgetText日志级别更新处理

Redis方式

Redis其实除了缓存的功能也提供了类似MQ的发布订阅的模式集群节点通过订阅一个channel发布端通过此channel来发布消息

privatevoidwatcherPathsthrowsJMSExceptionjedissubscribenewJedisPubSubOverridepublicvoidonMessageStringchannelStringmessageStringlogLevelmessage日志级别更新处理LOGLEVEL

SpringBoot内置

SpringBoot20之后可以通过actuator动态调整日志级别主要是通过暴露loggers这个endpoint来实现具体步骤如下

需要引入actuator

orgspringframeworkboot

springbootstarteractuator

暴露loggers

在applicationproperties中添加如下配置

managementendpointswebexposureincludeloggers

查看日志级别

启动服务可以通过查看当前项目每个包的日志级别

levelsOFFERRORWARNINFODEBUGTRACEloggersROOTconfiguredLevelINFOeffectiveLevelINFO

动态修改日志级别

发送POST请求到包路径

需要在body中指定configuredLevel参数比如修改整个项目日志级别为error关于SpringBoot内部是如何实现动态改变日志级别的可以查看其实现核心类LoggersEndpoint

EndpointidloggerspublicclassLoggersEndpointprivatefinalLoggingSystemloggingSystemWriteOperationpublicvoidconfigureLogLevelSelectorStringnameNullableLogLevelconfiguredLevelAssertnotNullnameNamemustnotbeemptythisloggingSystemsetLogLevelnameconfiguredLevel

具体通过LoggingSystem来对日志系统动态改变级别上面也介绍了主流使用的日志系统SpringBoot也都支持这些系统这是一个抽象类具体实现类

JavaLoggingSystem

Log4J2LoggingSystem

LogbackLoggingSystem

NoOpLoggingSystem

分别对应了几种日志系统这几个类内部其实也是调用上面介绍的方法去改变日志级别当然SpringBoot自动会识别出当前使用的是哪个日志系统然后使用哪个LoggingSystem

总结

大部分公司其实更多的还是使用配置中心的方式来动态改变日志级别这种方式更加灵活而且配置中心已经成为很多公司的标配组件不光用来改变日志级别所有有可能改变的参数都可以使用

感谢关注

可以关注回滚吧代码第一时间阅读文章持续更新专注Java源码架构算法和面试

版权属于: 自由随风-天行健,君子以自强不息;地势坤,君子以厚德载物

发表评论

表情:
评论列表 (暂无评论,4人围观)

还没有评论,来说两句吧...