Java log levels - When to use What - java

When should i use below log levels? If there is any example that would be great.
Trace Vs Debug
Warn Vs Error Vs Fatal
WARN VS ERROR Vs FATAL
Will I need to use FATAL in my application code in first place?
I have never seen FATAL logging in any code still now in projects that i worked on till now.
I have read that, in case of FATAL program will end. If this is the case, I wonder how my log statement will execute.
Moreover, I think FATAL can not be used in the case of memory allocation as JVM will throw out of memory exception and exit the program. Hence developer can not log anything. If this is correct then where exactly i will use FATAL?
For ERROR and Warning:
In catch block, if I do not have a alternate logic (for error condition) to perform then, I will go and log exception with Error level, the exception will be transformed into user specific and displayed in screen.
At the same time, the Warn will be used when we have alternate flow /path to the exception logic.
For Debug
This will be to validate what and where the exception been thrown. What means the data that casued the error. Hence this can be used just before and after the complex logic of the code.
Please let me know if my understanding is correct
example:
class myLogLevel{
void method1( int empId)
{
log.trace("method1 starting") ;
try{
log.info("befor getting data from DB");
log.debug("executing the value for emp id : " + empId );
//DBConnection and code here
} catch (Exception1 e1) {
log.warn("record not found. So assigning default value");
// Code logic to assign default value
}
catch (Exception1 e1) {
// Due to DB connection error. Connection nor established
log.error("DB connection not established");
}
log.trace("method1 ending") ;
}
}

In my past experiences, a somewhat common practice is
Always use DEBUG for your debugging purpose. I seldom see people use TRACE.
For stuff which is bad for the system but not necessarily cause problem (i.e. if it's an error depends on the calling context), use WARN; E.g. you could write a function which sometimes return NaN; but NaN might not be an error for the caller depends on your context.
For stuff that's surely an error somewhere in the system or in the caller input data; that definitely needs human involvement (i.e. someone needs to look at it from your production support team), uses ERROR. E.g. you want to write a person's record into database but found the primary key (firstname, lastname) is NULL.
For stuff that would cause the entire system to shut down or cause seriously impact on the system, use FATAL. That means people needs to look at it immediately. Examples include problems that cause startup failure; memory allocation failure; A messaging processing system failed to initialize the messaging layer; etc.
Hope the above helps.

Related

Information Exposure Through an Error Message in checkmarx

try {
//code
} catch (ParseException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
LOG.error("Error in finding Resource Bundle", e);
}
I wrote like that, but when I am using Checkmarx code analysis tool I am getting "Information Exposure Through an Error Message". How to resolve and when this we get.
What is Information Exposure Through an Error Message?
The software generates an error message that includes sensitive information about its environment, users, or associated data.
The sensitive information may be valuable information on its own (such as a password), or it may be useful for launching other, more deadly attacks. If an attack fails, an attacker may use error information provided by the server to launch another more focused attack.
(Quote taken from CWE-209: Information Exposure Through an Error Message
)
You did not specify, but I'm assuming that the Checkmarx tool pointed to printStackTrace() as the problematic end point of the flow.
By using this method, an exception (including its entire stack trace) will be printed to the standard error stream. This might include information that may be sensitive by itself (like usernames or passwords) or at least disclose some environment data. If this data is exposed to a user, it can be abused or used maliciously for more effective attacks.
There are many others reasons not to use printStackTrace() that way, as can be seen here: Why is exception.printStackTrace() considered bad practice?
First of all remove e.printStackTrace();.
Now, As its compulsory to log errors so, you can;t remove LOG.error("Error in finding Resource Bundle", e);.
So, just provide the closure for this .. that Logs are being generated. As this is LOW critical their is no big issue.
This happens every-time with our project too :P .

Why does squid:S1166 not accept exception messages only when logging caught exceptions?

Quote from the description of the rule (SonarQube 4.5.5):
// Noncompliant - exception is lost (only message is preserved)
try { /* ... */ }
catch (Exception e) { LOGGER.info(e.getMessage()); }
By providing the exception class to the logger a stack trace is written to the logs.
The problem in our code base is this:
By following the Tell, don't ask principle, we use checked exceptions as part of the, what we consider, normal execution paths and we don't want them to result in unreasonably large log messages.
A few examples: Servers responding with error codes, database statement executions failing on optimistic locking (concurrent users)...
My suggestion: Split this case in two.
// Noncompliant - exception is lost (only message is preserved)
try { /* ... */ }
catch (Exception e) { LOGGER.info(e.getMessage()); }
and
// Compliant - exception is lost (only message is preserved) but there is business logic handling the situation
try {
/* ... */
} catch (Exception e) {
LOGGER.info(e.getMessage());
*/ exception handling */
}
The rule squid:S00108 (code blocks must not be empty) would not catch the problem since there is a logging statement.
Is this not reasonable? Have I missed something of importance?
Note: I've rewritten the question to clarify my use case
I understand the arguments for maintaining the stack trace and all that, but I think it's going to bloat your logs for a < ERROR level event. One solution is to log the message as a WARN and log the exception object as DEBUG or TRACE. That way a normal user log config would not be flooded with business as usual stack traces, but it would still be possible to get a stack trace if necessary.
If it's causing hundreds of what you consider to be FP's then you should think about turning the rule off, or excluding it from your project files.
But to answer your question:
The point of exception logging is to leave enough information for investigators to figure out the cause of a problem.
If your messages are detailed, e.g.
The x in the y method broke because the frabjous was not day enough
then perhaps they fulfill that purpose. But what about a message like
Something went wrong
?
Further, you know exactly what each exception message means, but someday you'll presumably move on to bigger and better things. Will the next guy who supports the system have the same depth of knowledge? He may be grateful for the stacktraces and line numbers that tell him where to start looking...
But finally, I have to ask: why are you getting and logging so many exceptions that you flood the logger?
(Adding another answer to address the question as rewritten:)
Why would you both handle the exception and log it? If it's handled, there's no reason to log.
try to pass whole object to method than just a e.getMessage()LOGGER.info("INFO "e.);

Should we log the stacktrace for managed exception?

I made many research on this subject without found a real answer.
Try to imagine a program which execute a multi thread calling a Callable.
For that, we launch an ExecutorService with a specific timeout which invoke all process.
So we have a try...catch block with multiple exception :
CancellationException for a timeout
ExecutionException if an exception is raised in the thread
InterruptedException for an abrupt stop...
Is the philosophy to log an message only, or to log the message and the throwable (so the stacktrace) ?
To sum up, should we do this :
} catch (CancellationException ce) {
logger.error("Timeout. Process cancelled", ce);
}
or just log the message error ?
Is stacktrace considered to appear only for bugs ?
Thank you.
For coding you should stick with the following pattern:
} catch (CancellationException ce) {
logger.error("Timeout. Process cancelled", ce);
}
The reason is that the Throwable captures the complete context of an error. If you omit parts of that context from the logger you'll never be able to access it later on if you need it. Even the Throwable class included with Java has been modified over time to include things like chained and suppressed exceptions. So even if you only want the message from this throwable you still might want to see the full stack traces for suppressed exceptions and exceptions causes.
On the output side, I think you can make that case that for some exceptions the stack trace is not important. In some cases the target audience must not or does not want to see exception stack traces. For these cases should leverage the features of the framework to change the published output to please the target audience. If the needs change over time you can tweak logging configuration without having to fix the application code.

