Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add README for Metrics #4528

Merged
merged 4 commits into from
May 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 11 additions & 8 deletions OpenTelemetry.sln
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,16 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
.dockerignore = .dockerignore
.editorconfig = .editorconfig
CONTRIBUTING.md = CONTRIBUTING.md
Directory.Packages.props = Directory.Packages.props
test\Directory.Packages.props = test\Directory.Packages.props
examples\Directory.Packages.props = examples\Directory.Packages.props
docs\Directory.Packages.props = docs\Directory.Packages.props
global.json = global.json
LICENSE = LICENSE
NuGet.config = NuGet.config
OpenTelemetry.proj = OpenTelemetry.proj
README.md = README.md
VERSIONING.md = VERSIONING.md
Directory.Packages.props = Directory.Packages.props
test\Directory.Packages.props = test\Directory.Packages.props
examples\Directory.Packages.props = examples\Directory.Packages.props
docs\Directory.Packages.props = docs\Directory.Packages.props
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{7CB2F02E-03FA-4FFF-89A5-C51F107623FD}"
Expand Down Expand Up @@ -153,6 +153,9 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "trace", "trace", "{5B7FB835-3FFF-4BC2-99C5-A5B5FAE3C818}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "metrics", "metrics", "{3277B1C0-BDFE-4460-9B0D-D9A661FB48DB}"
ProjectSection(SolutionItems) = preProject
docs\metrics\README.md = docs\metrics\README.md
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "logs", "logs", "{3862190B-E2C5-418E-AFDC-DB281FB5C705}"
ProjectSection(SolutionItems) = preProject
Expand Down Expand Up @@ -553,10 +556,6 @@ Global
{9C99621C-343E-479C-A943-332DB6129B71}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9C99621C-343E-479C-A943-332DB6129B71}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9C99621C-343E-479C-A943-332DB6129B71}.Release|Any CPU.Build.0 = Release|Any CPU
{62AF4BD3-DCAE-4D44-AA5B-991C1071166B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{62AF4BD3-DCAE-4D44-AA5B-991C1071166B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{62AF4BD3-DCAE-4D44-AA5B-991C1071166B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{62AF4BD3-DCAE-4D44-AA5B-991C1071166B}.Release|Any CPU.Build.0 = Release|Any CPU
{FD8433F4-EDCF-475C-9B4A-625D3DE11671}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FD8433F4-EDCF-475C-9B4A-625D3DE11671}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FD8433F4-EDCF-475C-9B4A-625D3DE11671}.Release|Any CPU.ActiveCfg = Release|Any CPU
Expand All @@ -569,6 +568,10 @@ Global
{D438EF9C-7959-47A0-B2A2-DEBFCDC2A8DC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D438EF9C-7959-47A0-B2A2-DEBFCDC2A8DC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D438EF9C-7959-47A0-B2A2-DEBFCDC2A8DC}.Release|Any CPU.Build.0 = Release|Any CPU
{62AF4BD3-DCAE-4D44-AA5B-991C1071166B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{62AF4BD3-DCAE-4D44-AA5B-991C1071166B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{62AF4BD3-DCAE-4D44-AA5B-991C1071166B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{62AF4BD3-DCAE-4D44-AA5B-991C1071166B}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
94 changes: 94 additions & 0 deletions docs/metrics/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# OpenTelemetry .NET Metrics

## 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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
instrument is created a `static` field and then used in the application. You
instrument is created and stored in 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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

which shows a more Dependency Injection friendly way of doing this. -> I think this much is sufficient, to avoid too much details here.

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.

```csharp

// If you emit the tag keys in this order: name -> color -> taste, stick to this order of tag keys for subsequent measurements.
MyFruitCounter.Add(5, new("name", "apple"),new("color", "red"), new("taste", "sweet"));
...
...
...
// Same measurement with the order of tags changed: color -> name -> taste. This order of tags is different from the one that was first encountered by the SDK.
MyFruitCounter.Add(7, new("color", "red"), new("name", "apple"), new("taste", "sweet")); // <--- DON'T DO THIS
```

- When emitting metrics with more than three tags, use `TagList` for better
performance. Using
[`TagList`](https://learn.microsoft.com/dotnet/api/system.diagnostics.taglist?view=net-7.0#remarks)
avoids allocating any memory for up to eight tags, thereby, reducing the
pressure on GC to free up memory.

```csharp
var tags = new TagList
utpilla marked this conversation as resolved.
Show resolved Hide resolved
{
{ "DimName1", "DimValue1" },
{ "DimName2", "DimValue2" },
{ "DimName3", "DimValue3" },
{ "DimName4", "DimValue4" },
};

// 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<string, object>("DimName1", "DimValue1");
var tag2 = new KeyValuePair<string, object>("DimName2", "DimValue2");
var tag3 = new KeyValuePair<string, object>("DimName3", "DimValue3");
var tag4 = new KeyValuePair<string, object>("DimName4", "DimValue4");

counter.Add(100, tag1, tag2, tag3, tag4); // <--- DON'T DO THIS

var readOnlySpanOfTags = new KeyValuePair<string, object>[4] { tag1, tag2, tag3, tag4};
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.

## Common issues that lead to missing metrics

- The `Meter` used to create the instruments is not added to the
`MeterProvider`. Use `AddMeter` method to enable the processing for the
required metrics.
- Instrument name is invalid. When naming instruments, ensure that the name you
utpilla marked this conversation as resolved.
Show resolved Hide resolved
choose meets the criteria defined in the
[spec](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#instrument-name-syntax).
A few notable characters that are not allowed in the instrument name: `/`
(forward slash), `\` (backward slash), any space character in the name.
- MetricPoint limit is reached. By default, the SDK limits the number of maximum
MetricPoints (unique combination of keys and values for a given Metric stream)
to `2000`. This limit can be configured using
`SetMaxMetricPointsPerMetricStream` method. Refer to this
[doc](../../docs/metrics/customizing-the-sdk/README.md#changing-maximum-metricpoints-per-metricstream)
for more information. The SDK would not process any newer unique key-value
combination that it encounters, once this limit is reached.
utpilla marked this conversation as resolved.
Show resolved Hide resolved
- MeterProvider is disposed. You need to ensure that the `MeterProvider`
utpilla marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- MeterProvider is disposed. You need to ensure that the `MeterProvider`
- MeterProvider is disposed incorrectly/earlier than desired. You need to ensure that the `MeterProvider`

instance is kept active for metrics to be collected. In a typical application,
utpilla marked this conversation as resolved.
Show resolved Hide resolved
a single MeterProvider is built at application startup, and is disposed of at
application shutdown. For an ASP.NET Core application, use `AddOpenTelemetry`
and `WithMetrics` methods from the `OpenTelemetry.Extensions.Hosting` package
to correctly setup `MeterProvider`. Here's a [sample ASP .NET Core
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sample -> example
ASP .NET -> ASP.NET

app](../../examples/AspNetCore/Program.cs) for reference. For simpler
applications such as Console apps, refer to this
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
applications such as Console apps, refer to this
applications such as console apps, refer to this

[example](../../docs/metrics/getting-started-console/Program.cs).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also show asp.net example from controib repo.