Showing posts with label logging. Show all posts
Showing posts with label logging. Show all posts

Thursday, August 20, 2015

Logging your application with App Insights instead of Windows Azure Diagnostics

We've recently started deploying applications to Microsoft Azure. Unfortunately, we don't use Cloud Apps for our web apps, and instead use MSDeploy on the command line to enable automated deployment. Consequently, we don't have any .csdef files in which to implement Windows Azure Diagnostics (WAD).

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

This is an annoying and almost entirely useless error. It can be caused by any number of things. However, in my case today, it was caused by the fact that the EventLog Source hadn't been created when I tried to install my Windows Service using the WiX installer that I had developed (which it turned out wasn't quite complete). Fortunately, WiX (at least as of 3.5) has built-in support for creating Windows Event Log sources as part of the installation process. Fortunately, I was able to rely on this article on stackoverflow.com to guide me through the process. The gist of the article:
  1. Add the "http://schemas.microsoft.com/wix/UtilExtension" namespace to your .wxs file root XML element
  2. 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
  3. Problem solved


Tuesday, May 14, 2013

Journey to robust windows services: creating custom actions for your WiX installers

I've lately been trying to update my WiX installers to perform custom actions so that I can do some security configuration of my applications after they're installed. I got started with this article on CodeProject, but it was missing some information. Apparently, in addition to creating the separate project for the CustomAction DLL, you need to include as part of that assembly a CustomAction.config file with the following contents:


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

One of the quickest and best ways to debug issues with the services you're developing is to log and trace all activity with WCF along with the messages being sent back and forth. This page on MSDN will provide you with the instructions required to setup logging and tracking for WCF.

Tuesday, April 30, 2013

Creating a logging service using the Microsoft Enterprise Library Logging Application Block

As part of my recent foray into creating various Windows services, I've come across the need for logging (like all serious apps do) and decided to use the Microsoft Enterprise Library Logging Application Block. We used it at a previous company and it got very good reviews from the developers there who used it. Unfortunately, all of the tutorials out there are a bit useless when it comes to doing anything real with the Logging Application Block, like using custom configuration. Fortunately, it was easy enough to figure out how to get customized configuration of logging working just by looking in the assembly and writing some unit tests to experiment.

For my needs, I like to keep all of my configuration as compartmentalized as possible. To that end, I usually end up using .NET Configuration files on a per-assembly basis. Fortunately, this works very well with the Logging Application Block because you can configure logging with arbitrary Configuration files. To get custom logging working easily in Visual Studio, do the following:
  1. Open Visual Studio (I'm using 2010)
  2. Install NuGet from the Extension Manager, if you haven't already.
  3. Install EnterpriseLibrary.Config from the Extension Manager if you haven't already.
  4. Create your solution and project that requires logging.
  5. 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.
  6. 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).
  7. 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.
  8. Now that you've got your configuration, create a class to be your logging service wrapper.
  9. Figure out where your application config file is going to end up after your application is built.
  10. 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.
  11. 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.
  12. For each instance of your logging service, use this static factory that you've created to create a LogWriter.
  13. Implement whatever methods you need to wrap the logging service.
  14. You're done.
Your code should now look something like the following :
    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 .

Sunday, December 02, 2007

Resolving logging issues with Tomcat

An idea for resolving the logging issues in Tomcat just occurred to me. I should probably be putting the logging jars in the individual lib directories for each of the webapps. I'll have to give this a try and post my results.