思路
利用Zookeeper监听机制,为一个节点添加监听器,当该节点发生变化时,更改日志级别。在本机和虚拟机上分别发布一套服务,连接同一个Zookeeper服务,在Zookeeper客户端修改节点的值,动态更改项目中日志级别
项目目录结构如下
说明:主要代码在LogbackListener和ZKUtils中
application.properties中只是更改了Tomcat端口号,zk.properties中配置了ZK启动参数等。
ZKUtils
@Component(value = "zkClient")
@PropertySource({"classpath:zk/zk.properties"})
public class ZKUtils {
private static CuratorFramework client = null;
private final static Logger log = LoggerFactory.getLogger(ZKUtils.class);
@Value("${zk.host}")
private String ZK_HOST;
@Value("${zk.port}")
private Integer ZK_PORT;
@Value("${zk.retryPolicy.baseSleepTimeMS}")
private Integer baseSleepTimeMS;
@Value("${zk.retryPolicy.maxRetries}")
private Integer maxRetries;
@Value("${zk.sessionTimeoutMs}")
private Integer sessionTimeoutMs;
@Value("${zk.log.level.path}")
private String path; //监听节点的路径
/**
* 初始化
*/
public void init() {
try {
//创建重试策略
RetryPolicy retryPolicy = new ExponentialBackoffRetry(baseSleepTimeMS, maxRetries);
//创建zookeeper客户端
client = CuratorFrameworkFactory
.builder()
.connectString(ZK_HOST + ":" + ZK_PORT)
.sessionTimeoutMs(sessionTimeoutMs)
.retryPolicy(retryPolicy)
.build();
client.start();
/**
* 设置监听节点
*
*/
final NodeCache nodeCache = new NodeCache(client, path);
nodeCache.getListenable().addListener(() -> {
ch.qos.logback.classic.LoggerContext loggerContext = (ch.qos.logback.classic.LoggerContext) LoggerFactory.getILoggerFactory();
//得到Node数据
String level = new String(nodeCache.getCurrentData().getData());
loggerContext.getLogger("root").setLevel(ch.qos.logback.classic.Level.toLevel(level));
log.info("日志级别更新:level = {}", level);
});
nodeCache.start();
log.info("zookeeper初始化成功");
} catch (Exception e) {
log.error("zookeeper初始化失败");
e.printStackTrace();
}
}
}
LogbackListener,项目启动时执行init
@Component
public class LogbackListener implements ServletContextListener {
@Autowired
private ZKUtils zkUtils;
@Override
public void contextInitialized(ServletContextEvent event) {
zkUtils.init();
}
}
测试
在Zookeeper bin目录下运行zKServer.cmd,启动服务
运行springboot项目,查看日志
本机:
虚拟机
执行 java -jar tuzki-web-0.0.1-SNAPSHOT.jar
可以看到现在的日志级别都是INFO
在zkCli.cmd中,执行 set /zk debug,更改日志级别
由于为该节点设置了监听,当节点发生变化时,会执行ZKUtils监听器中的代码,更改日志级别
再次查看项目日志
至此,以实现动态更改日志级别