Saturday, December 22, 2018

Setting up an Azure DevOps Post Deployment Gate that checks Application Insights for any Server Exceptions in the last 10 minutes.

We have a release pipleline which deploys a web site to an Azure App Service and then runs a bunch of Selenium tests against the website.

However that does not test the Azure Function we also deploy. Nor does it check for any errors being reported by the server.

What we will do is make use of a Post Deployment Gate, which will go and look inside Application Insights and check if any Server Exceptions were logged in the time since the web site was released.

If any server exceptions are found then the release will not progress to the next environment.


1. Enable API Access in Application Insights

Create an API Key if you do not already have one e.g.

image

2. Add a ‘Post Deployment’ gate

In the release definition click ‘Post-deployment conditions’ then enable ‘Gates’.

image

Set the delay before evaluation = 2 minutes (this allows extra time for the application insights data to come in before the gates are evaluated, although data should be there because Selenium tests will be running before this step)


Add an Invoke REST API task

Connection type: Generic

Generic service connection: Choose the one for the application insights account or Click ‘Manage’ and add this:

New Service Connection -> Generic

Connection name: give it a name e.g. Application Insights Connection

Server URL: https://api.applicationinsights.io/v1/apps/

Username & password can remain empty

e.g.

image

Method: Post

Headers (replace with this):

{

     "Content-Type":"application/json",

     "x-api-key": "$(ApplicationInsightsAPIKey)"

}


Body:

For all server exceptions use:

{

    "query": "exceptions | where client_Type != 'Browser' | where timestamp > ago(10m) | count"

}

To filter exceptions to within an assembly you can use (e.g. for all Unity server exceptions):

{

    "query": "exceptions | where client_Type != 'Browser' | where assembly contains 'Unity' | where timestamp > ago(10m) | count"

}

Or to filter on trace messages

e.g. If you have an Azure Function that sends emails and writes a trace message when it’s running you can ensure emails are not failing by checking the trace messages.

{

    "query": "traces | where operation_Name == 'SendEmailFunction' | where message contains 'Success' | where client_Type != 'Browser'| where timestamp > ago(10m)| count"

}


Note: The timestamp is something to play around with, it basically needs to cover:

  • The time the automated Selenium tests take to run (start to finish) - for us approx. 2 minutes
  • + ‘the delay before evaluation’ (2 minutes we set above)
  • + If the Gates fail they re-evaluate until the 6 minute timeout so we need to ensure the time range allows for this too.

The reason for this is once the Selenium tests stop they will not generate application insights data so by the time it re-evaluates the gate again there may be no data in app insights and the gate would incorrectly pass.

Therefore we need to be checking around the last 10 minutes worth of Application Insights data


Url suffix and parameters:

$(ApplicationInsightsApplicationID)/query


Advanced

Completion event:

ApiResponse

Success criteria (The below checks for a count of 0 records to be returned):

    eq(jsonpath('$.tables[0].rows[0]')[0][0],0)

Or this makes sure there are records being returned (e.g. > 0)

    ne(jsonpath('$.tables[0].rows[0]')[0][0],0)


Evaluation options

Time between re-evaluation of gates: 5 minutes

Minimum duration for steady results after a successful gate evaluation: 0 minutes

The timeout after which all gates fail: 6 minutes

Gates and approvals: On successful gates, ask for approvals

Example:

1

3. Set Release variables

Add these keys with a scope to the Environment you are releasing:

ApplicationInsightsAPIKey - This one should be a secret so hide the value

ApplicationInsightsApplicationID

image


4. Save and test it by creating a release



Useful Websites

The API Explorer web site was very useful in constructing the correct message

https://dev.applicationinsights.io/apiexplorer/postQuery

Application Insights ‘Analytics’ was useful in constructing the query

image