java 如何将 log4j 输出读取到网页?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2555865/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to read log4j output to a web page?
提问by Ran
I have a web page, used for admin purposes, which runs a task (image fetching from a remote site).
In order to be able to debug the task using the browser only, no ssh etc, I'd like to be able to read all log output from the executing thread and spit it out to the web page.
The task boils down to:
我有一个用于管理目的的网页,它运行一个任务(从远程站点获取图像)。
为了能够仅使用浏览器调试任务,不使用 ssh 等,我希望能够从执行线程读取所有日志输出并将其吐出到网页。
任务归结为:
- Changing log level for current thread at the beginning of the call and restore when the call is done.
- Reading all log output by current thread and storing it in a string.
- 在调用开始时更改当前线程的日志级别,并在调用完成后恢复。
- 通过当前线程读取所有日志输出并将其存储在一个字符串中。
So in pseudocode my execute() method would look like this: (I'm using struts2)
所以在伪代码中,我的 execute() 方法看起来像这样:(我使用的是 struts2)
public String execute() throws Exception {
turnLoggingLevelToDebugOnlyForThisThread()
... do stuff...
restoreLoggingLevelForThisThread()
String logs = readAllLogsByThisThread();
}
Can this be done with log4j?
这可以用 log4j 完成吗?
I'm using tomcat, struts2, log4j and slf4j.
我正在使用 tomcat、struts2、log4j 和 slf4j。
EDIT 1: I should note that the motivation is to be able to see the existing logs on a web page without needing to add new log lines in code. Think of a nice web debug interface that lets you run your operation and the result spits out the logs of the operation.
EDIT 2: I should also note that I'm already using log4j (via slf4j) and a log4j.xml, so the solution I'm seeking needs to live aside the currently logging system, not ruin it.
编辑 1:我应该注意到动机是能够在网页上查看现有日志而无需在代码中添加新的日志行。想想一个不错的 Web 调试界面,它可以让您运行您的操作,结果会输出操作日志。
编辑 2:我还应该注意,我已经在使用 log4j(通过 slf4j)和 log4j.xml,所以我正在寻求的解决方案需要将当前的日志系统放在一边,而不是破坏它。
回答by Miklos Csuka
You can create a log4j appender to write to a StringWriter. Here is an example I did some time ago:
您可以创建一个 log4j appender 来写入 StringWriter。这是我前段时间做的一个例子:
consoleWriter = new StringWriter();
WriterAppender appender = new WriterAppender(new PatternLayout("%d{ISO8601} %p - %m%n"),consoleWriter);
appender.setName("CONSOLE_APPENDER");
appender.setThreshold(org.apache.log4j.Level.ERROR);
Logger.getRootLogger().addAppender(appender);
It writes all ERROR logs to the consoleWriter, but you can set the scope or the level of the logs as you wish. The scope (logger name) should be a unique identifier of the thread. something like this:
它将所有 ERROR 日志写入 consoleWriter,但您可以根据需要设置日志的范围或级别。范围(记录器名称)应该是线程的唯一标识符。像这样:
Logger.getLogger("Thread-00001").addAppender(appender);
Your thread should write to this logger.
您的线程应该写入此记录器。
Logger.getLogger("Thread-00001").info("blah blah blah");
And when you want to finish logging the thread:
当你想完成记录线程时:
Logger.getLogger("Thread-00001").removeAppender("CONSOLE_APPENDER");
UPDATE: Here is a working example. Writes error logs to a file (set in log4j.xml) + writes all thread logs to a StringWriter, when enabled:
更新:这是一个工作示例。将错误日志写入文件(在 log4j.xml 中设置)+ 将所有线程日志写入 StringWriter,启用时:
import java.io.StringWriter;
import org.apache.log4j.Logger;
import org.apache.log4j.Level;
import org.apache.log4j.WriterAppender;
import org.apache.log4j.PatternLayout;
public class Log4jTest implements Runnable {
public static final String CONSOLE_APPENDER = "CONSOLE_APPENDER";
private static WriterAppender appender = null;
private static int counter = 1;
public static synchronized String getNextId() {
return "Thread_00"+(counter++);
}
public void run() {
String id="UNKNOWN";
try {
id = getNextId();
Logger log = Logger.getLogger(id);
log.addAppender(appender);
log.setLevel(Level.DEBUG);
log.info(id+" log message 1");
log.removeAppender(CONSOLE_APPENDER);
log.info(id+" log message 2");
log.error(id+" log message 3");
} catch (Exception e) {
System.out.println("Error in "+id);
e.printStackTrace();
}
}
public static void main(String [] args) {
try {
StringWriter consoleWriter = new StringWriter();
appender = new WriterAppender(new PatternLayout("%d{ISO8601} %p - %m%n"),consoleWriter);
appender.setName(CONSOLE_APPENDER);
appender.setThreshold(org.apache.log4j.Level.DEBUG);
for (int i=0; i<5; i++) {
Thread t = new Thread(new Log4jTest());
t.start();
}
Thread.sleep(200);
System.out.println(consoleWriter.getBuffer().toString());
} catch (Exception e) {
e.printStackTrace();
}
}
}
And here is my log4j.xml:
这是我的 log4j.xml:
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration>
<appender name="FILE" class="org.apache.log4j.RollingFileAppender">
<param name="File" value="./Log4jTest.log" />
<param name="MaxFileSize" value="1000KB" />
<param name="MaxBackupIndex" value="5" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{ISO8601} %p - %m%n" />
</layout>
<filter class="org.apache.log4j.varia.LevelRangeFilter">
<param name="LevelMin" value="WARN" />
<param name="LevelMax" value="FATAL" />
</filter>
</appender>
<root>
<level value="ERROR" />
<appender-ref ref="FILE" />
</root>
</log4j:configuration>

