Thursday, August 20, 2015
Logging your application with App Insights instead of Windows Azure Diagnostics
Fortunately, there's a suitable replacement for applications in Azure App Service (rather than Cloud Services): Application Insights. Not only does this provide a TraceListener for tracing your application, but also provides a whole suite of other useful diagnostics, making this something that you should really be using anyway. Using the links here and here, I was able to get up to speed with App Insights within an hour and a half, and implement a working solution for our application.
Saturday, May 25, 2013
Journey to robust windows services: Service could not be installed. Verify that you have sufficient privileges to install system services
- Add the "http://schemas.microsoft.com/wix/UtilExtension" namespace to your .wxs file root XML element
- Add a util:EventSource Log="Application" Name="MyServiceLogSourceName" EventMessageFile="%SystemRoot%\Microsoft.NET\Framework\v2.0.50727\EventLogMessages.dll" element to each component which requires an Event Log source
- Problem solved
Tuesday, May 14, 2013
Journey to robust windows services: creating custom actions for your WiX installers
xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v2.0" />
<supportedRuntime version="v3.5" />
<supportedRuntime version="v4.0" />
</startup>
</configuration>
But what really got the thing working was targeting the CustomAction DLL to .NET framework v3.5, rather than 4.0 because I was getting some bad image format exceptions when trying to run it. Thankfully I found the MSDN article on enabling MSI logging. These two articles on stackoverflow.com also really helped out.
Monday, May 06, 2013
Journey to robust web services: debugging services and logging messages
Tuesday, April 30, 2013
Creating a logging service using the Microsoft Enterprise Library Logging Application Block
- Open Visual Studio (I'm using 2010)
- Install NuGet from the Extension Manager, if you haven't already.
- Install EnterpriseLibrary.Config from the Extension Manager if you haven't already.
- Create your solution and project that requires logging.
- If your project (web or application) comes with a .config file already (i.e. Web.config or App.config respectively) you can use that, otherwise, you can create an app.config file for the assembly in which you're creating your logging service.
- Once you've figured out which app.config (or Web.config) file you're going to be using (i.e. the same assembly where you're placing your logging class, right click on the .config file. You should see an 'Edit configuration file' entry with an orange logo (provided by the add-in installed in Step 3 above).
- Follow any other tutorial out there on the internet for configuring the Logging Application Block. (repeating such information here would be redundant and pointless). There's one such article here.
- Now that you've got your configuration, create a class to be your logging service wrapper.
- Figure out where your application config file is going to end up after your application is built.
- In your logging service wrapper, create a Microsoft.Practices.EnterpriseLibrary.Common.Configuration.FileConfigurationSource, giving the configuration file path as the sole parameter to the constructor.
- Create a new Microsoft.Practices.EnterpriseLibrary.Logging.LogWriterFactory, providing the FileConfigurationSource you just created as the sole parameter. You'll probably want to store this as a static object, because we only need a single factory.
- For each instance of your logging service, use this static factory that you've created to create a LogWriter.
- Implement whatever methods you need to wrap the logging service.
- You're done.
using System;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Text;
using Interfaces;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Logging;
using Support.Extensions;
///
/// A logging services that uses the Microsoft Enterprise Patterns and
/// Practices library to provide logging support.
///
public class MicrosoftPracticesLoggingService : ILoggingService
{
///
/// The log writer factory
///
private static readonly LogWriterFactory LogWriterFactory;
///
/// Initializes the class.
///
static MicrosoftPracticesLoggingService()
{
string configFilePath = typeof(MicrosoftPracticesLoggingService).Assembly.GetCodeBaseFile().FullName + ".config";
if (File.Exists(configFilePath) == false)
{
throw new InvalidOperationException(String.Format("Configuration file could not be found at '{0}'", configFilePath));
}
FileConfigurationSource configSource = new FileConfigurationSource(configFilePath);
LogWriterFactory = new LogWriterFactory(configSource);
}
///
/// The log writer used by this service to write to logs.
///
private readonly LogWriter logWriter;
///
/// Initializes a new instance of the class.
///
public MicrosoftPracticesLoggingService()
{
this.logWriter = LogWriterFactory.Create();
}
#region Implementation of ILoggingService
///
[SuppressMessage("Microsoft.StyleCop.CSharp.DocumentationRules", "SA1604:ElementDocumentationMustHaveSummary", Justification = "InheritDoc")]
[SuppressMessage("Microsoft.StyleCop.CSharp.DocumentationRules", "SA1611:ElementParametersMustBeDocumented", Justification = "InheritDoc")]
public void LogException(Exception ex, string messageFormat, params object[] parameters)
{
if (ex == null)
{
throw new ArgumentNullException("ex");
}
if (messageFormat == null)
{
throw new ArgumentNullException("messageFormat");
}
StringBuilder messageBuilder = new StringBuilder();
messageBuilder.AppendFormat(messageFormat, parameters).AppendLine();
messageBuilder.AppendLine(ex.StackTrace);
if (ex.InnerException != null)
{
Exception root = ex;
while (root.InnerException != null)
{
root = root.InnerException;
}
messageBuilder.AppendLine("Caused by:");
messageBuilder.AppendLine(root.StackTrace);
}
LogEntry logEntry = new LogEntry
{
Message = messageBuilder.ToString(),
Severity = TraceEventType.Error
};
this.logWriter.Write(logEntry);
}
#endregion
}
Thursday, May 08, 2008
Logging for tests using the Spring Framework
It's been a while since I've posted to the blog 'cause I've been so busy, and it seems fitting that this be a good way to resume posting, as this issue has pissed me off quite a bit and been a major thorn in my side for the longest time.
The Spring Framework has some pretty good support for creating test classes for your application, however it by default does not properly initialize log4j logging when doing tests, and I found out today why. When running your application in a Servlet container, you'd configure Spring logging in web.xml. However, when running in a standalone context, Spring has no way of knowing how you want logging configured, so it leaves it up to log4j to configure itself. On that front, you have to realize what log4j's default configuration strategy is : reading a 'log4j.properties' file from the root of the classpath. Once this hits you (and it took me a while), getting logging running for your test cases becomes a simple matter of placing a valid 'log4j.properties' config file in the root of your test classpath, and logging starts working properly, so now you can read those pesky hibernate generated queries off your test log .