我们使用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
<listener> <listener-class>com.polyvirtual.webapp.util.StdOutErrInitializer</listener-class> </listener>
log4j.xml的配置文件,举个例子可以简单的配置成这样:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"> <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender"> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%p [%t] %c{1}.%M(%L) | %m%n"/> </layout> </appender> <appender name="FILE" class="org.apache.log4j.RollingFileAppender"> <param name="File" value="polyvirtual_logs/polyvirtual_portal.log"/> <param name="MaxFileSize" value="512KB" /> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%d - %c -%-4r [%t] %-5p %x - %m%n" /> </layout> </appender> <logger name="my.test"> <level value="DEBUG"/> </logger> <root> <level value="WARN"/> <appender-ref ref="CONSOLE"/> <appender-ref ref="FILE"/> </root> </log4j:configuration>
这样System.out和System.err的输入都重定向写入到log文件里了,同时也输出到了Console,便于在IDE里开发时查看。
相关推荐
例如,可用于将浏览器console重定向到process.stdout和process.stderr 。安装npm install console-redirect --save例子 var redirect = require ( 'console-redirect' )// redirect browser's console.log and ...
controller日志: 输出到stdout,通过启动参数中的–log_dir可已配置输出到文件,重定向到文件后会自动轮转,但不会自动清理 accesslog:输出到stdout,通过nginx-configuration中的字段可以配置输出到哪个文件。...
现在可以根据需要将日志文件重定向到STDOUT和STDERR,可以对其进行自定义以仅重定向访问日志或仅重定向错误日志,或者两者都不重定向。 可以通过设置LOG_CONF环境变量来完成,支持的值为: 价值 行为 全部 将访问...
这允许(分别)记录一个进程的stdout和stderr,如果您没有记录任何内容,则输出不会与在终端上看到的输出不同。 $ cargo install faketty $ faketty bazel build :target > log/out 2> log/err ~~~~~~~~~~~~~~~~...
catalina.out是tomcat把stdout和stderr重定向到文件后生成的日志文件,其生成是不受logging.properties 或 log4j.properties配置文件所影响的,需要另行安装工具(如cronolog或rotatelogs之类)进行处理。...
这里的每条规则都指定'log.stdout'和'log.stderr',可用于重定向snakemake提交的每个PBS作业的stdout和stderr。 使用-o {log.stdout} -e {log.stderr}指定时qsub在呼叫--cluster的参数snakemake 。 添加新规
它还在 Pry 会话期间重定向$stdout和$stderr ,以捕获从任何puts或类似语句发出的所有输出。 所有输出数据在记录后转发到原始配置的Pry.config.output机制,并且这个插件应该(希望)尊重任何配置的输出器。 日志...
:nail_polish: 花哨的输出,具有回退功能,适用于最小的环境 :electric_plug: 可插拔的记者 :laptop_computer: 一致的命令行界面(CLI)经验 :label: 标签支持 :bus_stop: 将console和stdout/stderr重定向到consola...
易于使用 :nail_polish: 花哨的输出,具有回退功能,适用于最小的环境 :electric_plug: 可插拔的记者 :laptop: 一致的命令行界面(CLI)经验 :label: 标签支持 :bus_stop: 将console和stdout/stderr重定向到consola...
logexec 是一个简单的命令,它运行一个命令并将其 stdout 发送到INFO级别的 syslog,并将其 stderr 发送到ERROR级别的 syslog。 例子: logexec -tag=hello echo hi 导致在INFO级别记录以下内容。 Oct 22 23:18...
至此do_basic_setup()函数返回init(),在释放启动内存段(free_initmem())并给内核解锁以后,init()打开 /dev/console设备,重定向stdin、stdout和stderr到控制台,最后,搜索文件系统中的init程序(或者由init=...