我该如何将logback的操作记录到文件中?

5

我希望使用Logback将“ch.qos.logback”类记录到日志文件中,但它只记录在控制台而不是文件中。

这个可行吗?

我需要这个来调查一些与logback有关的问题。

这是我的logback配置文件:

<?xml version="1.0" encoding="ISO-8859-1"?>
<configuration scan="true" scanPeriod="60 seconds">

    <property name="base-path" value="../../xpto/sysX/logs"/>
    <property name="application-name" value="app_X"/>

    <appender class="ch.qos.logback.core.ConsoleAppender" name="CONSOLE">
        <param name="Threshold" value="INFO"/> 
        <encoder>
            <pattern>%d{dd/MM/yyyy HH:mm:ss.SSS} %-5level %logger{30} - %msg%n</pattern>
        </encoder>
    </appender>
    <appender class="ch.qos.logback.core.rolling.RollingFileAppender" name="FILE_LOGBACK">
            <param name="Threshold" value="DEBUG"/>
            <file>${base-path}/mylog.log</file>
            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <fileNamePattern>${base-path}/%d{yyyy-MM-dd_HH}/mylog.%i.log</fileNamePattern>
                <maxHistory>72</maxHistory>
                <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                    <maxFileSize>20MB</maxFileSize>
                </timeBasedFileNamingAndTriggeringPolicy>
            </rollingPolicy>
            <encoder>
                <pattern>%date{yyyy-MM-dd HH:mm:ss.SSS} [%.30thread] %-5level %logger{50} - %msg%n</pattern>
            </encoder>
        </appender>
        <appender class="ch.qos.logback.classic.AsyncAppender" name="FILE_LOGBACK_ASYNC">
            <param name="Threshold" value="DEBUG"/>
            <appender-ref ref="FILE_LOGBACK"/>
            <queueSize>1000</queueSize>
            <discardingThreshold>0</discardingThreshold>
        </appender> 
        <logger additivity="false" level="DEBUG" name="ch.qos.logback">
            <appender-ref ref="FILE_LOGBACK"/>
        </logger>
        <root level="INFO">
           <appender-ref ref="CONSOLE"/> 
           <appender-ref ref="FILE_LOGBACK_ASYNC"/>
        </root>
</configuration>

这是一个在控制台中记录的示例,我希望将它记录到文件中而不仅仅是在控制台中。

14:17:37,117 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [FILE_LOGBACK]
14:17:37,117 |-WARN in ch.qos.logback.core.joran.util.PropertySetter@7f7f557 - No setter for property [Threshold] in ch.qos.logb ack.core.rolling.RollingFileAppender.
14:17:37,118 |-INFO in c.q.l.core.rolling.TimeBasedRollingPolicy@671885015 - No compression will be used
14:17:37,118 |-INFO in c.q.l.core.rolling.TimeBasedRollingPolicy@671885015 - Will use the pattern ../../xpto/sysX/logs/%d{ yyyy-MM-dd_HH}/mylog.%i.log for the active file
14:17:37,119 |-INFO in ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP@35ca01cb - The date pattern is 'yyyy-MM-dd_HH' from fil e name pattern '.../../xpto/sysX/logs/%d{yyyy-MM-dd_HH}/mylog.%i.log'.
14:17:37,119 |-INFO in ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP@35ca01cb - Roll-over at the top of every hour.
14:17:37,119 |-INFO in ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP@35ca01cb - Setting initial period to Mon Oct 02 14:17:3

我正在使用以下依赖项:

log4j-over-slf4j-1.7.2.jar
logback-classic-1.1.7.jar
logback-core-1.1.7.jar
slf4j-api-1.7.2.jar

提前感谢你的帮助。

2个回答

5

背景:这个输出是一个在你的计算机上运行的程序所产生的结果。

