APM Agent for .NET: How can I prevent traces being created for browsers' preflight (OPTIONS) requests?

I have integrated the APM Agent for .NET in an ASP.NET Core application. I have added the HttpDiagnosticsSubscriber in the call to UseElasticApm, so all my controller actions are automatically instrumented.

For normal requests that are handled by a controller action, a trace will be logged that uses the name of the controller and action, and the name(s) of the action's parameters:

POST Object/Post {objectGuid}

But some browsers will send preflight requests, using the HTTP OPTIONS verb. And this is handled by my application, since I enabled the CORS middleware, to ensure the browser receives the right response to such a request.

Such a request looks something like this when done with curl:

curl -i -X OPTIONS "https://localhost:5001/object/5e8a35a3-e45e-4bea-bd72-5998877e13ef" -H "Origin: https://example.com" -H "Access-Control-Request-Method: POST"

The application will respond with headers to indicate if the browser should allow a POST request to that URL from a page on https://example.com:

HTTP/1.1 204 No Content
Date: Thu, 17 Dec 2020 16:13:06 GMT
Access-Control-Allow-Methods: POST
Access-Control-Allow-Origin: *

The problem is that the APM agent also captures traces for these OPTIONS requests. But since there is not controller and action handling the request, it uses the full URL for the name of the trace:

OPTIONS /object/5e8a35a3-e45e-4bea-bd72-5998877e13ef

On our production environment, we are seeing thousands of these 'unique' transaction names, and a warning that we are exceeding the limit.

! This view shows a subset of reported transactions.

The number of unique transaction names exceeds the configured value of 1000. Try reconfiguring your agents to group similar transactions or increase the value of xpack.apm.ui.transactionGroupBucketSize [Learn more in the docs]

So, what can we do?

Hi @michielvoo,

could the TransactionIgnoreUrls setting maybe help here?

With that you could ignore all these transactions - you could set it to something like /object/* - that way HTTP requests with URLs that include the given pattern won't be captured.

Hi @GregKalapos,

Thank you for the suggestion! Unfortunately, these preflight requests only differ from the other URL by HTTP verb. So if I were to add /object/* to that TransactionIgnoreUrls setting, then the agent would also stop capturing the traces that I am actually interested in.

Do you know of any other way to filter transactions? Or to ensure each GUID used in a request is not used as part of the name of the transaction?

Oh - I see.

You could also use the filter API, but for that you'll need to write a bit of a C# code. With filter you have full access to each event before it gets sent to APM Server. If you return null in a filter, the event will be dropped.

Something like this would do the job - you can have more specific checks, you have access to a whole bunch of properties on the ITransaction, this is just my quick example:

Agent.AddFilter(t =>
{
	// if the transaction matches the if block, we return `null`, so the transaction will be dropped and not sent to APM Server
	if (t.Context?.Request != null && t.Context.Request.Method.Equals("OPTIONS", StringComparison.InvariantCultureIgnoreCase)
		&& t.Context.Request.Url.Full.Contains("/object/", StringComparison.InvariantCultureIgnoreCase))
		return null;

	// otherwise just return the transaction without any modification - in this case it'll be sent to APM Server
	return t;
});
1 Like

Thanks so much for the suggestion @GregKalapos! I completely overlooked the filter API, but I am going to implement this right away.

Edit: works like a charm :rocket:

1 Like

This topic was automatically closed 20 days after the last reply. New replies are no longer allowed.