views:

308

answers:

5

How can I configure Logback to suppress all of its output to the console (standard output)? In particular, I wish to suppress (or redirect) Logback's own log messages such as the following:

16:50:25,814 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback-test.xml]
16:50:25,814 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Found resource [logback.xml] at [file:/opt/dap/domains/ap0491/uat1/domain/instance-config/logback.xml]
16:50:25,816 |-WARN in ch.qos.logback.classic.LoggerContext[default] - Resource [logback.xml] occurs multiple times on the classpath.
16:50:25,816 |-WARN in ch.qos.logback.classic.LoggerContext[default] - Resource [logback.xml] occurs at [file:/opt/dap/domains/ap0491/uat1/domain/instance-config/logback.xml]
16:50:25,816 |-WARN in ch.qos.logback.classic.LoggerContext[default] - Resource [logback.xml] occurs at [file:/opt/dap/domains/ap0491/uat1/domain/instance-config/logback.xml]
16:50:25,923 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - debug attribute not set
16:50:25,924 |-INFO in ch.qos.logback.classic.turbo.ReconfigureOnChangeFilter@1a15291 - Will scan for changes in file [/opt/dap/domains/ap0491/uat1/domain/instance-config/logback.xml] every 60 seconds. 

I need to disable all logging to standard output because our production environment disallows applications from printing any messages to standard output.

Note I'm using Logback 0.9.21, SLF4J 1.6.0, and our application runs in WebLogic 10.3.2.

+1  A: 

I'm not familiar with Logback. But if it's printing to System.out or System.err, these are simply public static PrintStream variables in the System class. You could subclass PrintStream and set the system output variables to your subclass, thus controlling how it works.

For example:

public class NOPPrintStream extends PrintStream
{
    public NOPPrintStream() { super((OutputStream)null); }

    public void println(String s) { /* Do nothing */ }
    // You may or may not have to override other methods
}

public class MyClass
{
    public static void main(String[] args)
    {
        System.out = new NOPPrintStream();
        // Start program
    }
}

(This code is untested)

Brian S
I'm not sure how to apply this solution to my particular case. My application runs inside a WebLogic container, so `main()` is not my application entry point and I don't know how WebLogic "starts" the application. Furthermore, I don't know how WebLogic or Logback may set the `System.out` and `System.err` variables.
Derek Mahar
Well, you could set `System.out` in your code (presumably you know the first section of **your** code which runs), and the worst thing that could happen is that it doesn't work :)
Brian S
WebLogic may invoke one or more optional initialization methods in an application at startup, but I'll have to investigate which ones these may be. Our application does not have any such initialization routines. Our application consists of two sub-systems: a Web application that receives Web service requests and forwards them to an EJB application that processes the request, accesses a database, and sends a response back to the Web application. Both of these use Logback to log their activities, and each must have its own separate initialization process.
Derek Mahar
I suppose that if I'm unable to identify which routines WebLogic invokes at startup, I could sets `System.out` in the static initializer of some singleton class. That way I'd be certain that my application would invoke it exactly once (assuming that it uses the class).
Derek Mahar
Note that one disadvantage of this approach is that it will disable all standard output for every environment, but we need to disable it only for our production environment.
Derek Mahar
Giving it some more thought, I could always conditionally redirect `System.out` using a system property that specifies the current environment.
Derek Mahar
Your `PrintStream` subclass also doesn't necessarily have to be NOP, it was just example code :)
Brian S
+1  A: 

Those messages only show if

  • you have debugging enabled in the logback.xml file
  • you have an error in your configuration. Thats the case here - logback complains about multiple configuration files found.

Fix it and those messages should go away.

