用Spring与Log4J进行动态日志配置切换

spring boot log4j环境不同日志级别控制 在上一章节中我们介绍了,仅通过log4j-spring.properties对日志级别进行控制,对于需要多环境部署的环境不是很方便,可能我们在开发环境大部分模块需要采用DEBUG级别,在测试环境可能需要小部分采用DEBUG级别,而在生产环境时我们又希望采用INFO级别。这个时候,我们要自己手工编辑log4j-spring.properties文件来调整日志级别,不论在版本库中默认保存哪个环境的级别 阅读详情
 利用 Spring 与 Log4J 巧妙地进行动态日志配置切换并立即生效
    引言:
    在开发与生产环境中,我们有时候需要对日志的配置进行动态切换,要调试、监控和检查系统的运行时信息。
    一般有两种方法
    1、通过 Spring 的 Log4jConfigListener 在启动时开启定时器进行定时加载配置文件     2、通过 JMX 动态控制
    以上可以从我的《利用Spring来管理控制自己的应用程序》专题演讲资料中获取到更加详细的信息,包括示例的源程序,地址为     http://yulimin.javaeye.com/blog/52354
    先说一下上面两种方法的不同与缺点:
    1、通过 Spring 的 Log4jConfigListener,则必须在后台打开线程,现定时扫描,然后来定时工作,有点浪费;     2、通过 JMX 动态控制的则必须供一个管理的端口,不仅有可能端口被占用(当然有个 workaround 来解决它),还有存在 防火墙等等需要配置这个管理端口进行对外暴露等等。
    虽然上述两种方法存在着一些不足,但是这两种方法在特定的场合下,都可以很好地来利用它进行完美地工作。
    现在,利用它进行封装与扩展,我们可以巧妙地进行定制,并通过 Web Console 界面来更方便地进行动态切换配置信息,而且不需要重新启动正在运行中的应用程序。
     二、分析
    通过分析 Log4jConfigListener,完整的类名为 org.springframework.web.util.Log4jConfigListener ,可以得到动态加载的过程与原理。
    Log4jConfigListener.java

    

public class Log4jConfigListener implements ServletContextListener {
 
    public void contextInitialized(ServletContextEvent event) {
       Log4jWebConfigurer.initLogging(event.getServletContext());
    }
 
    public void contextDestroyed(ServletContextEvent event) {
       Log4jWebConfigurer.shutdownLogging(event.getServletContext());
    }
}
    进而可以得知,一切都是由 Log4jWebConfigurer 来进行操作了,再分析其中的代码,可以得到 Log4jWebConfigurer 的工作过程,并由此进行到 Log4jConfigurer 中。

    最后我们可以得到最直接有用的三个方法,分别如下:
    1、Log4jConfigurer.initLogging(location);
    根据给定的配置文件进行初始化日志配置
    2、Log4jConfigurer.initLogging(location, refreshInterval);
    根据给定的配置文件和间隔时间,进行初始化日志配置并定时重新加载配置文件,
    3、Log4jConfigurer.shutdownLogging();
    关闭日志
    根据以上分析,接下来就是需要进行重新封装的工作了,我们同时保留原来的定时加载的功能,但通过开关进行设置,同时对整个功能进行封装与扩展。
   三、封装与扩展
    1、设计一个名为 Log4JRefreshInterval 的 JavaBean
    1.1 定义如下可配置选项:

   

     private String CLASSPATH = "classpath:";
    private String location = CLASSPATH + "log4j.xml" ;
    private String locationRunning = location ;
    private long refreshInterval = 60000;
    private long refreshSecond = 0;  
    private long refreshMinute = 0;   
    private long refreshHour = 0;    
    private boolean refreshDaemon = false ;

    增加 refreshDaemon 开关,在配置里根据需要要打开是否定时进行加载日志的配置文件;
    增加一系列的时间配置参数,毫秒、秒、分、时,然后对这些时间进行加和,总和为定时的时间
    refreshHour * 3600 * 1000 + refreshMinute * 60 * 1000 + refreshSecond * 1000 + refreshInterval;
    1.2 封装方法如下方法进行控制

   

 publicinterface ILog4JRefreshInterval
{  
    public void init(); // 根据配置信息初始化日志
    public void destroy(); // 销毁日志
    public void refreshIntervalThread(); // 定时加载日志的配置信息
    public void refreshIntervalImmediately(); // 立即加载默认的日志配置信息
   public void refreshIntervalImmediatelyByFilePath(String log4jFilePath); // 立即加载指定的日志配置文件
   
    public void refreshIntervalImmediately( boolean isXmlConfig,String log4jConfigInfo); // 立即加载指定的日志配置文件
    public String getRunningConfing() throws Exception; // 获取正在运行的日志配置信息
}

    1.3 构建页面
    由于将通过 Web Console 页面进行管理控制,也更加方便,当然也可以通过 Web Services 等等之类的,因为 POJO 所以可以根据项目的实际情况来加以选择。
    创建 index.html 文件,代码如下:

   

 
