is java.util.logging.Logger class info() method a I/O operation? - java

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?).

Related

printStackTrace vs Logger Frameworks in Java

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.

How to handle exceptions in logging when use Log4j2 Async logging?

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.

Avoid printStackTrace(); use a logger call instead

In my application, I am running my code through PMD.It shows me this message:
Avoid printStackTrace(); use a logger call instead.
What does that mean?
It means you should use logging framework like logback or log4j and instead of printing exceptions directly:
e.printStackTrace();
you should log them using this frameworks' API:
log.error("Ops!", e);
Logging frameworks give you a lot of flexibility, e.g. you can choose whether you want to log to console or file - or maybe skip some messages if you find them no longer relevant in some environment.
If you call printStackTrace() on an exception the trace is written to System.err and it's hard to route it elsewhere (or filter it). Instead of doing this you are advised using a logging framework (or a wrapper around multiple logging frameworks, like Apache Commons Logging) and log the exception using that framework (e.g. logger.error("some exception message", e)).
Doing that allows you to:
write the log statement to different locations at once, e.g. the console and a file
filter the log statements by severity (error, warning, info, debug etc.) and origin (normally package or class based)
have some influence on the log format without having to change the code
etc.
A production quality program should use one of the many logging alternatives (e.g. log4j, logback, java.util.logging) to report errors and other diagnostics. This has a number of advantages:
Log messages go to a configurable location.
The end user doesn't see the messages unless you configure the logging so that he/she does.
You can use different loggers and logging levels, etc to control how much little or much logging is recorded.
You can use different appender formats to control what the logging looks like.
You can easily plug the logging output into a larger monitoring / logging framework.
All of the above can be done without changing your code; i.e. by editing the deployed application's logging config file.
By contrast, if you just use printStackTrace, the deployer / end user has little if any control, and logging messages are liable to either be lost or shown to the end user in inappropriate circumstances. (And nothing terrifies a timid user more than a random stack trace.)
In Simple,e.printStackTrace() is not good practice,because it just prints out the stack trace to standard error. Because of this you can't really control where this output goes.
Almost every logging framework provides a method in which we can pass the throwable object along with a message. Like:
public trace(Marker marker, String msg, Throwable t);
They print the stacktrace of the throwable object.
Let's talk in from company concept. Log gives you flexible levels (see Difference between logger.info and logger.debug). Different people want to see different levels, like QAs, developers, business people. But e.printStackTrace() will print out everything. Also, like if this method will be restful called, this same error may print several times. Then the Devops or Tech-Ops people in your company may be crazy because they will receive the same error reminders.
I think a better replacement could be log.error("errors happend in XXX", e)
This will also print out whole information which is easy reading than e.printStackTrace()
The main reason is that Proguard would remove Log calls from production. Because by logging or printing StackTrace, it is possible to see them (information inside stack trace or Log) inside the Android phone by for example Logcat Reader application. So that it is a bad practice for security. Also, we do not access them during production, it would better to get removed from production. As ProGuard remove all Log calls not stackTrace, so it is better to use Log in catch blocks and let them removed from Production by Proguard.

Is it ok to log the source class name and method name in a java product?

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.

What's wrong with using System.err in Java?

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.

Categories