-
Notifications
You must be signed in to change notification settings - Fork 780
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'metrics' of https://github.com/open-telemetry/opentelem…
…etry-dotnet into metrics
- Loading branch information
Showing
20 changed files
with
1,401 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
// <copyright file="MeterProvider.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.Concurrent; | ||
using System.Collections.Generic; | ||
using System.Diagnostics.Metrics; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
|
||
#nullable enable | ||
|
||
namespace OpenTelemetry.Metrics | ||
{ | ||
public class MeterProvider | ||
: IDisposable | ||
{ | ||
private BuildOptions options; | ||
private ConcurrentDictionary<Meter, int> meters; | ||
private MeterListener listener; | ||
private CancellationTokenSource cts; | ||
private Task observerTask; | ||
|
||
internal MeterProvider(BuildOptions options) | ||
{ | ||
this.options = options; | ||
|
||
this.meters = new ConcurrentDictionary<Meter, int>(); | ||
|
||
this.listener = new MeterListener() | ||
{ | ||
InstrumentPublished = (instrument, listener) => this.InstrumentPublished(instrument, listener), | ||
MeasurementsCompleted = (instrument, state) => this.MeasurementsCompleted(instrument, state), | ||
}; | ||
this.listener.SetMeasurementEventCallback<double>((i, m, l, c) => this.MeasurementRecorded(i, m, l, c)); | ||
this.listener.SetMeasurementEventCallback<float>((i, m, l, c) => this.MeasurementRecorded(i, m, l, c)); | ||
this.listener.SetMeasurementEventCallback<long>((i, m, l, c) => this.MeasurementRecorded(i, m, l, c)); | ||
this.listener.SetMeasurementEventCallback<int>((i, m, l, c) => this.MeasurementRecorded(i, m, l, c)); | ||
this.listener.SetMeasurementEventCallback<short>((i, m, l, c) => this.MeasurementRecorded(i, m, l, c)); | ||
this.listener.SetMeasurementEventCallback<byte>((i, m, l, c) => this.MeasurementRecorded(i, m, l, c)); | ||
|
||
this.listener.Start(); | ||
|
||
this.cts = new CancellationTokenSource(); | ||
|
||
var token = this.cts.Token; | ||
this.observerTask = Task.Run(async () => | ||
{ | ||
while (!token.IsCancellationRequested) | ||
{ | ||
try | ||
{ | ||
await Task.Delay(this.options.ObservationPeriodMilliseconds, token); | ||
} | ||
catch (TaskCanceledException) | ||
{ | ||
} | ||
|
||
this.listener.RecordObservableInstruments(); | ||
} | ||
}); | ||
} | ||
|
||
public Meter GetMeter(string name, string version) | ||
{ | ||
var meter = new Meter(name, version); | ||
this.meters.TryAdd(meter, 0); | ||
|
||
return meter; | ||
} | ||
|
||
public void Dispose() | ||
{ | ||
this.cts.Cancel(); | ||
this.observerTask.Wait(); | ||
} | ||
|
||
internal void InstrumentPublished(Instrument instrument, MeterListener listener) | ||
{ | ||
bool isInclude = false; | ||
|
||
if (this.options.IncludeMeters != null && this.options.IncludeMeters.Length > 0) | ||
{ | ||
foreach (var meterFunc in this.options.IncludeMeters) | ||
{ | ||
if (meterFunc(instrument)) | ||
{ | ||
isInclude = true; | ||
break; | ||
} | ||
} | ||
} | ||
else | ||
{ | ||
isInclude = this.meters.TryGetValue(instrument.Meter, out var _); | ||
} | ||
|
||
if (isInclude) | ||
{ | ||
// Enable this Instrument if it should be included. | ||
listener.EnableMeasurementEvents(instrument, null); | ||
|
||
if (this.options.Verbose) | ||
{ | ||
Console.WriteLine($"Instrument {instrument.Meter.Name}:{instrument.Name} published."); | ||
} | ||
} | ||
} | ||
|
||
internal void MeasurementsCompleted(Instrument instrument, object? state) | ||
{ | ||
if (this.options.Verbose) | ||
{ | ||
Console.WriteLine($"Instrument {instrument.Meter.Name}:{instrument.Name} completed."); | ||
} | ||
} | ||
|
||
internal void MeasurementRecorded<T>(Instrument instrument, T value, ReadOnlySpan<KeyValuePair<string, object?>> attribs, object? state) | ||
{ | ||
if (this.options.Verbose) | ||
{ | ||
Console.WriteLine($"Instrument {instrument.Meter.Name}:{instrument.Name} recorded {value}."); | ||
} | ||
} | ||
|
||
internal class BuildOptions | ||
{ | ||
public Func<Instrument, bool>[] IncludeMeters { get; set; } = new Func<Instrument, bool>[0]; | ||
|
||
public bool Verbose { get; set; } = true; | ||
|
||
public int ObservationPeriodMilliseconds { get; set; } = 1000; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
// <copyright file="MeterProviderBuilderSdk.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 | ||
{ | ||
public class MeterProviderBuilderSdk | ||
{ | ||
private List<Func<Instrument, bool>> includeMeters = new List<Func<Instrument, bool>>(); | ||
private MeterProvider.BuildOptions options = new MeterProvider.BuildOptions(); | ||
|
||
public MeterProviderBuilderSdk() | ||
{ | ||
} | ||
|
||
public MeterProviderBuilderSdk IncludeInstrument(Func<Instrument, bool> meterFunc) | ||
{ | ||
this.includeMeters.Add(meterFunc); | ||
return this; | ||
} | ||
|
||
public MeterProviderBuilderSdk SetObservationPeriod(int periodMilli) | ||
{ | ||
this.options.ObservationPeriodMilliseconds = periodMilli; | ||
return this; | ||
} | ||
|
||
public MeterProviderBuilderSdk Verbose(bool verbose) | ||
{ | ||
this.options.Verbose = verbose; | ||
return this; | ||
} | ||
|
||
public MeterProvider Build() | ||
{ | ||
this.options.IncludeMeters = this.includeMeters.ToArray(); | ||
return new MeterProvider(this.options); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
// <copyright file="Counter.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.Collections.Generic; | ||
|
||
#nullable enable | ||
|
||
namespace System.Diagnostics.Metrics | ||
{ | ||
/// <summary> | ||
/// The counter is a non-observable Instrument that supports non-negative increments. | ||
/// e.g. Number of completed requests. | ||
/// </summary> | ||
/// <typeparam name="T">TBD.</typeparam> | ||
public sealed class Counter<T> : Instrument<T> | ||
where T : unmanaged | ||
{ | ||
internal Counter(Meter meter, string name, string? description, string? unit) | ||
: base(meter, name, description, unit) | ||
{ | ||
this.Publish(); | ||
} | ||
|
||
/// <summary> | ||
/// TBD. | ||
/// </summary> | ||
public void Add(T measurement) | ||
{ | ||
this.RecordMeasurement(measurement); | ||
} | ||
|
||
/// <summary> | ||
/// TBD. | ||
/// </summary> | ||
public void Add( | ||
T measurement, | ||
KeyValuePair<string, object?> tag1) | ||
{ | ||
this.RecordMeasurement(measurement, tag1); | ||
} | ||
|
||
/// <summary> | ||
/// TBD. | ||
/// </summary> | ||
public void Add( | ||
T measurement, | ||
KeyValuePair<string, object?> tag1, | ||
KeyValuePair<string, object?> tag2) | ||
{ | ||
this.RecordMeasurement(measurement, tag1, tag2); | ||
} | ||
|
||
/// <summary> | ||
/// TBD. | ||
/// </summary> | ||
public void Add( | ||
T measurement, | ||
KeyValuePair<string, object?> tag1, | ||
KeyValuePair<string, object?> tag2, | ||
KeyValuePair<string, object?> tag3) | ||
{ | ||
this.RecordMeasurement(measurement, tag1, tag2, tag3); | ||
} | ||
|
||
/// <summary> | ||
/// TBD. | ||
/// </summary> | ||
public void Add( | ||
T measurement, | ||
ReadOnlySpan<KeyValuePair<string, object?>> tags) | ||
{ | ||
this.RecordMeasurement(measurement, tags); | ||
} | ||
|
||
/// <summary> | ||
/// TBD. | ||
/// </summary> | ||
public void Add( | ||
T measurement, | ||
params KeyValuePair<string, object?>[] tags) | ||
{ | ||
this.RecordMeasurement(measurement, tags); | ||
} | ||
} | ||
} |
Oops, something went wrong.