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

Introducing Metrics APIs #52685

Merged
merged 3 commits into from
May 15, 2021
Merged
Show file tree
Hide file tree
Changes from 2 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
1 change: 1 addition & 0 deletions eng/Versions.props
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
<SystemDiagnosticsToolsVersion>4.3.0</SystemDiagnosticsToolsVersion>
<SystemDiagnosticsTracingVersion>4.3.0</SystemDiagnosticsTracingVersion>
<SystemDynamicRuntimeVersion>4.3.0</SystemDynamicRuntimeVersion>
<SystemLinqVersion>4.3.0</SystemLinqVersion>
<SystemLinqExpressionsVersion>4.3.0</SystemLinqExpressionsVersion>
<SystemMemoryVersion>4.5.4</SystemMemoryVersion>
<SystemNetHttpVersion>4.3.4</SystemNetHttpVersion>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -271,3 +271,132 @@ public sealed class ActivityListener : IDisposable
}
}

namespace System.Diagnostics.Metrics
{
public readonly struct Measurement<T> where T : struct
tarekgh marked this conversation as resolved.
Show resolved Hide resolved
{
public Measurement(T value) { throw null; }
public Measurement(T value, System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string, object?>>? tags) { throw null; }
public Measurement(T value, params System.Collections.Generic.KeyValuePair<string, object?>[]? tags) { throw null; }
public Measurement(T value, ReadOnlySpan<System.Collections.Generic.KeyValuePair<string, object?>> tags) { throw null; }
public ReadOnlySpan<System.Collections.Generic.KeyValuePair<string, object?>> Tags { get { throw null; } }
public T Value { get { throw null; } }
}

public class Meter : IDisposable
{
public Meter(string name) { throw null; }
public Meter(string name, string? version) { throw null; }
public string Name { get { throw null; } }
public string? Version { get { throw null; } }
public Counter<T> CreateCounter<T>(string name, string? unit = null, string? description = null) where T : struct { throw null; }
public Histogram<T> CreateHistogram<T>(string name, string? unit = null, string? description = null) where T : struct { throw null; }
public ObservableCounter<T> CreateObservableCounter<T>(
string name,
Func<T> observeValue,
string? unit = null,
string? description = null) where T : struct { throw null; }
public ObservableCounter<T> CreateObservableCounter<T>(
string name,
Func<Measurement<T>> observeValue,
string? unit = null,
string? description = null) where T : struct { throw null; }
public ObservableCounter<T> CreateObservableCounter<T>(
string name,
Func<System.Collections.Generic.IEnumerable<Measurement<T>>> observeValues,
string? unit = null,
string? description = null) where T : struct { throw null; }
public ObservableGauge<T> CreateObservableGauge<T>(
string name,
Func<T> observeValue,
string? unit = null,
string? description = null) where T : struct { throw null; }
public ObservableGauge<T> CreateObservableGauge<T>(
string name,
Func<Measurement<T>> observeValue,
string? unit = null,
string? description = null) where T : struct { throw null; }
public ObservableGauge<T> CreateObservableGauge<T>(
string name,
Func<System.Collections.Generic.IEnumerable<Measurement<T>>> observeValues,
string? unit = null,
string? description = null) where T : struct { throw null; }
public void Dispose() { throw null; }
}
public abstract class Instrument
{
protected Instrument(Meter meter, string name, string? unit, string? description) {throw null;}
protected void Publish() {throw null;}
public Meter Meter { get {throw null;} }
public string Name { get {throw null;} }
public string? Description { get {throw null;} }
public string? Unit { get {throw null; } }
public bool Enabled { get {throw null; } }
public virtual bool IsObservable { get {throw null; } }
}
public abstract class Instrument<T> : Instrument where T : struct
{
protected Instrument(Meter meter, string name, string? unit, string? description) : base(meter, name, unit, description) { throw null; }
protected void RecordMeasurement(T measurement) { throw null; }
protected void RecordMeasurement(T measurement, System.Collections.Generic.KeyValuePair<string, object?> tag) { throw null; }
protected void RecordMeasurement(T measurement, System.Collections.Generic.KeyValuePair<string, object?> tag1, System.Collections.Generic.KeyValuePair<string, object?> tag2) { throw null; }
protected void RecordMeasurement(T measurement, System.Collections.Generic.KeyValuePair<string, object?> tag1, System.Collections.Generic.KeyValuePair<string, object?> tag2, System.Collections.Generic.KeyValuePair<string, object?> tag3) { throw null; }
protected void RecordMeasurement(T measurement, ReadOnlySpan<System.Collections.Generic.KeyValuePair<string, object?>> tags) { throw null; }
}
public abstract class ObservableInstrument<T> : Instrument where T : struct
{
protected ObservableInstrument(Meter meter, string name, string? unit, string? description) : base(meter, name, unit, description) { throw null; }
protected abstract System.Collections.Generic.IEnumerable<Measurement<T>> Observe();
public override bool IsObservable { get { throw null; } }
}
public sealed class Counter<T> : Instrument<T> where T : struct
{
internal Counter(Meter meter, string name, string? unit, string? description) :
base(meter, name, unit, description) { throw null; }
public void Add(T delta) { throw null; }
public void Add(T delta, System.Collections.Generic.KeyValuePair<string, object?> tag) { throw null; }
public void Add(T delta, System.Collections.Generic.KeyValuePair<string, object?> tag1, System.Collections.Generic.KeyValuePair<string, object?> tag2) { throw null; }
public void Add(T delta, System.Collections.Generic.KeyValuePair<string, object?> tag1, System.Collections.Generic.KeyValuePair<string, object?> tag2, System.Collections.Generic.KeyValuePair<string, object?> tag3) { throw null; }
public void Add(T delta, ReadOnlySpan<System.Collections.Generic.KeyValuePair<string, object?>> tags) { throw null; }
public void Add(T delta, params System.Collections.Generic.KeyValuePair<string, object?>[] tags) { throw null; }
}
public sealed class Histogram<T> : Instrument<T> where T : struct
{
internal Histogram(Meter meter, string name, string? unit, string? description) : base(meter, name, unit, description) { throw null; }
public void Record(T value) { throw null; }
public void Record(T value, System.Collections.Generic.KeyValuePair<string, object?> tag) { throw null; }
public void Record(T value, System.Collections.Generic.KeyValuePair<string, object?> tag1, System.Collections.Generic.KeyValuePair<string, object?> tag2) { throw null; }
public void Record(T value, System.Collections.Generic.KeyValuePair<string, object?> tag1, System.Collections.Generic.KeyValuePair<string, object?> tag2, System.Collections.Generic.KeyValuePair<string, object?> tag3) { throw null; }
public void Record(T value, ReadOnlySpan<System.Collections.Generic.KeyValuePair<string, object?>> tags) { throw null; }
public void Record(T value, params System.Collections.Generic.KeyValuePair<string, object?>[] tags) { throw null; }
}
public sealed class ObservableCounter<T> : ObservableInstrument<T> where T : struct
{
internal ObservableCounter(Meter meter, string name, string? unit, string? description) : base(meter, name, unit, description) { throw null; }

/// <summary>
tarekgh marked this conversation as resolved.
Show resolved Hide resolved
/// Observe() fetches the current measurements being tracked by this observable counter.
/// </summary>
protected override System.Collections.Generic.IEnumerable<Measurement<T>> Observe() { throw null;}
}
public sealed class ObservableGauge<T> : ObservableInstrument<T> where T : struct
{
internal ObservableGauge(Meter meter, string name, string? unit, string? description) : base(meter, name, unit, description) { throw null; }
protected override System.Collections.Generic.IEnumerable<Measurement<T>> Observe() { throw null; }
}
public delegate void MeasurementCallback<T>(Instrument instrument, T measurement, ReadOnlySpan<System.Collections.Generic.KeyValuePair<string, object?>> tags, object? state);
tarekgh marked this conversation as resolved.
Show resolved Hide resolved
public sealed class MeterListener : IDisposable
{
public MeterListener() { throw null; }
public Action<Instrument, MeterListener>? InstrumentPublished { get { throw null; } set { throw null; } }
public Action<Instrument, object?>? MeasurementsCompleted { get { throw null; } set { throw null; } }
public void EnableMeasurementEvents(Instrument instrument, object? state = null) { throw null; }
public object? DisableMeasurementEvents(Instrument instrument) { throw null; }
public void SetMeasurementEventCallback<T>(MeasurementCallback<T>? measurementCallback) where T : struct { throw null; }
public void Start() { throw null; }
public void RecordObservableInstruments() { throw null; }
public void Dispose() { throw null; }
}
}


