This week there was a small outage within the Azure Data Lake Store service and as consequence I wondered how could I Read Azure Service Health Activity Logs with .NET Core.

Let’s go for it:

Create a folder for your new project


Open a command promt an run:

1mkdir azure.health

Create the project


1cd azure.health
2dotnet new console

Add the references needed to query Azure Health Events


1dotnet add package Microsoft.Azure.Insights -v 0.15.0-preview
2dotnet add package Microsoft.Azure.Management.Fluent
3dotnet restore

Microsoft.Azure.Insights will let you query the events and Microsoft.Azure.Management.Fluent will let the application authenticate to Azure

Replace the content of Program.cs


Replace the content of Program.cs with the following contents:

  1/// <summary>
  2/// Query Azure.Health Events using .NET Core
  3/// The code was inspired on: How to Retrieve Azure Service Health Event Logs (https://code.msdn.microsoft.com/windowsapps/How-To-Programmatically-49df487d/view/Reviews)
  4/// by Matt Loflin
  5/// </summary>
  6namespace azure.health
  7{
  8    using System;
  9    using System.Linq;
 10    using Microsoft.Azure.Insights;
 11    using Microsoft.Azure.Insights.Models;
 12    using Microsoft.Azure.Management.Fluent;
 13    using Microsoft.Azure.Management.ResourceManager.Fluent;
 14    using Microsoft.Rest.Azure.OData;
 15
 16    class Program
 17    {
 18        static void Main(string[] args)
 19        {
 20            // The file with the Azure Service Principal Credentials.
 21            var authFile = "my.azureauth";
 22
 23            // Parse the credentials from the file.
 24            var credentials = SdkContext.AzureCredentialsFactory.FromFile(authFile);
 25
 26            // Authenticate with Azure
 27            var azure = Azure
 28                .Configure()
 29                .Authenticate(credentials)
 30                .WithDefaultSubscription();
 31
 32            // Create an InsightsClient instance.
 33            var client = new InsightsClient(credentials);
 34
 35            // If we subscription is not set the API call will fail. 
 36            client.SubscriptionId = credentials.DefaultSubscriptionId;
 37
 38            // Create the OData filter for a time interval and the Azure.Health Provider.
 39            // Search back one day.
 40            var days = -1;
 41            var endDateTime = DateTime.Now;
 42            var startDateTime = endDateTime.AddDays(days);
 43            string filterString = FilterString.Generate<EventDataForFilter>(eventData =>
 44                (eventData.EventTimestamp >= startDateTime) &&
 45                (eventData.EventTimestamp <= endDateTime) &#038;&#038;
 46                (eventData.ResourceProvider == "Azure.Health"));
 47
 48            // Get the Events from Azure.
 49            var response = client.Events.List(filterString);
 50            while (response != null &#038;&#038; response.Any())
 51            {
 52                foreach (var eventData in response)
 53                {
 54                    // Set the Console Color according to the Event Status. 
 55                    if (eventData.Status.Value != "Resolved" &#038;&#038;
 56                        eventData.Level <= EventLevel.Warning)
 57                    {
 58                        Console.ForegroundColor = ConsoleColor.Red;
 59                    }
 60                    else if (eventData.Status.Value == "Resolved")
 61                    {
 62                        Console.ForegroundColor = ConsoleColor.Green;
 63                    }
 64                    else
 65                    {
 66                        Console.ForegroundColor = ConsoleColor.White;
 67                    }
 68
 69                    // Write event data to the console
 70                    Console.WriteLine($"{eventData.EventTimestamp.ToLocalTime()} - {eventData.ResourceProviderName.Value} - {eventData.OperationName.Value}");
 71                    Console.WriteLine($"Status:\t {eventData.Status.Value}");
 72                    Console.WriteLine($"Level:\t {eventData.Level.ToString()}");
 73                    Console.WriteLine($"CorrelationId:\t {eventData.CorrelationId}");
 74                    Console.WriteLine($"Resource Type:\t {eventData.ResourceType.Value}");
 75                    Console.WriteLine($"Description:\t {eventData.Description}");
 76                }
 77
 78                // Get more events if available.
 79                if (!string.IsNullOrEmpty(response.NextPageLink))
 80                {
 81                    response = client.Events.ListNext(response.NextPageLink);
 82                }
 83                else
 84                {
 85                    response = null;
 86                }
 87            }
 88
 89            Console.ForegroundColor = ConsoleColor.Green;
 90            Console.WriteLine("No more events...");
 91            Console.ForegroundColor = ConsoleColor.White;
 92        }
 93    }
 94
 95    // EventData Filter. 
 96    public class EventDataForFilter
 97    {
 98        /// <summary>
 99        /// Event Timestamp
100        /// </summary>
101        public DateTime EventTimestamp { get; set; }
102
103        /// <summary>
104        /// Resource Provider
105        /// </summary>
106        public string ResourceProvider { get; set; }
107    }
108}

Create the my.azureauth file


To authenticate you’ll need a my.azureauth file with the following format:

1subscription=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
2client=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
3tenant=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
4key=XXXXXX
5managementURI=https\://management.core.windows.net/
6baseURL=https\://management.azure.com/
7authURL=https\://login.windows.net/
8https\://graph.windows.net/

As you can see you’ll be needing your Azure Subscription Id, Tenand Id and a valid Service Principal and Key.

If you check my previous post: Create a Service Principal and write required parameters to a .azureauth file and run the script you’ll get a file with the credentials.

Run the application


Run the following command:

1dotnet run

You can get the code here.

Hope it helps!