14:17:37,117 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [FILE_LOGBACK]
14:17:37,117 |-WARN in ch.qos.logback.core.joran.util.PropertySetter@7f7f557 - No setter for property [Threshold] in ch.qos.logb ack.core.rolling.RollingFileAppender.
14:17:37,118 |-INFO in c.q.l.core.rolling.TimeBasedRollingPolicy@671885015 - No compression will be used
14:17:37,118 |-INFO in c.q.l.core.rolling.TimeBasedRollingPolicy@671885015 - Will use the pattern ../../xpto/sysX/logs/%d{ yyyy-MM-dd_HH}/mylog.%i.log for the active file
14:17:37,119 |-INFO in ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP@35ca01cb - The date pattern is 'yyyy-MM-dd_HH' from fil e name pattern '.../../xpto/sysX/logs/%d{yyyy-MM-dd_HH}/mylog.%i.log'.
14:17:37,119 |-INFO in ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP@35ca01cb - Roll-over at the top of every hour.
14:17:37,119 |-INFO in ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP@35ca01cb - Setting initial period to Mon Oct 02 14:17:3

以下情况下,Logback会发出以下日志:
  • 您的配置已启用调试模式(例如 <configuration debug="true">...</configuration>
  • Logback已确定您的配置中有一些需要发出ERROR或WARN消息的内容
  • 在您的类路径上找到了多个Logback配置文件

这些日志事件在Logback初始化您的配置之前发出,因此在发出时,Logback不知道您配置的appender等信息。唯一安全的目标是ConsoleAppender,Logback为此目的创建。

因此,没有办法告诉Logback将其自己的启动日志事件定向到文件appender。

但是,您是否真的需要这个Logback输出?如果不需要,则可以通过以下任一方式来抑制它:

  • 消除其原因;将您的配置更改为debug=false,并且没有ERROR/WARN事件,并且在类路径上只有一个Logback配置文件
  • 将无操作状态侦听器添加到您的配置文件中:<statusListener class="ch.qos.logback.core.status.NopStatusListener" />

如果确实需要此输出,则可以执行以下操作:

  • 在运行Java进程时将STDOUT重定向到日志文件。例如:
    • 在Java应用程序的主方法中添加以下内容(在初始化Logback之前):System.setOut(new PrintStream("/Users/al/Projects/Sarah2/std.out"));
    • 将Java输出导向文件:java -jar ... > /some/directory/application_stdout.log
  • 提供ch.qos.logback.core.status.StatusListener的自己的实现(而不是NopStatusListener),以将这些状态事件写入您选择的文件
  • 使用ch.qos.logback.core.status.StatusListenerAsList(而不是NopStatusListener),然后添加一些内容到您的应用程序,将getStatusList()的内容写入您选择的文件

1
非常感谢您的解释! 我正在考虑一个关于大客户生产环境中登录问题的调查。所以简单地将所有的输出记录在一个单独的文件中是很复杂的。 logback 只会停止在一个文件中记录(如果我打开控制台,它就会继续在控制台中记录并停止在文件中)。通常只配置为文件记录。 我会等待更多想法,但我真的很感激您的帮助! - Jardel Novaes

2
您可以编写自己的StatusListener来写入文件。我在外面找不到很多例子,但如果您查看OnConsoleStatusListener的源代码,就可以很容易地采取那里的内容并修改以写入文件。

import ch.qos.logback.core.status.Status;
import ch.qos.logback.core.status.StatusListener;
import ch.qos.logback.core.util.StatusPrinter;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;

public class FileStatusListener implements StatusListener {

    private final static String fileName = "path/logbackStatusMessages.log";

    @Override
    public void addStatusEvent(Status status) {
        StringBuilder sb = new StringBuilder();
        StatusPrinter.buildStr(sb, "", status);

        BufferedWriter writer = null;
        try {
            writer = new BufferedWriter(new FileWriter(fileName, true));
            writer.append(sb.toString());
        } catch (Throwable ex) {
            System.out.println("Error writing to file in FileStatusListener");
            ex.printStackTrace(System.err);
        } finally {
            if (writer != null) {
                try {
                    writer.close();      
                } catch (IOException ex) {
                    System.err.println("Error closing file in FileStatusListener");
                    ex.printStackTrace(System.err);
                }
            }
        }
    }
}

然后,在您的配置文件中将您的类指定为状态监听器类即可:<statusListener class="FileStatusListener" /> 当然,您可能希望将代码写得更加健壮一些,例如写入滚动文件。更好的选择是OnPrintStreamStatusListenerBase,它是一个抽象类,提供了一个更加健壮的框架来写入文件。它可能比上面的代码更好。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接