tarekgh marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -165,4 +165,7 @@
<data name="UnableToInitialize" xml:space="preserve">
<value>Unable to initialize all required reflection objects</value>
</data>
<data name="UnsupportedType" xml:space="preserve">
<value>{0} is unsupported type for this operation. The only supported types are byte, short, int, long, float, double and decimal.</value>
tarekgh marked this conversation as resolved.
Show resolved Hide resolved
</data>
</root>
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
(which is netstandard1.1). Again we duplicate in a portable-* folder
to work with older NuGet clients -->
<PackageTargetFramework Condition="'$(TargetFramework)' == 'netstandard1.1'">netstandard1.1;portable-net45+win8+wpa81</PackageTargetFramework>
<DefineConstants Condition="'$(TargetFramework)' == 'netstandard1.1' or '$(TargetFramework)' == 'net45'">$(DefineConstants);NO_EVENTSOURCE_COMPLEX_TYPE_SUPPORT</DefineConstants>
<DefineConstants Condition="'$(TargetFramework)' == 'netstandard1.1' or '$(TargetFramework)' == 'net45'">$(DefineConstants);NO_EVENTSOURCE_COMPLEX_TYPE_SUPPORT;NO_ARRAY_EMPTY_SUPPORT</DefineConstants>
<DefineConstants Condition="'$(TargetFramework)' != 'netstandard1.1'">$(DefineConstants);EVENTSOURCE_ACTIVITY_SUPPORT</DefineConstants>
<DefineConstants Condition="'$(TargetFramework)' != 'netstandard1.1' and '$(TargetFramework)' != 'netstandard1.3'">$(DefineConstants);EVENTSOURCE_ENUMERATE_SUPPORT</DefineConstants>
<DefineConstants Condition="$(TargetFramework.StartsWith('net4'))">$(DefineConstants);ALLOW_PARTIALLY_TRUSTED_CALLERS;ENABLE_HTTP_HANDLER</DefineConstants>
Expand Down Expand Up @@ -49,7 +49,20 @@
<Compile Include="System\Diagnostics\ActivityListener.cs" />
<Compile Include="System\Diagnostics\ActivitySource.cs" />
<Compile Include="System\Diagnostics\DiagnosticSourceActivity.cs" />
<Compile Include="System\Diagnostics\LinkedList.cs" />
<Compile Include="System\Diagnostics\RandomNumberGenerator.cs" />
<Compile Include="System\Diagnostics\Metrics\Counter.cs" />
<Compile Include="System\Diagnostics\Metrics\Histogram.cs" />
<Compile Include="System\Diagnostics\Metrics\Instrument.cs" />
<Compile Include="System\Diagnostics\Metrics\Instrument.common.cs" />
<Compile Include="System\Diagnostics\Metrics\Instrument.netcore.cs" Condition="'$(TargetFramework)' == '$(NetCoreAppCurrent)' Or '$(TargetFramework)' == 'net5.0'" />
tarekgh marked this conversation as resolved.
Show resolved Hide resolved
<Compile Include="System\Diagnostics\Metrics\Instrument.netfx.cs" Condition="'$(TargetFramework)' != '$(NetCoreAppCurrent)' And '$(TargetFramework)' != 'net5.0'" />
tarekgh marked this conversation as resolved.
Show resolved Hide resolved
<Compile Include="System\Diagnostics\Metrics\Measurement.cs" />
<Compile Include="System\Diagnostics\Metrics\Meter.cs" />
<Compile Include="System\Diagnostics\Metrics\MeterListener.cs" />
<Compile Include="System\Diagnostics\Metrics\ObservableCounter.cs" />
<Compile Include="System\Diagnostics\Metrics\ObservableGauge.cs" />
<Compile Include="System\Diagnostics\Metrics\ObservableInstrument.cs" />
<None Include="ActivityUserGuide.md" />
</ItemGroup>
<ItemGroup Condition="$([MSBuild]::GetTargetFrameworkIdentifier('$(TargetFramework)')) == '.NETCoreApp'">
Expand Down Expand Up @@ -93,6 +106,7 @@
<Reference Include="System.Diagnostics.Debug" />
<Reference Include="System.Diagnostics.Tracing" />
<Reference Include="System.Memory" />
<Reference Include="System.Linq" />
tarekgh marked this conversation as resolved.
Show resolved Hide resolved
<Reference Include="System.Reflection" />
<Reference Include="System.Runtime" />
<Reference Condition="'$(TargetFramework)' == '$(NetCoreAppCurrent)'" Include="System.Runtime.CompilerServices.Unsafe" />
Expand All @@ -115,6 +129,7 @@
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard1.3'">
<PackageReference Include="System.AppContext" Version="$(SystemAppContextVersion)" />
<PackageReference Include="System.Linq" Version="$(SystemLinqVersion)" />
<PackageReference Include="System.Runtime.Extensions" Version="$(SystemRuntimeExtensionsVersion)" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' != 'netstandard1.1' and
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1323,62 +1323,6 @@ public ActivityIdFormat IdFormat
private set => _state = (_state & ~State.FormatFlags) | (State)((byte)value & (byte)State.FormatFlags);
}

