【问题标题】:How can I log the logback actions into a file?如何将 logback 操作记录到文件中?
【发布时间】:2018-03-13 19:50:57
【问题描述】:

我想使用 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

提前致谢

【问题讨论】:

    标签: java logback rollingfileappender logback-classic


    【解决方案1】:

    对于背景,这个输出...

    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 发出:

    • 您的配置已启用调试(例如&lt;configuration debug="true"&gt;...&lt;/configuration&gt;
    • Lo​​gback 已确定您的配置有某些内容需要发出 ERROR 或 WARN 消息
    • 在您的类路径中找到多个 Logback 配置文件

    这些日志事件是在使用您的配置初始化 Logback 之前发出的,因此在发出它们时,Logback 对您配置的附加程序等一无所知。这些事件的唯一安全目标是 Logback 为此目的创建的ConsoleAppender .

    因此,没有办法告诉 Logback 将其自己的 on-startup-log-events 定向到文件追加器。

    然而,你真的想要这个 Logback 输出吗?如果没有,那么您可以通过 ...

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

    如果你确实想要这个输出,那么你可以...

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

    【讨论】:

    • 非常感谢您的解释!我正在考虑调查一个大客户的生产环境中的日志问题。因此,简单地将所有 stout 记录在一个文件中是很复杂的。 logback 只是停止仅在文件中登录(如果我打开控制台,它会继续仅在控制台中登录并在文件中停止)通常它只是为文件配置。我会等待更多的想法,但我真的很感谢你的帮助!!
    【解决方案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);
                    }
                }
            }
        }
    }
    

    然后只需在配置文件中将您的类指定为状态侦听器类:

    &lt;statusListener class="FileStatusListener" /&gt;

    当然,您可能想让代码更健壮一些,但要写入滚动文件。

    编辑:

    更好的是,OnPrintStreamStatusListenerBase 是一个抽象类,它为写入文件提供了更强大的框架。这可能是比上面的代码更好的选择。

    【讨论】:

      猜你喜欢
      • 2013-11-10
      • 1970-01-01
      • 2014-04-30
      • 1970-01-01
      • 2014-07-24
      • 1970-01-01
      • 2014-11-19
      • 1970-01-01
      • 2019-10-24
      相关资源
      最近更新 更多