运行环境下动态修改日志级别
2017-06-25 00:00
471 查看
摘要: 调试能力是程序员能力重要组成部分,而日志几乎可以说是我们调试的根本,通过分&...
调试能力是程序员能力重要组成部分,而日志几乎可以说是我们调试的根本,通过分析日志我们可以了解程序的运行情况,可以分析出那个环节出现问题。
但是调试日志过多,很多无用的日志信息占了95%,甚至更高。严重影响我们的视线、严重影响我们定位相关日志记录、严重影响我们的工作效率。
特别是在测试环境下(测试环境一般都是编译好的,不能像开发环境一样顺畅的、方便的使用断点),修改日志级别需要不停的启动或重新部署服务器。这个时候我们需要动态的改变日志的级别。
我的做法是:把不相关的代码日志级别设置为warn甚至error.把当前业务的代码日志级别设置为debug或info这就需要动态的修改日志的级别(修改日志配合,然后重新部署也可以,不过效率太低)。
首先是log4j动态修改日志级别,这个很简单,直接看我的代码(log4j.jsp),使用jsp也是方便我随时copy,随时根据需要修改。
再来看log4j2,代码如下:
log4j2要比log4j复杂一点
当然最后,也再着重提示一下这个代码的使用场景和存在的问题
使用场景:
第一、开发环境:几乎没必要
第二、测试环境:建议在问题不好定位,日志太多的情况下使用
第三、生产环境:不要使用,很危险
存在的问题:动态修改日志级别,会导致我日志输出的内容减少,很多时候我们的日志是输出到不同的目标(控制台、文件、数据库),这样一修改,就会导致所有的日志输出目标的日志减少,特别是在生产环境。宁愿效率低一点,也要保证日志的完整性,这样才能保证可追溯性。
调试能力是程序员能力重要组成部分,而日志几乎可以说是我们调试的根本,通过分析日志我们可以了解程序的运行情况,可以分析出那个环节出现问题。
但是调试日志过多,很多无用的日志信息占了95%,甚至更高。严重影响我们的视线、严重影响我们定位相关日志记录、严重影响我们的工作效率。
特别是在测试环境下(测试环境一般都是编译好的,不能像开发环境一样顺畅的、方便的使用断点),修改日志级别需要不停的启动或重新部署服务器。这个时候我们需要动态的改变日志的级别。
我的做法是:把不相关的代码日志级别设置为warn甚至error.把当前业务的代码日志级别设置为debug或info这就需要动态的修改日志的级别(修改日志配合,然后重新部署也可以,不过效率太低)。
首先是log4j动态修改日志级别,这个很简单,直接看我的代码(log4j.jsp),使用jsp也是方便我随时copy,随时根据需要修改。
<%@page import="java.util.Enumeration"%> <%@page import="org.apache.log4j.Logger"%> <%@page import="org.apache.commons.lang3.StringUtils"%> <%@page import="org.apache.log4j.Level"%> <%@page import="java.util.ArrayList"%> <%@page import="java.util.Iterator"%> <%@page import="java.util.Collection"%> <%@page import="java.util.Arrays"%> <%@page import="java.util.Collections"%> <%@page import="org.apache.log4j.LogManager"%> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <% //需要修改的日志名称和级别 String logName = request.getParameter("logName"); String level = request.getParameter("level"); //传递了参数 if(StringUtils.isNotEmpty(logName)&&StringUtils.isNotEmpty(level)){ System.out.println(logName.trim()); Level l = Level.toLevel(level); System.out.println(l); Logger logger = LogManager.getLogger(logName.trim()); logger.setLevel(l);//修改日志级别 System.out.println(logger.getLevel()); } //获取所有的日志 Enumeration<Logger> loggers = LogManager.getCurrentLoggers(); //分类存放,方便页面展示 ArrayList<Logger> debugs = new ArrayList(); ArrayList<Logger> infos = new ArrayList(); ArrayList<Logger> warns = new ArrayList(); ArrayList<Logger> errors = new ArrayList(); while(loggers.hasMoreElements()){ Logger logger = loggers.nextElement(); Level l = logger.getLevel(); int i = logger.getLevel().toInt(); if(i<=Level.ERROR.toInt()){ errors.add(logger); continue; } if(i<=Level.WARN.toInt()){ warns.add(logger); continue; } if(i<=Level.INFO.toInt()){ infos.add(logger); continue; } if(i<=Level.DEBUG.toInt()){ debugs.add(logger); continue; } } %> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>log4j</title> <style type="text/css"> .title{ height: 25px; background-color: #ccc; color: #000; font-weight: bold; padding-left: 20px; margin-bottom: 2px; } </style> </head> <body> <form action="" style="padding-left: 50px;line-height: 30px;"> 日志名称:<input name="logName" style="width: 500px;"><br/> 日志级别:<select name="level"> <option>debug</option> <option>info</option> <option>warn</option> <option>error</option> </select><br/> <input type="submit" value="修改日志级别"> </form> <div class="title">debug</div> <% for(int i=0;i<debugs.size();i++ ){ Logger logger = debugs.get(i); out.println(logger.getName()+"</br>"); } %> <div class="title">info</div> <% for(int i=0;i<infos.size();i++ ){ Logger logger = infos.get(i); out.println(logger.getName()+"</br>"); } %> <div class="title">warn</div> <% for(int i=0;i<warns.size();i++ ){ Logger logger = warns.get(i); out.println(logger.getName()+"</br>"); } %> <div class="title">error</div> <% for(int i=0;i<errors.size();i++ ){ Logger logger = errors.get(i); out.println(logger.getName()+"</br>"); } %> </body> </html>
再来看log4j2,代码如下:
<%@page import="com.c503.sc.base.entity.SysLoginParaEntity"%> <%@page import="org.springframework.web.context.support.WebApplicationContextUtils"%> <%@page import="org.springframework.context.ApplicationContext"%> <%@page import="com.c503.sc.system.service.ILoginService"%> <%@page import="com.alibaba.fastjson.JSON"%> <%@page import="com.c503.sc.utils.cache.ICache"%> <%@page import="com.c503.sc.utils.cache.CacheManager"%> <%@page import="com.c503.sc.system.utils.CacheManagerFactory"%> <%@page import="org.apache.commons.lang3.StringUtils"%> <%@page import="org.apache.logging.log4j.Level"%> <%@page import="java.util.ArrayList"%> <%@page import="org.apache.logging.log4j.core.Logger"%> <%@page import="java.util.Iterator"%> <%@page import="java.util.Collection"%> <%@page import="java.util.Arrays"%> <%@page import="java.util.Collections"%> <%@page import="org.apache.logging.log4j.core.LoggerContext"%> <%@page import="org.apache.logging.log4j.LogManager"%> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <% //需要修改的日志名称和级别 String logName = request.getParameter("logName"); String level = request.getParameter("level"); if(StringUtils.isNotEmpty(logName)&&StringUtils.isNotEmpty(level)){ //传递了参数 System.out.println(logName.trim()); Level l = Level.toLevel(level); System.out.println(l); //注意此Logger为org.apache.logging.log4j.core.Logger (实现) //一般我们使用的是 org.apache.logging.log4j.Logger (接口),接口没有setLevel方法 Logger logger = (Logger)LogManager.getLogger(logName.trim()); logger.setLevel(l); System.out.println(logger.getLevel()); } /* 同样的道理,获取所有的日志,先要获取上下文,再获取所有的日志 * 此处获取日志上线文为org.apache.logging.log4j.core.LoggerContext(实现) * 一般我们使用的是org.apache.logging.log4j.spi.LoggerContext (接口),接口没有getLoggers方法 */ LoggerContext logContext = (LoggerContext)LogManager.getContext(); //获取所有日志 Collection<Logger> loggers = logContext.getLoggers(); Iterator<Logger> it = loggers.iterator(); //分类存放,方便页面展示 ArrayList<Logger> debugs = new ArrayList(); ArrayList<Logger> infos = new ArrayList(); ArrayList<Logger> warns = new ArrayList(); ArrayList<Logger> errors = new ArrayList(); for(;it.hasNext(); ){ Logger logger = (Logger) it.next(); int i = logger.getLevel().intLevel(); if(i<=Level.ERROR.intLevel()){ errors.add(logger); continue; } if(i<=Level.WARN.intLevel()){ warns.add(logger); continue; } if(i<=Level.INFO.intLevel()){ infos.add(logger); continue; } if(i<=Level.DEBUG.intLevel()){ debugs.add(logger); continue; } } %> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>log4j2</title> <style type="text/css"> .title{ height: 25px; background-color: #ccc; color: #000; font-weight: bold; padding-left: 20px; margin-bottom: 2px; } </style> </head> <body> <form action="" style="padding-left: 50px;line-height:30px;"> 日志名称:<input name="logName" style="width: 500px;"><br/> 日志级别:<select name="level"> <option>debug</option> <option>info</option> <option>warn</option> <option>error</option> </select><br/> <input type="submit" value="修改日志级别"> </form> <div class="title">debug</div> <% for(int i=0;i<debugs.size();i++ ){ Logger logger = debugs.get(i); out.println(logger.getName()+"</br>"); } %> <div class="title">info</div> <% for(int i=0;i<infos.size();i++ ){ Logger logger = infos.get(i); out.println(logger.getName()+"</br>"); } %> <div class="title">warn</div> <% for(int i=0;i<warns.size();i++ ){ Logger logger = warns.get(i); out.println(logger.getName()+"</br>"); } %> <div class="title">error</div> <% for(int i=0;i<errors.size();i++ ){ Logger logger = errors.get(i); out.println(logger.getName()+"</br>"); } %> </body> </html>
log4j2要比log4j复杂一点
当然最后,也再着重提示一下这个代码的使用场景和存在的问题
使用场景:
第一、开发环境:几乎没必要
第二、测试环境:建议在问题不好定位,日志太多的情况下使用
第三、生产环境:不要使用,很危险
存在的问题:动态修改日志级别,会导致我日志输出的内容减少,很多时候我们的日志是输出到不同的目标(控制台、文件、数据库),这样一修改,就会导致所有的日志输出目标的日志减少,特别是在生产环境。宁愿效率低一点,也要保证日志的完整性,这样才能保证可追溯性。
相关文章推荐
- [C#] 将NLog输出到RichTextBox,并在运行时动态修改日志级别过滤
- [C#] 将NLog输出到RichTextBox,并在运行时动态修改日志级别过滤
- 基于Spring框架开发的Web程序,如何动态修改日志级别
- springboot【21】日志管理之1.5.x新特性:动态修改日志级别
- log4j2动态修改日志级别及拓展性使用
- Spring Boot 1.5.x新特性:动态修改日志级别
- Spring Boot教程(九)Spring Boot 1.5.x新特性:动态修改日志级别
- Spring Cloud Spring Boot mybatis分布式微服务云架构(四十五)动态修改日志级别(2)
- Spring Boot 1.5.x 新特性 动态修改日志级别
- 动态修改日志级别
- Spring Boot 1.5.x新特性:动态修改日志级别
- SpringBoot系列十一:SpringBoot整合Restful架构(使用 RestTemplate 模版实现 Rest 服务调用、Swagger 集成、动态修改日志级别)
- 动态修改log4j的日志级别,不重启服务器
- springboot1.5.6版本运行时动态切换日志级别
- logback动态修改配置文件实现打印不同级别日志
- Spring Cloud Spring Boot mybatis分布式微服务云架构(四十四)动态修改日志级别(1)
- 修改Oracle的Job Scheduler 日志级别及删除运行日志 推荐
- springboot动态修改系统日志级别
- 动态修改log4j日志级别
- SpringBoot动态修改日志级别