</ head >
< body >
< img src = "logger.jpg" alt = " 日志动态配置管理控制台 " />
< form action = "log4JRefresh.do" method = "post" >
    < p > 配置内容:(两者只取其一) </ p >
    < p >< input checked type = "radio" name = "configMethod"
onclick = "isXmlConfig.disabled=true;log4jConfigInfo.value
='';log4jConfigInfo.disabled=true;log4jFilePath.disabled
=false;log4jFilePath.focus();" /> 1、 Log4J 的文件路径,格式如下:
< input name = "log4jFilePath" ondblclick = "this.value='/var/
log4j.properties'" size = "100" /></ p >
    < ul >
    < li > classpath:log4j.properties 或者 classpath:log4j.xml </ li >
    < li > file:C:/log4j.properties 或者 file:C:/log4j.xml </ li >
    < li > C:/log4j.properties 或者 C:/log4j.xml </ li >
    </ ul >
    < p >< input type = "radio" name = "configMethod" onclick = "log4jFilePath.value='';log4jFilePath.disabled=
true;isXmlConfig.disabled=false;log4jConfigInfo.disabled=
false;log4jConfigInfo.focus();" /> 2、 Log4J 的详细配置信息: </ p >
    < p > 配置方式:
    < select name = "isXmlConfig" >
       < option value = "0" selected > Property </ option >
       < option value = "1" > XML </ option >
    </ select > (请根据实际的配置内容选择相应的类型) </ p >
    < textarea name = "log4jConfigInfo" rows = "23" cols = "123" ondblclick = "this.value=''" >
 
# default.layout.ConversionPattern = %t [%c{3}]-[%-5p]:[%L]:%m%n
default.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [%t] [%c{3}]-[%-5p]:[%L]:%m%n
 
</ textarea >
    < input type = "submit" value = " 提 交 " />   
    < input type = "reset" value = " 重 置 " />
</ form >
< br >
< a href = "log4JRunning.do" title = " 查看正在运行的 Log4J 配置信息。 " > 查看配置信息 </ a >
  
< a href = "log4JRefresh.do" title = " 立刻重新加载通过配置文件加载的 Log4J 配置信息。 " > 立刻重新加载 </ a >
  
< a href = "log4JShutdown.do" title = " 立刻停止 Log4J 的服务,所有日志关停。 " > 立刻停止日志 </ a >
  
< a href = "HelloServlet" title = " 调用 Servlet 来测试 Log4J 信息是否正常。 " > 测试是否正常 </ a >
</ body >
</ html >

