Skip to content

Commit

Permalink
Introducing Metrics APIs (#52685)
Browse files Browse the repository at this point in the history
  • Loading branch information
tarekgh authored May 15, 2021
1 parent f704511 commit 67c5e8b
Show file tree
Hide file tree
Showing 19 changed files with 2,446 additions and 108 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,14 @@ public Activity(string operationName) { }
public System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string, string?>> Baggage { get { throw null; } }
public static System.Diagnostics.Activity? Current
{
#if ALLOW_PARTIALLY_TRUSTED_CALLERS
[System.Security.SecuritySafeCriticalAttribute]
#endif
get { throw null; }
#if ALLOW_PARTIALLY_TRUSTED_CALLERS
[System.Security.SecuritySafeCriticalAttribute]
#endif
set { }
}
public static System.Diagnostics.ActivityIdFormat DefaultIdFormat { get { throw null; } set { } }
public System.TimeSpan Duration { get { throw null; } }
public static bool ForceDefaultIdFormat { get { throw null; } set { } }
public string? Id
{
#if ALLOW_PARTIALLY_TRUSTED_CALLERS
[System.Security.SecuritySafeCriticalAttribute]
#endif
get { throw null; }
}

Expand Down Expand Up @@ -120,9 +111,6 @@ public enum ActivityIdFormat
Hierarchical = 1,
W3C = 2,
}
#if ALLOW_PARTIALLY_TRUSTED_CALLERS
[System.Security.SecuritySafeCriticalAttribute]
#endif
public readonly partial struct ActivitySpanId : System.IEquatable<System.Diagnostics.ActivitySpanId>
{
private readonly object _dummy;
Expand Down Expand Up @@ -162,9 +150,6 @@ public enum ActivityTraceFlags
None = 0,
Recorded = 1,
}
#if ALLOW_PARTIALLY_TRUSTED_CALLERS
[System.Security.SecuritySafeCriticalAttribute]
#endif
public readonly partial struct ActivityTraceId : System.IEquatable<System.Diagnostics.ActivityTraceId>
{
private readonly object _dummy;
Expand Down Expand Up @@ -271,3 +256,125 @@ public sealed class ActivityListener : IDisposable
}
}

namespace System.Diagnostics.Metrics
{
public sealed class Counter<T> : Instrument<T> where T : struct
{
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; }
internal Counter(Meter meter, string name, string? unit, string? description) :
base(meter, name, unit, description) { 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 abstract class Instrument
{
public string? Description { get {throw null;} }
public bool Enabled { get {throw null; } }
protected Instrument(Meter meter, string name, string? unit, string? description) {throw null;}
public virtual bool IsObservable { get {throw null; } }
public Meter Meter { get {throw null;} }
public string Name { get {throw null;} }
protected void Publish() {throw null;}
public string? Unit { 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 readonly struct Measurement<T> where T : struct
{
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 delegate void MeasurementCallback<T>(Instrument instrument, T measurement, ReadOnlySpan<System.Collections.Generic.KeyValuePair<string, object?>> tags, object? state);
public class Meter : IDisposable
{
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 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 sealed class MeterListener : IDisposable
{
public object? DisableMeasurementEvents(Instrument instrument) { throw null; }
public void Dispose() { throw null; }
public void EnableMeasurementEvents(Instrument instrument, object? state = null) { 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 MeterListener() { throw null; }
public void RecordObservableInstruments() { throw null; }
public void SetMeasurementEventCallback<T>(MeasurementCallback<T>? measurementCallback) where T : struct { throw null; }
public void Start() { 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; }
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 abstract class ObservableInstrument<T> : Instrument where T : struct
{
public override bool IsObservable { get { throw null; } }
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();
}
}
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>
</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'" />
<Compile Include="System\Diagnostics\Metrics\Instrument.netfx.cs" Condition="'$(TargetFramework)' != '$(NetCoreAppCurrent)' And '$(TargetFramework)' != 'net5.0'" />
<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
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

0 comments on commit 67c5e8b

Please sign in to comment.