zoukankan      html  css  js  c++  java
  • 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里开发时查看。


  • 相关阅读:
    肥胖儿筛选标准
    文章索引
    面向对象66原则
    [精]Xpath路径表达式
    [精]XPath入门教程
    孕产期高危因素
    “华而不实”的转盘菜单(pie menu)
    xmind用例导excel用例,然后再用python排版
    NSObject
    [self class]与[super class]
  • 原文地址:https://www.cnblogs.com/silyvin/p/9106693.html
Copyright © 2011-2022 走看看