if every exception catch should log it?

some books mentioned that the followed mode is bad. It says every exception if be rethrowed shouldn't log it to avoid to dupliacte exception log.? any other issues?
I am confused that if I can't log any exception when rethrow it , if the issue exist?
or if I log it, I am confused if the too many log generated if everybody do it.
catch (NoUserException e) {
LOG.error("No user available", e);
throw new UserServiceException("No user available", e);
}
the reference
http://today.java.net/pub/a/today/2006/04/06/exception-handling-antipatterns.html#logAndThrow
I'm not sure about the books you mentioned, but to me, as someone who'll have to debug the code and find the root cause of the bugs, I'd like to read about it later in the logs as close as possible to the place where it first triggered.
Every LOG function have a switch to disable that log message so you have to LOG all exception if it is unexpected one. If you expected that exception, for example you check if the String is a number and you would like to know the result on exception, then you do not need to do the Log.
As far as exceptions are concerned, the most important log message should be located in service layer. Important thing is keeping the whole stack trace so the issue can be easily located even after several rethrows.
You can always put logs in all layers and manipulate logging level for certail layers to see only logs from layer you are currently debugging/working on. Other logs can be set to OFF. Read documentation for your favorite logger to learn more about that.

Strategies/techniques for crash reporting in Java

I'm developing a new Java desktop application and would like to include a crash reporting facility - you know the kind of thing - program crashes, box pops up asking user to click okay to send it, etc.
I'm comfortable with how the error will be sent back to our servers - probably via a simple web service. What I'm more unsure about is how the mechanism for capturing the failure should be implemented?. I would welcome any advice from anyone that has implemented something similar.
There is a command line option you can give the JVM that will run a batch file after the JVM crashes with a memory dump. All you do is create a external program that does the error reporting and then use the JVM option to send the core dump in email using the utility you made.
-XX:-HeapDumpOnOutOfMemoryError -XX:OnError="<cmd args>;<cmd args>"
Use Thread.setUncaughtExceptionHandler and the static Thread.setDefaultUncaughtExceptionHandler to (attempt to) report exceptions to your logging system.
I see three cases:
Catastrophes. The JVM itself is either dead or dying. You cannot assume that any of your code will be able to work - for example you can't allocate any memory. Hence in this case you can't reasonably hope to be able to send any diagnostics. The best you can hope for is to have some diagnostics such as core dumps left in the ashes of the dead program.
In this case you could on startup of a new run look for such debris and suggest that the user gather it or, rather more effort attempt to assemble a diagnostic package yourself.
The low-level application code does not catch an exception, perhaps a RunTime exception such as a NullPointer exception. In this case you could in your main (assuming you have one) you could catch Exception and have some hope your that your Crash Reporter code will work.
Pass the exception, and it's stack trace, to the Crash Reporter.
You low level code catches something really unhealthy. Not enough to terminate process, but worth reporting. Here you not only have the exception to hand but other contextual information. We have rather more to send to the Crash Reporter.
Use logging. The generic pattern works like this:
Create an appender that sends the error message to the server (most logging frameworks support appenders that transmit log messages via mail or even JDBC). If there is no existing appender, they have examples how to do that.
Add that appender to the root logger and set it's threshold to ERROR
Log an error when you notice an exception. The logging framework will then do the plumbing for you.
I don't know if this is the best that Java currently has to offer, but this is what I did a while back.
First all interesting activity likely to crash was dispatched via a command pattern. This application consisted of hitting an application server over the internet, so a lot could go wrong. The exceptions were caught by the command dispatcher and the appropriate result displayed to the user (generally showing an error dialog followed by a shutdown and an e-mail sent about the crash).
Second, a custom event queue was used in Swing to catch any exceptions that happen on the event thread. I would hope that Java has a better solution by now, but basically when an exception happened you had to check if your code was involved, otherwise some Swing bugs could crash your application, which isn't pleasant. And of course recursion had to be checked for (the crash repeating itself over and over again as you try to display a message to the user).
By the way, most any crash will keep your JVM going, including out of memory errors, enough to send an e-mail in most cases, as after an out of memory error generally the error releases enough of the stack (and therefore heap) to allow for further garbage collection and letting your code live. But in such an event you should still exit quickly. IDEA keeps going after an out of memory error, but often isn't functioning well. They would be better off exiting, IMO.
You push a new Queue with the following and subclass EventQueue to link in your behavior.
Toolkit.getDefaultToolkit().getSystemEventQueue().push(newQueue);
One option would be to use BugSense. It is targeted towards mobile-application crash reporting but the API states that it could be used for any kind of crash reporting. It's quite simple from what I've read and all one needs to do is create a simple POST request with all the values.
{
"client": {
"name": "bugsense-android", // Obligatory
"version": "0.6"
},
"request": {
"remote_ip": "10.0.0.1",
"custom_data": {
"key1": "value1",
"key2": "value2"
}
},
"exception": {
"message": "java.lang.RuntimeException: exception requested", // Obligatory
"where": "MainActivity.java:47", // Obligatory
"klass": "java.lang.RuntimeException", // Type of exception
"backtrace": "java.lang.RuntimeException: exception requested\r\nat com.sfalma.trace.example.MainActivity$1.onClick(MainActivity.java:47)\r\nat android.view.View.performClick(View.java:2408)\r\nat android.view.View$PerformClick.run(View.java:8816)\r\nat android.os.Handler.handleCallback(Handler.java:587)\r\nat android.os.Handler.dispatchMessage(Handler.java:92)\r\nat android.os.Looper.loop(Looper.java:123)\r\nat android.app.ActivityThread.main(ActivityThread.java:4627)\r\nat java.lang.reflect.Method.invokeNative(Native Method)\r\nat java.lang.reflect.Method.invoke(Method.java:521)\r\nat com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)\r\nat com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)\r\nat dalvik.system.NativeStart.main(Native Method)\\n" // Obligatory
},
"application_environment": {
"phone": "android", // Device model (could be PC or Max) Obligatory
"appver": "1.2", // Obligatory
"appname": "com.sfalma", // Obligatory
"osver": "2.3", // Obligatory
"wifi_on": "true",
"mobile_net_on": "true",
"gps_on": "true",
"screen_dpi(x:y)": "120.0:120.0",
"screen:width": "240",
"screen:height": "400",
"screen:orientation": "normal"
}
}
You can read more about it here.

Categories

Resources