Cross process Application Insights with Multi-Role Application Map

Use Multi-Role Application Map to monitor cross process dependencies

Advertisements

When using Application Insights to monitor your Microservices environment, it would be nice to track calls over process boundaries. Application Insights has a preview for Multi-Role Application Maps. This enables you to visualize the dependencies over multiple processes and name the different processes. In this blog posts I will explain how to enable Multi Role Application Maps preview, give you different process names and add dependency tracking into your application.

Enable Multi Role Application Preview
As long as this feature is in preview, you have to enable it in the portal by going to you Application Insights instance. Go to previews and enable the Multi-role Application Map:

Multi process Application Insights Application Map Enable Preview
Enable Multi-role Application Map

When you have enable the preview feature you can start with giving your processes different names.

Naming processes/applications/microserives in Application Insights
Naming process can be done by filling the Cloud Role in the ITelemetry Context. The CloudRole is a property of the Cloud context. Setting it can be done by adding a TelemetryInitializer to the active initialize on start up. This will run each time a new Telemetry item is created.

private void ConfigureAppInsights(IServiceCollection services)
{
    services.AddApplicationInsightsTelemetry(Configuration);
    TelemetryConfiguration.Active.TelemetryInitializers
       .Add(new ServiceNameInitializer());
}

The implementation of ServiceNameInitializer to set the Cloud RoleName:

public class ServiceNameInitializer : ITelemetryInitializer
{
    public void Initialize(ITelemetry telemetry)
    {
        telemetry.Context.Cloud.RoleName = "MyProcessName";
    }
}

Now you have set the name of the Application, you are ready to create the dependency tracking.

Multi process Application Insights Application Map2Add dependency tracking to your application
DependencyTelemetry allows you to track  dependencies over process boundaries in one Application Insights instance, or within one process in case of async process with queues. This works by creating a DependencyTelemetry before calling or triggering you external process. In you external process you first create an other DependencyTelemetry with the same OperationId and OperationParentId. Around the actial processing of the request you create a RequestTelemetry for Application Insights.

protected override async Task PublishImpl(string message)
{
    var queuename = "MessageBus";
    using (var operation = _telemetryClient.StartOperation<DependencyTelemetry>($"Enqueue {queuename}"))
    {
        operation.Telemetry.Type = "Service Bus Queue";
        operation.Telemetry.Data = $"Enqueue publisher {queuename}";
        var brokeredMessage = new Message(System.Text.Encoding.Unicode.GetBytes(message));
        brokeredMessage.UserProperties["RootId"] = operation.Telemetry.Context.Operation.Id;
        brokeredMessage.UserProperties["ParentId"] = operation.Telemetry.Id;
        try
        {
            await _topicClient.SendAsync(brokeredMessage).ConfigureAwait(false) ;
            operation.Telemetry.Success = true;
        }
        catch
        {
            operation.Telemetry.Success = false;
            throw;
        }
    }
}

In this case a ServiceBus message is created. The correlation between the processes is done with the Operation.Id and Operation.ParentId. Thay are saved in the UserProperties of the queue message.

private async Task ProcessMessagesAsync(Message message, CancellationToken token)
{
    var operationId = message.UserProperties["RootId"].ToString();
    var parentOperationId = message.UserProperties["ParentId"].ToString();
    var queuename = "MessageBus";

    var telemetry = new DependencyTelemetry
    {
        Type = "Service Bus Queue",
        Name = $"Dequeue subscriber {queuename}"
    };
    telemetry.Start();

    telemetry.Context.Operation.Id = operationId;
    telemetry.Context.Operation.ParentId = parentOperationId;

    try
    {
        string json = Encoding.Unicode.GetString(message.Body);
        EventData eventData = JsonConvert.DeserializeObject<EventData>(json);

        // After the message is dequeued from the queue, create RequestTelemetry to track its processing.
        RequestTelemetry requestTelemetry = new  { Name = $"Process {queuename}" };

        requestTelemetry.Context.Operation.Id = operationId;
        requestTelemetry.Context.Operation.ParentId = parentOperationId;

        using (var requestOperation = _telemetryClient.StartOperation(requestTelemetry))
        {
            try
            {
                await ProcessEvent(eventData).ConfigureAwait(false);
            }
            catch //Log error on higher level
            {
                requestOperation.Telemetry.Success = false;
                throw;
            }
        }
        await _subscriptionClient.CompleteAsync(message.SystemProperties.LockToken).ConfigureAwait(false);
    }
    catch (Exception ex)
    {
        telemetry.Success = false;
        //Log error
    }
    finally
    {
        telemetry.Stop();
        _telemetryClient.Track(telemetry);
    }
}

Now you are ready to run and track your dependencies over different applications or within your application when doing async processing with for example a queue.

 

application overview
Application overview

Final thoughts
The feature is currently in preview, the drill down isn’t exactly working as I wanted. Within a process I want to create multiple dependency layers. We have high level commands that can have multiple events. It would be nice to have the events as leaves of the commands. This will probably be able in time. I’ll update the blog when I’m able to create such graph.

 

The Multi-role Application Map is really nice to monitor you application. This will enable you to quickly identify and solve problems with your application. If a dependency fails all parent nodes will show something is not correct. Besides the fast problem identification you are able to see all timings of the operations you are monitoring. This will give you great insights in the current timing and state of your application.

For extra reading:
Track custom operations with Application Insights .NET SDK

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s