How can I log the logback actions into a file?

放肆的年华 提交于 2019-12-05 20:29:56

For background, this ouput ...

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

... is emitted by Logback under the following conditions:

  • Your configuration has debug enabled (e.g. <configuration debug="true">...</configuration>
  • Logback has determined that there is something about your configuration which warrants the emission of an ERROR or WARN message
  • Multiple Logback configuration files are found on your classpath

These log events are emitted before Logback has been initialised with your configuration so at the time they are emitted Logback knows nothing about your configured appenders etc. The only safe target for these event is a ConsoleAppender which Logback creates for this purpose.

So, there is no way to tell Logback to direct its own on-startup-log-events to a file appender.

However, do you actually want this Logback output? If not then you can suppress it by either of ...

  • Removing its cause; change your configuration so that debug=false and there are no ERROR/WARN events and there is a single Logback configuration file on the classpath
  • Add the no-op status listener to your configuration file: <statusListener class="ch.qos.logback.core.status.NopStatusListener" />

If you do want this output then you could ...

  • Redirect STDOUT to a log file when running your Java process. For example:
    • Add this to the main method in your Java application (before initialising Logback): System.setOut(new PrintStream("/Users/al/Projects/Sarah2/std.out"));
    • Pipe the Java output to a file: java -jar ... > /some/directory/application_stdout.log
  • Provide your own implementation of ch.qos.logback.core.status.StatusListener (instead of NopStatusListener) to write these status events ot a file of your choosing
  • Use ch.qos.logback.core.status.StatusListenerAsList (instead of NopStatusListener) and then add something to your application which writes the contents of getStatusList() to a file of your choosing

You can write your own StatusListener that writes to a file. I couldn't find a lot of examples out there, but if you look at the source code for OnConsoleStatusListener, it's pretty simple to take what's there and modify to write to a file.


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);
                }
            }
        }
    }
}

Then just specify your class as the Status Listener class in your config file:

<statusListener class="FileStatusListener" />

Of course you might want to make the code a little more robust, but writing to a rolling file.

Edit:

Better yet, the OnPrintStreamStatusListenerBase is an abstract class that provides a little more robust framework for writing to a file. It would probably be a better choice than the code above.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!