Skip to content

Commit

Permalink
Docs and fixes for histogram (#2269)
Browse files Browse the repository at this point in the history
  • Loading branch information
cijothomas authored Aug 21, 2021
1 parent 95e6851 commit d649b3d
Show file tree
Hide file tree
Showing 10 changed files with 257 additions and 67 deletions.
8 changes: 8 additions & 0 deletions OpenTelemetry.sln
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "metrics", "metrics", "{3277B1C0-BDFE-4460-9B0D-D9A661FB48DB}"
ProjectSection(SolutionItems) = preProject
docs\metrics\building-your-own-exporter.md = docs\metrics\building-your-own-exporter.md
docs\metrics\README.md = docs\metrics\README.md
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "logs", "logs", "{3862190B-E2C5-418E-AFDC-DB281FB5C705}"
Expand Down Expand Up @@ -213,6 +214,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentati
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests", "test\OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests\OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests.csproj", "{4D7201BC-7124-4401-AD65-FAB58A053D45}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "getting-started-histogram", "docs\metrics\getting-started-histogram\getting-started-histogram.csproj", "{92ED77A6-37B4-447D-B4C4-15DB005A589C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -423,6 +426,10 @@ Global
{4D7201BC-7124-4401-AD65-FAB58A053D45}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4D7201BC-7124-4401-AD65-FAB58A053D45}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4D7201BC-7124-4401-AD65-FAB58A053D45}.Release|Any CPU.Build.0 = Release|Any CPU
{92ED77A6-37B4-447D-B4C4-15DB005A589C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{92ED77A6-37B4-447D-B4C4-15DB005A589C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{92ED77A6-37B4-447D-B4C4-15DB005A589C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{92ED77A6-37B4-447D-B4C4-15DB005A589C}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -455,6 +462,7 @@ Global
{08D29501-F0A3-468F-B18D-BD1821A72383} = {5B7FB835-3FFF-4BC2-99C5-A5B5FAE3C818}
{64E3D8BB-93AB-4571-93F7-ED8D64DFFD06} = {5B7FB835-3FFF-4BC2-99C5-A5B5FAE3C818}
{DFB0AD2F-11BE-4BCD-A77B-1018C3344FA8} = {3277B1C0-BDFE-4460-9B0D-D9A661FB48DB}
{92ED77A6-37B4-447D-B4C4-15DB005A589C} = {3277B1C0-BDFE-4460-9B0D-D9A661FB48DB}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {55639B5C-0770-4A22-AB56-859604650521}
Expand Down
4 changes: 4 additions & 0 deletions docs/metrics/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Getting Started with OpenTelemetry .NET Metrics in 5 Minutes

* [Getting started with Counter](.\getting-started\README.md)
* [Getting started with Histogram](.\getting-started-histogram\README.md)
55 changes: 55 additions & 0 deletions docs/metrics/getting-started-histogram/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// <copyright file="Program.cs" company="OpenTelemetry Authors">
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// </copyright>

using System;
using System.Collections.Generic;
using System.Diagnostics.Metrics;
using System.Threading;
using System.Threading.Tasks;
using OpenTelemetry;
using OpenTelemetry.Metrics;

public class Program
{
private static readonly Meter MyMeter = new Meter("TestMeter", "0.0.1");
private static readonly Histogram<long> MyHistogram = MyMeter.CreateHistogram<long>("histogram");
private static readonly Random RandomGenerator = new Random();

public static async Task Main(string[] args)
{
using var meterProvider = Sdk.CreateMeterProviderBuilder()
.AddSource("TestMeter")
.AddConsoleExporter()
.Build();

using var token = new CancellationTokenSource();
Task writeMetricTask = new Task(() =>
{
while (!token.IsCancellationRequested)
{
MyHistogram.Record(
RandomGenerator.Next(1, 1000),
new KeyValuePair<string, object>("tag1", "value1"),
new KeyValuePair<string, object>("tag2", "value2"));
Task.Delay(10).Wait();
}
});
writeMetricTask.Start();

token.CancelAfter(10000);
await writeMetricTask;
}
}
67 changes: 67 additions & 0 deletions docs/metrics/getting-started-histogram/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Getting Started with OpenTelemetry .NET in 5 Minutes

First, download and install the [.NET Core
SDK](https://dotnet.microsoft.com/download) on your computer.

Create a new console application and run it:

```sh
dotnet new console --output getting-started-histogram
cd getting-started
dotnet run
```

You should see the following output:

```text
Hello World!
```

Install the
[OpenTelemetry.Exporter.Console](../../../src/OpenTelemetry.Exporter.Console/README.md)
package:

```sh
dotnet add package OpenTelemetry.Exporter.Console
```

Update the `Program.cs` file with the code from [Program.cs](./Program.cs):

Run the application again (using `dotnet run`) and you should see the metric
output from the console, similar to shown below:

<!-- markdownlint-disable MD013 -->
```text
Export 14:30:58.201 14:30:59.177 histogram [tag1=value1;tag2=value2] Histogram, Meter: TestMeter/0.0.1
Value: Sum: 33862 Count: 62
(-? - 0) : 0
(0 - 5) : 0
(5 - 10) : 0
(10 - 25) : 2
(25 - 50) : 0
(50 - 75) : 1
(75 - 100) : 1
(100 - 250) : 6
(250 - 500) : 18
(500 - 1000) : 34
(1000 - ?) : 0
```
<!-- markdownlint-enable MD013 -->

Congratulations! You are now collecting histogram metrics using OpenTelemetry.

What does the above program do?

The program creates a
[Meter](https:/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#meter)
instance named "TestMeter" and then creates a
[Histogram](https:/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#histogram)
instrument from it. This histogram is used to repeatedly report random metric
measurements until exited after 10 seconds.

An OpenTelemetry
[MeterProvider](https:/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#meterprovider)
is configured to subscribe to instruments from the Meter `TestMeter`, and
aggregate the measurements in-memory. The pre-aggregated metrics are exported
every 1 second to a `ConsoleExporter`. `ConsoleExporter` simply displays it on
the console.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<ProjectReference Include="$(RepoRoot)\src\OpenTelemetry\OpenTelemetry.csproj" />
<ProjectReference Include="$(RepoRoot)\src\OpenTelemetry.Exporter.Console\OpenTelemetry.Exporter.Console.csproj" />
</ItemGroup>
</Project>
14 changes: 12 additions & 2 deletions src/OpenTelemetry.Exporter.Console/ConsoleMetricExporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,15 @@ public override ExportResult Export(in Batch<MetricItem> batch)
case MetricType.Histogram:
{
var histogramMetric = metric as IHistogramMetric;
valueDisplay = string.Format("Sum: {0} Count: {1}", histogramMetric.PopulationSum, histogramMetric.PopulationCount);
var bucketsBuilder = new StringBuilder();
bucketsBuilder.Append($"Sum: {histogramMetric.PopulationSum} Count: {histogramMetric.PopulationCount} \n");
foreach (var bucket in histogramMetric.Buckets)
{
bucketsBuilder.Append($"({bucket.LowBoundary} - {bucket.HighBoundary}) : {bucket.Count}");
bucketsBuilder.AppendLine();
}

valueDisplay = bucketsBuilder.ToString();
break;
}

Expand All @@ -102,7 +110,7 @@ public override ExportResult Export(in Batch<MetricItem> batch)

string time = $"{metric.StartTimeExclusive.ToLocalTime().ToString("HH:mm:ss.fff")} {metric.EndTimeInclusive.ToLocalTime().ToString("HH:mm:ss.fff")}";

var msg = new StringBuilder($"Export {time} {metric.Name} [{string.Join(";", tags)}] {metric.MetricType} Value: {valueDisplay}");
var msg = new StringBuilder($"Export {time} {metric.Name} [{string.Join(";", tags)}] {metric.MetricType}");

if (!string.IsNullOrEmpty(metric.Description))
{
Expand All @@ -124,6 +132,8 @@ public override ExportResult Export(in Batch<MetricItem> batch)
}
}

msg.AppendLine();
msg.Append($"Value: {valueDisplay}");
Console.WriteLine(msg);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ namespace OpenTelemetry.Metrics
{
public struct HistogramBucket
{
internal double LowBoundary;
internal double HighBoundary;
internal long Count;
public double LowBoundary;
public double HighBoundary;
public long Count;
}
}
70 changes: 70 additions & 0 deletions src/OpenTelemetry/Metrics/MetricAggregators/HistogramMetric.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// <copyright file="HistogramMetric.cs" company="OpenTelemetry Authors">
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// </copyright>

using System;
using System.Collections.Generic;
using System.Diagnostics.Metrics;

namespace OpenTelemetry.Metrics
{
internal class HistogramMetric : IHistogramMetric
{
internal HistogramMetric(string name, string description, string unit, Meter meter, DateTimeOffset startTimeExclusive, KeyValuePair<string, object>[] attributes, int bucketCount)
{
this.Name = name;
this.Description = description;
this.Unit = unit;
this.Meter = meter;
this.StartTimeExclusive = startTimeExclusive;
this.Attributes = attributes;
this.MetricType = MetricType.Histogram;
this.BucketsArray = new HistogramBucket[bucketCount];
}

public string Name { get; private set; }

public string Description { get; private set; }

public string Unit { get; private set; }

public Meter Meter { get; private set; }

public DateTimeOffset StartTimeExclusive { get; internal set; }

public DateTimeOffset EndTimeInclusive { get; internal set; }

public KeyValuePair<string, object>[] Attributes { get; private set; }

public bool IsDeltaTemporality { get; internal set; }

public IEnumerable<IExemplar> Exemplars { get; private set; } = new List<IExemplar>();

public long PopulationCount { get; internal set; }

public double PopulationSum { get; internal set; }

public IEnumerable<HistogramBucket> Buckets => this.BucketsArray;

public MetricType MetricType { get; private set; }

internal HistogramBucket[] BucketsArray { get; set; }

public string ToDisplayString()
{
return $"Count={this.PopulationCount},Sum={this.PopulationSum}";
}
}
}
Loading

0 comments on commit d649b3d

Please sign in to comment.