How to properly handle error logs? - java

I tried to do several searches before posting this question. If this is a duplicate, please let me know and I will delete it.
My question revolves around the proper way to handle errors produced through our web application. We currently log everything through log4j. If an error happens, it just says "An error has occurred. The IT Department has been notified and will work to correct this as soon as possible" right on the screen. This tells the user nothing... but it also does not tell the developer anything either when we try to reproduce the error. We have to go to the error log folder and try finding this error. Let me also mention that the folder is full of logs from the past week. Each time there is an error, one log file is created for that user and email is sent to the IT staff assigned to work on errors. This email does not mention the log file name but it is a copy of the same error text written that is in the log file.
So if Alicia has a problem at 7:15 with something, but there are 10 other errors that happen that same minute, I have to go through each log file trying to find hers.
What I was proposing to my fellow co-workers is adding an Error Log table into the database. This would write a record to the table for each error, record who it is for, the error, what page it happened on, etc. The bonus of this would be that we can return the primary key value from the table (error_log_id) and show that on the page with a message like "Error Reference Id (1337) has been logged and the proper IT staff has been notified. Please keep this reference id handy for future use". When we get the email, it would tell us the id of the error for quick reference. Or if the user is persistent, they can contact us with the id and we can find the error rather quickly.
How do you setup your error logging? By the way, our system uses Java Servlets that connect to a SQL Server database.

I answered a similar question here, but I will adapt that answer to your question.
We use requestID for this purpose - assign a request ID to each incoming (HTTP) request, at the very beginning of processing (in filter) and then log that on every log line, so you can easily grep those logs later by that ID and find all relevant lines.
If you think it is very tedious to add that ID to every log statement, then you are not alone - java logging frameworks have made it transparent with the use of Mapped Diagnostic Context (MDC) (at least log4j and logback have this).
RequestID can also work as a handy reference number, to spit out, in case of errors (as you already suggested). However, as others have commented, it is not wise to load those details to database - better use file-system. Or, the simplest approach is to just use the requestID - then you do not need to do anything special at the moment error occurs. It just helps you to locate the correct logfile and search inside that file.
How would one requestID look like?
We use the following pattern:
<instanceName>:<currentTimeInMillis>.<counter>
In consists of the following variables:
instanceName uniquely identifies particular JVM in particular deployment environment / .
currentTimeInMillis is quite self-explanatory. We chose to represent it in human-readable format "yyyyMMddHHmmssSSS", so it is easy to read request start time from it (beware: SimpleDateFormat is not thread-safe, so you need to either synchronize it or create a new one on each request).
counter is request counter in that particular millisecond - in the rare case you might need to generate more than one request ID in one millisecond
As you can see, the ID format has been set up in such a way that currentTimeInMillis.counter combination is guaranteed to be unique in particular JVM and the whole ID is guaranteed to be globally unique (well, not in the true sense of "global", but it is global enough for our purposes), without the need to involve database or some other central node. Also, the use of instanceName variable gives you the possibility to limit the number of log files you later need to look in to find that request.
Then, the final question: "that is fine and dandy in single-JVM solution, but how do you scale that to several JVMs, communicating over some network protocol?"
As we use Spring Remoting for our remoting purposes, we have implemented custom RemoteInvocationFactory (that takes request ID from context and saves it to RemoteInvocation attributes) and RemoteInvocationExecutor (that takes request ID from attributes and adds it to diagnostic context in the other JVM).
Not sure how you would implement it with plain-RMI or other remoting methods.

If multiple servers are running and each server leaves log messages on itself, it is really difficult to trace them. So,somebody or a tool should gather and sort them in time order.
It is a good way to have a central point where all messages are sent.

