Skip to content

Commit

Permalink
Add basic docs for Metrics api and sdk (#2452)
Browse files Browse the repository at this point in the history
  • Loading branch information
cijothomas committed Oct 6, 2021
1 parent 08049d6 commit 8159df1
Show file tree
Hide file tree
Showing 2 changed files with 124 additions and 13 deletions.
68 changes: 55 additions & 13 deletions docs/metrics/customizing-the-sdk/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,25 @@
As shown in the [getting-started](../getting-started/README.md) doc, a valid
[`MeterProvider`](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#meterprovider)
must be configured and built to collect metrics with OpenTelemetry .NET Sdk.
`MeterProvider` holds all the configuration for tracing like metricreaders,
views, etc. Naturally, almost all the customizations must be done on the
`MeterProvider` holds all the configuration for metrics like MetricReaders,
Views, etc. Naturally, almost all the customizations must be done on the
`MeterProvider`.

## Building a MeterProvider

Building a `MeterProvider` is done using `MeterProviderBuilder` which must be
obtained by calling `Sdk.CreateMeterProviderBuilder()`. `MeterProviderBuilder`
exposes various methods which configures the provider it is going to build. These
includes methods like `AddSource`, `AddView` etc, and are explained in
exposes various methods which configure the provider it is going to build.
These include methods like `AddMeter`, `AddView` etc, and are explained in
subsequent sections of this document. Once configuration is done, calling
`Build()` on the `MeterProviderBuilder` builds the `MeterProvider` instance.
Once built, changes to its configuration is not allowed. In most cases,
a single `MeterProvider` is created at the application startup,
and is disposed when application shuts down.
Once built, changes to its configuration is not allowed. In most cases, a single
`MeterProvider` is created at the application startup, and is disposed when
application shuts down.

The snippet below shows how to build a basic `MeterProvider`. This will create
a provider with default configuration, and is not particularly useful. The
subsequent sections shows how to build a more useful provider.
The snippet below shows how to build a basic `MeterProvider`. This will create a
provider with default configuration, and is not particularly useful. The
subsequent sections show how to build a more useful provider.

```csharp
using OpenTelemetry;
Expand All @@ -36,9 +36,10 @@ using var meterProvider = Sdk.CreateMeterProviderBuilder().Build();

`MeterProvider` holds the metrics configuration, which includes the following:

1. The list of `Meter`s from which measurements are collected.
1. The list of `Meter`s from which instruments are created to report
measurements.
2. The list of instrumentations enabled via
[InstrumentationLibrary](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#instrumentation-library).
[Instrumentation Library](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#instrumentation-library).
3. The list of
[MetricReaders](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#metricreader),
including exporting readers which exports metrics to
Expand All @@ -52,7 +53,48 @@ using var meterProvider = Sdk.CreateMeterProviderBuilder().Build();

### Meter

// TODO
[`Meter`](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#meter)
is used for creating
[`Instruments`](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#instrument),
which are then used to report
[Measurements](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#measurement).
The SDK follows an explicit opt-in model for listening to meters. i.e, by
default, it listens to no meters. Every meter which is used to create
instruments must be explicitly added to the meter provider.

`AddMeter` method on `MeterProviderBuilder` can be used to add a `Meter` to the
provider. The name of the `Meter` (case-insensitive) must be provided as an
argument to this method. `AddMeter` can be called multiple times to add more
than one meters. It also supports wild-card subscription model.

It is **not** possible to add meters *once* the provider is built by the
`Build()` method on the `MeterProviderBuilder`.

The snippet below shows how to add meters to the provider.

```csharp
using OpenTelemetry;
using OpenTelemetry.Metrics;

using var meterProvider = Sdk.CreateMeterProviderBuilder()
// The following enables instruments from Meter
// named "MyCompany.MyProduct.MyLibrary" only.
.AddMeter("MyCompany.MyProduct.MyLibrary")
// The following enables instruments from all Meters
// whose name starts with "AbcCompany.XyzProduct.".
.AddMeter("AbcCompany.XyzProduct.*")
.Build();
```

See [Program.cs](./Program.cs) for complete example.

**Note:**
A common mistake while configuring `MeterProvider` is forgetting to add the
required `Meter`s to the provider. It is recommended to leverage the wildcard
subscription model where it makes sense. For example, if your application is
expecting to enable instruments from a number of libraries from a company "Abc",
the you can use `AddMeter("Abc.*")` to enable all meters whose name starts with
"Abc.".

### View

Expand Down
69 changes: 69 additions & 0 deletions src/OpenTelemetry.Api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,75 @@ and
[extract](../../examples/MicroserviceExample/Utils/Messaging/MessageReceiver.cs)
context.

## Introduction to OpenTelemetry .NET Metrics API

Metrics in OpenTelemetry .NET are a somewhat unique implementation of the
OpenTelemetry project, as the Metrics API is incorporated directly into the .NET
runtime itself, as part of the
[`System.Diagnostics.DiagnosticSource`](https://www.nuget.org/packages/System.Diagnostics.DiagnosticSource/6.0.0-rc.1.21451.13)
package. This means, users can instrument their applications/libraries to emit
metrics by simply using the `System.Diagnostics.DiagnosticSource` package. This
package can be used in applications targeting any of the officially supported
versions of [.NET Core](https://dotnet.microsoft.com/download/dotnet-core), and
[.NET Framework](https://dotnet.microsoft.com/download/dotnet-framework) except
for versions lower than `.NET Framework 4.6.1`.

## Instrumenting a library/application with .NET Metrics API

### Basic metric usage

1. Install the `System.Diagnostics.DiagnosticSource` package version
`6.0.0-rc.1.21451.13` or above to your application or library.

```xml
<ItemGroup>
<PackageReference
Include="System.Diagnostics.DiagnosticSource"
Version="6.0.0-rc.1.21451.13"
/>
</ItemGroup>
```

2. Create a `Meter`, providing the name and version of the library/application
doing the instrumentation. The `Meter` instance is typically created once and
is reused throughout the application/library.

```csharp
static Meter meter = new Meter(
"companyname.product.instrumentationlibrary",
"semver1.0.0");
```

The above requires import of the `System.Diagnostics.Metrics` namespace.

**Note:**
It is important to note that `Meter` instances are created by using its
constructor, and *not* by calling a `GetMeter` method on the
`MeterProvider`. This is an important distinction from the [OpenTelemetry
specification](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#get-a-meter),
where `Meter`s are obtained from `MeterProvider`.

3. Use the `Meter` instance from above to create instruments, which can be used
to report measurements. Just like meter instances, the instrument instances
are to be created once and reused throughout the application/library.

```csharp
static Counter<long> MyFruitCounter = meter.CreateCounter<long>("MyFruitCounter");
```

4. Use the instruments to report measurements, along with the attributes.

```csharp
MyFruitCounter.Add(1, new("name", "apple"), new("color", "red"));
```

The above showed the usage of a `Counter` instrument. The following sections
describes more kinds of instruments.

### Instrument types

// TODO - add all instruments.

## References

* [OpenTelemetry Project](https://opentelemetry.io/)

0 comments on commit 8159df1

Please sign in to comment.