From 47974a94df073cc3ac8d69856afd7e6702cd6160 Mon Sep 17 00:00:00 2001 From: Alan West <3676547+alanwest@users.noreply.github.com> Date: Wed, 9 Sep 2020 09:35:39 -0700 Subject: [PATCH 1/4] Document HTTP instrumentation options --- .../README.md | 121 +++++++++++++++++- 1 file changed, 120 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Instrumentation.Http/README.md b/src/OpenTelemetry.Instrumentation.Http/README.md index f9e15e9ca78..52d5fdda2a3 100644 --- a/src/OpenTelemetry.Instrumentation.Http/README.md +++ b/src/OpenTelemetry.Instrumentation.Http/README.md @@ -66,7 +66,126 @@ This instrumentation can be configured to change the default behavior by using `HttpClientInstrumentationOptions` and `HttpWebRequestioninstrumentationOptions`. -TODO - describe options +### Propagator + +TODO + +### SetHttpFlavor + +By default, this instrumentation does not add the `http.flavor` attribute. The +`http.flavor` attribute specifies the kind of HTTP protocol used +(e.g., `1.1` for HTTP 1.1). The `SetHttpFlavor` option can be used to include +the `http.flavor` attribute. + +The following example shows how to use `SetHttpFlavor`. + +```csharp +using Sdk.CreateTracerProviderBuilder() + .AddHttpClientInstrumentation( + options => options.SetHttpFlavor = true) + .AddConsoleExporter() + .Build(); +``` + +### Filter + +This instrumentation by default collects all the outgoing HTTP requests. It +allows filtering of requests by using the `Filter` function option. +This can be used to filter out any requests based on some condition. The Filter +receives the request object - `HttpRequestMessage` for HttpClient or +`HttpWebRequest` for HttpWebRequest - of the outgoing request and filters out +the request if the Filter returns false or throws an exception. + +The following shows an example of `Filter` being used to filter out all POST +requests. + +```csharp +using Sdk.CreateTracerProviderBuilder() + .AddHttpClientInstrumentation( + options => options.Filter = + httpRequestMessage => + { + // filter out all HTTP POST requests. + return httpRequestMessage.Method != HttpMethod.Post; + }) + .AddConsoleExporter() + .Build(); +``` + +It is important to note that this `Filter` option is specific to this +instrumentation. OpenTelemetry has a concept of a +[Sampler](https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/trace/sdk.md#sampling), +and the `Filter` option does the filtering *before* the Sampler is invoked. + +### Special topic - Enriching automatically collected telemetry + +This instrumentation library stores the raw request, response and any exception +object in the activity. These can be accessed in ActivityProcessors, and can be +used to further enrich the Activity with additional tags as shown below. + +#### HttpClient instrumentation + +The key name for HttpRequestMessage custom property inside Activity is +"OTel.HttpHandler.Request". + +The key name for HttpResponseMessage custom property inside Activity is +"OTel.HttpHandler.Response". + +The key name for Exception custom property inside Activity is +"OTel.HttpHandler.Exception". + +#### HttpWebRequest instrumentation + +The key name for HttpWebRequest custom property inside Activity is +"OTel.HttpWebRequest.Request". + +The key name for HttpWebResponse custom property inside Activity is +"OTel.HttpWebRequest.Response". + +The key name for Exception custom property inside Activity is +"OTel.HttpWebRequest.Exception". + +```csharp +internal class MyHttpEnrichingProcessor : ActivityProcessor +{ + public override void OnStart(Activity activity) + { + // Retrieve the HttpRequestMessage object. + var request = activity.GetCustomProperty("OTel.HttpHandler.Request") + as HttpRequestMessage; + if (request != null) + { + // Add more tags to the activity + activity.SetTag("mycustomtag", request.Headers["myheader"]); + } + } + + public override void OnEnd(Activity activity) + { + // Retrieve the HttpResponseMessage object. + var response = activity.GetCustomProperty("OTel.HttpHandler.Response") + as HttpResponseMessage; + if (response != null) + { + var statusCode = response.StatusCode; + bool success = statusCode < 400; + // Add more tags to the activity or replace an existing tag. + activity.SetTag("myCustomSuccess", success); + } + } +} +``` + +The custom processor must be added to the provider as below. It is important to +add the enrichment processor before any exporters so that exporters see the +changes done by them. + +```csharp +using Sdk.CreateTracerProviderBuilder() + .AddProcessor(new MyHttpEnrichingProcessor()) + .AddConsoleExporter() + .Build(); +``` ## References From add5f296ca6e01b3ac0828b650ea7706ea68e8e7 Mon Sep 17 00:00:00 2001 From: Alan West <3676547+alanwest@users.noreply.github.com> Date: Wed, 9 Sep 2020 15:31:00 -0700 Subject: [PATCH 2/4] Clarify HttpClient vs. HttpWebRequest instrumentation --- src/OpenTelemetry.Instrumentation.Http/README.md | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Http/README.md b/src/OpenTelemetry.Instrumentation.Http/README.md index 52d5fdda2a3..5e469fb3b69 100644 --- a/src/OpenTelemetry.Instrumentation.Http/README.md +++ b/src/OpenTelemetry.Instrumentation.Http/README.md @@ -55,10 +55,13 @@ For an ASP.NET application, adding instrumentation is typically done in the `Global.asax.cs`. Refer to documentation for [OpenTelemetry.Instrumentation.AspNet](../OpenTelemetry.Instrumentation.AspNet/README.md). **`AddHttpClientInstrumentation` vs. `AddHttpWebRequestInstrumentation`** -For .NET Framework, `AddHttpWebRequestInstrumentation` can be used to only add -instrumentation for `HttpWebRequest`. Using `AddHttpClientInstrumentation` in a -.NET Framework application will add instrumentation for both `HttpClient` and -`HttpWebRequest`. + +For .NET Framework, two extensions methods exist: +`AddHttpClientInstrumentation` and `AddHttpWebRequestInstrumentation`. +.NET Framework's implementation of HttpClient uses HttpWebRequest internally, +so using one extension method over the other allows for configuring options +independently for HttpClient instrumentation vs. HttpWebRequest +instrumentation. ## Advanced configuration @@ -92,8 +95,8 @@ using Sdk.CreateTracerProviderBuilder() This instrumentation by default collects all the outgoing HTTP requests. It allows filtering of requests by using the `Filter` function option. This can be used to filter out any requests based on some condition. The Filter -receives the request object - `HttpRequestMessage` for HttpClient or -`HttpWebRequest` for HttpWebRequest - of the outgoing request and filters out +receives the request object - `HttpRequestMessage` for .NET Core and +`HttpWebRequest` for .NET Framework - of the outgoing request and filters out the request if the Filter returns false or throws an exception. The following shows an example of `Filter` being used to filter out all POST From 2d2125e02400b25fb7818a59014b5e0e84133fff Mon Sep 17 00:00:00 2001 From: Alan West <3676547+alanwest@users.noreply.github.com> Date: Thu, 10 Sep 2020 17:25:10 -0700 Subject: [PATCH 3/4] Remove section about adding HttpClient vs. HttpWebRequest instrumentation --- src/OpenTelemetry.Instrumentation.Http/README.md | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Http/README.md b/src/OpenTelemetry.Instrumentation.Http/README.md index 5e469fb3b69..3b67a126961 100644 --- a/src/OpenTelemetry.Instrumentation.Http/README.md +++ b/src/OpenTelemetry.Instrumentation.Http/README.md @@ -54,15 +54,6 @@ the `ConfigureServices` of your `Startup` class. Refer to documentation for For an ASP.NET application, adding instrumentation is typically done in the `Global.asax.cs`. Refer to documentation for [OpenTelemetry.Instrumentation.AspNet](../OpenTelemetry.Instrumentation.AspNet/README.md). -**`AddHttpClientInstrumentation` vs. `AddHttpWebRequestInstrumentation`** - -For .NET Framework, two extensions methods exist: -`AddHttpClientInstrumentation` and `AddHttpWebRequestInstrumentation`. -.NET Framework's implementation of HttpClient uses HttpWebRequest internally, -so using one extension method over the other allows for configuring options -independently for HttpClient instrumentation vs. HttpWebRequest -instrumentation. - ## Advanced configuration This instrumentation can be configured to change the default behavior by using From b679d4d8375a387aa5ba59be969ced663af996e0 Mon Sep 17 00:00:00 2001 From: Alan West <3676547+alanwest@users.noreply.github.com> Date: Thu, 5 Nov 2020 11:54:55 -0800 Subject: [PATCH 4/4] Update documentation on Enrich option --- .../README.md | 99 +++++++++---------- 1 file changed, 47 insertions(+), 52 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Http/README.md b/src/OpenTelemetry.Instrumentation.Http/README.md index 3b67a126961..c18c576e0d0 100644 --- a/src/OpenTelemetry.Instrumentation.Http/README.md +++ b/src/OpenTelemetry.Instrumentation.Http/README.md @@ -60,10 +60,6 @@ This instrumentation can be configured to change the default behavior by using `HttpClientInstrumentationOptions` and `HttpWebRequestioninstrumentationOptions`. -### Propagator - -TODO - ### SetHttpFlavor By default, this instrumentation does not add the `http.flavor` attribute. The @@ -111,75 +107,74 @@ instrumentation. OpenTelemetry has a concept of a [Sampler](https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/trace/sdk.md#sampling), and the `Filter` option does the filtering *before* the Sampler is invoked. -### Special topic - Enriching automatically collected telemetry +### Enrich -This instrumentation library stores the raw request, response and any exception -object in the activity. These can be accessed in ActivityProcessors, and can be -used to further enrich the Activity with additional tags as shown below. +This option allows one to enrich the activity with additional information +from the raw request and response objects. The `Enrich` action is +called only when `activity.IsAllDataRequested` is `true`. It contains the +activity itself (which can be enriched), the name of the event, and the +actual raw object. #### HttpClient instrumentation -The key name for HttpRequestMessage custom property inside Activity is -"OTel.HttpHandler.Request". +For event name "OnStartActivity", the actual object will be +`HttpRequestMessage`. -The key name for HttpResponseMessage custom property inside Activity is -"OTel.HttpHandler.Response". +For event name "OnStopActivity", the actual object will be +`HttpResponseMessage`. -The key name for Exception custom property inside Activity is -"OTel.HttpHandler.Exception". +For event name "OnException", the actual object will be +`Exception`. #### HttpWebRequest instrumentation -The key name for HttpWebRequest custom property inside Activity is -"OTel.HttpWebRequest.Request". +For event name "OnStartActivity", the actual object will be +`HttpWebRequest`. + +For event name "OnStopActivity", the actual object will be +`HttpWebResponse`. -The key name for HttpWebResponse custom property inside Activity is -"OTel.HttpWebRequest.Response". +For event name "OnException", the actual object will be +`Exception`. -The key name for Exception custom property inside Activity is -"OTel.HttpWebRequest.Exception". +The following code snippet shows how to add additional tags using `Enrich`. ```csharp -internal class MyHttpEnrichingProcessor : ActivityProcessor +services.AddOpenTelemetryTracing((builder) => { - public override void OnStart(Activity activity) + builder + .AddHttpClientInstrumentation(opt => opt.Enrich + = (activity, eventName, rawObject) => { - // Retrieve the HttpRequestMessage object. - var request = activity.GetCustomProperty("OTel.HttpHandler.Request") - as HttpRequestMessage; - if (request != null) + if (eventName.Equals("OnStartActivity")) { - // Add more tags to the activity - activity.SetTag("mycustomtag", request.Headers["myheader"]); + if (rawObject is HttpRequestMessage request) + { + activity.SetTag("requestVersion", request.Version); + } } - } - - public override void OnEnd(Activity activity) - { - // Retrieve the HttpResponseMessage object. - var response = activity.GetCustomProperty("OTel.HttpHandler.Response") - as HttpResponseMessage; - if (response != null) + else if (eventName.Equals("OnStopActivity")) { - var statusCode = response.StatusCode; - bool success = statusCode < 400; - // Add more tags to the activity or replace an existing tag. - activity.SetTag("myCustomSuccess", success); + if (rawObject is HttpResponseMessage response) + { + activity.SetTag("responseVersion", response.Version); + } } - } -} + else if (eventName.Equals("OnException")) + { + if (rawObject is Exception exception) + { + activity.SetTag("stackTrace", exception.StackTrace); + } + } + }) +}); ``` -The custom processor must be added to the provider as below. It is important to -add the enrichment processor before any exporters so that exporters see the -changes done by them. - -```csharp -using Sdk.CreateTracerProviderBuilder() - .AddProcessor(new MyHttpEnrichingProcessor()) - .AddConsoleExporter() - .Build(); -``` +[Processor](../../docs/trace/extending-the-sdk/README.md#processor), +is the general extensibility point to add additional properties to any +activity. The `Enrich` option is specific to this instrumentation, and is +provided to get access to raw request, response, and exception objects. ## References