log4j重定向stdout和stderr到log文件

        我们使用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,因此我们实现一个这样的类:

import java.io.PrintStream;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


public class StdOutErrRedirect {
	private final static Log logger = LogFactory.getLog(StdOutErrRedirect.class);

    public static void redirectSystemOutAndErrToLog() {
    	PrintStream printStreamForOut = createLoggingWrapper(System.out, false);
    	PrintStream printStreamForErr = createLoggingWrapper(System.out, true);
        System.setOut(printStreamForOut);
        System.setErr(printStreamForErr);
    }

    public static PrintStream createLoggingWrapper(final PrintStream printStream, final boolean isErr) {
        return new PrintStream(printStream) {
        	@Override
            public void print(final String string) {
        		if (!isErr){
        			logger.debug(string);
        		}else{
        			logger.error(string);
        		}
            }
        	@Override
            public void print(boolean b) {
        		if (!isErr){
        			logger.debug(Boolean.valueOf(b));
        		}else{
        			logger.error(Boolean.valueOf(b));
        		}
            }
        	@Override
            public void print(char c) {
        		if (!isErr){
            		logger.debug(Character.valueOf(c));
        		}else{
        			logger.error(Character.valueOf(c));
        		}
            }
        	@Override
            public void print(int i) {
        		if (!isErr){
        			logger.debug(String.valueOf(i));
        		}else{
        			logger.error(String.valueOf(i));
        		}
            }
        	@Override
            public void print(long l) {
        		if (!isErr){
        			logger.debug(String.valueOf(l));
        		}else{
        			logger.error(String.valueOf(l));
        		}
            }
        	@Override
            public void print(float f) {
        		if (!isErr){
        			logger.debug(String.valueOf(f));
        		}else{
        			logger.error(String.valueOf(f));
        		}
            }
        	@Override
            public void print(double d) {
        		if (!isErr){
            		logger.debug(String.valueOf(d));
        		}else{
        			logger.error(String.valueOf(d));
        		}
            }
        	@Override
            public void print(char[] x) {
        		if (!isErr){
            		logger.debug(x == null ? null : new String(x));
        		}else{
        			logger.error(x == null ? null : new String(x));
        		}
            }
        	@Override
            public void print(Object obj) {
        		if (!isErr){
        			logger.debug(obj);
        		}else{
        			logger.error(obj);
        		}
            }
        };
    }
}

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

 

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

 

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

例如:

 

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class StdOutErrInitializer implements ServletContextListener {

	@Override
	public void contextDestroyed(ServletContextEvent arg0) {

	}

	@Override
	public void contextInitialized(ServletContextEvent arg0) {
		StdOutErrRedirect.redirectSystemOutAndErrToLog();
	}

}

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

 

	
		com.polyvirtual.webapp.util.StdOutErrInitializer
	

 

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






    
        
            
        
    
    
      
		
		
		  
			  
		  
	   

    
        
    

    
        
        
        
    

 

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

你可能感兴趣的:(log4j重定向stdout和stderr到log文件)