A possible solution, have your error page include a 'send email to whatever' link. When the user clicks this email the body of the e-mail might start with a few blank lines followed by something like:
----Please do not modify the information below this line.---
Error details
Any users complaining via this link will automatically send you the info you need and if you are reproducing the error you have quick access to the error message. You might even have a form for sending the e-mail so that the user never sees this (which may be important to some) but then you are relying on your system being at least able to send an e-mail.
Actually I find it useful to print the error details in an HTML comment on error pages like this so that I can always get at them myself.
I do agree with david above that I do not like storing this kind of information in a DB.

For the strategies of logging you can see the discussion Logging best practices.

I have used an approach like the one you're suggesting ( log to a db ) in the past and it has been very helpful.
Not only you cat get the error via SQL but you can also generate reports of what's the most recurring errors and attend them first.
On the design we did, equals stacktraces belong to the same records ( since they were originated exactly in the same place )
We had an small app that pooled that db and we knew then a new exception was generated instead of getting an e-mail that summed with the rest of the previous weeks were ignored altogether.
Of course this database design was very specific for the application we had and additional identifications were possible, we had software version, build, some times input parameters , etc. etc.
With time, the system administrators get to know what to do with each kind of exception and proceed accordingly.
But! Your application may not be that big anyway. Probably you can have the same just parsing the log files.

I'd oppose the idea of storing error logs in a database. The logging system should be as simple as possible and not involve components that are not 100% necesary to write a log record.
Things can get pretty complex when logging into a DB - e.g. you can having troubles logging any database-related errors (how to log errors that occured because DB not responding, e.g. because of a heavy load or a infrastructure error); other issue I'd see is a potential need to have separate transactions for logging, etc.
On the other hand, having a reference ID for an error is not a bad idea, but again, this it also means to increase complexity of logging system ( e.g. how would you propagate the ref. ID through all layers of your application when a error occurs? )
In projects I'm involved to, the general guideline is to log errors as verbosely as possible, and to include as much context information as possible (to write the logs, we use a 'conventional' approach usually - log4j or simillar). Usually, this works well even for heavy loaded systems.

Related

A table that contains View objects tags

First of all I must say I'm new to both Android dev and Java.
I'm trying to find a list of the tags that are used for logging in Android studio.
The examples I've been researching include using:
Log.i(tag:"Info","message");
Log.i(tag:"Values","another message");
Log.i(tag:"Seekbar changed", "and another message");
I tried for the past couple of hours to find a document online, that has a table to describe the reserved tags for View objects, any help will be appreciated.
There is no fixed list of "reserved tags" one can use for logging in Android. You decide for yourself which tags you want to use and what additional information about the state of your objects or primitive types you want to display.
The Log class has six different log levels (debug, error, info, verbose, warn and wtf [What a Terrible Failure]) and corresponding (static) methods (Log.d, Log.e, Log.i, Log.v, Log.w and Log.wtf) each of which you call with two string parameters, one string parameter and one Throwable or two string parameters and one Throwable.
The most commonly used is probably the variant with two string parameters, one parameter for a tag (chosen by you) and one parameter for a message (also chosen by you). See this post for information about which level to choose.
During debugging I often use commands like this one:
Log.e(String.valueOf(myIntVariable), String.valueOf(myOtherVariable));
Let me explain the reason for using the Log class like this. I use the error level because it will give you red entries in the LogCat output (inside an IDE, e.g. Android Studio), and the same IDE will also let you filter out all logs below the error level. However, this is for debugging only; make sure to get rid of those log commands before your app enters production.
Instead of using logs in the way I do, you can also use breakpoints in the debug mode. I guess it is mainly a question of taste if you prefer one or the other. Toasts would be third option (with more boilerplate though).
If you use logs a lot in your code, it makes sense to use real tags. Either you define a string called TAG (or something else) in your class, or you put the name of the containing method as the first parameter. This will give you a sense of the order by which your methods are being called. You can also use other tags as well, and it doesn't have to follow a specific convention either (though you should have a system for it to make sense of it).

Persistent background checking with Selenium

