In my application, I am using Log4j2 in Async mode (Async logger using Disruptor), can some one pls tell me how to handle an exception that happens in the logging process. Logging is very critical for my application, I don't want to miss a single log statement. If something goes wrong with logging, that needs to be alerted immediately.
As per Apache Log4j page, suggests to use ExceptionHandler, but I couldn't find a helping topic on how to use this.
Error handling. If a problem happens during the logging process and an
exception is thrown, it is less easy for an asynchronous logger or
appender to signal this problem to the application. This can partly be
alleviated by configuring an ExceptionHandler, but this may still not
cover all cases. For this reason, if logging is part of your business
logic, for example if you are using Log4j as an audit logging
framework, we would recommend to synchronously log those audit
messages. (Note that you can still combine them and use asynchronous
logging for debug/trace logging in addition to synchronous logging for
the audit trail.)
Waiting for suggestions.
I suggest first trying to implement a simple class that implements the ExceptionHandler interface and confirm that it gets called when a problem occurs. Once this is confirmed you can move on to implementing your custom fallback mechanism.
Secondly, it may be difficult to develop a robust fallback: your fallback may not be able to write to disk if the reason why log4j failed was that the disk is full or damaged. Similarly you may not be able to make a network connection... I suggest that your fallback incorporates multiple options to increase the probability of one of these options succeeding.
Hardware is cheap, so consider adding a separate network card or a separate hard disk for your fallback mechanism. Don't forget to send notifications if the fallback mechanism is used so you can address the original problem.
Depending on how mission-critical this is you may want to investigate vendor products that give high availability - this usually covers more than just logging, not sure what your needs are here.
Related
I saw in the stack overflow when it comes to server side industrial level applications using a logger framework over System.out.println() is an efficient way to deal with Logging.And I also red that System.out.println() is an I/O operation,because of that it needs more CPU usage.So I need to know is logger.info() [which is a builtin class comes with java] is an I/O operation or not and a explanation why if it is not.
It depends on the registered handler(s).
By default, JUL outputs to console via a ConsoleHandler, that is an IO operation. If logging is configured with a handler that logs to file (FileHandler) or via Network (SocketHandler), that would also be an IO operation.
There is also a MemoryHandler, which wouldn't make logging an IO operation. But it has a very, very limited usefulness.
Using another log framework like SLF4J doesn't change that. Logging is inherently an IO operation, since you want the log to be accessible outside of the application and even after the termination of the process. It is still advantageous to use a framework like SLF4J, though, for various reasons (cf. Why not use java.util.logging?).
In Java, exception handling can be done in multiple ways. Let's differentiate exception handling using Logging framework as log4j or sl4j, where both of these could either redirect the logs to a file in addition to handle the exception.
If, instead of Logger framework, we use exception class method printStackTrace() to handle the exception and to get the exception call stack by redirecting it to a file rather than to standard error output/console, now, following are the questions:
Would the later implementation handle the exception at all OR will simply print the exception to file?
On what grounds does implementing Logger framework is prefered over printStacktrace() in Production environment?
Thanks in advance!
There are a lot of reasons why you shouldn't use printStackTrace() and, once it's not a recent thing here, let's not reivent the wheel (special attention for the God's Perfect Exception link, very good one indeed).
Logging frameworks allow us many things (so many):
Send our logs to different places at the same time. Most of them come with several appenders that do things like console and file output and send logging messages using email or JMS, e.g.;
Customize messages with severity levels, origin, filter keyring, etc;
Easy and custom configuration based in xml/properties files, without needing to change Java code;
Good async handling, mainly for distributed systems;
Verbosity configuration, setting the way your exceptions will be logged;
etc.
The custom appender feature, specially, is great because we can send logs to non-file destinations, like Splunk, Sumo Logic, Loggly, logstash, etc. just as many companies already do nowadays to analyse and monitor their production systems.
Plus, consider analysing the right logging framework for your needs.
To 2)
The logging frameworks aren't better file handler but, for example, extract the configuration of the logging out of the code. So when you change the configuration (e.g. other detail level of logs for development and production) you don't have to change the code - you just use other logging framework configurations for each test stage.
If you want to change the log file names, the log file size (rotation) or the specific log detail of different packages or classes, you can easily do that by modifying the configuration.
i am currently working on a java application for some network monitoring tool. In my code i am supposed to use logging a lot. Since its a network management software, the information in logs is quite useful to the user hence its compulsory to use them. But now I am bit confused with what kind of logger method i should prefer. Right now i am using Logger.lop(...//...) since with its help we are also logging the class name and method so its becoming very easy for me (developers) to debug the code and find the error. But finally I am confused should i deliver it to the end user with the same logging mechanism??? Is it any harm to let your user know what kind of class is executing currently , in which method error has occured. I have seen many times in many product in exception handling stacktrace is used so normally we get class name as well. So is there is no problem to let enduser know what your class name and method is??
Before considering the security implications of it, consider the performance. In most logging systems, getting the actual classname and method name dynamically by the logging facility requires reflection and dramatically slows down the logging - usually a synchronous operation. My guess is that in a network monitoring application, you really don't want that.
If you're hard-coding the method name into the log message (either by making it part of the message or by the category), that's a different story. As a security person, I don't consider it to be that big of a deal - if your code is in Java, it can be reversed anyhow, so your code should operate in such a way that it would be secure even if the code was given away.
All that being said, you could either use a different logging configuration for development and production, or those fine-grained messages could go in debug, trace, etc. If you're using log4j, it's generally advisable to use isDebugEnabled to wrap any logging statements which include anything dynamically-calculated as those get calculated before the logging statement determines whether it's enabled.
log4j/logback/slf4j allow you to have different formats for different appenders. For development you can enable a console appender where you include the class name in the format, while for the end-users you can omit it (for a file appender)
It's worth mentioning that such logging is performance costly in Java, contrary to C++ where it is usually implemented with preprocessor. Fortunately, with log4j/logback you can switch it on and off — follow Bozho's advice.
I'm using the Enerjy (http://www.enerjy.com/) static code analyzer tool on my Java code. It tells me that the following line:
System.err.println("Ignored that database");
is bad because it uses System.err. The exact error is: "JAVA0267 Use of System.err"
What is wrong with using System.err?
Short answer: It is considered a bad practice to use it for logging purposes.
It is an observation that in the old times when there where no widely available/accepted logging frameworks, everyone used System.err to print error messages and stack traces to the console. This approach might be appropriate during the development and local testing phase but is not appropriate for a production environment, because you might lose important error messages. Because of this, in almost all static analysis tools today this kind of code is detected and flagged as bad practice (or a similarly named problem).
Logging frameworks in turn provide the structured and logical way to log your events and error messages as they can store the message in various persistent locations (log file, log db, etc.).
The most obvious (and free of external dependencies) hack resolution is to use the built in Java Logging framework through the java.util.logging.Logger class as it forwards the logging events to the console by default. For example:
final Logger log = Logger.getLogger(getClass().getName());
...
log.log(Level.ERROR, "Something went wrong", theException);
(or you could just turn off that analysis option)
the descriptor of your error is:
The use of System.err may indicate residual debug or boilerplate code. Consider using a
full-featured logging package such as Apache Commons to handle error logging.
It seems that you are using System.err for logging purposes, that is suboptimal for several reasons:
it is impossible to enable logging at runtime without modifying the application binary
logging behavior cannot be controlled by editing a configuration file
problably many others
Whilst I agree with the points above about using a logging framework, I still tend to use System.err output in one place: Within shut-down hooks. This is because I discovered that when using the java.util.logging framework log statements are not always displayed if they occur in shut-down hooks. This is because the logging library presumably contains its own shutdown hook to clean up log files and other resources, and as you can't rely on the order in which shutdown hooks run, you cannot rely on java.util.logging statements working as expected.
Check out this link (the "Comments" section) for more information on this.
http://weblogs.java.net/blog/dwalend/archive/2004/05/shutdown_hooks_2.html
(Obviously the other alternative is to use a different logging framework.)
System.err is really more for debugging purposes than anything else. Proper exception handling and dealing with errors in a manner that is more user-friendly is preferred. If the user is meant to see the error, use a System.out.println instead.
If you want to keep track of those errors from a developer's standpoint, you should use a logger.
Things written to System.err are typically lost at runtime, so it is considered a better practice to use a logging framework that is more flexible about where to output the message, so it can be stored as a file and analyzed.
System.err and System.out for non-console applications is only ever seen by the developer running the code in his or her IDE, and useful information may get lost if the item is triggered in production.
System.err.println and System.out.println should not be used as loggging-interface. STD-Output and STD-Error (these are written by System.out and .err) are for messages from command-line-tools.
System.err prints to the console. This may be suitable for a student testing their homework, but will be unsuitable for an application where these messages won't be seen (Console only store so many lines).
A better approach would be to throw an exception holding the message that would normally get sent to the console. An alternative to this would be use third party logging software which would store this messages in a file which can be stored forever.
In the log4j.properties file I've set the Level to ERROR. For certain users I need to set Level to DEBUG. I was able to change the logging level at run time, but this will be enabled for all the users accessing the application at the same time.
Is there any other method by which we can enable logging for selected users? Any help will be greatly appreciated.
I presume you have a web application or similar, and multiple identifiable users accessing it simultaneously ?
You can't easily alter configuration per user in Log4j. However I would consider the following (this assumes a web server or similar, with each user request being on a separate thread):
identify the user making a server call as soon as they make that call. Store that user data in a MDC
Implement a custom Log4J appender. For each incoming call, you can inspect the user stored in the MDC, and adjust the severity/logging as required.
That's a little bit of work (given the above assumptions) but should work. Obviously it's not valid if the assumptions I've made about your architecture are incorrect.
This problem is solved in logback (log4j's successor) with TurboFilters. See the example entitled "MDCFilter and MarkerFilter configuration". If you need further help, contact the logback-user mailing list.
Yes, but.
You could make your loggers named with the class + user involved, rather than just the class, and create the logger on the method (or if you want to get fancy, cache loggers in some kind of pool keyed by user), and then configure logging appropriately.
It is very messy and intrusive to the code, but since the user is a runtime property, I don't see how (short of AspectJ or its cousins) how you avoid that kind of mess.
Another option is to specially format your log messages and include the user name in the log message, and then parse the logs afterwards. This would enable debugging for everyone (which may be a performance issue, obviously) but if the concern is more about isolating a users logging rather than limiting the amount of debug calls, that may be a solution.