Logging Service Fabric application to Azure Application Insights

This post is more or less a copy of this article.

Software

  • Visual Studio Professional 2015 Update 3
  • Service Fabric Tools (VS extension) version 1.4
  • Microsoft Azure Service Fabric SDK version 2.6.204
  • Microsoft Azure Service Fabric Runtime version 5.6.204

Create Service Fabric Application

From Visual Studio, File -> New Project -> Cloud -> Service Fabric Application -> Stateless Service

Update Target Framework of project to at least 4.6

Add EventFlow to Project

(requires update of framework version to at least 4.6)

Install the following NuGet packages to the Stateless service project:

  • Diagnostics.EventFlow.Inputs.EventSource (v1.1.1)
  • Diagnostics.EventFlow.Outputs.ApplicationInsights (v1.1.3)
  • Diagnostics.EventFlow.ServiceFabric (v1.1.3)

Configuring and enabling log collection

A configuration file named “eventFlowConfig.json” is installed as part of NuGet package into the following path in the Stateless service project: \PackageRoot\Config

Edit the json file (see also link at top of page)

{
  "inputs": [
    {
      "type": "EventSource",
      "sources": [
        { "providerName": "Microsoft-ServiceFabric-Services" },
        { "providerName": "Microsoft-ServiceFabric-Actors" },
        // (replace the following value with your service's ServiceEventSource name)
        { "providerName": "your-service-EventSource-name" }
      ]
    }
  ],
  "filters": [
    {
      "type": "drop",
      "include": "Level == Verbose"
    }
  ],
  "outputs": [
    {
      "type": "ApplicationInsights",
      // (replace the following value with your AI resource's instrumentation key)
      "instrumentationKey": "00000000-0000-0000-0000-000000000000"
    }
  ],
  "schemaVersion": "2016-08-11"
}

You must edit the configuration by entering your own provider name and instrumentation key.

The provider name is found in the EventSource attribute of the ServiceEventSource class in ServiceEventSource.cs file in the root of your service project.

Eg, extract from ServiceEventSource.cs

namespace Stateless1
{
    [EventSource(Name = "MyCompany-Application2-Stateless1")]
    internal sealed class ServiceEventSource : EventSource
    {
        public static readonly ServiceEventSource Current = new ServiceEventSource();
... 
... 
...

The instrumentation key is obtained from the Azure portal (link to Azure portal). Search for Application Insights, then select the one you want to use (or create a new one see here) and get the instrumentation key from the Overview tab.

appinsights

Instantiate EventFlow pipeline in your service’s startup code

The final step is to instantiate EventFlow pipeline in your service’s startup code.

Open file “Program.cs” in the root folder of your service project, and add a using statement around the block of code that starts your service:

using System;
using System.Diagnostics;
using System.Fabric;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.ServiceFabric.Services.Runtime;

using Microsoft.Diagnostics.EventFlow.ServiceFabric;

namespace Stateless1
{
    internal static class Program
    {
        ///
<summary>
        /// This is the entry point of the service host process.
        /// </summary>

        private static void Main()
        {
            try
            {
                // The ServiceManifest.XML file defines one or more service type names.
                // Registering a service maps a service type name to a .NET type.
                // When Service Fabric creates an instance of this service type,
                // an instance of the class is created in this host process.

                using (
                    var diagnosticsPipeline =
                        ServiceFabricDiagnosticPipelineFactory.CreatePipeline(
                            "MyTestApp-MyService-DiagnosticsPipeline"))
                {
                    ServiceRuntime.RegisterServiceAsync("Stateless1Type",
                        context => new Stateless1(context)).GetAwaiter().GetResult();

                    ServiceEventSource.Current.ServiceTypeRegistered(Process.GetCurrentProcess().Id,
                        typeof(Stateless1).Name);

                    // Prevents this host process from terminating so services keep running.
                    Thread.Sleep(Timeout.Infinite);
                }
            }
            catch (Exception e)
            {
                ServiceEventSource.Current.ServiceHostInitializationFailed(e.ToString());
                throw;
            }
        }
    }
}

Viewing trace logs

The trace logs will be available to be viewed when debugging locally and when deployed to Azure.

Find your Application Insights in the Azure portal and click the Search link.

Error importing a module in Powershell using Import-Module

Following schoolboy errors:

Error 1 : Operation is not supported

Add-Type : Could not load file or assembly ‘xxx’ or one of its dependencies. Operation is not supported. (Exception from HRESULT: 0x80131515)

This is possibly caused by downloading module from internet.  If so you need to unblock the dll. (Browse to Dll, right-click, select Properties, and check ‘unblock’ on the General tab.

Error 2: An attempt was made to load a program with an incorrect format

Add-Type : Could not load file or assembly ‘file:///C:\PwrShell\System.Fabric.CSMTemplate\System.Fabric.CSMTemplate.dll’ or one of its dependencies. An attempt was made to load a program with an incorrect format.

This is probably caused by using Powershell (x86) instead of Powershell