Thorbjørn Ravn Andersen
What about the `INFO` messages? I see many more of those than the warnings. I just listed a sample.
Derek Mahar
How can I redirect the warnings to standard error (or another file) instead of standard output?
Derek Mahar
Then you have more problems with your logback configuration. Fix them and the messages will go away. I do not believe the messages can be redirected - have a look in the logback source to see.
Thorbjørn Ravn Andersen
Actually the messages always show up if there are multiple configurations on the classpath (which is the reason for the warning but often a completely legitimate situation), and logback currently does NOT pick one but rather reverts to default settings. Please also see my comment at http://jira.qos.ch/browse/LBCLASSIC-130?focusedCommentId=11801#action_11801
Holger Hoffstätte
@Thorbjørn: Logback outputs these messages to standard output even before it has completely read the configuration file (apparent from the message "debug attribute not set"), so I cannot see how my Logback configuration can be to blame for the informational messages. I'll do as you suggest and look at the Logback source code to see what it does at startup.
Derek Mahar
Another thought: might I suppress these messages by turning off the root logger or by attaching it to an appender that writes to a file?
Derek Mahar
What you see is Logbacks _internal_ logging which is completely decoupled from whatever you choose to do. It is normally not printed anywhere, _except_ when an error occurs during the configuration phase in which case it is listed to Standard out. So, just _fix_ what it complains about, and it will not appear.
Thorbjørn Ravn Andersen
@Holger, why is it a legitimate situation, and which logback.xml file should logback have picked?
Thorbjørn Ravn Andersen
@Holger: I'm certain that Logback uses one of the two configuration files that it finds on the classpath and according to Ceki Gulcu's comments (http://jira.qos.ch/browse/LBCLASSIC-130?focusedCommentId=11799#action_11799) in the thread to which you refer, it uses the first one that it finds.
Derek Mahar
@Thorbjørn: Yes, I agree that this is Logback's internal logging. So you say that when Logback detects a configuration error, it outputs not only its error or warning messages, but all of its internal log messages (including those that occur before the error, for example, "Could NOT find resource [logback-test.xml]")?
Derek Mahar
Yes, see http://logback.qos.ch/manual/joran.html. "If and only if there are warnings or errors during the parsing of the configuration file, logback will automatically print status data on the console". If you read the messages carefully you can identify what is wrong, and fix it so the messages will go away.
Thorbjørn Ravn Andersen
Also note that the "Could NOT..:" is INFO, not WARN. This is simply to aid, not a problem.
Thorbjørn Ravn Andersen
@Thorbjørn: According http://jira.qos.ch/browse/LBCLASSIC-85?focusedCommentId=10987#action_10987, Logback class `ContextInitializer` is responsible for printing these log messages, so I'll review its source code to see how it works and determine whether there is some way I can disable the output. If not, I may make a request to the developers to give users the option to suppress or redirect these messages (at least the `INFO` messages).
Derek Mahar
@Thorbjørn: Yes, "Could NOT find resource..." is an `INFO` message and does not indicate a problem, but I would still like to suppress or redirect these messages and any other messages that Logback prints to standard output because our production environment disallows all standard output.
Derek Mahar
@Derek, if no ERROR or WARN messages are generated the INFO messages are _not_ printed. Hence, eliminate the underlying reasons that triggers the ERROR and WARN messages, and this output - including INFO and DEBUG messages - goes _ENTIRELY_ away.
Thorbjørn Ravn Andersen
@Thorbjørn: Understood, but according to Robert Elliot in http://qos.ch/pipermail/logback-user/2010-August/001719.html, this duplicate classpath message may actually be a bug in Logback, so eliminating these messages may be easier said than done.
Derek Mahar
Very interesting. He sees this with WebLogic. What container do you use?
Thorbjørn Ravn Andersen
WebLogic 10.3.2.
Derek Mahar
+1  A: 

Actually the fact that the same logback.xml location is reported multiple times seems more like a bug in logback than anything else. Either report this to the logback JIRA (here) or first check whether the jar in question is on the classpath multiple times.

Holger Hoffstätte
First, I'll check with our administrators to see why our WebLogic server instance sees the Logback configuration location twice on the classpath. The `logback.xml` file is not actually in a jarfile, but exists outside the EAR in a separate location.
Derek Mahar
No, that is a deliberate decision by the logback designer.
Thorbjørn Ravn Andersen
I agree, I think that reporting the multiple classpath locations is actually a useful message and not a bug.
Derek Mahar
The messages quoted report the same physical location twice. I vaguely recall to have seen this before as being a fixed bug. Double check that you are using the latest version of logback.
Thorbjørn Ravn Andersen
Derek Mahar
@Thorbjørn: Do you happen to have a reference to the Jira item that resolves duplicate classpath entry issue?
Derek Mahar
The reason that this happens in Logback may be the same reason why it causes http://bugzilla.slf4j.org/show_bug.cgi?id=138 in SLF4J.
Derek Mahar
After reviewing the code, this problem still exists in Logback 0.9.24: http://github.com/ceki/logback/blob/v_0.9.24/logback-classic/src/main/java/ch/qos/logback/classic/util/ContextInitializer.java and http://github.com/ceki/logback/blob/v_0.9.24/logback-core/src/main/java/ch/qos/logback/core/util/Loader.java.
Derek Mahar
It's important to point out that users have reported this problem when running their applications inside WebLogic or Resin.
Derek Mahar
I would strongly suggest that you register and comment that this is a production issue for you, to LBCLASIC-159 issue. If this is a showstopper you might even purchase support for Logback from QOS.ch (not affiliated, just suggesting) to get immediate attention.
Thorbjørn Ravn Andersen
@Thorbjørn: I fixed LBCLASSIC-159. See http://stackoverflow.com/questions/3401051/suppress-all-logback-output-to-console/3411015#3411015.
Derek Mahar
Great :) Glad you found it.
Thorbjørn Ravn Andersen
+1  A: 

Holger Hoffstätte was correct in his diagnosis that the duplicate classpath entry message is a symptom of a bug in how Logback counts classpath entries. Robert Elliot also characterized the problem in a thread on the Logback user mailing list. According to Robert and others in this related disussion on the SLF4J mailing list, when an application that uses Logback runs in a WebLogic container, due to the way the WebLogic classloader operates, Logback reports duplicate classpath entries for the logback.xml configuration file. However, regardless of whether the WebLogic classloader should or should not report only unique classpath entries, Logback should certainly count only unique classpath entries so that it does not print this confusing, spurious message.

I have implemented a fix for LBCLASSIC-159 that essentially does what Robert Elliot recommends and uses a set instead of a list to hold the resources that the classloader returns, effectively eliminating any duplicate classpath resources. I have successfully tested the fix with Logback 0.9.24, SLF4J 1.6.1, and WebLogic 10.3.2. As Thorbjørn predicted in his answer, with this fix in place, Logback no longer displays the duplicate classpath entry status messages (or any of the other informational messages) to standard output.

I hope that the maintainers will integrate my fix into the main Logback source code repository and include it in the next release.

Derek Mahar
A: 

So I had the same problem but found that removing the incorrect <layout /> entry which was deprecated somewhere around 0.9.4 and the messages went away...

You appender should look some thing like

<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">

<filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>info</level> </filter>

<encoder>

<pattern>%d{yyyy-MM-dd} %d{HH:mm:ss} %.-1level %thread %logger{36}: %m%n</pattern>

</encoder>

</appender>

I've blogged about a more complete description of what I changed that worked for me

Michael McCallum
Thank you for your answer, but my Logback configuration contains no `<layout/>` elements. None of its appenders include threshold filters, either. Only the loggers filter according to threshold.
Derek Mahar
Did you try adding an 'info' threshold filter on console?
Michael McCallum