opentelemetry-dotnet icon indicating copy to clipboard operation
opentelemetry-dotnet copied to clipboard

Question: How can I read the response body in the EnrichWithHttpResponse method

Open shamsipav opened this issue 1 year ago • 7 comments

Question

I tried to read the response body in the EnrichWithHttpResponse method in the AddAspNetCoreInstrumentation hook, however httpResponse.Body.CanRead in this case returns false, unlike the httpRequest.Body.CanRead in the EnrichWithHttpRequest method, which is true.

Code example:

            services.AddOpenTelemetry()
                .WithTracing(builder => builder
                    .AddAspNetCoreInstrumentation(o =>
                    {
                        o.EnrichWithHttpRequest = async (activity, httpRequest) =>
                        {
                            // True.
                            if (httpRequest.Body.CanRead)
                            {
                                string requestBody = await new StreamReader(httpRequest.Body).ReadToEndAsync();
                                Console.WriteLine($"requestBody: {requestBody}");
                            }
                        };

                        o.EnrichWithHttpResponse = async (activity, httpResponse) =>
                        {
                            // False.
                            if (httpResponse.Body.CanRead)
                            {
                                string responseBody = await new StreamReader(httpResponse.Body).ReadToEndAsync();
                                Console.WriteLine($"responseBody: {responseBody}");
                            }
                        };
                    })
                    .AddJaegerExporter());

Is there any way to get the body of the response?

Environment

ASP.NET Core 3.1 Web API project

shamsipav avatar Mar 02 '23 06:03 shamsipav

@shamsipav

First a warning...

Warning Don't do this it is super bad for perf. ASP.NET Core tries really hard to not buffer into memory to achieve great throughput.

If you still want to proceed check out this issue it has some code: https://github.com/open-telemetry/opentelemetry-dotnet/issues/1657

CodeBlanch avatar Mar 02 '23 17:03 CodeBlanch

Thanks for the answer @CodeBlanch!

I wanted to repeat the solution you proposed, but, unfortunately, there is no Enrich method in the current version, there are only methods EnrichWithHttpRequest, EnrichWithHttpResponse and EnrichWithException (Pull Request)

builder.AddAspNetCoreInstrumentation(options => options.Enrich = EnrichAspNetCore);

Is it possible to apply your solution to the current version?

Thank you in advance!

shamsipav avatar Mar 02 '23 18:03 shamsipav

Hi @CodeBlanch @shamsipav. We are in the same situation and it's a big loss of functionality for us.

rubencc avatar Jun 02 '23 11:06 rubencc

Thanks for the answer @CodeBlanch!

I wanted to repeat the solution you proposed, but, unfortunately, there is no Enrich method in the current version, there are only methods EnrichWithHttpRequest, EnrichWithHttpResponse and EnrichWithException (Pull Request)

builder.AddAspNetCoreInstrumentation(options => options.Enrich = EnrichAspNetCore);

Is it possible to apply your solution to the current version?

Thank you in advance!

Enrich is simply replace with more specific methods. There is no loss of functionality with that change. Whatever you were able to achieve with Enrich, is still possible with Enrich_NewVariants.

cijothomas avatar Jun 02 '23 14:06 cijothomas

Its better to leverage built-in capabilities if you want to log additional things: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/http-logging/?view=aspnetcore-7.0

Note that this uses Logs, not Span/Activity.

cijothomas avatar Jun 02 '23 14:06 cijothomas

@shamsipav did you solve it?

ekjuanrejon avatar Jul 20 '23 17:07 ekjuanrejon

Hi, any kind of updates about?

Sbolder avatar Mar 14 '24 14:03 Sbolder

Thanks for the answer @CodeBlanch! I wanted to repeat the solution you proposed, but, unfortunately, there is no Enrich method in the current version, there are only methods EnrichWithHttpRequest, EnrichWithHttpResponse and EnrichWithException (Pull Request)

builder.AddAspNetCoreInstrumentation(options => options.Enrich = EnrichAspNetCore);

Is it possible to apply your solution to the current version? Thank you in advance!

Enrich is simply replace with more specific methods. There is no loss of functionality with that change. Whatever you were able to achieve with Enrich, is still possible with Enrich_NewVariants.

Is it? Since the new variants use the Http*Message objects, it seems to me some details were lost - no access to the HttpContext or the connection anymore.

Is there an alternative way to do that with the new variants?

ransagy avatar May 09 '24 08:05 ransagy

Thanks for the answer @CodeBlanch! I wanted to repeat the solution you proposed, but, unfortunately, there is no Enrich method in the current version, there are only methods EnrichWithHttpRequest, EnrichWithHttpResponse and EnrichWithException (Pull Request)

builder.AddAspNetCoreInstrumentation(options => options.Enrich = EnrichAspNetCore);

Is it possible to apply your solution to the current version? Thank you in advance!

Enrich is simply replace with more specific methods. There is no loss of functionality with that change. Whatever you were able to achieve with Enrich, is still possible with Enrich_NewVariants.

Is it? Since the new variants use the Http*Message objects, it seems to me some details were lost - no access to the HttpContext or the connection anymore.

Is there an alternative way to do that with the new variants?

> Is it? Since the new variants use the Http*Message objects, it seems to me some details were lost - no access to the HttpContext or the connection anymore.

Nothing should be lost. The same objects are available as before : https://github.com/open-telemetry/opentelemetry-dotnet/pull/3749/files

cijothomas avatar May 09 '24 15:05 cijothomas

@cijothomas I think you're right and i confused the support within the basic Http instrumentation and the AspNetCore one; the latter, as expected, does have the full HttpRequest/HttpResponse objects that include the connection info and similar things. Sorry for the false alarm :]

ransagy avatar May 09 '24 17:05 ransagy

Closing this issue as the original question is answered. It is still recommended to leverage logging for this as suggested here.

cijothomas avatar May 09 '24 19:05 cijothomas