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

来源:互联网 发布:证件照软件 免费 编辑:程序博客网 时间:2024/05/12 22:19

对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的拼写,这块我已经实现,有兴趣的可以给我留言。

0 0
原创粉丝点击