tags:

views:

30

answers:

3

Hi all,

currently we're running quite a few applications on our WebSphere Portal Server, and most of the have their own log-file, so the System.out won't be too overloaded. However, once an error happens in an application it's easy to miss. If an errors is logged, I would like to get a warning in the System.out with a notice to take a look at the related log-file. For now I did this by wrapping the log4j logger into a class with equal methods to the logger-class, and it just delegates all calls to the logger. only when the error- and fatal-messages methods are called, the file to log at is retrieved from the logger, and a warning is written to the System.out. This is working fine, except that now the LoggerWrapper is the caller to the logger-methods, und thus is written to the log files as the caller, not the original caller.

Is there any way around this, maybe even with a completely different approach? I would like to avoid having to rewrite all exception-handlers to add the message to the System.out themselves.

Christian

+2  A: 

You could simply configure a Log4J appender to write to stdout (or rather stderr in this case). That is the standard way. By setting the log threshold to WARNING, you can filter out the bulk of the log messages.

The price is that the error messages will appear both on stderr and in the log file(s), however to me that would not be an issue. In fact, it may help finding the specific logs corresponding to a given stderr message.

Péter Török
this would cause to log the stacktrace of every error that happend to the System.out (or .err). from experience these stack-traces are often many pages long, and once an application crashes happen quite often. this would totally spam the log and make it absolutly useless until the error is fixed. this notice should basically just indicate for the admin that an application (and which) has a problem, but giving no details, which are usualy just interesting only to the maintainer of the application.
Christian
@Christian, good point, but IMO it can be resolved with two error messages: one higher level (e.g. ERROR) and brief, the other at lower level (e.g. WARNING) and including the exception with its stack trace. Or you can do it the other way around and configure your stderr appender to display _only_ the WARNING messages. As a side note, frequent app crashes are supposed to be a temporary issue only, as you are going to fix the underlying bugs soon, aren't you? :-)
Péter Török
@Christian, or an entirely different approach: log only into files and run a simple log parser on these regularly to get lines containing error messages and display, or even email, them to you.
Péter Török
A: 

I do a very similar thing in our application, in which I administer all logging.

I've solved the problem by attaching an "ErrorConsoleAppender" to my root logger. All loggers in my configuration file are additive (of course, meaning they "bubble up" appropriately).

As one would suspect, the "ErrorConsoleAppender" pushes errors to the console and only errors. It works amazingly well for us, keeping our console clean unless there's a serious problem. My code for that is as below:

...
    <appender name="ErrorConsoleAppender" class="org.apache.log4j.ConsoleAppender">
            <errorHandler class="org.apache.log4j.helpers.OnlyOnceErrorHandler"/> 
            <layout class="org.apache.log4j.PatternLayout">
                  <param name="ConversionPattern" value="[%d{ABSOLUTE}] %-5p > %m%n" />
            </layout>
            <filter class="org.apache.log4j.varia.LevelRangeFilter">
                  <param name="LevelMin" value="ERROR" />
                  <param name="LevelMax" value="ERROR" />
                  <param name="AcceptOnMatch" value="true" />
            </filter>
            <filter class="org.apache.log4j.varia.DenyAllFilter" />
    </appender>
...
    <root>
            <priority value="ALL" />
            <appender-ref ref="ErrorConsoleAppender" />
    </root>

Of course, to make this work in the manner you described, you would have to have add simple log.error(String) calls that do not dump stack traces, as suggested above by Peter.


If editing the log.error(String) calls is not practical, then I would suggest using AspectJ to crosscut your code and provide the functionality you need. Even if you're not familiar with aspect-oriented programming, it's fairly simple to achieve what you've described with it. In fact, one of the primary use cases for AOP is precisely the scenario you've described. Aspects are great for logging.

On the surface, it seems most fitting approach, in your case, would be to use the "after throwing" syntax to take appropriate, logging action when specific exceptions occur.

I hope all that helps in some way, let me know if you have further questions about how AOP can address your problem,

-gMale

gmale
A: 

Thanks for the ideas. After discussing this internally I ended up writing a simple appender, which is attached to all loggers, and which will output a short notice to the System.out when an error or fatal-message is logged. Since the appender has access to the calling logger, it can analyze all other appenders and find out where they log to, and add this to the notice.

Christian

Christian