1.4 构建 Controller
      在此示例中直接采用简单易用的 Spring MVC 进行控制。       直接 implements Controller 来创建三个 Controller ,分别如下:      Log4JRefreshController  重新加载日志配置文件的控制器      Log4JShutdownController 关闭日志的控制器      Log4JRunningController  获取正在运行的日志配置信息的控制器
    1.5 构建一个 Servlet
    用来测试日志配置信息是否成功加载

   

 publicclass HelloServlet extends HttpServlet
{
    privatestaticfinallongserialVersionUID = -4506255419343502640L;
    privatestaticfinal Logger logger = Logger.getLogger(HelloServlet.class);
 
    publicvoid doGet(HttpServletRequest request,HttpServletResponse response)
    {
       try
       {
           ServletOutputStream out = response.getOutputStream();
       out.println("<html xmlns=/"http://www.w3.org/1999/xhtml/">");
           out.println("<head>");
           out.println("<meta http-equiv=/"Content-Type/" content=/"text/html; charset=GBK/"/>");
           out.println("<title>动态配置测试页面</title>");
           out.println("<link href=/"facade.css/" rel=/"stylesheet/" type=/"text/css/"/>");
           out.println("</head><body>");
           out.println("<img src=/"logger.jpg/" alt=/"日志动态配置管理控制台/"/>");
           out.println("<p>Begin:" + new Date() + "<br/>");
           if(logger.isDebugEnabled())
           {
              logger.debug("DEBUG级别的信息:debugging<p>");
              out.println("DEBUG级别的信息:debugging</p>");
                         }
           if(logger.isInfoEnabled())
           {
              logger.info("INFO级别的信息:information<p>");
              out.println("INFO级别的信息:information</p>");
                         }
           logger.warn("warning");
           logger.error("error");
           logger.fatal("fatal");
           out.println("End:" + new Date() + "<br/>");
           out.println("<p><a href=/"JavaScript:history.go(-1)/">返  回</a>");
           out.println("</p></body></html>");
           out.flush();
       }
       catch(IOException e)
       {
           e.printStackTrace();
       }
    }
}

    1.6 构建两个 JSP 页面
    一个成功的页面 RefreshSuccess.jsp,代码如下

   

 <%@page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>动态配置操作成功</title>
<link href="facade.css" rel="stylesheet" type="text/css"/>
</head>
 
<body>
<img src="logger.jpg" alt="日志动态配置管理控制台"/>
<p>
恭喜:动态配置操作成功!
<p>
当前的配置为:
<textarea rows="23" cols="123" ReadOnly><%=request.getAttribute("RunningConfig")%></textarea>
<p>
<a href="JavaScript:history.go(-1)">返  回</a>
</body>
</html>

  以及一个失败的页面 RefreshFailed.jsp ,代码略
    1.7 配置 Spring 的 Bean 文件(Service)
    beanRefLog4J.xml

   

 
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
    <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.
PropertyPlaceholderConfigurer">
       <property name="locations">
           <list>
              <value>classpath:LoggerConsole.properties</value>
           </list>
       </property>
    </bean>
    <bean id="log4JRefreshInterval" class="net.agile.springtime.logger.util.Log4JRefreshInterval" init-method="init" destroy-method="destroy">
       <property name="location" value="${logger.log4j.location}"/>
       <property name="refreshDaemon" value="${logger.log4j.refreshDaemon}"/>
       <property name="refreshInterval" value="${logger.log4j.refreshInterval}"/>
       <property name="refreshSecond" value="${logger.log4j.refreshSecond}"/>       <property name="refreshMinute" value="${logger.log4j.refreshMinute}"/>       <property name="refreshHour" value="${logger.log4j.refreshHour}"/>    </bean>
</beans>

    1.8 配置 Spring 的 Bean 文件(MVC)
    beanRefMVC.xml

  

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
       <bean id="urlMapping" class="org.springframework.web.servlet.handler.
SimpleUrlHandlerMapping">
       <property name="mappings">
           <props>
              <prop key="/log4JRefresh.do">log4JRefreshController</prop>
              <prop key="/log4JShutdown.do">log4JShutdownController</prop>
              <prop key="/log4JRunning.do">log4JRunningController</prop>
           </props>
       </property>
    </bean>
    <bean id="viewResolver" class="org.springframework.web.servlet.
view.InternalResourceViewResolver">
       <property name="prefix">
           <value>/WEB-INF/jsp/</value>
       </property>
       <property name="suffix">
           <value>.jsp</value>
       </property>
    </bean>
    <bean id="log4JRefreshController" class="net.agile.springtime.logger.web.Log4JRefreshController">
       <property name="successView" value="RefreshSuccess"/>
       <property name="failedView" value="RefreshFailed"/>
       <property name="log4JRefreshInterval"
ref="log4JRefreshInterval"/>
    </bean>
       <bean id="log4JShutdownController" class="net.agile.springtime.logger.web.Log4JShutdownController">
       <property name="successView" value="RefreshSuccess"/>
       <property name="failedView" value="RefreshFailed"/>
       <property name="log4JRefreshInterval"
 ref="log4JRefreshInterval"/>
    </bean>
       <bean id="log4JRunningController" class="net.agile.springtime.logger.web.Log4JRunningController">
       <property name="successView" value="RefreshSuccess"/>
       <property name="failedView" value="RefreshFailed"/>
       <property name="log4JRefreshInterval"
ref="log4JRefreshInterval"/>
    </bean>
</beans>

    1.9 在你现有的应用中引入这两个 Spring 的配置文件,或者根据你的项目结构进行调整即可

   

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
    <import resource="beanRefLog4J.xml" />
    <import resource="beanRefMVC.xml" />
</beans>

    1.10 配置 web.xml 文件
    在 web.xml 中增加 Spring MVC 的配置以及测试用的 Servlet 的配置,完整的配置如下:

   

 
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
    <display-name>Spring Log4J Refresh Web Application</display-name>
    <description>Spring Log4J Refresh Web Application</description>
       <context-param>
       <param-name>contextConfigLocation</param-name>
       <param-value>/WEB-INF/classes/beanRefApplication.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener
</listener-class>
    </listener>
       <servlet>
       <servlet-name>dispatcherServlet</servlet-name>
       <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
       <load-on-startup>50</load-on-startup>
    </servlet>
   <servlet>
       <servlet-name>HelloServlet</servlet-name>
       <display-name>HelloServlet</display-name>
       <servlet-class>net.agile.springtime.logger.web.HelloServlet</servlet-class>
    </servlet>
    <servlet-mapping>
       <servlet-name>HelloServlet</servlet-name>
       <url-pattern>/HelloServlet</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
       <servlet-name>dispatcherServlet</servlet-name>
       <url-pattern>*.do</url-pattern>
    </servlet-mapping>
</web-app>

    这样,你的项目就具有了动态日志配置切换的功能了。
  四、校验日志是否成功改变

    1. 启动应用,访问 http://localhost:8080/Log4J_Spring_Web/  如下图所示

   

    可以选择"Log4J的文件路径"或者直接输入详细的配置文件的"Log4J的详细配置信息"方式进行动态切换

    2.查看配置信息

      可以查看到当前正在运行的配置信息,如下图:

   

  3.立刻重新加载

      可以立即加载默认的日志配置 文件,并返回默认的配置内容,如下图:

   

    4.立刻停止日志

      可以立即停止日志,并显示停止前的日志配置信息,如下图:

   

    5.测试是否正常

     可通过此测试用的 Servlet 来查看日志是否成功,在重新加载新的配置文件后,建议都调用一下来测试是否切换成功,如下图:

        先提交 INFO 等级的配置

   

    然后查看测试的结果信息,如下:

 

   

    只显示 INFO 级别的信息

   更改为 DEBUG级别,并提交,如下:

   

    然后查看测试的结果信息,如下:

    五、总结

    一个简单的封装与扩展,实现了对日志的配置进行动态切换,调试、监控和检查系统的运行时信息,方便了许多,提升了开发效率。

用5毫欧采样电阻实现高精度电流检测?数字可调电源控制板的硬件设计陷阱 本文深入探讨了在数字可调电源控制板设计中,如何利用5毫欧采样电阻实现高精度电流检测。从微小信号放大电路设计、采样电阻布局热管理,到电源切换电池管理电路优化,提供了全面的硬件设计解决方案和实用技巧,帮助工程师规避常见设计陷阱,提升系统性能。 阅读详情

相关推荐

如何使用C#自带的GDI+双缓冲类BufferedGraphics实现双缓冲功能

小白摸索着编写一个上位机界面,将遇到的问题及解决方法记录下,以供后来的小白使用哈。这篇文章解决的问题是在绘图时候的闪烁问题。其中网上有些介绍的设置控制方式controlstyle的方法,这个方法我的理解是比较适合于在一个完整的窗口当中绘图。如果要在一个窗口当中的内部容器或者控件内画图的话就不太适合,通常按照前述的方法设置后没有任何效果。对于在窗口内部的绘图的来说,比较有效的方法是在内存当中开辟一块

z20110411的博客 4781

Spring如何动态自定义logback日志目录详解

主要给大家介绍了关于Spring如何动态自定义logback日志目录的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

一种具有多角度喷射功能的消防机器人的制作方法.docx

一种具有多角度喷射功能的消防机器人的制作方法.docx

Spring MVC集成 Log4j

目录(?)[-] 项目目录项目依赖log4jpropertiesSpring MVC Controller Message Logging源码下载 环境及工具:  Log4j 2.6.2  Spring 4.3.2.RELEASE  Maven 3  Tomcat 8(idea中tomcat配,参考:http://blog.csdn.net/jiankunkin

zhangbin666的专栏 909

项目生产环境log4jspring MVC视图解析viewResolvers的配置

为什么80%的码农都做不了架构师?>>> ...

weixin_33670713的博客 119

Spring Boot的日志文件

Spring Boot的日志文件

m0_62360856的博客 990

java log4j 动态配置_Java Web动态配置log4j

//查询logging level,并传到web页面@RequestMapping(value="/logging_view", method =RequestMethod.GET)publicString toLoggingView(HttpServletRequest request,Model model){Properties props= newProperties();try{//读取...

weixin_27012835的博客 287

log4j.properties 详解配置步骤

一、log4j.properties 的使用详解 1.输出级别的种类 ERROR、WARN、INFO、DEBUGERROR 为严重错误 主要是程序的错误WARN 为一般警告,比如session丢失INFO 为一般要显示的信息,比如登录登出DEBUG 为程序的调试信息   2.配置日志信息输出目的地 log4j.appender.appenderName = fully.qualifi

yinbenyang的专栏 301

Spring Log4J 进行动态日志配置切换

引言:     在开发生产环境中,我们有时候需要对日志配置进行动态切换,要调试、监控和检查系统的运行时信息。     一般有两种方法     1、通过 SpringLog4jConfigListener 在启动时开启定时器进行定时加载配置文件     2、通过 JMX 动态控制     以上可以从我的《利用Spring来管理控制自己的应用程序》专题演讲资料中获取到更加详细的信息

iCreateX的专栏 1987

利用 Spring Log4J 巧妙地进行动态日志配置切换并立即生效

  [b]引言:[/b]   在开发生产环境中,我们有时候需要对日志配置进行动态切换,要调试、监控和检查系统的运行时信息。   [b]一般有两种方法[/b]   1、通过 SpringLog4jConfigListener 在启动时开启定时器进行定时加载配置文件   2、通过 JMX 动态控制   以上可以从我的《利用Spring来管理控制自己的应用程序》专题演...

简单就是美! 311

智能生成 Spring-JCL 日志发现应用:快马平台 5 分钟实现动态日志框架切换

最近在开发一个需要灵活切换日志框架的 Spring Boot 项目时,遇到了日志配置的挑战。经过实践,我发现通过 Spring-JCL(Spring 对 Apache Commons Logging 的实现)可以轻松实现动态日志框架发现和切换。下面分享一下我的经验,以及如何利用。的 AI 辅助,我只需描述需求就能快速生成完整的日志配置代码,省去了大量查找文档的时间。对于需要灵活日志管理的项目,这套方案既保持了代码的简洁性,又提供了运行时的灵活性,是 Spring 生态中日志处理的优雅解决方案。

JetRaven12的博客 405

切换Log4j级别配置

欢迎和大家交流技术相关问题:邮箱: jiangxinnju@163.com博客园地址: http://www.cnblogs.com/jiangxinnjuGitHub地址: https://github.com/jiangxincode知乎地址: https://www.zhihu.com/people/jiangxinnju 做一个产品或者项目,在测试时一般要打印详细的log,发布以后...

weixin_30378623的博客 156

Spring Boot 3.3高级日志配置详解:从 Logback 到 Log4j 2 的全面掌握

从 Logback 切换Log4j 2 涉及到依赖管理、配置文件的更改、属性设置的调整以及可能的性能优化。Spring Boot 3.3 提供了灵活的配置选项,使得这种切换相对简单。确保在切换过程中测试你的应用程序,以验证日志记录行为符合预期。

sunsiny 1508

springboot学习系列:使用log4j2日志框架,根据spring变量动态创建日志文件

旧项目切换为微服务框架,其中为了兼容旧项目的日志框架,使用了log4j2框架。切换log4j2框架之后,日志配置和原来的logback的日志配置有比较大的不同,其中没办法根据环境变量读取进而进行变量的转换。本篇文章主要是针对这种情况进行解决。

枫夜 3031

Log4j详细教程

一、入门实例 1.新建一个JAva工程,导入包log4j-1.2.17.jar,整个工程最终目录如下 2、src同级创建并设置log4j.properties ### 设置### log4j.rootLogger = debug,stdout,D,E ### 输出信息到控制抬 ### log4j.appender.stdout = org.apache.log4j.Conso...

weixin_34233421的博客 141

SpringBoot 005】 整合log4j2.xml 配置详解

如果启动时出现 Class path contains multiple SLF4J bindings ,说明还有多个jar 里面包含,需要排查移除。1、需要将 spring-boot-starter-web 中的默认日志系统排除。如果引入的jar 很多,可能其它包里面的也要排除。每一行都添加的注释。

qq_32057039的博客 1318

用AI快速验证SLF4J日志方案原型

对于需要快速验证技术方案的场景,这种低成本的试错方式确实高效。建议新手可以从简单的日志级别调整开始体验,逐步探索更复杂的日志聚合、ELK集成等高级功能。比如我原本只写了基础日志代码,AI建议补充了MDC上下文日志、异步日志等高级特性,还自动生成了对应的示例代码注释。最近在开发一个Java项目时需要引入日志功能,调研发现SLF4J是最常用的日志门面框架。的一键部署功能特别实用。生成的原型系统可以直接在线运行,团队成员通过浏览器就能看到实时日志效果,不用每个人都配置本地环境。对于需要演示不同日志方案的项目,

YellowSun24的博客 434

Spring Boot 基础系列教程 | 第二十五篇:对log4j进行多环境不同日志级别的控制

推荐 Spring Boot/Cloud 视频: Java 微服务实践 - Spring Boot Java 微服务实践 - Spring Cloud 之前介绍了在《Spring boot中使用log4j记录日志》,仅通过log4j.properties对日志级别进行控制,对于需要多环境部署的环境不是很方便,可能我们在开发环境大部分模块需要采用DEBUG级别,在测试环境可能需要小部分采用DEB...

qq_43253123的博客 251
上一篇: Subversion1.5发布
下一篇: spring学习资料和知识库集锦
elimago
博客等级 码龄25年 105粉丝 18原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值