Testing availability on your Azure API Management API’s

Testing availability on your Azure API Management API’s header image

I recently started using Azure API Management to expose some web services. As it is a great way to control access and usage of the services you provide. When setting things up we encountered that sometimes our calls would fail, and thus result in errors. This could be a bit confusing as it could be misconfiguration in Azure API Management, or an error on the back-end system. Luckily Azure API Management allows you to pass in a parameter to retrieve a trace-log of the call. Retrieving this information can be helpful when trying to identify the root cause of a failure.

On any given request there is the option to pass an extra header. By passing the ocp-apim-trace parameter into the call you will receive a response that contains a ocp-apim-trace-location parameter in the header. That parameter contains a location to a file with the trace-log. The file is formatted as a JSON object and contains everything Azure API management can log regarding the call. The location is only valid for a certain amount of time. Therefore it would be wise to download JSON file directly or at least within a few minutes, as the longer you wait the higher the risk the file got deleted. The trace location usually paints a pretty clear picture on where things are failing and is a great help in identifying any issues.

Besides doing this manual there is also an option to do it with a script. In our scenario we wanted to test how stable our back-end system was over an extensive period of time. So we decided an automated script that would poll and verify if the service was running correctly was in place. Whenever the service would fail we would need to download the trace and store is. By downloading and storing it we could make sure the trace logs where persevered and could be subjected to inspection.

When running a web request to test a service it is important to know that if it fails you get an exception object. In order to retrieve any relevant information regarding the response you will need to use the response from that exception rather result of the web request.

try {
    $test_APIM = Invoke-Webrequest -Uri $URL
}
catch {
    # $test_APIM does not contain any output
    $response = $_.Exception.Response;
}

So the flow of a complete test script will look something like the following; simply hitting an array of API once every ‘n’ seconds for ‘n’ amount runs. You could then pass in several different URL’s if needed. Every hit that will be done should logs the response if succeeded. If the call would fail it will try and get the trace file from the headers, and use that location to try and download the file. Once the file is downloaded the user should be notified the file is available. In order to do that we created a small snippet script that allows us to do a test run once every 10 seconds for 10 runs.

>$apis = @{ Instance = "APIM service"; URL =  "https://mytestservice.azure-api.net/echo/?subscription-key=d31ad1d084d841668346c5efcb7eda3b" }

$run = 1;
$runs = 10;
$headers = @{"ocp-apim-trace"= "true"}

do {
    ForEach ( $api in $apis)
    {
        $url = [string]($api.Url)
        $instName = $api.Instance

        try {
            Write-Host "Invoke Request for:" $instName
            $test_APIM = Invoke-WebRequest -Uri $URL -Headers $headers -TimeoutSec 60 -ErrorAction SilentlyContinue

            Write-Host -NoNewline " response:" $test_APIM.StatusCode
        }
        catch {
               if ($_.Exception.Response.Headers["ocp-apim-trace-location"] -ne $null) {
                $traceloc = $_.Exception.Response.Headers["ocp-apim-trace-location"]
                if ( -not [string]::IsNullOrEmpty($traceloc) ) {
                    $qs= ConvertFrom-StringData -StringData (([URI]$traceloc).Query).Replace("&", "`n")
                    $traceid = $qs["traceId"]
                } else {
                    $traceid = ""
                }

                if ($traceid -ne "" ) {
                    Write-Warning "Logging and downloading $TraceID"
                    $FileName = "$($_.Exception.Response.StatusCode)-{0:D5}-$($TraceID).json" -f $([int]$Duration.TotalMilliseconds)
                    Invoke-WebRequest -Uri $TraceLoc -OutFile $FileName
                }
                Write-Host "Downloaded to:" $FileName
            }
        }
    }
    $run++
    Start-Sleep 10
} while ($run -le $runs)

This script will help you quickly testing and downloading the results if something fails. Therefore making it easier to identify problems.

Loading comments…