silent
silent

Reputation: 16178

Azure APIM - how to send trace from within policy expression?

I have the below policy in Azure API Management. It works fine like that:

<return-response>
<set-status code="302" />
<set-header name="Location" exists-action="override">
    <value>@{
        try
        {
            // ... doing something here that might throw an Exception
            return "http://example.com";
        }
        catch (Exception e)
        {
            // If something failed, it is usually because of an transient error. Then we just send the user to the same URL again to retry.
            return "/";
        }
    }</value>
</set-header>
</return-response>

Now I would like to log/trace a message inside the Catch block. Basically something like this, but this of course does not work.

catch (Exception e)
{
    <trace source="MyApi" severity="error">
        <message>Error foo</message>
        <metadata name="ErrorMessage" value="@(e.Message)"/>
    </trace>
    return "/";
}

How can I do this or how otherwise send logs to the connected Application Insights instance?

Upvotes: 1

Views: 3538

Answers (1)

Kai Walter
Kai Walter

Reputation: 4031

You let <on-error> section handle the tracing:

<policies>
    <inbound>
        <base />
        <return-response>
            <set-status code="302" />
            <set-header name="Location" exists-action="override">
                <value>@{
                        int d = 0;
                        int result = 42 / d;
                        return result.ToString();
                }</value>
            </set-header>
        </return-response>
    </inbound>
    <backend>
        <base />
    </backend>
    <outbound>
        <base />
    </outbound>
    <on-error>
        <base />
        <trace source="ErrorInformation" severity="error">
            <message>ErrorInformation</message>
            <metadata name="EsbCorrelationId" value="@((!context.Variables.ContainsKey("esb-correlation-id") || context.Variables.GetValueOrDefault<string>("esb-correlation-id").Equals(string.Empty)) ? "-none-" : context.Variables.GetValueOrDefault<string>("esb-correlation-id"))" />
            <metadata name="IpAddress" value="@(context.Request.IpAddress.ToString())" />
            <metadata name="LastError.Source" value="@((context.LastError.Source == null || context.LastError.Source.Equals(string.Empty)) ? "-none-" : context.LastError.Source.ToString())" />
            <metadata name="LastError.Reason" value="@((context.LastError.Reason == null || context.LastError.Reason.Equals(string.Empty)) ? "-none-" : context.LastError.Reason.ToString())" />
            <metadata name="LastError.Message" value="@((context.LastError.Message == null || context.LastError.Message.Equals(string.Empty)) ? "-none-" : context.LastError.Message.ToString())" />
            <metadata name="LastError.Scope" value="@((context.LastError.Scope == null || context.LastError.Scope.Equals(string.Empty)) ? "-none-" : context.LastError.Scope.ToString())" />
            <metadata name="LastError.Section" value="@((context.LastError.Section == null || context.LastError.Section.Equals(string.Empty)) ? "-none-" : context.LastError.Section.ToString())" />
            <metadata name="LastError.Path" value="@((context.LastError.Path == null || context.LastError.Path.Equals(string.Empty)) ? "-none-" : context.LastError.Path.ToString())" />
            <metadata name="LastError.PolicyId" value="@((context.LastError.PolicyId == null || context.LastError.PolicyId.Equals(string.Empty)) ? "-none-" : context.LastError.PolicyId.ToString())" />
        </trace>
    </on-error>
</policies>

which will give you an entry in traces with this content in customDimensions:

LastError.Message
Expression evaluation failed. Attempted to divide by zero.

LastError.Path
return-response

LastError.PolicyId
-none-

LastError.Reason
ExpressionValueEvaluationFailure

LastError.Scope
operation

LastError.Section
inbound

LastError.Source
set-header

Upvotes: 3

Related Questions