Exception Standard for different logging levels - java

Which is more suitable out of these two exception object (e) or e.getMessage() for log.info() and log.error() or log.debug().
What should be followed/rule of thumb for different logging levels.

It really depends on the reason of the exception being thrown. I would add here WARN level consideration as well. If this is an unexpected error that should not happen, meaning that this is something wrong with codebase you should definitely log the whole exception object, especially to get the stacktrace that allow developer to find and potentially fix issue faster. Therefore such situation should be logger on ERROR level if this is something wrong with the system, or WARN if this is something wrong with client's data.
INFO level should really not contain exception details, it should keep information easy to read by non-developers(for example testers) and describe the most important parts of the data processing flow.
I think it is up to you to put exception in DEBUG level but I would still recommend not to do it just to keep things clearer OR use e.getMessage() to describe it.
P.S. In general, I would redirect this question to this page since it is a general SE question but since you asked about using particular Java feature I wanted to keep things in the right place.

Don't try to create a fixed rule about including or not including the stacktrace depending on the log level. Instead, when creating a log entry, ask yourself:
Who will read that entry? A user, a system administrator, or a developer?
What information will be useful to that reader for understanding the situation? It's better to add too much information than to omit important parts.
If the entry is to be read by a developer, is the text enough or should I include the stacktrace? Non-developers typically get confused when seeing a stacktrace, but developers very much appreciate it.
This will greatly improve the quality of your logging.
As a very rough rule of thumb, include the stacktrace whenever you log an exception. An exception means that something went wrong, which might involve analysis by a developer, who will be very unhappy if the log entry only reads "NullPointerException" without a hint where it came from.
Of the typical log levels, INFO might be the one not addressing developers (thus not asking for a stacktrace), but generally you don't want to use INFO for exceptions.

Related

Best approach to wrap Apache Log4j into a custom class. Keep in memory logging management

I know that there are some answers already on wrapping logger around here, but none of them were satisfactory. I want to wrap Apache Log4j and also to keep an in memory management of errors (like class who thrown that error, reason and a count) and the scope is multiple: not to spam the log with the same error multiple times, to provide an close to user readable way of the root error cause, to have an overview classifications of errors and from where they came from etc.
Has anyone developed something similar? Is there any open source framework that can do that already?

define error code, number or string?

When I use enterprise application, I am usually greeted by some error that needs to consult help desk. I found many application still lean to use number as error code instead of a human readable string. Given most enterprise applications are written in modern language like java/C#, I can not figure out what's the benefit in using numeric error code.
So the question is, for enterprise application, is there a common adopted pattern for defining error code? is any reason number preferred to string?
BTW: I understand application using REST API likely use http status code for error code, this is understood as http status code itself is number. but for others, I don't understand
It's usually convenient to have both, a code, numeric or otherwise, and something human-readable.
The code makes it easy for machines to know what happened (and serve as shorthand for humans), and is verbiage- and locale- independent.
The single greatest benefit of error codes -- along with more informative strings -- is that they can be looked up even after your code has been translated into another language which you may not read.
The next greatest benefit is that if someone ever writes code that reads your error messages -- perhaps your own company, to help folks manage your appliction -- it is tremendously helpful for them to have an error code at the start of the message. That both speeds up their decision of what to do, and partially guards them against the risk that you might rephrase the message later (which would mess up attempts to search for the message text).
Any convention can work if you reliably stick with it. If you're thinking about the long term and multiple products, you'll probably want the code to include some indication of which code (application and/or library and/or other module) issued the error, and then you want to be able to quickly find the error in that product's support table.
IBM usually uses a moderately recognizable alphabetic prefix to identify the code, and a numeric suffix to indicate the specific message. Other companies probably do it differently.
I had recently similar problem and I have decided to use following rules:
Similar errors are grouped in types (in Java these would be Exception Classes)
Each error has enumerated value that identifies it (that is an error code)
Each error has human readable message
Errors optionally can have a cause (in many situations your errors were generated because some other error occurred, and that error is a cause)
You could argue about the need of the second rule since you could have as many types as possible errors. However if your system is growing, sooner or later you will find the need of introducing new types of errors, which will entail modification of your API and that's not always possible and even if it is, it might be not very easy since you will have to modify all of your clients. Enumerated error code list is simply easier to maintain in that case.

Java Log Coverage tool

Are there any tools or strategies for generating a "Log coverage" report on (Java, log4j)? Like code coverage, but ensuring that there aren't large methods, classes, or packages which don't log anything.
When coding web services, me team doesn't write many log statements. When debugging a real time problem with running, production code, we always wish we had. Inevitably we try to reproduce the bug in our test environment with either a debugger attached or additional log statements added, which can be very difficult depending on the structures and inter-operation involved.
Does anyone use this as a code-quality metric?
Code coverage takes special instrumentation because you're trying to find out whether a piece of production code is exercised by any test. What you're asking is a little more vague and could be either much easier ("is any logging done for this large class?") or much harder to the point of impossible ("did we log the method that's going to break in production?").
For the first question, you could whip up a shell script pretty quickly to do the job. Here's a skeleton in Perl, for example. Here, I assume that we're using SLF4J and that seeing the import of "LoggerFactory" is enough evidence to assume there's a logger.
while ($filename = shift) {
open my $in, "<$filename";
my $loc = 0;
my $log = "NO LOGGER";
while (<$in>) {
$loc++;
if (m/import org.slf4j.LoggerFactory/) {
$log = "has logger";
}
}
print "$filename : $loc LOC $log\n";
$total{$log} += $loc;
}
print "\n\nTOTAL LOGGED: $total{'has logger'}\nTOTAL UNLOGGED: $total{'NO LOGGER'}\n";
and I can run this from my shell to run over all the Java files in a little project with
$ find . -name \*.java -exec perl haslog.pm {} \+
This only works for small-sized projects, and it's fairly brittle but it wouldn't be a ton of work to make a more robust version of this.
Lots of logs can be noise and in my experience I always found tracing through logs painful. Having said that if the logs are managed well you can get good diagnostics/reporting. One of the reason for the code not being tested properly is because of having lots of logs in production code. What developers tend to do is add a log statement when they are developing to check the code works, consequently it encourages not writing a test with the right assertion. What you need is lots of little classes that are well tested composed together. The assertion should exactly tell you why the test is failing.
Lets say in your code path you are expecting something to happen which is its main responsibility (e.g Created a DB entry to register user/or someone logging in), when I say its main responsibility I am not talking about a side effect that happens in your code path. If you have an error condition in the main code path the exception should be thrown all the way up the stack were you can log and convert that to a user friendly message. RuntimeExceptions are a good here because you dont want to be catching these exceptions until its all the way up to the view layer. Side effects can be logged as well because they are like info/warnings.