private sealed partial class LinkedListNode<T>
{
public LinkedListNode(T value) => Value = value;
public T Value;
public LinkedListNode<T>? Next;
}

// We are not using the public LinkedList<T> because we need to ensure thread safety operation on the list.
private sealed class LinkedList<T> : IEnumerable<T>
{
private LinkedListNode<T> _first;
private LinkedListNode<T> _last;

public LinkedList(T firstValue) => _last = _first = new LinkedListNode<T>(firstValue);

public LinkedList(IEnumerator<T> e)
{
_last = _first = new LinkedListNode<T>(e.Current);

while (e.MoveNext())
{
_last.Next = new LinkedListNode<T>(e.Current);
_last = _last.Next;
}
}

public LinkedListNode<T> First => _first;

public void Add(T value)
{
LinkedListNode<T> newNode = new LinkedListNode<T>(value);

lock (this)
{
_last.Next = newNode;
_last = newNode;
}
}

public void AddFront(T value)
{
LinkedListNode<T> newNode = new LinkedListNode<T>(value);

lock (this)
{
newNode.Next = _first;
_first = newNode;
}
}

// Note: Some consumers use this GetEnumerator dynamically to avoid allocations.
public Enumerator<T> GetEnumerator() => new Enumerator<T>(_first);
IEnumerator<T> IEnumerable<T>.GetEnumerator() => GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}

private sealed class BaggageLinkedList : IEnumerable<KeyValuePair<string, string?>>
{
private LinkedListNode<KeyValuePair<string, string?>>? _first;
Expand Down Expand Up @@ -1662,42 +1606,6 @@ public override string ToString()
}
}

// Note: Some consumers use this Enumerator dynamically to avoid allocations.
private struct Enumerator<T> : IEnumerator<T>
{
private LinkedListNode<T>? _nextNode;
[AllowNull, MaybeNull] private T _currentItem;

public Enumerator(LinkedListNode<T>? head)
{
_nextNode = head;
_currentItem = default;
}

public T Current => _currentItem!;

object? IEnumerator.Current => Current;

public bool MoveNext()
{
if (_nextNode == null)
{
_currentItem = default;
return false;
}

_currentItem = _nextNode.Value;
_nextNode = _nextNode.Next;
return true;
}

public void Reset() => throw new NotSupportedException();

public void Dispose()
{
}
}

[Flags]
private enum State : byte
{
Expand Down
Loading