gpt4 book ai didi

spring - 如何将 log4j 输出重定向到 HttpServletResponse 输出流?

转载 作者:行者123 更新时间:2023-12-02 08:10:28 29 4
gpt4 key购买 nike

我在 JBoss AS 7.1.1.Final 上部署的 Spring 3.1.1.RELEASE 应用程序中使用 log4j 1.2.15。我正在尝试将 log4j 中写入的输出路由到我的响应输出流。我的输出是这样写的

private static final Logger LOG = Logger.getLogger(TrainingSessionServiceImpl.class);

LOG.info("Creating/updating training session associated with order #:" + order.getId());

我正在尝试将其路由到我的输出流,就像这样......

@RequestMapping(value = "/refreshPd", method = RequestMethod.GET)
public void refreshPD(final HttpServletResponse response) throws IOException
{
...
final WriterAppender appender = new WriterAppender(new PatternLayout("%d{ISO8601} %p - %m%n"),response.getWriter());
appender.setName("CONSOLE_APPENDER");
appender.setThreshold(org.apache.log4j.Level.DEBUG);
Logger.getRootLogger().addAppender(appender);

worker.work();

Logger.getRootLogger().removeAppender("CONSOLE_APPENDER");

但遗憾的是,即使我知道(通过调试)正在调用日志记录语句,我的浏览器也没有任何输出。有谁知道我如何调整我的设置以使其正常工作?下面是我的 log4j.properties 文件,部署到我的 war 的 WEB-INF/classes 目录。

log4j.rootLogger=DEBUG, CA, FA

#Console Appender
log4j.appender.CA=org.apache.log4j.ConsoleAppender
log4j.appender.CA.layout=org.apache.log4j.PatternLayout
log4j.appender.CA.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n

#File Appender
log4j.appender.FA=org.apache.log4j.FileAppender
log4j.appender.FA.File=/usr/java/jboss/server/default/log/log4j.log
log4j.appender.FA.layout=org.apache.log4j.PatternLayout
log4j.appender.FA.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n

# Set the logger level of File Appender to WARN
log4j.appender.FA.Threshold = DEBUG

谢谢,-戴夫

最佳答案

这是一个有趣的问题。 关键是编写自己的附加程序。我查找了内置的 org.apache.log4j.ConsoleAppender 代码以获取灵感。我已经在我的 tomcat 中对此进行了测试并验证了它的工作原理。我使用了 log4j-1.2.17 (希望不重要)

1) 首先实现你自己的appender。此附加程序会将所有日志事件写入当前线程的输出流

package com.tstwbprj.log;

import org.apache.log4j.Layout;
import org.apache.log4j.WriterAppender;

import java.io.IOException;
import java.io.OutputStream;

public class HttpLogAppender extends WriterAppender {

static ThreadLocal<OutputStream> streamPerHttpThread = new ThreadLocal<OutputStream>();

public HttpLogAppender() {

}

public HttpLogAppender(Layout layout) {
setLayout(layout); //super-class method
activateOptions();
}

public void setCurrentHttpStream(OutputStream stream) {
streamPerHttpThread.set(stream);
}


public void activateOptions() {
setWriter(createWriter(new CurrentHttpThreadOutStream()));
}


/**
* An implementation of OutputStream that redirects to the
* current http threads servlet output stream
*/
private static class CurrentHttpThreadOutStream extends OutputStream {
public CurrentHttpThreadOutStream() {
}

public void close() {
}

public void flush() throws IOException {
OutputStream stream = streamPerHttpThread.get();
if (stream != null) {
stream.flush();
}
}

public void write(final byte[] b) throws IOException {
OutputStream stream = streamPerHttpThread.get();
if (stream != null) {
stream.write(b);
}
}

public void write(final byte[] b, final int off, final int len)
throws IOException {
OutputStream stream = streamPerHttpThread.get();
if (stream != null) {
stream.write(b, off, len);
}
}

public void write(final int b) throws IOException {
OutputStream stream = streamPerHttpThread.get();
if (stream != null) {
stream.write(b);
}
}
}
}

2)像其他设置一样将此附加程序添加到您的 log4j 配置文件中

log4j.rootLogger=DEBUG, CA, FA , HA
..
log4j.appender.HA=com.tstwbprj.log.HttpLogAppender log4j.appender.HA.layout=org.apache.log4j.PatternLayout log4j.appender.HA.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n

3) 在您的 servlet 中添加一小段代码,以便此附加程序正常工作。这是我的 servlet。

import org.apache.log4j.Category;
import org.apache.log4j.Logger;
import javax.servlet.ServletOutputStream;
import java.io.IOException;

public class LogServlet extends javax.servlet.http.HttpServlet {

private static final Logger LOG = Logger.getLogger(LogServlet.class);

protected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {

}

protected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {
ServletOutputStream outstream = response.getOutputStream();
configureLogForCurrentRequest(outstream);

LOG.info("Got request");//this is now send to the servlet output stream !!
LOG.info("Hello!!");
LOG.info("Done!!");
}

private void configureLogForCurrentRequest(ServletOutputStream outstream) {

HttpLogAppender appender = (HttpLogAppender) LOG.getAppender("HA");
while (appender == null) {
Category parent = LOG.getParent();
if (parent == null) {
break; //This ideally shouldn't happen. Navigated all the way to root logger and still did not find appender !!..something wrong with log4j configuration setup
}
appender = (HttpLogAppender) parent.getAppender("HA");

}
appender.setCurrentHttpStream(outstream);
}
}

警告:这没有经过彻底的测试,特别是对于多个 servlet 请求等。也不确定为什么要这样做。将日志消息通过管道传输到浏览器并不常见。谨慎行事..:)-

关于spring - 如何将 log4j 输出重定向到 HttpServletResponse 输出流?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14408822/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com