通过JMX以HTTP的方式动态管理Logback的配置

对Logback的配置基本了解后,我们在实际项目中就可以应用它,不知大家有没有碰到这样一种业务,使用JMX动态管理Logback的配置(对JMX不了解的,建议上网搜索相关资料),而无需重启服务器。好在Logback内部实现了JMX,我们只需在logback.xml中添加<jmxConfigurator />这样一条配置就可以在Jconsole中进行管理,如下图:


总共有六个方法:


我们可以写个线程让主程序不断运行并打印日志,然后通过JConsole修改日志的级别,输出不同的日志信息。

然而了解JMX的人都知道,JMX管理Mbean有一种是基于Http

从官网下载logback的jar包,我们观察logback内部源码的JMX实现。


打开JMXConfiguratorMBean.java  ,发现它就是一个接口

public interfaceJMXConfiguratorMBean {

 

  void reloadDefaultConfiguration() throwsJoranException;

 

  void reloadByFileName(String fileName) throwsJoranException, FileNotFoundException;

 

  void reloadByURL(URL url) throwsJoranException;

 

  void setLoggerLevel(String loggerName, StringlevelStr);

 

  String getLoggerLevel(String loggerName);

 

  String getLoggerEffectiveLevel(StringloggerName);

 

  List<String> getLoggerList();

 

  List<String> getStatuses();

}

正好是我们在Jconsole中操作的方法,那么我们只要将JMXConfigurator注册到JMX中就可以管理logback了,下面通过一个简单例子说明:

logback.xml:

<?xml version="1.0" encoding="UTF-8"?>
	<!-- 根节点,设置为调试模式 自动重扫描配置文件 间隔为30秒 -->
<configuration>
    <span style="color:#ff0000;"><jmxConfigurator /> </span>
	<!-- 定义控制台输出 -->
	<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
		<!-- 定义过滤器 相比logger内定义优先级高   -->
<!--				<filter class="ch.qos.logback.classic.filter.ThresholdFilter">-->
<!--					<level>warn</level>-->
<!--				</filter>-->
		<!-- 定义日志格式 -->
		<layout class="ch.qos.logback.classic.PatternLayout">
			<pattern>
				%date{yyyy-MM-dd HH:mm:ss} %level [%thread] %10logger[%file:%line] - %msg%n
			</pattern>
		</layout>
	</appender>

	<!-- 单独对指定的日志设定级别,使该日志对象输出地日志级别限定在:“INFO”级别,不受跟级别的限制   目标可以是类或者包-->
<!--	<logger name="com.ztgame.logback.test" level="info">-->
<!--		<appender-ref ref="SIZE_BASE" />-->
<!--	</logger>-->

    <root level="INFO">
		<appender-ref ref="CONSOLE" />
	</root>
</configuration>
ReloadConfigJmx.java 编写JMX服务端(注册服务 注册连接)

package cn.gt.logback;

import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.ObjectName;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.jmx.JMXConfigurator;
import com.sun.jdmk.comm.HtmlAdaptorServer;


public class ReloadConfigJmx {

	public static final String DOMAIN_NAME = "logback_jmx";
	public static final String RELOAD_CONFIG_NAME = "reloadConfig";
	public static final String CONNECTOR_NAME = "htmlConnector";
	private static MBeanServer mBeanServer;
	private static JMXConfigurator reloadConfig;
	private static HtmlAdaptorServer connector;
	private static int port = 8092;

	public static void init(LoggerContext loggerContext) throws Exception {
		mBeanServer = MBeanServerFactory.createMBeanServer(DOMAIN_NAME);
		// 注册服务
		ObjectName on = new ObjectName(DOMAIN_NAME + ":name=" + RELOAD_CONFIG_NAME);
		reloadConfig = new JMXConfigurator(loggerContext, mBeanServer, on);
		mBeanServer.registerMBean(reloadConfig, new ObjectName(DOMAIN_NAME + ":name=" + RELOAD_CONFIG_NAME));
		// 注册连接
		connector = new HtmlAdaptorServer();
		connector.setPort(port);
		mBeanServer.registerMBean(connector, new ObjectName(DOMAIN_NAME + ":name=" + CONNECTOR_NAME));

		connector.start();
	}

	public static void destroy() throws Exception {
		connector.stop();

		mBeanServer = null;
		reloadConfig = null;
		connector = null;
		port = 0;
	}
}

启动一个线程,通过http动态修改配置,观察控制台输出。

CommonTest.java

package cn.gt.logback;
import org.slf4j.LoggerFactory;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
/**
 * logback + JMX 
 * @author gengtao
 */
public class CommonTest {
	public static LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
	private  static  Logger logger = lc.getLogger("CONSOLE");
	public void run(){
		int i =0;
		System.out.println(logger.getName());
		for(int j = 0; j < 300; j++){
			System.out.println("测试第 " + ++i + "次循环,请注意观察控制台输出");
			logger.trace("do trace");
			logger.debug("do debug");
			logger.info("do info");
			logger.warn("do warn");
			logger.error("do error");
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	public static void main(String[] args) throws Exception{
		ReloadConfigJmx.init(lc);
		CommonTest test =new CommonTest();
		test.run();
	}
}

然后我们运行这个主函数,eclipse控制台输出为:(只截取了片段)


通过浏览器访问localhost:8092,点击name=reloadConfig,就会看到如下页面:


然后我们设置Logger的级别:


点击setLoggerLevel按钮后会提示操作成功,然后我们测试getLoggerLevel:


点击按钮会看到,设置已经生效:


然后我们回到eclipse控制台观看输出信息(截取片段如下):


info 和 warn级别的信息消失了,事实证明我们实现了Http方式通过JMX管理Logback,其他4个方法,有兴趣的人可以研究一下,和这个类似,比如重载配置,会立即生效。

另外不知大家有没有注意到,当你在浏览器中操作时会自动生成一条连接:


这个连接是JMX自动生成的。在实际开发中我们有可能面临这样一种情况:在linux系统下,我们希望通过Java脚本来达成我们的目的,一条命令就可以动态管理我们的配置,那么这条连接就有作用了,我们自己编写网络连接以及URL的拼写,这块我已经实现,有兴趣的可以给我留言。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值