把在程序中的System.out.print()的信息自动转成log4j日志信息
2011-08-01 16:25
405 查看
问题:老的系统中,程序未使用log4j,而是使用System.out.println()将信息打印到了tomcat。现在客户提出要保存打印到tomcat的日志信息,引入log4j固然需要,但修改代码及后续测试的工作量与风险也让人头大。如何解决这样的问题呢? 回答:System.setOut(PrintStream ps)方法允许程序员自行定义System.out输出流,我们可以将我们改造好的PrintStream替换java原来的System.out对象。
为了能在web服务器启动以后完成这个替换的过程,我们定义一个ServletContextListener监听器,在web服务器启动时完成替换。
package com;
import java.io.PrintStream;import javax.servlet.ServletContextEvent;import javax.servlet.ServletContextListener;import org.apache.commons.logging.impl.LogFactoryImpl;/** * 把在程序中的System.out.print()的信息自动转成日志信息 */public class StdoutListener implements ServletContextListener { public void contextDestroyed(ServletContextEvent event) { } private void log(Object info) { LogFactoryImpl.getLog(getClass()).info(info); } public void contextInitialized(ServletContextEvent event) { PrintStream printStream = new PrintStream(System.out) { public void println(boolean x) { log(Boolean.valueOf(x)); } public void println(char x) { log(Character.valueOf(x)); } public void println(char[] x) { log(x == null ? null : new String(x)); } public void println(double x) { log(Double.valueOf(x)); } public void println(float x) { log(Float.valueOf(x)); } public void println(int x) { log(Integer.valueOf(x)); } public void println(long x) { log(x); } public void println(Object x) { log(x); } public void println(String x) { log(x); } }; System.setOut(printStream); System.setErr(printStream); }} 在web.xml里配置这个监听器,完善log4j.properties文件。搞定!
附:
web.xml中配置监听器:
<listener> <listener-class>com.bettersoft.filters.StdoutListener</listener-class> </listener>
我的 log4j.properties文件:
log4j.rootLogger=INFO,Stdout,Rlog4j.appender.Stdout=org.apache.log4j.ConsoleAppenderlog4j.appender.Stdout.layout=org.apache.log4j.PatternLayoutlog4j.appender.Stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %m%nlog4j.appender.R=org.apache.log4j.DailyRollingFileAppenderlog4j.appender.R.File=../logs/stdout.loglog4j.appender.R.datePattern='.'yyyy-MM-dd'.txt'log4j.appender.R.layout=org.apache.log4j.PatternLayoutlog4j.appender.R.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %m%n
说明:
log4j.rootLogger=INFO,Stdout,R 指定INFO及以上级别的日志会被输出到Stdout 和 R 两个终端
log4j.appender.Stdout=org.apache.log4j.ConsoleAppender 输出到控制台
log4j.appender.R=org.apache.log4j.DailyRollingFileAppender 指定了每天产出一个日志文件(R是自定义的)。
log4j.appender.R.File=../logs/stdout.log 指定了日志文件的路径和文件名,这样配置以后,我的日志文件就在D:\tomcat5\logs目录下。
log4j.appender.R.datePattern='.'yyyy-MM-dd'.txt' 指定了日志文件名的格式,比如8月6日的文件名就是stdout.log.2011-08-06.txt。
经过测试发现,当天的日志会被暂存在名为 stdout.log的日志文件中,只有日期更迭以后才会自动变更为符合
格式的文件名。
续:
经过试验, 如果在tomcat下有两个应用A和B,A如上述一般配置,B中未配置,但B的lib中有log4j的jar包,那么在tomcat启动时可能会报一个堆栈溢出的异常。
原因是在tomcat启动时,B程序中的log4j包会用到System.out.println(),而这个System.out.println()会被A的StdoutListener监听到而引发死循环调用。至于为什么A中的监听器会监听到B中的调用,还不清楚。
暂时的解决办法:在B中也做上述配置,引入StdoutListener,编写log4j.properties。
为了能在web服务器启动以后完成这个替换的过程,我们定义一个ServletContextListener监听器,在web服务器启动时完成替换。
package com;
import java.io.PrintStream;import javax.servlet.ServletContextEvent;import javax.servlet.ServletContextListener;import org.apache.commons.logging.impl.LogFactoryImpl;/** * 把在程序中的System.out.print()的信息自动转成日志信息 */public class StdoutListener implements ServletContextListener { public void contextDestroyed(ServletContextEvent event) { } private void log(Object info) { LogFactoryImpl.getLog(getClass()).info(info); } public void contextInitialized(ServletContextEvent event) { PrintStream printStream = new PrintStream(System.out) { public void println(boolean x) { log(Boolean.valueOf(x)); } public void println(char x) { log(Character.valueOf(x)); } public void println(char[] x) { log(x == null ? null : new String(x)); } public void println(double x) { log(Double.valueOf(x)); } public void println(float x) { log(Float.valueOf(x)); } public void println(int x) { log(Integer.valueOf(x)); } public void println(long x) { log(x); } public void println(Object x) { log(x); } public void println(String x) { log(x); } }; System.setOut(printStream); System.setErr(printStream); }} 在web.xml里配置这个监听器,完善log4j.properties文件。搞定!
附:
web.xml中配置监听器:
<listener> <listener-class>com.bettersoft.filters.StdoutListener</listener-class> </listener>
我的 log4j.properties文件:
log4j.rootLogger=INFO,Stdout,Rlog4j.appender.Stdout=org.apache.log4j.ConsoleAppenderlog4j.appender.Stdout.layout=org.apache.log4j.PatternLayoutlog4j.appender.Stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %m%nlog4j.appender.R=org.apache.log4j.DailyRollingFileAppenderlog4j.appender.R.File=../logs/stdout.loglog4j.appender.R.datePattern='.'yyyy-MM-dd'.txt'log4j.appender.R.layout=org.apache.log4j.PatternLayoutlog4j.appender.R.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %m%n
说明:
log4j.rootLogger=INFO,Stdout,R 指定INFO及以上级别的日志会被输出到Stdout 和 R 两个终端
log4j.appender.Stdout=org.apache.log4j.ConsoleAppender 输出到控制台
log4j.appender.R=org.apache.log4j.DailyRollingFileAppender 指定了每天产出一个日志文件(R是自定义的)。
log4j.appender.R.File=../logs/stdout.log 指定了日志文件的路径和文件名,这样配置以后,我的日志文件就在D:\tomcat5\logs目录下。
log4j.appender.R.datePattern='.'yyyy-MM-dd'.txt' 指定了日志文件名的格式,比如8月6日的文件名就是stdout.log.2011-08-06.txt。
经过测试发现,当天的日志会被暂存在名为 stdout.log的日志文件中,只有日期更迭以后才会自动变更为符合
格式的文件名。
续:
经过试验, 如果在tomcat下有两个应用A和B,A如上述一般配置,B中未配置,但B的lib中有log4j的jar包,那么在tomcat启动时可能会报一个堆栈溢出的异常。
原因是在tomcat启动时,B程序中的log4j包会用到System.out.println(),而这个System.out.println()会被A的StdoutListener监听到而引发死循环调用。至于为什么A中的监听器会监听到B中的调用,还不清楚。
暂时的解决办法:在B中也做上述配置,引入StdoutListener,编写log4j.properties。
相关文章推荐
- 把在程序中的System.out.print()的信息自动转成log4j日志信息
- 把在程序中的System.out.print()的信息自动转成log4j日志信息
- 告别System.out.print()—J2SDK1.4新增Java日志框架 (一)
- system.out.print和log4j
- MR程序中查看使用System.out.print()输出的内容
- 告别System.out.print()—J2SDK1.4新增Java日志框架(
- 【技术贴】MyEclipse打出syso代码不能自动补全补全不能输出system.out.print
- 用log4j输出system.out的日志
- 请问能否把程序运行时出现的异常堆栈信息也保存进log4j指定的日志文件中
- 【技术贴】MyEclipse打出syso代码不能自动补全补全不能输出system.out.print
- 告别System.out.print()—J2SDK1.4新增Java日志框架(三)
- JAVA Catch中异常信息的输出 System.out.println(e) e.printStackTrace()
- 告别System.out.print()—J2SDK1.4新增Java日志框架(二)
- windows下使用log4j将日志输出到文件,包括system.out
- 把system.out.println的内容用log4j输出到tomcat日志里方法
- 将程序运行信息打印到 系统日志
- Android logcat中system.out.println()可以输出,但是log.d()的却看不到输出信息
- Tomcat下使用Log4j 接管 catalina.out 日志文件生成方式
- Log和system.out日志之学习笔记
- 安装sql server 2000时出现:安装程序配置服务器失败。参考服务器错误日志和 C:\WINDOWS\sqlstp.log 了解更多信息。