First time poster, long time lurker. I've gotten a lot of great advice to problems from this site, but I haven't found anything here for the topic of this question. Normally I would bug our SME at the office but he's indisposed.
So, we use Selenium Web Driver to do automated tests. I'm working on an application with some mapping and demographics features, so my tests are very function vs. form oriented.
My tests are written such that I have classes/methods that are a part of the puzzle (the site is essentially one workflow where you go from page 1 to page 5 and the same actions need to be performed in steps 2-3, for example, but test A might do something different on page 4 to see the result in page 5. Clear as mud?
Anyways, during manual tests, I can sometimes see an error message pop up on the site (a hidden div that will become visible if it detects an error, but it's usually a very generic/vague error). This error sometimes pops up even if you're able to go through the flow with no other ill-effects. However, I want to capture when these errors happen so I can look for patterns - if this means just logging it to console or failing the test...I can figure that out later.
The immediate problem is having a persistent check in place that will always look for this error during every test. I could create a method and call it in my "action" methods, though this would leave gaps and slow the tests down. Is there any clever way of implementing something like this without slowing the tests down or calling this check every time I do a step in the process? Also, forgive me, I'm still learning Java and the selenium web driver, so if I've said anything stupid, that's why.
Since this message is persistent if it is there, you might try adding a check for it in your test case teardown method. (I would recommend that you reduce the implicit wait time before you do that check, though, otherwise each test will take an extra amount of time waiting for an error message that isn't there.)
Another possible option is to define your own listener on your own test runner and update the testFinished() method to go check for your error message. See this for some ideas.
Since it sounds like the error messages are always in known locations on each page, I would create a method (or methods, depending on how many error message locations there are on a given page) that looks to see if an error exists and then log it before leaving the page. It sounds like you might be using the page object model. If so, you can add these methods to the each relevant page object for easy access.
NOTE: Checking for errors once before you leave the page may not be enough. You may need to check each time you do some action that might cause an error. This is probably not a bad practice anyway because it will help in debugging errors because you will notice an error closer to the time it was triggered, thus narrowing down what caused the error.
If you have the ability, do something like log it as a warning so that it doesn't fail your test but stands out (and is searchable) in your logs.
You seem concerned that checking for all these errors will significantly slow your script. If properly written, it shouldn't add a significant delay. One significant delay you might run into is if you have implicit waits turned on and are checking for elements that don't exist (e.g., unless there's an error). This will cause the implicit wait to be applied each time you search for the missing element and will likely add significant time to the run time. My suggestion is to turn off implicit waits and add explicit waits only where needed. Searching for any element will add some time but 25ms here and there should be negligible in an overall script run.
Have you tried using EventFiringWebDriver?
There is an answer here on what it does:
What is EventFiringWebDriver in selenium?
Newer selenium versions have more types of events present in the interface, which can broaden its use on these types of tests.

Performance Impact of logging class name , method name and line number

I am implementing logging in my java application , so that I can debug potential issues that might occur once the application goes in production.
Considering in such cases one wouldn't have the luxury of using an IDE , development tools (to run things in debug mode or step thorough code) , it would be really useful to log class name , method name and line number with each message.
I was searching the web for best practices for logging and I came across this article which says:
You should never include file name, class name and line number,
although it’s very tempting. I have even seen empty log statements
issued from the code:
log.info("");
because the programmer assumed that the line number will be a part of
the logging pattern and he knew that “If empty logging message appears
in 67th line of the file (in authenticate() method), it means that the
user is authenticated”. Besides, logging class name, method name
and/or line number has a serious performance impact.
I am trying to understand how logging class name , method name and line number degrade performance.
Is the above true for all logging frameworks or only some of them? (The author makes a reference to Logback in the same topic) . I am interested in knowing about performance impacts of doing something like this in Log4j.
There are different concerns at play here.
First of all, what is the impact of logging a simple string. This largely depends on the infrastructure you use. Recently I did run some benchmarks, and just logging a string to a file using the standard java logging API is extremely expensive. You're going to get better results using the log4j logging infrastructure, which my tests show are in the order of 15 or 20 times faster.
Now let's consider the file name and line number problem. As opposed to C, java doesn't have a __FILE__ and __LINE__ constant which are resolved by the compiler (or the preprocessor in case of C). If you want to log file name and line number, you have two options:
You actually write such file name and line number yourself as constants. This may be acceptable for the filename, but the line number will change if you introduce any line above the one where you're logging, so you will have to go and change all the line numbers there. Not really reasonable
You use java APIs to get a stack trace as mentioned here. This operation though is very expensive at runtime, and hence will slow down your program.

Is it correct or safe to throw an Exception whose message includes the offending value?

Let's say you are writing a generic doSomething method where you check a string argument for validity:
public void doSomething(String argument) {
if(!checkArgument(argument)) {
// Argument is not valid
throw new IllegalArgumentException("Argument " + argument + " is not valid");
}
...
Is throwing an Exception whose message can contain potentially arbitrary text safe? Or can it expose the program to log forging or some other security issues?
Is there any best practice to handle such cases?
It really depends on what you are going to do with the exception after it is thrown.
In general, I'd say this is probably a bad idea. As a rule of thumb you should never "use" unsanitized arguments. Here are a few attack scenarios this might open you up to.
This is for a webpage and you are displaying this error to the user. In this case the attacker could execute a XSS attack, among other things.
This error will be printed to a log. Here it may seem safe, but the attacker still has some (all be it limited) access to your file system. They could use this mechanism to store code for future use, or possibly damage the log (or other aspects of the file system). This is especially true if argument is written byte for byte to a file.
This error will be stored in a database. Here with enough schema information the attacker may be able to alter, or destroy the entirety of the database.
On it's own this might not be enough for an attacker to steal any information, but combined with other bugs this could be used to gain control of the machine. You could do some basic sanitization though and avoid most of these issues.
As suggested by #assylias perform length checking.
Ensure all characters in argument are alphanumeric (or whatever you expect things in arg to be).
If alphanumeric is to restrictive, pass through any whitelist that doesn't include html/javascript/sql syntax characters (e.g. '<','>',';') Usually these characters do not need to be present for debugging anyways.
Generally safe, but you should decide whether to allow exceptions to be visible to end users if the code is executing on a system under your control (e.g. a web server). Showing internal information in error messages in exceptions is a form of Information Leakage as it can reveal information about how your system is built and an attacker can probe for vulnerabilities by forcing exceptions. This may not apply if it is a desktop application, as this is effectively under user control anyway, but extra caution is needed to anything web or internet based.
However, you could add logic to your custom error handler page to only show the details of exceptions that derive from MyUserExceptionClass which you make it your policy to only use when the end user can rectify the error. In this case you'll probably only want to show the message itself and not output any stack trace or other details, in which case your exception message should contain details of the argument name if it is relevant to the end user.
To address the points in diedthreetimes's answer, these should not be of concern to the exception throwing class or the exception class itself. The class that uses the unsanitised data should sanitise it for the context it is output.
e.g.
If output in an HTML page, HTML encode the exception message at point of output, not at point of exception throwing.
The error logging class should sanitise the unsanitised text into the correct format for the log. If there is a character limit or if it is a CSV formatted file then this class should ensure that any commas and quote characters in the message are formatted properly at this point.
If written to the database, it is up to the Data Access Layer to correctly write the information into the database using parameterised queries.
I broadly agree with SilverlightFox's answer. Worry about injection vulnerabilities at the point they occur (and make sure they cannot occur).
However, confidentiality issues are a real problem with exceptions. Elsewhere (unless we have globals) we are dealing with interactions over a single layer-interface. Bring in exceptions and we have non-local issues.
For example:
SSNs are the canonical example of data that needs tight controls. Some low-level parsing library may throw an exception with details of the string. That may be caught and shoved into a log. Neither generic parsing code nor logging code know about SSNs but they've ended up introducing an SSN vulnerability.
Web sites that put exception messages into web pages (sometimes in comments - that doesn't help!) disclose information about the web site implementation that may be helpful to an adversary. Web sites should not do this, but they do. Therefore, you need to think carefully about any code that throws exception and could end up in a web app some day.
Exceptions propagated between processes, or machines, or operating system to pross, or whatever, may carry confidential information.
Where there is mobile code, confidential information may be slip down to less privileged code. File paths are the obvious candidate here.
It's also worth noting that adding mutable data to exceptions is a bad idea, as it needs a deep copy to be safe. It's a shame that 1.4 made Throwable itself "usefully" mutable.
You can log the argument and include a substring in exception.
For your concern on security it depends on access control model of your application and infrastructure.
If server is not accessible to all, then logging is a good idea at least you can have a look at what argument caused exception.
If security is a higher concern, I would suggest storing exception details in a database table along with parameter for analysis.
If you want to go crazy you can encrypt your database column.
In any case I think one would like to have a look at what argument caused exception.
Cheers !!

How to know when there's too much logging messages?

I came across one very good library for parsing CUE files. But when I started to read its source code, I realized that it is almost unreadable:
public void setParent(final CueSheet parent) {
FileData.logger.entering(FileData.class.getCanonicalName(), "setParent(CueSheet)", parent);
this.parent = parent;
FileData.logger.exiting(FileData.class.getCanonicalName(), "setParent(CueSheet)");
}
every method has logger.entering() and logger.exiting() messages. Isn't that too much?
There's another java library for parsing audio tags. It also had like 15 log messages for each file it read. It was annoying so I commented out every call to logger. And the library became twice as fast, because they used a lot of string concatenation for log messages.
So the question is: should I really log everything, even if it is not large enterprise application? Because these libraries obviously don't need any logging, except for error messages. And my experience shows that loggers are terrible tool for debugging. Why should I use it?
How to know when is too much logging? When you know that the logged information isn't important in the long term, such as for straightforward debug actions or bug correction, or for when the application doesn't deal with too much important information.
Sometimes you need to log almost everything. Is performance or full possibility of analysis the most important part of an application? It really depends.
I've worked in the past with some integration with a lot of different webservices, like 10 in a same app. We logged all xml requests and responses. Is this an overhead? In the long term, I don't think so because we worked with a lot of credit card operations and should have every process made with the server logged. How to know what happened when there was a bug?
You wouldn't believe what I've seen in some of the xml responses. I've even received a xml without closing tags, from a BIG airplane company. Were the "excessive logs" a bad practice? Say that to your clients when you have to prove that the error came from the other vendor.
Ideally, you use a logger that allows logging levels; log4j has fatal/error/warn/debug/info, for example. That way, if you set the level to "only show errors", you don't lose speed to the software building log messages you didn't need.
That said, it's only too much logging until you wind up needing something that would have been logged. It sounds like most of the logging that's slowing you down should be "trace" level, though; it's showing you what a profiler would have.
Most logging libraries incorporate a means to confirm that logging is enabled before processing an instruction:
For example:
public void foo(ComplicatedObject bar) {
Logger.getInstance(Foo.class).trace("Entering foo(" + bar + ")");
}
Could be quite costly depending on the efficiency of the bar.toString() method. However, if you instead wrap that in a check for the logging level before doing the string concatenation:
static {
Logger log = Logger.getInstance(Foo.class);
public void foo(ComplicatedObject bar) {
if (log.isTraceEnabled()) {
log.trace("Entering foo(" + bar + ")");
}
}
Then the string concatenation only occurs if at least one appender for the class is set to Trace. Any complicated log message should do this to avoid unnecessary String creation.
This level of logging is canonically bad - in fact, I saw code exactly like this in the Daily WTF a few days ago.
But logging is in general a Very Good Thing.
It depends, it this code for an application, or a library? For an application, logger are useful once the code is in production. It should not be used to debug, but to help you replicate a bug. When a user tells you that your application crashed, you always want the maximum logging information.
I agree that it makes the code less readable. It even make the application slower!
It's a total different game for a library. You should have consistent logging with adequate level. The library SHOULD inform the development team when an error occurs.
Logging should provide you with information that a stack trace can't in order to track down a problem. This usually means that the info is some kind of historical trace of what the program did, as opposed to what state it's in at the time of failure.
Too much historical data will be ignored. If you can safely deduce that a method was called without having to actually log its entry and exit, then it's safe to remove those logging entries.
Another bad sign is if your logging files start to use up a huge amounts of disk space. You're not only sacrificing space, you're probably slowing down the app too much.
To answer the question, why should I use loggers?
Have you ever encountered a piece of software where the only error indicated presented to the end user is Fatal error occured. Would it not be nice to find out what have caused it?
Logging is a tool that can really help you narrow these kind of problems in the field.
Remember, end-user systems don't have nice IDE's to debug and the end-users usually are not knowledgeable enough to run these tools. However end-users, in most cases, are capable of copying log configuration files ( written by us, clever programmers ) into predefined location and fetch log files and email them back to us ( poor soles for having to parse megabytes of log output ) when they encounter problems.
Having said this, logging should be highly configurable and under normal conditions produce minimal output. Also, guards should protect finer level logging from consuming too many resources.
I think in the example that you have provided all logging should have been done on a TRACE level. Also, because nothing bad can really happen between function entry point and exit, it probably make sense to have only one log statement there.
Over the years I've swayed backwards and forwards between promoting logging everything at the appropriate levels (trace, info, etc...) and thinking that any is a complete waste of time. In reality it depends on what is going to be useful to track down or required (logging can be a cheap way of maintaining an audit trail).
Personally, I tend to log entry/exit at a component or service level and then log significant points in the processing such as a business logic decision or a call on another service/component. Of course errors are always logged, but once only and at the place they were handled (the stack trace and exception message should have sufficient info to diagnose the problem) and any service/component interface should always handle an errors (even if it is just converting it into another more appropriate to the caller).
The problem with logging stuff on the off chance something goes wrong is that you end up with too much information that it is impossible to identify the issue, especially if it is running under a server as you end up with loads of intertwined log entries. Obviously you can get around that by incorporating a request id in the entry and using some software to filter on that. Of course you also have the case where your application is distributed and/or cluster and you have multiple logs.
Nowadays I would never actually write trace entering/exiting entries code, the code just gets in the way and it is so much easier to use something like aspectj if it is really needed. Using aspectj also would guarantee to be consistent (you can change the log format in one place rather than having to change every operation) and accurate (in case some refactoring adds a new paramater and teh developer forgets to add it to the logging).
One thing I have thought about doing or looking to see if someone already has is a logger that will hold the entries in memory, then if an error is encountered they are written, if the operation succeeds the entries are just discarded. If anyone knows of one (ideally for log4j) please let me know, alternatively I have a few ideas on how to implement this if anyone is interested in doing one.
This is where log levels are helpful. In general, log levels in the order of verbosity and priority are TRACE, DEBUG, INFO, WARN, ERROR, FATAL.
The developer has to take a conscious call to use the correct log level while logging in the code.
While creating an instance of Logger we have to pass the correct log level by choosing it from a config (always prefer config). This decides which levels to be logged. For example, while creating the logger, if the config for log level is set to "INFO", anything below "INFO" (TRACE, DEBUG) won't be logged.
For instance, in the example you mentioned above, a TRACE OR DEBUG level would make more sense.
In runtime in production, the config for log level should always be set to INFO.
When an issue occurs in production and if the developer wants to find out the root cause, they can request for changing the log level to TRACE or DEBUG (mostly inside a QA environment where they can replicate the scenario), to see what exactly is happening (The app sometimes has to be restarted to have the log level changed, but it is helpful).
Log levels is a great practice, as most of the times, we won't be able to launch a debugger in the landscapes. As we are skipping the unnecessary file writes by choosing a higher log level, the performance won't take a hit

Categories