What kind of information should an Application Log ideally contain? How is it different from Error Log?
You are going to get a lot of different opinions for this question.....
Ultimately it should contain any information that you think is going to be relevant to your application. It should also contain information that will help you determine what is happening with the application. That is not to say it should contain errors, but could if you wanted to use it that way.
At a minimum I would suggest that you include:
application start/stop time
application name
pass/fail information (if applicable)
Optional items would be:
call processing (if not too intensive)
errors if you decide to combine application and error logs
messaging (if not too intensive)
One thing you want to keep in mind is that you do not want to be writing so much information to your logs that you impact your application performance. Also, want to make sure you don't grow your log files so large that you run out of disk space.
A true error log should really contain:
The stack trace of where the error took place
The local variables present at the point of error.
A timestamp of when the error took place.
Detail of the exception thrown (if it is an exception).
A general application log file, for tracking events, etc, should contain less internal information, and perhaps be more user friendly.
To be honest, the answer really depends on what software the log is for.
Ideally, it should contain exactly the information you need to diagnose an application problem, or analyze a particular aspect of its past behavior. The only thing that makes this hard to do is that you do not know in advance exactly what problems will occur or which aspects of the application behavior will interest you in the future. You can't log every single change in application state, but you have to log enough. How much is enough? That's hard to say and very application-dependent. I doubt a desktop calculator logs anything.
An error log would just log any errors that occur. Unexpected exceptions and other unexpected conditions.
An application log usually contains errors, warning, events and non-critical information in difference to an error log that usually contains only errors and critical warnings.
The application log should contain all the information necessary for audit. This may include such things as successful/unsuccessful log on and any specific actions. The error log can be a subset of the application log or a separate log containing only information related to errors in the application.
Related
In an application with long running task and dependency injection log files can easily become flooded with useless data. This makes it harder to follow log files and drains storage space.
Examples:
A background service that polls a database every 10 seconds for data and logs to say that it is checking for data and how much data is retrieved
A transient service (DI) that has some logging in a method called by the constructor
For example 1, the background service logging is useful for diagnostics when something goes wrong but can easily flood the log file.
For example 2, each time the transient service is constructed, (which might be a lot) that logging in the method called by the constructor is logged.
Obviously, the logs can be split into different files e.g. debug level log file and general log file - this can make the general log file easier to follow but doesn't deal with log files taking up too much space. It also may result in the separation some info that paints a clearer picture of what is happening.
Is there anything more that can be done apart from splitting up the log files and being more selective about what's logged. Are there any best practices for this or any resources that provide good approaches to tackling this problem, or is it just a case of figuring out what's best to do in the specific scenario at hand?
You want to control the logging behaviour by using the correct LogLevel when logging messages.
You should have a look at the LogLevel Enum as it will clearly show you when to use which level.
In the appsettings.json of your application you can then set the minimum log level depending on the deployment environment.
You are referring to trace or information logging which should only be used in a test or development environment in order to get as much information as possible when something is wrong.
Usually only enabled when you are trying to reproduce a known error.
In a production environment you will only log Error or Critical messages. In your exception handling you could log some additional information about parameters that where passed into the failing method along with the stack trace. This should give you enough information to reproduce the error in dev or test where you can debug the application or enable trace logs.
Consider using Structured Logging for those scenarios.
I try to write my first demo using EF7.
I have installed Microsoft.Extensions.Logging.Console 1.0.0-rc2-final
To log.
But when i try to use the follwoing code:
public static void LogToConsole(this DbContext context)
{
var contextServices = ((IInfrastructure<IServiceProvider>) context).Instance;
var loggerFactory = contextServices.GetRequiredService<ILoggerFactory>();
loggerFactory.AddConsole(LogLevel.Verbose);
}
I couldn't find the Verbose enum !
Instead i get the following :
Could someone help me to explain what's happened and which one should i use to log ?
Back in December, the original log levels were changed a bit to be more consistent with other logging systems. As part of this change, Verbose was renamed to Trace and moved in severity below Debug.
As for what log level you should use, it depends a lot on what you want to log and what you expect to see. See the recommendations in the documentation; to quote the first three bullet points:
Log using the correct LogLevel. This will allow you to consume and route logging output appropriately based on the importance of the messages.
Log information that will enable errors to be identified quickly. Avoid logging irrelevant or redundant information.
Keep log messages concise without sacrificing important information.
To choose the correct log level, you should first familiarize yourself with what they mean. Ordered from lowest severity to highest:
Trace – For the most detailed messages, containing possibly sensitive information. Should never be enabled in production.
Debug – For possibly interactive investigation during development; useful for debugging but no real long term value.
Information – For tracking the flow of the application.
Warning – For unnormal (but expected) events in the application, including errors and exceptions, which are properly handled and do not impact the application’s execution (but could still be a sign of potential problems).
Error – For real failures which cause the current activity to fail, leaving the application in a recoverable state though, so other activities will not be impacted.
Critical – For failures on the application level which leaves the application in a unrecoverable state and impacts further execution.
You can find similar explanations in the offical documentation and in the project’s logging guidelines.
Use LogLevel.Debug. The levels got renamed and shuffled around in RC2. See the announcement for more details.
I've recently come across a situation when theoretically operation was completed but logger failed to write some info to the file (no write access to folder with log) and operation was reported as failed (even application broke down with exception). In my project we often use code like
try { /*Business logic*/}
catch (BusinessLogicEx1) {...}
catch (BusinessLogicEx2) {...}
catch (SomeKindOfException ex)
{
LogThisException(ex);
}
What if log is unavailable for some reason? How do you usually treat this situation? Do you notify user somehow?
I check the log path, file availability and file access priviledges in the beginning to make sure such things don`t happen a lot.. if you still run into a locked/unavailable file
I normally inform the user via Gui and write to a temp destination so the logging doen`t get lost
In case no Gui is available I write a windows event entry
System.Diagnostics.EventLog appLog = new System.Diagnostics.EventLog();
appLog.Source = "This Application's Name";
appLog.WriteEntry("An entry to the Application event log.");
on big projects there's a configuration management that get`s checked in the beginning and remembers errors so when the application is executed in administrator mode it can show any internal errors that occured
the best solution will be depending on your scenario
You do a best effort graceful degradation. Try to terse log, try to log to an alternative target, using different API etc. If possible, queue the message so that it can be logged later. It really boils down to how much effort you're willing to put in, how important. And try really hard not to make a bad situation worse (cause more problems/crash app by trying hard to log).
The interesting question is whether to notify the user. Consider:
is there an user to start with? If you're a service then there is nobody to see your message.
is the current user the right one to notify? If this is a clerk using your kiosk then no, you should notify an admin instead.
can the user do anything about it? "anything" may include "notify the appropiate admin". If this is the case then make sure the error message is descriptive and actionable.
should the user (or an admin on the user site) be the one notified, or you, the developer (or your company)? Often time you do want to hear about issues, so you know what is broken in code, what usually breaks due to bad config, what dependency is fragile (think a REST api you depend on). I will no enter into a Privacy discussion here, but you should clearly consider that angle, from legal/PR pov.
often time you log something and display the user something else. Different audiences (end user vs. debug/admin).
I hope this proves the point that only you can answer the question, knowing that what your app does and how is used. Personally I've been in many situations where I had to clearly notify user, just as many situation where I had to silently log, and some cases where the code had to 'phone home' and report the problem to me.
I'm coding in Java, on Android platform, but this isn't really a question for a specific programming language.
So ... If an error occurs in my program, i catch it within a try-catch statement and i would like to create an error number which I'll display to the user, giving him the opportunity to send me this error number.
The catch is that i would like to code the error in such a way that i get a small number (let's say a maximum of 5 digits) which i later on can decode and can find out exactly in which class, in which method and at which line number the error occured.
I'm guessing this is more of a cryptography issue, so has anyone got any ideas on how i should go about doing this?
EDIT
I was thinking of giving a number to each file, each method and somehow use these values to create the error number, but i'm not sure how to calculate the actual error number so that it will work the other way around (decode it correctly).
I will say it, this is a dreadful approach to debugging issues. What you want to do is set up an enumeration that dictates the error codes + descriptions. This would be similar to how Microsoft does it
ERROR_SUCCESS
0 (0x0)
The operation completed successfully
So on and so forth. That way you can publish these things to your users, so you reduce the amount of emails / complaints that you get (to some degree). Obfuscating the stack trace is going to be a nightmare for you, because it would almost seem that you are locking yourself into an unmanageable reporting system. As your code base grows and/or you add more custom exceptions you will quickly break your design. Also, this is a strong case of security through obscurity, wherein someone will potentially reverse engineer your process and start writing malicious code against you.
Better approach:
Get a JIRA account where the more technically savvy users can post the error plus description. I believe FogBugz also has this functionality where you can upload these types of things and it allows the users to crop the images to focus on what you are looking for specifically.
My question actually comes in two parts hence the ambiguous title.
Part One
As far as I'm aware, you should never swallow an exception. Not even logging it and forgetting about. In general cases, I try to solve an exception and retry the code - for example, let's say I get a FileNotFound exception.
I prompt the user to check the file exists and try again, offering another file chooser dialog and hoping for the best. Failing attempting to solve the problem I end up notifying the user and logging the exception. I've been told that this isn't the correct thing to do in a catch block, so am I doing it right by attempting to solve the issue?
I can't think what else I should do. I suspect I'm being fed misinformation - I'm a gullable soul.
Part Two
Creating a log in my program directory to log an exception is fine I think, but again I'm being told that exceptions should be written to the windows eventlog. Is this correct? Under what circumstances should you write to the event log?
Silly questions need silly answers.
Edit:
There is no context to this question other than a general vague domain. My friend and I were blabbering about the right things to do in particular circumstances.
First off if you ever hear the word Never your ears should perk up... That is why they are called "Best Practices" and not "Rules written in Stone that you must follow..."
here is Microsoft's Exception Handling Best Practices Guide
And there are going to be plenty others...
It really boils down to you as a developer, your teams standards, your customer, etc. What do you want the application to do?
Question 1: Do you want the application to be able to continue on if an exception it thrown? Then I would "swallow" the exception.
Question 2: Is there a benefit to logging a particular exception to the event log or is it just going to bloat it with useless information, You may want to write every exception to the log during development and testing and have verbose information and then in production streamline it... I hope I have answered your question even though there really isn't an generic one...
I would say you should have some general guidelines and then if you have more specific situations then it would be a good time to re-post to this site and get some feedback from people that have tried different routes and can speak to the pros and cons.
The Code Analysis Team Blog is a great place to start on this topic. Also look at
Martin Fowler - Fail Fast
MSDN on Exception Handling
Checked vs Unchecked Exceptions
The second part of your question really depends. In many applications where you need central exception reporting, writing to the event log is a good idea. There are plenty of other cases where it would be a waste of time to do that, you'll have to use your own judgment on that.
Part One
Generally, you don't want to have exception generating behaviour in a catch block.
try
{
ExceptionThrowingMethod();
}
Catch(Exception ex)
{
//Log It
//Try Again
ExceptionThrowingMethod();
}
Clearly, the second exception will be uncaught, and you generally don't want to have try-catches nested within a catch-block.
Generally your catch block should
Log the error. Always. Even if you set it to your lowest logging level, and never read those logs.
Determine whether your current state is recoverable. (Are the right variables set or null? Did it break during a critical function, or between them?)
If you can recover, set some variables that indicate 'try-again', and allow execution to flow OUT of the catch-block. If you cannot recover, try to add some context, and then re-throw the error.
Catch blocks are for error recovery, not for regular execution. So, even through FileNotFound is an exceptional occurrence, prompting the user to try and locate their file is not, and so it should happen in its own try-catch (or loop back to the initial one).
Part Two
Generally, I would prefer writing logs to their own directory, because that way I know exactly where they are, and I also know that everything in the log is relevant. If your application is a critical application, (I.E. a service that needs to be running for a framework to work) then you might consider logging to the eventviewer. There's also the everybody wins method of logging to both. You could have thorough logs in your program directory, and log any critical errors to your event viewer.
Without knowing what reason you were given to log to the event viewer, I can't tell whether or not it's good advice.
Here are some best-practices for exception handling.
Best practices for exception management in Java or C#
I found this to answer part two of my question and it seems from a bit of further research that logging exceptions to the event log isn't a mysterious and dark practice. Thanks for your help everyone.