Skip to content

[feature request] Filter at end of activity #2464

Open
@DannyRichardsonWG

Description

Component

OpenTelemetry.Instrumentation.AspNetCore

Is your feature request related to a problem?

I'd like the ability to be able to filter logged items based on the status code of the HTTP Response.

What is the expected behavior?

At the end of the activity processing have a filter that is able to exclude items. Similar to the filter that is applied at the start of the activity.

Which alternative solutions or features have you considered?

The goal is to drop any logging for a request to a specific endpoint with a certain status code

e.g. anything sent to / with a 401 response code.

So I call UseAzureMonitor

OpenTelemetryBuilder monitor = services.AddOpenTelemetry()
            .UseAzureMonitor(options =>
            {
                options.ConnectionString = appInsightsConnectionString;
                options.SamplingRatio = samplingRatio;
            }).ConfigureResource(resource => { resource.AddService(serviceName); });

And added a processor

public class SuperAwesomeProcessor : BaseProcessor<Activity>
{
    public override void OnEnd(Activity activity)
    {

        int responseCode = -99;
        if (activity.TryGetTagObject("url.path", out string? url))
        {
            if (activity.TryGetTagObject("http.response.status_code", out responseCode, -123))
            {
                // if it's a root call and 401 response we can ignore it
                if (url == "/"
                    && responseCode == (int)HttpStatusCode.Unauthorized)
                {
                    activity.ActivityTraceFlags &= ~ActivityTraceFlags.Recorded;
                    return;
                }

            }
        }

        base.OnEnd(activity);
    }
}


public static class SuperAwesomeExtensions{

  public static bool TryGetTagObject<T>(this Activity? activity, string key, out T? value, T defaultValue)
    {
        value = defaultValue;
        if (activity?.TagObjects == null)
        {
            return false;
        }
        
        foreach (var tag in activity.TagObjects)
        {
            if (tag.Key == key)
            {
                if (!(tag.Value is T tagValue))
                {
                    return false;
                }

                value = tagValue;
                return true;
            }
        }

        return false;
    }

}

Which when hooked up partially worked, it removes the dependencies of the request but the parent request was still getting logged in the requests table in application insights.

After a bit more digging I found you can add a filter to the AddAspNetCoreInstrumentation call but as we're calling UseAzureMonitor we need to call configure using AspNetCoreTraceInstrumentationOptions

        services.Configure<AspNetCoreTraceInstrumentationOptions>(options =>
        {
            options.Filter = (context) =>
            {
                var path = context.Request.Path.ToString();
                if (path.StartsWithIgnoreCase("/") 
                    && context.Response.StatusCode == (int)HttpStatusCode.Unauthorized
                    )
                    return false;

                return true;
            };
        });

The problem is the StatusCode is 200 and not 401, I'm assuming because the logging/filter fires before the authentication middleware has kicked in as the filter runs in OnStartActivity in HttpInListener.

Is there a filter that fires at the end of the request like the OnEnd of the processor or is there a better way of achieving the goal?

Cheers,

Danny

Additional context

No response

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions