What if logger can't log? - c#

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.

Related

Terminating a .net-core WebApp if there is a critical error

In order to make deployment easier I want my application to self create pre-defined roles on the database.
If for some reason it is the first time running on the current database but it fails to create the roles, PE, there was a connection error, the application immediately terminates with an Environment.Exit(-1);.
Is this a bad practice? If yes, why? What are my alternatives?
EDIT for clarity: I'm logging every exception/error with log4net.
Yes it is bad practice, however it depends on who uses this. Are you the only one or are people going to be disturbed by a force quit with no explanation?
Showing an alert/message with a little bit of explanations or an error code would be useful in a lot of cases. Log the error you get from the database if possible and if the users from your app know what to do with it you can also share it in the alert/message.
As long as you know why the application terminated, it could be fine. If this is in Production, you also should get an alert if this happens.
At the very least, you should log the error. For a DB connection, you can add logic to try to reconnect either for some time or forever depending on your requirements. Depending on the error you get back from the database, you can either try again or not.
In my applications, I take an approach of forever attempts but make sure to log any errors I get back such as bad credentials or timeout. It is also good to have a 3rd system to monitor for errors and alert you.

How to identify internal failures in a Windows service

We use a lot of custom Windows services in our applications. However, the one I'm currently working on has an infuriating problem: while the service keeps running, it simply stops functioning.
The Main method of the service is wrapped in a try/catch block, like this:
static void Main()
{
IRepository rep = new Repository();
ILogger log = LogManager.GetLogger(GetType().Name);
TimeSpan loadWindowStart = new TimeSpan(9, 0, 0);
TimeSpan loadWindowEnd = new TimeSpan(18, 0, 0);
foreach (SuppressionLoad sl in rep.GetSuppressionLoads().ToList())
{
try
{
// do stuff
}
catch(Exception ex)
{
// log error
}
}
}
The service also logs as it does stuff, and we can watch the logs fill up while it's busy.
Sometimes, however, the logs just stop. And activity elsewhere in the database suggests the entire service has stopped working. Checking in Services on the server, the service still shows a Status of "Started". It takes up almost zero system resources while it's in this state, although it's normally quite processor intensive. If you try and stop it, it just times out trying and, as far as we can tell, it never stops of its own accord. The process has to be killed in Task Manager.
There is nothing untoward in the log in the run up to these stalls. There is also nothing we can find in Event Viewer.
Since it doesn't log an error, I'm at a loss as to what's going on here, or what we can do to try and diagnose the fault from here. It's highly intermittent - it will often run for several days without problem before entering the state. What can we do to investigate what's going on?
Matt; Obscure problems such as these are difficult to find in the best of conditions - if your service happens to use threads (which I assume it does), it becomes tremendously more difficult and you can't rely on global try/catch.
A simple thing to try would be NBug (no association). It will catch un-handled exceptions and give you some info about them. I don't think it will get you enough though.
The general way to find these sorts of things is log, log, log. You have to be able to come as close to recreating the problem as possible - you need logs that tell your entry points into each method, the variable values, exception stack traces if hit, how long you spent in each method, etc. There are some really good tools out there for logging some logging tools so I won't bother with recommending any. You can wrap your logging in a conditional compile switch so once you find your issue you won't suffer a performance hit when you turn it off.
Probably not the answer you wanted, but the only thing that has really worked for me over the years.
SteveJ
It sounds like the issue could be anywhere and doesn't necessarily have much to do with code provided.
Suggestions on how to go about it
When service hangs, attach a debugger and take a look at threads and see where each one is. You may need to rebuild and run a debug version of your solution so that debugger has necessary contextual symbol data. Questions to ask:
Are all the threads that I'm expecting to be there are there, or are some gone or unaccounted for?
Are threads stuck in a deadlock (I'm suspecting that's what's happening), and if so, on what resources.
Turn on detailed logging and sprinkle in more debug log statements to isolate where in code flow it last was and where it didn't make it to, and then keep narrowing down the location. Consider logging contextual data so that when you isolate problematic line or code block, you have context to try to understand why odd behavior takes place. Just be mindful of logging sensitive information (i.e. passwords, PII, etc.)
With full credit to IInspectable's comment, you can try to take a full dump of the process (SysInternal's Process Explorer or ProcDump let's you do that, or Task Manager). It tends to be quite an involved experience using the tool, but used right can give a lot of insight, and possibly find the issue on first occurrence.
Considering that it happens infrequently, and the field of what and where is wide open, it'll likely take a few iterations of having the problem trigger in order to narrow down the scope.

Can I get away with sending exception reports without asking the user?

I write small to medium sized applications, many of which I release onto the Internet. Hopefully, all will be well, but if by some unthinkably hideous disaster, an exception occurs, can I quietly submit that report?
I could make every effort to remove the account name, and I would probably only collect the exception text.
Surely what a user doesn't know has just been sent can't hurt them, or me and my programs.
So far, users have to manually report bugs to me, but I would like to get away from this if I can, and I just want to know whether you think I can get away with this, and what you guys do.
Thanks a lot in advance!
User needs to approve that application can send out error information somewhere on the net.
Usually this is part of EULA, so most of users do not realize that they gave that approval.
My opinion is that it's better to add checkbox to error dialog "Send this error to YourCompanyName" with default value to "true".
If you send data from the user's machine without the user's permission, you run the risk of users bringing legal action against you. You may also get flagged as a virus or malicious app.
I am not a lawyer, but my understanding is that US and EU privacy and data protection laws require disclosure of and user acceptance of your application's handling of personal information, which can include userids, machine IP addresses, and even stack traces that show modules loaded or function parameter values.
Even if you are confident that the data you're sending is fully anonymous to the letter of the law(s), if your app is found to be sending "mysterious" data without user permission, it will likely be flagged as a potential virus, zombie, or other malicious label.
Recall that the Prodigy network client app in the early 90's was slammed by user hysteria over claims that the client app "scans your hard disk to harvest personal info". The reality was that the client app merely opened a swap file on disk and did not zero out the disk sectors, so old data from deleted files would occasionally "appear" to be residing in the client app swap file. This is an example of where the truth (Prodigy was doing nothing wrong) was irrelevant, perception created the hysteria and did the damage.
I wouldn't do this. It is considered a bad practice to send any information (anonymous or not) without the user's consent. Prompting the user to explain to them what data will be sent, or requiring them to agree to send data reports before they install the app is a better way to do it.
If this is something running on your server with your client/customer using it, I would not think twice about collecting my own information.
If it is something installed on a customer's machine, I'd think about Sony's lawsuit with their Root Kit.
Also, notice how Microsoft politely asks if a person will allow this before they proceed.
I do not know personally if gathering customer's permission is legal, but I would not want to be caught doing it.
You can, just state it clearly in the EULA users agree to when installing. Do make sure you have an opt-out possibility.

What should an Application Log ideally contain?

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.

All About Exceptions: What to do and Where to log?

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.

Categories