Retrieve App Insights logs from a function using API Rest

Tanguy SCHOUBERT
Published by Tanguy SCHOUBERT
Category : .Net / Azure Functions
26/08/2022

Here, we need to expose an API used to find all the logs relating to the execution of a flow in Application Insights. To do so, we are going to use a function as a back-end. This is what we will look at together in this article.

 

Requirements

 

Firstly, the log format in the source flow has to be defined and known in advance. This is why we have to log a property that is common to all execution logs, i.e. a runID. We can then use this runID as a key in the query made to the App Insights API. For example, the first log in the source flow function might look as follows:

 

log.LogInformation("{FUNCTION_NAME} | {runID} | {status}", FUNCTION_NAME, runID, FunctionStatus.TRIGGERED);

 

We will consequently be able to retrieve the other properties we are interested in; in our case, the function name and the flow status.

The query needs two parameters:

    • the Application ID for the App Insights namespace;
    • an API key that can be used to call the API. This key must be created manually beforehand.

These data items are found in the API Access section of the App Insights namespace:

 

 

Retrieving the logs

 

Our function starts with this code snippet:

 

var query = String.Format(@"traces
| project
    customDimensions.prop__runID,
    customDimensions.prop__FUNCTION_NAME,
    customDimensions.prop__status,
| where customDimensions_prop__runID == '{0}'", runID);

var appId = System.Environment.GetEnvironmentVariable("AppInsightsId");
var apiKey = System.Environment.GetEnvironmentVariable("AppInsightsAPIKey");
string url = string.Format("https://api.applicationinsights.io/v1/apps/{0}/query?query={1}",
                    appId,
                    query);
HttpRequestMessage appInsightRequest = new HttpRequestMessage();
appInsightRequest.Method = HttpMethod.Get;
appInsightRequest.Headers.Add("x-api-key", apiKey);
appInsightRequest.RequestUri = new Uri(url);
HttpResponseMessage appInsightResponse = httpClient.SendAsync(appInsightRequest).Result;
string appInsightResponseString = appInsightResponse.Content.ReadAsStringAsync().Result;

 

Parsing the logs

 

At this stage, we have retrieved all the logs containing our runID. To be able to now access the properties, we need to parse the response using the following model:

 

public class AppInsightQueryResponseModel
{
    public List<Table> tables { get; set; }
}
public class Table
{
    public string name { get; set; }
    public List<Column> columns { get; set; }
    public List<List<string>> rows { get; set; }
}
public class Column
{
    public string name { get; set; }
    public string type { get; set; }
}

 

Following the order defined in the “project” part of our query, we can now access our properties:

 

AppInsightQueryResponseModel content = JsonConvert.DeserializeObject<AppInsightQueryResponseModel>(appInsightResponseString);
var traces = content.tables[0].rows;
foreach (var trace in traces)
{
    string runID = trace[0]};
    string functionName = trace[1]};
    string status = trace[2]};
}

 

All that remains is to adjust the format to match the format that our API will return.