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.
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:
These data items are found in the API Access section of the App Insights namespace:
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;
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.