Introduction
When something goes wrong "in the field," the users oftentimes have no clue how to describe it; their explanations tend to be quite vague, such as simply, "it doesn't work."
An aid for developers to be proactive and get more specific information about errors thrown by their software is to email details of such to themselves. The FOSS package Log4Net makes this pretty simple. Here is the easiest possible way (that I know of) to set up Log4Net emailing of error messages in an ASP.NET app:
Note: Instructions apply to Visual Studio 2013; other versions may differ a little (the older the version, the more they would possibly diverge.)
Steps for Installing and Using Log4Net
- Download and install Log4Net into your project via NuGet (Tools > Library Package Manager > Manage NuGet Packages for Solution... > Online, search for "log4net" > Install).
- Add this to Web.config below/within the
<configuration>
section:
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
</configSections>
<log4net>
<appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender">
<param name="File" value="HandheldServer.log"/>
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="2" />
<maximumFileSize value="1MB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %-5p %c %m%n"/>
</layout>
</appender>
<appender name="SmtpAppender" type="log4net.Appender.SmtpAppender,log4net">
<threshold value="ERROR" />
<to value="bufordpusser@att.net" />
<from value="helenwheels@gmail.com" />
<subject value="log4net err msg - My ASP.NET app" />
<smtpHost value="smtp.gmail.com" />
<port value="587"/>
<authentication value="Basic" />
<username value="rupertpupkin@gmail.com"/>
<password value="kennwort42"/>
<EnableSsl value="true" />
<bufferSize value="1" />
<lossy value="true" />
<layout type="log4net.Layout.PatternLayout,log4net">
<conversionPattern value="%property{log4net:HostName} :: %level :: %message
%newlineLogger: %logger%newlineThread: %thread%newlineDate:
%date%newlineNDC: %property{NDC}%newline%newline" />
</layout>
</appender>
<root>
<level value="INFO"/>
<appender-ref ref="LogFileAppender" />
<appender-ref ref="SmtpAppender" />
</root>
</log4net>
Note that many/most of the entries in the "SmtpAppender
" <appender>
section can be changed, and in fact you will need to change the following values to those that are appropriate for you:
<to value="bufordpusser@att.net" />
<from value="helenwheels@gmail.com" />
<smtpHost value="smtp.gmail.com" />
<port value="587"/>
<username value="rupertpupkin@gmail.com"/>
<password value="kennwort42"/>
- Append this to AssemblyInfo.cs:
[assembly: log4net.Config.XmlConfigurator(ConfigFile = "Web.config", Watch = true)]
- In each class where you want to use Log4Net, add this (Intellisense should help you add the required using clauses):
private readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
- In the classes where you've performed step 3, call one of Log4Net's methods, such as
Error
:
log.Error("es klappt einfach nicht");
For example, you might do this in a catch
block:
catch (Exception ex)
{
log.Error(ex.Message);
}
- Test that Log4Net is working by temporarily wreaking some sort of mayhem (in your debug environment, of course), such as deliberately dividing by zero:
try
{
int i = 0;
int j = 1 / i;
}
catch (Exception ex)
{
log.Error(ex.Message);
}
When you run this code with the setup above, you will both get an error message logged to a file in your project's folder named <MyProject>.log with content similar to this:
2013-10-24 09:57:12,348 [9] ERROR <MyProject>.<subfolder>.<methodName> Attempted to divide by zero.
...and you will receive an email with content similar to this:
<computerName> :: ERROR :: Attempted to divide by zero.
Logger: <MyProject>.<subfolder>.<methodName>
Thread: 7
Date: 2013-10-24 09:53:14,717
NDC: (null)
Conclusion
By using this tip, you may be able to discover and fix exceptions thrown in your ASP.NET app before users even get a chance to report them. At the very least, it arms you with more actionable information than the vague, "It's broke" that users are wont to proffer.
Even when testing apps in the dev environment, logging errors can be very enlightening, leading to more efficient debugging; as an example, yesterday when I was testing a Web API server / Winforms client pair of apps, an error dialog displayed in my client app due to an exception on the server. The vague message being shown was "The remote server returned an error: (405) Method Not Allowed."
When I looked at the log file created by Log4Net for my server app, it gave me more specific/useful info, namely "Specified cast is not valid" - that tells me a lot more than the other message, which basically said, "it's not working."