What information to include at each log level? [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicates:
Where/what level should logging code go?
Debug Levels
Is there a convention, a standard, or a widely used guide which will help with logging in Java? Specifically, what to include at each level (verbose, debug, ... etc.) rather than the actual mechanism of logging.
There are many guides out there of what to include at each log level, but none of them are specific; they're all vague, and this makes it hard to "follow orders".
Any tips would be appreciated.
It's subject to personal interpretation, but mine is (in order from finest to coursest):
Trace - The finest logging level. Can be used to log very specific information that is only relevant in a true debugging scenario, e.g., log every database access or every HTTP call etc.
Debug - Information to primary help you to debug your program. E.g., log every time a batching routine empties its batch or a new file is created on disk etc.
Info - General application flow, such as "Starting app", "connecting to db", "registering ...". In short, information which should help any observer understand what the application is doing in general.
Warn - Warns of errors that can be recovered. Such as failing to parse a date or using an unsafe routine. Note though that we should still try to obey the fail fast principle and not hide e.g., configuration errors using warning message, even though we a default value might be provided by the application.
Error - Denotes an often unrecoverable error. Such as failing to open a database connection.
Fatal/Critical Used to log an error the application cannot recover from, which might lead to an immediate program termination.
In the end it's up to you to define what suits you best. Personally, I run most production system with logging level of Info, where I'm mostly interested in following the applications main logic, and of course catch all warnings/errors.
Except for code cluttering, there is no such thing as too much logging. All logging which helps you reproduce or understand problems better are good logging. On a performance note, most logging systems (e.g., log4j) allows configuring which level to actually append to the physical log which is a great thing.
For what it's worth, we're using the following log levels:
DEBUG level messages give highly-detailed and/or specific information, only useful for tracking down problems.
INFORMATION messages give general information about what the system is doing. (e.g. processing file X)
WARNING messages warn the user about things which are not ideal, but should not affect the system. (e.g. configuration X missed out, using default value)
ERROR messages inform the user that something has gone wrong, but the system should be able to cope. (e.g. connection lost, but will try again)
CRITICAL messages inform the user when an un-recoverable error occurs. (i.e. I am about to abort the current task or crash)
I think the most important thing with log levels is to figure out a scheme, document it, and stick with it. Although making log level consistent between programs would be nice, as long as you've used common sense in defining your log levels, users will tolerate a certain amount of variance between programs.
Simple log what yuo think is important if you were to come back later and need to read the logs. This of course means that your Object.toStrings now need to be nice and readable and not a dump of crap thats impossible to read. This also means you need to do sensible things like quoting strings etc..

General debugging log practices

Due to recent events, i am trying to figure out how much debugging logs i should use for code in general.
What i have been doing is using debugging logs pretty sparingly, and just in cases where i wanted some extra information or what have you. This made sense to me, as it seems like you shouldn't log every little thing your code does, as that could make flood you with so much information that it would be easier to miss something that was actually important (or go crazy from digging through and verifying logs).
On the other hand, i present an example: I just started using logback/slf4j for my java project, and to test that i had the .xlm file set up correctly i added a debugging log statement to the end of a method that initializes gui components. Normally i would have never put a log statement there, because it is pretty obvious if your gui components don't initialize correctly when you run the program. However this time i ran the program, and low and behold the logs showed that the gui components were being initialized twice, even though only one set of them were being displayed. A decent sized bug, but something i likely wouldn't have caught without without those debugging statements.
So my question: Is there any "best practices" out there when it comes to debugging logs? I have seen many best practice questions when it comes to info logs, exceptions, errors, etc, but haven't found much out there in regards to debugging logs.
Thanks :)
Some thoughts:
Don't just log what's happening, but take care to log the available parameters/method arguments etc. It's easy to overlook this.
It's easy to disable debug logging via configuration rather than logging in after the fact.
Don't worry about logging overhead until it really becomes an issue.
You can automate some logging (entry/exit of methods) by using an AOP framework (Spring / AspectJ etc.)
I don't think there are any "best practices" in deciding what / how much to log. It is one of those catch-22 situations. If you need to look at the logs, there is "never" enough information there, but if you don't then "all" logging is just code clutter and an unnecessary runtime overhead. You need to make a separate judgement about where to draw the line for each application.
One point to bear in mind though. If you and your customers are able to hack the code to add temporary debugging statements, then you don't need as much permanent logging code in place. But if you don't have the option of hacking on the (almost) production code to debug things, then you need a certain level of logging code in place, just in case ...

Categories

Resources