Microsoft Azure has a very powerful monitoring tool called Application Insights. It can monitor every aspect of our web application, including client and server metrics, error details, performance and so on. My blog is also using Application Insights, but everytime I want to see the data, I have to go to Azure portal, even for the basic metrics like page views or server response time. I want a way to retrive the data in my own App and use Azure Portal just for advanced analytics scenarios. Here's the solution.

The Application Insights service provides a set of REST APIs to let our developer consume the same data from Azure. I use this API in C# to retrive the data I need, you can also do it with jQuery, Java, PHP or whatever you like.

1. Get the Application ID and an API Key

In the Azure Portal, click "API Access" under your Application Insights blade.

Copy the Application ID, we will need it later. Then click "Create API key" if you don't have one.

 

Give it a description, and choose "Read telementry" checkbox. Then click "Generate key"

Once you key is generated, copy and save it to a safe place, because it will only show once on Azure Portal.

2. Test with API Explorer

Go to https://dev.applicationinsights.io/apiexplorer/metrics and use your Application ID, API Key to test the REST API.

For example, I need page views from last 24 hours, here's the test:

And we can see that the API Explorer generates the endpoint address with parameters:

GET /v1/apps/YOUR-APPLICATION-ID/metrics/pageViews/count?timespan=P1D&aggregation=sum HTTP/1.1
Host: api.applicationinsights.io
x-api-key: YOUR-API-KEY

The response is in Json format:

HTTP/1.1 200
content-type: application/json; charset=utf-8

{
  "value": {
    "start": "2018-12-17T11:17:13.443Z",
    "end": "2018-12-18T11:17:13.443Z",
    "pageViews/count": {
      "sum": 709
    }
  }
}

This means the API works for your Application ID and API key. We are going to use the same endpoint to integrate with our own App.

3. Integrate with ASP.NET Core Application

This step is totally up to your own implmentation, the example code is just for me used in my own blog for my own requirements, this is why there are so many hard coded things here.

My C# MetricsReader

public class MetricsReader
{
    private const string AzureAppInsightApiEndpointAddress = "https://api.applicationinsights.io/v1/apps/{0}/{1}/{2}?{3}";
    private const string AzureAppInsightAppId = "<YOUR-APPLICATION-ID>";
    private const string AzureAppInsightApiKey = "<YOUR-API-KEY>";

    public async Task<dynamic> GetP1DIntMetrics(string query, string aggregation)
    {
        var response = await GetAppInsightDataAsync(query, $"timespan=P1D&aggregation={aggregation}");
        if (response.IsSuccess)
        {
            var obj = JsonConvert.DeserializeObject<dynamic>(response.Item);
            return obj;
        }

        return null;
    }

    public async Task<Response<string>> GetAppInsightDataAsync
        (string queryPath, string parameterString)
    {
        return await GetAppInsightDataAsync(AzureAppInsightAppId, AzureAppInsightApiKey, "metrics", queryPath, parameterString);
    }

    private async Task<Response<string>> GetAppInsightDataAsync
        (string appid, string apikey, string queryType, string queryPath, string parameterString)
    {
        var client = new HttpClient();
        client.DefaultRequestHeaders.Accept.Add(
            new MediaTypeWithQualityHeaderValue("application/json"));
        client.DefaultRequestHeaders.Add("x-api-key", apikey);

        var req = string.Format(AzureAppInsightApiEndpointAddress, appid, queryType, queryPath, parameterString);
        var response = client.GetAsync(req).Result;

        if (!response.IsSuccessStatusCode)
        {
            return new FailedResponse<string>(ResponseFailureCode.RemoteApiFailure)
            {
                Message = response.ReasonPhrase
            };
        }

        var result = await response.Content.ReadAsStringAsync();
        return new SuccessResponse<string> { Item = result };
    }
}

In my ASP.NET Controller, I can have method to call the MetricsReader

[HttpGet("getpv")]
public async Task<int> GetPageViewsForLast24Hours()
{
    var response = await _metricsReader.GetP1DIntMetrics(MetricId.PageViewsCount, MetricAggregation.Sum);
    if (null != response)
    {
        return (int)response.value[MetricId.PageViewsCount].sum;
    }
    return -1;
}

Finally on the front-end, I use jQuery to retrive the values:

var aiMetricReader = {
    getMetricsNumber: function(url, funcSuccess) {
        $.ajax({
            url: url,
            datatype: 'json',
            success: function (data) {
                funcSuccess(data);
            },
            error: function(e) {
                toastr.error(e);
            }
        });
    }
};

aiMetricReader.getMetricsNumber('getpv',
    function (data) {
        $("#page-views").html(data);
    });

Now I can have a simple dashboard within my blog admin center, just show the basic metrics that I care the most.

For the complete and advanced information, I can still use Azure Portal.