From 9637eed7645625139c57fc82599bd5e6f3d26ef7 Mon Sep 17 00:00:00 2001 From: Cijo Thomas Date: Fri, 15 Dec 2023 09:51:14 -0800 Subject: [PATCH 1/5] Improve docs on Resources to encourage its usage --- docs/metrics/README.md | 50 ++++++++++++--------- docs/metrics/customizing-the-sdk/Program.cs | 7 ++- docs/metrics/customizing-the-sdk/README.md | 34 ++++++++++---- docs/trace/README.md | 10 ++++- docs/trace/customizing-the-sdk/Program.cs | 6 ++- docs/trace/customizing-the-sdk/README.md | 18 +++++--- 6 files changed, 88 insertions(+), 37 deletions(-) diff --git a/docs/metrics/README.md b/docs/metrics/README.md index 20bb5945b30..38528b44f51 100644 --- a/docs/metrics/README.md +++ b/docs/metrics/README.md @@ -2,20 +2,23 @@ ## Best Practices -- Instruments SHOULD only be created once and reused throughout the application - lifetime. This - [example](../../docs/metrics/getting-started-console/Program.cs) shows how an - instrument is created a `static` field and then used in the application. You - could also look at this ASP.NET Core - [example](../../examples/AspNetCore/Program.cs) which shows a more Dependency - Injection friendly way of doing this by extracting the `Meter` and an - instrument into a dedicated class called - [Instrumentation](../../examples/AspNetCore/Instrumentation.cs) which is then - added as a `Singleton` service. - -- When emitting metrics with tags, DO NOT change the order in which you provide - tags. Changing the order of tag keys would increase the time taken by the SDK - to record the measurement. +### Instruments should be singleton + +Instruments SHOULD only be created once and reused throughout the application +lifetime. This [example](../../docs/metrics/getting-started-console/Program.cs) +shows how an instrument is created a `static` field and then used in the +application. You could also look at this ASP.NET Core +[example](../../examples/AspNetCore/Program.cs) which shows a more Dependency +Injection friendly way of doing this by extracting the `Meter` and an instrument +into a dedicated class called +[Instrumentation](../../examples/AspNetCore/Instrumentation.cs) which is then +added as a `Singleton` service. + +### Ordering of Tags + +When emitting metrics with tags, DO NOT change the order in which you provide +tags. Changing the order of tag keys would increase the time taken by the SDK to +record the measurement. ```csharp // If you emit the tag keys in this order: name -> color -> taste, stick to this order of tag keys for subsequent measurements. @@ -27,6 +30,8 @@ MyFruitCounter.Add(5, new("name", "apple"), new("color", "red"), new("taste", "s MyFruitCounter.Add(7, new("color", "red"), new("name", "apple"), new("taste", "sweet")); // <--- DON'T DO THIS ``` +### Use TagList where appropriate + For the best performance, it is highly recommended to pass in tags in certain ways so allocations are only happening on the stack rather than the heap, which eliminates pressure on the GC (garbage collector): @@ -49,7 +54,6 @@ var tags = new TagList // Uses a TagList as there are more than three tags counter.Add(100, tags); // <--- DO THIS - // Avoid the below mentioned approaches when there are more than three tags var tag1 = new KeyValuePair("DimName1", "DimValue1"); var tag2 = new KeyValuePair("DimName2", "DimValue2"); @@ -63,11 +67,17 @@ counter.Add(100, readOnlySpanOfTags); // <--- DON'T DO THIS ``` - When emitting metrics with more than eight tags, the SDK allocates memory on - the hot-path. You SHOULD try to keep the number of tags less than or equal to - eight. Check if you can extract any shared tags such as `MachineName`, - `Environment` etc. into `Resource` attributes. Refer to this - [doc](../../docs/metrics/customizing-the-sdk/README.md#resource) for more - information. +the hot-path. You SHOULD try to keep the number of tags less than or equal to +eight. If you are exceeding this, check if you can model some of the tags as +Resource, as [shown here](#modelling-static-tags-as-resource). + +### Modelling static tags as Resource + +Tags such as `MachineName`, `Environment` etc. which are static throughout the +process lifetime should be be modelled as `Resource`, instead of adding them +to each `Activity`. Refer to this +[doc](../../docs/traces/customizing-the-sdk/README.md#resource) for details and +examples. ## Common issues that lead to missing metrics diff --git a/docs/metrics/customizing-the-sdk/Program.cs b/docs/metrics/customizing-the-sdk/Program.cs index 36539bd6d57..147aa8b783c 100644 --- a/docs/metrics/customizing-the-sdk/Program.cs +++ b/docs/metrics/customizing-the-sdk/Program.cs @@ -16,7 +16,12 @@ public class Program public static void Main() { using var meterProvider = Sdk.CreateMeterProviderBuilder() - .ConfigureResource(res => res.AddService("example-service")) + .ConfigureResource(r => r.AddAttributes(new List> + { + new KeyValuePair("static-attribute1", "v1"), + new KeyValuePair("static-attribute2", "v2"), + })) + .ConfigureResource(r => r.AddService("MyServiceName")) .AddMeter(Meter1.Name) .AddMeter(Meter2.Name) diff --git a/docs/metrics/customizing-the-sdk/README.md b/docs/metrics/customizing-the-sdk/README.md index fb41c28cdd9..933c6e47000 100644 --- a/docs/metrics/customizing-the-sdk/README.md +++ b/docs/metrics/customizing-the-sdk/README.md @@ -577,14 +577,27 @@ is to use a resource indicating this [Service](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/resource/README.md#service) and [Telemetry SDK](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/resource/README.md#telemetry-sdk). -The `ConfigureResource` method on `MeterProviderBuilder` can be used to set a -configure the resource on the provider. When the provider is built, it -automatically builds the final `Resource` from the configured `ResourceBuilder`. -There can only be a single `Resource` associated with a -provider. It is not possible to change the resource builder *after* the provider -is built, by calling the `Build()` method on the `MeterProviderBuilder`. +The `ConfigureResource` method on `MeterProviderBuilder` can be used to +configure the resource on the provider. `ConfigureResource` accepts an `Action` +to configure the `ResourceBuilder`. Multiple calls to `ConfigureResource` can be +made. When the provider is built, it builds the final `Resource` combining all +the `ConfigureResource` calls. There can only be a single `Resource` associated +with a provider. It is not possible to change the resource builder *after* the +provider is built, by calling the `Build()` method on the +`MeterProviderBuilder`. + `ResourceBuilder` offers various methods to construct resource comprising of -multiple attributes from various sources. +attributes from various sources. For example, `AddService()` adds +[Service](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/resource/README.md#service) +resource. `AddAttributes` can be used to add any additional attribute to the +`Resource`. It also allows adding `ResourceDetector`s. + +It is recommended to model attributes that are static throughout the lifetime of +the process as Resources, instead of adding them as attributes(tags) on each +measurement. + +Follow [this](../extending-the-sdk/README.md#resource-detector) document +to learn about writing custom resource detectors. The snippet below shows configuring the `Resource` associated with the provider. @@ -594,7 +607,12 @@ using OpenTelemetry.Metrics; using OpenTelemetry.Resources; using var meterProvider = Sdk.CreateMeterProviderBuilder() - .ConfigureResource(r => r.AddService("MyServiceName")) + .ConfigureResource(r => r.AddAttributes(new List> + { + new KeyValuePair("static-attribute1", "v1"), + new KeyValuePair("static-attribute2", "v2"), + })) + .ConfigureResource(resourceBuilder => resourceBuilder.AddService("service-name")) .Build(); ``` diff --git a/docs/trace/README.md b/docs/trace/README.md index e9925cf6565..a98c6865f0a 100644 --- a/docs/trace/README.md +++ b/docs/trace/README.md @@ -2,7 +2,7 @@ ## Best Practices -### ActivitySource singleton +### ActivitySource should be singleton `ActivitySource` SHOULD only be created once and reused throughout the application lifetime. This @@ -31,6 +31,14 @@ care of propagating/restoring the context across process boundaries. If the you need, it is generally recommended to enrich the existing Activity with that information, as opposed to creating a new one. +### Modelling static tags as Resource + +Tags such as `MachineName`, `Environment` etc. which are static throughout the +process lifetime should be be modelled as `Resource`, instead of adding them +to each `Activity`. Refer to this +[doc](../../docs/traces/customizing-the-sdk/README.md#resource) for details and +examples. + ## Common issues that lead to missing traces - The `ActivitySource` used to create the `Activity` is not added to the diff --git a/docs/trace/customizing-the-sdk/Program.cs b/docs/trace/customizing-the-sdk/Program.cs index 5da5da584f6..1c36b26f78d 100644 --- a/docs/trace/customizing-the-sdk/Program.cs +++ b/docs/trace/customizing-the-sdk/Program.cs @@ -33,7 +33,11 @@ public static void Main() // The following adds subscription to activities from all Activity Sources // whose name starts with "AbcCompany.XyzProduct.". .AddSource("AbcCompany.XyzProduct.*") - .ConfigureResource(resourceBuilder => resourceBuilder.AddTelemetrySdk()) + .ConfigureResource(r => r.AddAttributes(new List> + { + new KeyValuePair("static-attribute1", "v1"), + new KeyValuePair("static-attribute2", "v2"), + })) .ConfigureResource(r => r.AddService("MyServiceName")) .AddConsoleExporter() .Build(); diff --git a/docs/trace/customizing-the-sdk/README.md b/docs/trace/customizing-the-sdk/README.md index fd16648c820..76f4145d2e3 100644 --- a/docs/trace/customizing-the-sdk/README.md +++ b/docs/trace/customizing-the-sdk/README.md @@ -303,12 +303,14 @@ provider is built, by calling the `Build()` method on the `TracerProviderBuilder`. `ResourceBuilder` offers various methods to construct resource comprising of -multiple attributes from various sources. Examples include `AddTelemetrySdk()` -which adds [Telemetry -Sdk](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/resource/README.md#telemetry-sdk) -resource, and `AddService()` which adds +attributes from various sources. For example, `AddService()` adds [Service](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/resource/README.md#service) -resource. It also allows adding `ResourceDetector`s. +resource. `AddAttributes` can be used to add any additional attribute to the +`Resource`. It also allows adding `ResourceDetector`s. + +It is recommended to model attributes that are static throughout the lifetime of +the process as Resources, instead of adding them as attributes(tags) on each +`Activity`. Follow [this](../extending-the-sdk/README.md#resource-detector) document to learn about writing custom resource detectors. @@ -321,7 +323,11 @@ using OpenTelemetry.Resources; using OpenTelemetry.Trace; var tracerProvider = Sdk.CreateTracerProviderBuilder() - .ConfigureResource(resourceBuilder => resourceBuilder.AddTelemetrySdk()) + .ConfigureResource(r => r.AddAttributes(new List> + { + new KeyValuePair("static-attribute1", "v1"), + new KeyValuePair("static-attribute2", "v2"), + })) .ConfigureResource(resourceBuilder => resourceBuilder.AddService("service-name")) .Build(); ``` From 7bcbc8b2dfe016fd21f9e4e722623856e664ec28 Mon Sep 17 00:00:00 2001 From: Cijo Thomas Date: Fri, 15 Dec 2023 10:10:25 -0800 Subject: [PATCH 2/5] fix link --- docs/metrics/customizing-the-sdk/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/metrics/customizing-the-sdk/README.md b/docs/metrics/customizing-the-sdk/README.md index 933c6e47000..fb8fe31af35 100644 --- a/docs/metrics/customizing-the-sdk/README.md +++ b/docs/metrics/customizing-the-sdk/README.md @@ -596,7 +596,7 @@ It is recommended to model attributes that are static throughout the lifetime of the process as Resources, instead of adding them as attributes(tags) on each measurement. -Follow [this](../extending-the-sdk/README.md#resource-detector) document +Follow [this](../../trace/extending-the-sdk/README.md#resource-detector) document to learn about writing custom resource detectors. The snippet below shows configuring the `Resource` associated with the provider. From 55cf6fea45bb0f9ea4a7730a013c05a1bda753a6 Mon Sep 17 00:00:00 2001 From: Cijo Thomas Date: Fri, 15 Dec 2023 10:47:59 -0800 Subject: [PATCH 3/5] fix links --- docs/metrics/README.md | 2 +- docs/trace/README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/metrics/README.md b/docs/metrics/README.md index 38528b44f51..6be072594c5 100644 --- a/docs/metrics/README.md +++ b/docs/metrics/README.md @@ -76,7 +76,7 @@ Resource, as [shown here](#modelling-static-tags-as-resource). Tags such as `MachineName`, `Environment` etc. which are static throughout the process lifetime should be be modelled as `Resource`, instead of adding them to each `Activity`. Refer to this -[doc](../../docs/traces/customizing-the-sdk/README.md#resource) for details and +[doc](./customizing-the-sdk/README.md#resource) for details and examples. ## Common issues that lead to missing metrics diff --git a/docs/trace/README.md b/docs/trace/README.md index a98c6865f0a..2ef0ff07340 100644 --- a/docs/trace/README.md +++ b/docs/trace/README.md @@ -36,7 +36,7 @@ information, as opposed to creating a new one. Tags such as `MachineName`, `Environment` etc. which are static throughout the process lifetime should be be modelled as `Resource`, instead of adding them to each `Activity`. Refer to this -[doc](../../docs/traces/customizing-the-sdk/README.md#resource) for details and +[doc](./customizing-the-sdk/README.md#resource) for details and examples. ## Common issues that lead to missing traces From 85f165aacbf8abcb7bd82c0bf3c1bb52a5a1a4d9 Mon Sep 17 00:00:00 2001 From: Cijo Thomas Date: Mon, 18 Dec 2023 09:53:07 -0800 Subject: [PATCH 4/5] comments addressed --- docs/metrics/README.md | 11 +++++------ docs/metrics/customizing-the-sdk/Program.cs | 4 ++-- docs/metrics/customizing-the-sdk/README.md | 2 +- docs/trace/customizing-the-sdk/Program.cs | 4 ++-- 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/docs/metrics/README.md b/docs/metrics/README.md index 6be072594c5..ed56fe72e02 100644 --- a/docs/metrics/README.md +++ b/docs/metrics/README.md @@ -69,15 +69,14 @@ counter.Add(100, readOnlySpanOfTags); // <--- DON'T DO THIS - When emitting metrics with more than eight tags, the SDK allocates memory on the hot-path. You SHOULD try to keep the number of tags less than or equal to eight. If you are exceeding this, check if you can model some of the tags as -Resource, as [shown here](#modelling-static-tags-as-resource). +Resource, as [shown here](#modeling-static-tags-as-resource). -### Modelling static tags as Resource +### Modeling static tags as Resource Tags such as `MachineName`, `Environment` etc. which are static throughout the -process lifetime should be be modelled as `Resource`, instead of adding them -to each `Activity`. Refer to this -[doc](./customizing-the-sdk/README.md#resource) for details and -examples. +process lifetime should be be modeled as `Resource`, instead of adding them to +each metric measurement. Refer to this +[doc](./customizing-the-sdk/README.md#resource) for details and examples. ## Common issues that lead to missing metrics diff --git a/docs/metrics/customizing-the-sdk/Program.cs b/docs/metrics/customizing-the-sdk/Program.cs index 147aa8b783c..48c9a975311 100644 --- a/docs/metrics/customizing-the-sdk/Program.cs +++ b/docs/metrics/customizing-the-sdk/Program.cs @@ -16,12 +16,12 @@ public class Program public static void Main() { using var meterProvider = Sdk.CreateMeterProviderBuilder() - .ConfigureResource(r => r.AddAttributes(new List> + .ConfigureResource(resource => resource.AddAttributes(new List> { new KeyValuePair("static-attribute1", "v1"), new KeyValuePair("static-attribute2", "v2"), })) - .ConfigureResource(r => r.AddService("MyServiceName")) + .ConfigureResource(resource => resource.AddService("MyServiceName")) .AddMeter(Meter1.Name) .AddMeter(Meter2.Name) diff --git a/docs/metrics/customizing-the-sdk/README.md b/docs/metrics/customizing-the-sdk/README.md index fb8fe31af35..148d470f0aa 100644 --- a/docs/metrics/customizing-the-sdk/README.md +++ b/docs/metrics/customizing-the-sdk/README.md @@ -589,7 +589,7 @@ provider is built, by calling the `Build()` method on the `ResourceBuilder` offers various methods to construct resource comprising of attributes from various sources. For example, `AddService()` adds [Service](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/resource/README.md#service) -resource. `AddAttributes` can be used to add any additional attribute to the +resource. `AddAttributes` can be used to add any additional attributes to the `Resource`. It also allows adding `ResourceDetector`s. It is recommended to model attributes that are static throughout the lifetime of diff --git a/docs/trace/customizing-the-sdk/Program.cs b/docs/trace/customizing-the-sdk/Program.cs index 1c36b26f78d..fead3aa0be2 100644 --- a/docs/trace/customizing-the-sdk/Program.cs +++ b/docs/trace/customizing-the-sdk/Program.cs @@ -33,12 +33,12 @@ public static void Main() // The following adds subscription to activities from all Activity Sources // whose name starts with "AbcCompany.XyzProduct.". .AddSource("AbcCompany.XyzProduct.*") - .ConfigureResource(r => r.AddAttributes(new List> + .ConfigureResource(resource => resource.AddAttributes(new List> { new KeyValuePair("static-attribute1", "v1"), new KeyValuePair("static-attribute2", "v2"), })) - .ConfigureResource(r => r.AddService("MyServiceName")) + .ConfigureResource(resource => resource.AddService("MyServiceName")) .AddConsoleExporter() .Build(); From b1b581f6a15237f3818172917eb290509a47d983 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com> Date: Mon, 18 Dec 2023 13:21:21 -0800 Subject: [PATCH 5/5] Update docs/metrics/README.md --- docs/metrics/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/metrics/README.md b/docs/metrics/README.md index ed56fe72e02..4499281cdd8 100644 --- a/docs/metrics/README.md +++ b/docs/metrics/README.md @@ -6,7 +6,7 @@ Instruments SHOULD only be created once and reused throughout the application lifetime. This [example](../../docs/metrics/getting-started-console/Program.cs) -shows how an instrument is created a `static` field and then used in the +shows how an instrument is created as a `static` field and then used in the application. You could also look at this ASP.NET Core [example](../../examples/AspNetCore/Program.cs) which shows a more Dependency Injection friendly way of doing this by extracting the `Meter` and an instrument