Java 如何将log4j输出读取到网页?

Java 如何将log4j输出读取到网页?,java,tomcat,logging,log4j,slf4j,Java,Tomcat,Logging,Log4j,Slf4j,我有一个用于管理的网页,它运行一个任务(从远程站点获取图像)。 为了能够只使用浏览器而不使用ssh等来调试任务,我希望能够读取执行线程的所有日志输出并将其输出到网页。 这项任务归结为: 在调用开始时更改当前线程的日志级别,并在调用完成时恢复 读取当前线程的所有日志输出并将其存储在字符串中 因此,在伪代码中,我的execute()方法如下所示:(我使用的是struts2) 这可以用log4j完成吗 我使用的是tomcat、struts2、log4j和slf4j 编辑1:我应该注意,动机是能够在网页

我有一个用于管理的网页,它运行一个任务(从远程站点获取图像)。
为了能够只使用浏览器而不使用ssh等来调试任务,我希望能够读取执行线程的所有日志输出并将其输出到网页。
这项任务归结为:

  • 在调用开始时更改当前线程的日志级别,并在调用完成时恢复
  • 读取当前线程的所有日志输出并将其存储在字符串中
  • 因此,在伪代码中,我的execute()方法如下所示:(我使用的是struts2)

    这可以用log4j完成吗

    我使用的是tomcat、struts2、log4j和slf4j

    编辑1:我应该注意,动机是能够在网页上查看现有日志,而不需要在代码中添加新的日志行。想一想一个漂亮的web调试界面,它可以让您运行操作,结果会显示操作日志。

    编辑2:我还应该注意,我已经在使用log4j(通过slf4j)和log4j.xml,因此我寻求的解决方案需要搁置当前的日志系统,而不是破坏它。

    您可以创建一个log4j附加器来写入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);
    
    它会将所有错误日志写入consoleWriter,但您可以根据需要设置日志的范围或级别。作用域(记录器名称)应该是线程的唯一标识符。大概是这样的:

    Logger.getLogger("Thread-00001").addAppender(appender);
    
    您的线程应该写入此记录器

    Logger.getLogger("Thread-00001").info("blah blah blah");
    
    当您要完成线程日志记录时:

    Logger.getLogger("Thread-00001").removeAppender("CONSOLE_APPENDER");
    

    更新: 下面是一个工作示例。将错误日志写入文件(在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();
            }
        }
    }
    
    导入java.io.StringWriter;
    导入org.apache.log4j.Logger;
    导入org.apache.log4j.Level;
    导入org.apache.log4j.WriterAppender;
    导入org.apache.log4j.PatternLayout;
    公共类Log4jTest实现Runnable{
    公共静态最终字符串CONSOLE\u APPENDER=“CONSOLE\u APPENDER”;
    私有静态WriterAppender appender=null;
    专用静态整数计数器=1;
    公共静态同步字符串getNextId(){
    返回“Thread_00”+(计数器++);
    }
    公开募捐{
    字符串id=“未知”;
    试一试{
    id=getNextId();
    Logger log=Logger.getLogger(id);
    log.addAppender(appender);
    log.setLevel(Level.DEBUG);
    日志信息(id+“日志消息1”);
    日志删除附件(控制台附件);
    日志信息(id+“日志消息2”);
    日志错误(id+“日志消息3”);
    }捕获(例外e){
    System.out.println(“错误输入”+id);
    e、 printStackTrace();
    }
    }
    公共静态void main(字符串[]args){
    试一试{
    StringWriter控制台编写器=新建StringWriter();
    appender=newwriterAppender(新的模式布局(“%d{ISO8601}%p-%m%n”),consoleWriter);
    appender.setName(控制台\u appender);
    setThreshold(org.apache.log4j.Level.DEBUG);
    
    对于(int i=0;i您如何更改当前线程的日志级别?我或多或少意识到这是它应该工作的方向,但不幸的是,我无法让它为我工作…如果我有一个log4j.xml文件,它就不工作。如果我没有log4j.xml,它就工作了…我想添加appender并不像我想的那样工作:(@Ran)您的根日志记录器(也称为类别)可能设置为错误级别。您需要使用logger.setLevel()命令覆盖此设置,或者通过在log4j.xml中创建具有较低日志级别的父日志记录器配置来覆盖此设置。请查看log4j手册中的“日志记录器层次结构”。我已使用log4j.xml更新了一个工作示例来更新我的响应。我希望它能有所帮助。
    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();
            }
        }
    }
    
    <!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>