using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.Tracing;
using System.Globalization;
+using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using System.Threading;
WriteEvent(6, sessionId, meterName, meterVersion ?? "", instrumentName, unit ?? "", tags, quantiles, count, sum);
}
- // Sent when we begin to monitor the value of a intrument, either because new session filter arguments changed subscriptions
+ // Sent when we begin to monitor the value of a instrument, either because new session filter arguments changed subscriptions
// or because an instrument matching the pre-existing filter has just been created. This event precedes all *MetricPublished events
// for the same named instrument.
- [Event(7, Keywords = Keywords.TimeSeriesValues)]
+ [Event(7, Keywords = Keywords.TimeSeriesValues, Version = 1)]
#if !NET8_0_OR_GREATER
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode",
Justification = "This calls WriteEvent with all primitive arguments which is safe. Primitives are always serialized properly.")]
#endif
- public void BeginInstrumentReporting(string sessionId, string meterName, string? meterVersion, string instrumentName, string instrumentType, string? unit, string? description)
+ public void BeginInstrumentReporting(
+ string sessionId,
+ string meterName,
+ string? meterVersion,
+ string instrumentName,
+ string instrumentType,
+ string? unit,
+ string? description,
+ string instrumentTags,
+ string meterTags,
+ string meterScopeHash)
{
- WriteEvent(7, sessionId, meterName, meterVersion ?? "", instrumentName, instrumentType, unit ?? "", description ?? "");
+ WriteEvent(7, sessionId, meterName, meterVersion ?? "", instrumentName, instrumentType, unit ?? "", description ?? "",
+ instrumentTags, meterTags, meterScopeHash);
}
- // Sent when we stop monitoring the value of a intrument, either because new session filter arguments changed subscriptions
+ // Sent when we stop monitoring the value of a instrument, either because new session filter arguments changed subscriptions
// or because the Meter has been disposed.
- [Event(8, Keywords = Keywords.TimeSeriesValues)]
+ [Event(8, Keywords = Keywords.TimeSeriesValues, Version = 1)]
#if !NET8_0_OR_GREATER
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode",
Justification = "This calls WriteEvent with all primitive arguments which is safe. Primitives are always serialized properly.")]
#endif
- public void EndInstrumentReporting(string sessionId, string meterName, string? meterVersion, string instrumentName, string instrumentType, string? unit, string? description)
+ public void EndInstrumentReporting(
+ string sessionId,
+ string meterName,
+ string? meterVersion,
+ string instrumentName,
+ string instrumentType,
+ string? unit,
+ string? description,
+ string instrumentTags,
+ string meterTags,
+ string meterScopeHash)
{
- WriteEvent(8, sessionId, meterName, meterVersion ?? "", instrumentName, instrumentType, unit ?? "", description ?? "");
+ WriteEvent(8, sessionId, meterName, meterVersion ?? "", instrumentName, instrumentType, unit ?? "", description ?? "",
+ instrumentTags, meterTags, meterScopeHash);
}
[Event(9, Keywords = Keywords.TimeSeriesValues | Keywords.Messages | Keywords.InstrumentPublishing)]
WriteEvent(10, sessionId);
}
- [Event(11, Keywords = Keywords.InstrumentPublishing)]
+ [Event(11, Keywords = Keywords.InstrumentPublishing, Version = 1)]
#if !NET8_0_OR_GREATER
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode",
Justification = "This calls WriteEvent with all primitive arguments which is safe. Primitives are always serialized properly.")]
#endif
- public void InstrumentPublished(string sessionId, string meterName, string? meterVersion, string instrumentName, string instrumentType, string? unit, string? description)
+ public void InstrumentPublished(
+ string sessionId,
+ string meterName,
+ string? meterVersion,
+ string instrumentName,
+ string instrumentType,
+ string? unit,
+ string? description,
+ string instrumentTags,
+ string meterTags,
+ string meterScopeHash)
{
- WriteEvent(11, sessionId, meterName, meterVersion ?? "", instrumentName, instrumentType, unit ?? "", description ?? "");
+ WriteEvent(11, sessionId, meterName, meterVersion ?? "", instrumentName, instrumentType, unit ?? "", description ?? "",
+ instrumentTags, meterTags, meterScopeHash);
}
[Event(12, Keywords = Keywords.TimeSeriesValues)]
(i, s) => TransmitMetricValue(i, s, sessionId),
(startIntervalTime, endIntervalTime) => Parent.CollectionStart(sessionId, startIntervalTime, endIntervalTime),
(startIntervalTime, endIntervalTime) => Parent.CollectionStop(sessionId, startIntervalTime, endIntervalTime),
- i => Parent.BeginInstrumentReporting(sessionId, i.Meter.Name, i.Meter.Version, i.Name, i.GetType().Name, i.Unit, i.Description),
- i => Parent.EndInstrumentReporting(sessionId, i.Meter.Name, i.Meter.Version, i.Name, i.GetType().Name, i.Unit, i.Description),
- i => Parent.InstrumentPublished(sessionId, i.Meter.Name, i.Meter.Version, i.Name, i.GetType().Name, i.Unit, i.Description),
+ i => Parent.BeginInstrumentReporting(sessionId, i.Meter.Name, i.Meter.Version, i.Name, i.GetType().Name, i.Unit, i.Description,
+ FormatTags(i.Tags), FormatTags(i.Meter.Tags), FormatScopeHash(i.Meter.Scope)),
+ i => Parent.EndInstrumentReporting(sessionId, i.Meter.Name, i.Meter.Version, i.Name, i.GetType().Name, i.Unit, i.Description,
+ FormatTags(i.Tags), FormatTags(i.Meter.Tags), FormatScopeHash(i.Meter.Scope)),
+ i => Parent.InstrumentPublished(sessionId, i.Meter.Name, i.Meter.Version, i.Name, i.GetType().Name, i.Unit, i.Description,
+ FormatTags(i.Tags), FormatTags(i.Meter.Tags), FormatScopeHash(i.Meter.Scope)),
() => Parent.InitialInstrumentEnumerationComplete(sessionId),
e => Parent.Error(sessionId, e.ToString()),
() => Parent.TimeSeriesLimitReached(sessionId),
}
}
+ private static string FormatScopeHash(object? scope) =>
+ scope is null ? string.Empty : RuntimeHelpers.GetHashCode(scope).ToString(CultureInfo.InvariantCulture);
+
+ private static string FormatTags(IEnumerable<KeyValuePair<string, object?>>? tags)
+ {
+ if (tags is null)
+ {
+ return string.Empty;
+ }
+
+ StringBuilder sb = new StringBuilder();
+ bool first = true;
+ foreach (KeyValuePair<string, object?> tag in tags)
+ {
+ if (first)
+ {
+ first = false;
+ }
+ else
+ {
+ sb.Append(',');
+ }
+
+ sb.Append(tag.Key).Append('=');
+
+ if (tag.Value is not null)
+ {
+ sb.Append(tag.Value.ToString());
+ }
+ }
+ return sb.ToString();
+ }
+
private static string FormatTags(KeyValuePair<string, string>[] labels)
{
StringBuilder sb = new StringBuilder();
using System;
using System.Collections.Generic;
using System.Diagnostics.Tracing;
+using System.Globalization;
using System.Linq;
+using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
public void MultipleListeners_DifferentCounters()
{
using Meter meter = new Meter("TestMeter1");
- Counter<int> c = meter.CreateCounter<int>("counter1");
+ Counter<int> c = meter.CreateCounter<int>("counter1", null, null, new TagList() { { "Ck1", "Cv1" }, { "Ck2", "Cv2" } });
- using Meter meter2 = new Meter("TestMeter2");
+ using Meter meter2 = new Meter("TestMeter2", null, new TagList() { { "Mk1", "Mv1" }, { "Mk2", "Mv2" } }, new object());
Counter<int> c2 = meter2.CreateCounter<int>("counter2");
EventWrittenEventArgs[] events, events2;
public void MultipleListeners_ReuseCounter()
{
using Meter meter = new Meter("TestMeter1");
- Counter<int> c = meter.CreateCounter<int>("counter1");
+ Counter<int> c = meter.CreateCounter<int>("counter1", null, null, new TagList() { { "Ck1", "Cv1" }, { "Ck2", "Cv2" } });
- using Meter meter2 = new Meter("TestMeter2");
- Counter<int> c2 = meter2.CreateCounter<int>("counter2");
+ using Meter meter2 = new Meter("TestMeter2", null, new TagList() { { "Mk1", "Mv1" }, { "Mk2", "Mv2" } }, new object());
+ Counter<int> c2 = meter2.CreateCounter<int>("counter2", null, null, new TagList() { { "cCk1", "cCv1" }, { "cCk2", "cCv2" } });
EventWrittenEventArgs[] events, events2;
using (MetricsEventListener listener = new MetricsEventListener(_output, MetricsEventListener.TimeSeriesValues, isShared: true, IntervalSecs, "TestMeter1"))
[OuterLoop("Slow and has lots of console spew")]
public void MultipleListeners_CollectAfterDisableListener()
{
- using Meter meter = new Meter("TestMeter1");
- Counter<int> c = meter.CreateCounter<int>("counter1");
+ using Meter meter = new Meter("TestMeter1", null, new TagList() { { "Mk1", "Mv1" }, { "Mk2", "Mv2" } }, new object());
+ Counter<int> c = meter.CreateCounter<int>("counter1", null, null, new TagList() { { "Ck1", "Cv1" }, { "Ck2", "Cv2" } });
- using Meter meter2 = new Meter("TestMeter2");
- Counter<int> c2 = meter2.CreateCounter<int>("counter2");
+ using Meter meter2 = new Meter("TestMeter2", null, new TagList() { { "MMk1", "MMv1" } }, new object());
+ Counter<int> c2 = meter2.CreateCounter<int>("counter2", null, null, new TagList() { { "cCk1", "cCv1" }, { "cCk2", "cCv2" } });
EventWrittenEventArgs[] events, events2;
using (MetricsEventListener listener = new MetricsEventListener(_output, MetricsEventListener.TimeSeriesValues, isShared: true, IntervalSecs, "TestMeter1"))
using Meter meter = new Meter("TestMeter1");
Counter<int> c = meter.CreateCounter<int>("counter1");
- using Meter meter2 = new Meter("TestMeter2");
+ using Meter meter2 = new Meter("TestMeter2", null, new TagList() { { "Mk1", "Mv1" } }, new object());
Counter<int> c2 = meter2.CreateCounter<int>("counter2");
- using Meter meter3 = new Meter("TestMeter3");
+ using Meter meter3 = new Meter("TestMeter3", null, new TagList() { { "MMk1", null }, { "MMk2", null } }, new object());
Counter<int> c3 = meter3.CreateCounter<int>("counter3");
EventWrittenEventArgs[] events, events2, events3;
[OuterLoop("Slow and has lots of console spew")]
public void MultipleListeners_OverlappingListeners()
{
- using Meter meter = new Meter("TestMeter1");
- Counter<int> c = meter.CreateCounter<int>("counter1");
+ using Meter meter = new Meter("TestMeter1", null, new TagList() { { "Mk1", "Mv1" } }, new object());
+ Counter<int> c = meter.CreateCounter<int>("counter1", null, null, new TagList() { { "Ck1", "Cv1" }, { "Ck2", "Cv2" } });
using Meter meter2 = new Meter("TestMeter2");
- Counter<int> c2 = meter2.CreateCounter<int>("counter2");
+ Counter<int> c2 = meter2.CreateCounter<int>("counter2", null, null, new TagList() { { "cCk1", "cCv1" }, { "cCk2", "cCv2" } });
EventWrittenEventArgs[] events, events2;
using (MetricsEventListener listener = new MetricsEventListener(_output, MetricsEventListener.TimeSeriesValues, isShared: true, IntervalSecs, "TestMeter1"))
[OuterLoop("Slow and has lots of console spew")]
public void MultipleListeners_UnsharedSessionRejectsUnsharedListener()
{
- using Meter meter = new Meter("TestMeter7");
- Counter<int> c = meter.CreateCounter<int>("counter1", "hat", "Fooz!!");
+ using Meter meter = new Meter("TestMeter7", null, new TagList() { { "Mk1", "Mv1" } }, new object());
+ Counter<int> c = meter.CreateCounter<int>("counter1", "hat", "Fooz!!", new TagList() { { "Ck1", "Cv1" }, { "Ck2", "Cv2" } });
int counterState = 3;
- ObservableCounter<int> oc = meter.CreateObservableCounter<int>("observableCounter1", () => { counterState += 7; return counterState; }, "MB", "Size of universe");
+ ObservableCounter<int> oc = meter.CreateObservableCounter<int>("observableCounter1", () => { counterState += 7; return counterState; }, "MB", "Size of universe", new TagList() { { "ock1", "ocv1" }, { "ock2", "ocv2" } });
int gaugeState = 0;
- ObservableGauge<int> og = meter.CreateObservableGauge<int>("observableGauge1", () => { gaugeState += 9; return gaugeState; }, "12394923 asd [],;/", "junk!");
+ ObservableGauge<int> og = meter.CreateObservableGauge<int>("observableGauge1", () => { gaugeState += 9; return gaugeState; }, "12394923 asd [],;/", "junk!", new TagList() { { "ogk1", "ogv1" } });
Histogram<int> h = meter.CreateHistogram<int>("histogram1", "a unit", "the description");
- UpDownCounter<int> udc = meter.CreateUpDownCounter<int>("upDownCounter1", "udc unit", "udc description");
+ UpDownCounter<int> udc = meter.CreateUpDownCounter<int>("upDownCounter1", "udc unit", "udc description", new TagList() { { "udck1", "udcv1" }, { "udck2", "udcv2" } });
int upDownCounterState = 0;
ObservableUpDownCounter<int> oudc = meter.CreateObservableUpDownCounter<int>("observableUpDownCounter1", () => { upDownCounterState += 11; return upDownCounterState; }, "oudc unit", "oudc description");
[OuterLoop("Slow and has lots of console spew")]
public void MultipleListeners_UnsharedSessionRejectsSharedListener()
{
- using Meter meter = new Meter("TestMeter7");
- Counter<int> c = meter.CreateCounter<int>("counter1", "hat", "Fooz!!");
+ using Meter meter = new Meter("TestMeter7", null, new TagList() { { "Mk1", "Mv1" }, { "Mk2", "Mv2" } }, new object());
+ Counter<int> c = meter.CreateCounter<int>("counter1", "hat", "Fooz!!", new TagList() { { "Ck1", "Cv1" }, { "Ck2", "Cv2" } });
int counterState = 3;
ObservableCounter<int> oc = meter.CreateObservableCounter<int>("observableCounter1", () => { counterState += 7; return counterState; }, "MB", "Size of universe");
int gaugeState = 0;
Histogram<int> h = meter.CreateHistogram<int>("histogram1", "a unit", "the description");
UpDownCounter<int> udc = meter.CreateUpDownCounter<int>("upDownCounter1", "udc unit", "udc description");
int upDownCounterState = 0;
- ObservableUpDownCounter<int> oudc = meter.CreateObservableUpDownCounter<int>("observableUpDownCounter1", () => { upDownCounterState += 11; return upDownCounterState; }, "oudc unit", "oudc description");
+ ObservableUpDownCounter<int> oudc = meter.CreateObservableUpDownCounter<int>("observableUpDownCounter1", () =>
+ { upDownCounterState += 11; return upDownCounterState; }, "oudc unit", "oudc description", new TagList() { { "Ck1", "Cv1" }, { "Ck2", "Cv2" } });
EventWrittenEventArgs[] events;
using (MetricsEventListener listener = new MetricsEventListener(_output, MetricsEventListener.TimeSeriesValues, IntervalSecs, "TestMeter7"))
[OuterLoop("Slow and has lots of console spew")]
public void MultipleListeners_SharedSessionRejectsUnsharedListener()
{
- using Meter meter = new Meter("TestMeter7");
+ using Meter meter = new Meter("TestMeter7", null, new TagList() { { "Mk1", "Mv1" }, { "Mk2", "Mv2" } }, new object());
Counter<int> c = meter.CreateCounter<int>("counter1", "hat", "Fooz!!");
int counterState = 3;
ObservableCounter<int> oc = meter.CreateObservableCounter<int>("observableCounter1", () => { counterState += 7; return counterState; }, "MB", "Size of universe");
int gaugeState = 0;
- ObservableGauge<int> og = meter.CreateObservableGauge<int>("observableGauge1", () => { gaugeState += 9; return gaugeState; }, "12394923 asd [],;/", "junk!");
+ ObservableGauge<int> og = meter.CreateObservableGauge<int>("observableGauge1", () => { gaugeState += 9; return gaugeState; }, "12394923 asd [],;/", "junk!", new TagList());
Histogram<int> h = meter.CreateHistogram<int>("histogram1", "a unit", "the description");
UpDownCounter<int> udc = meter.CreateUpDownCounter<int>("upDownCounter1", "udc unit", "udc description");
int upDownCounterState = 0;
[OuterLoop("Slow and has lots of console spew")]
public void MultipleListeners_SharedSessionRejectsListenerWithDifferentArgs()
{
- using Meter meter = new Meter("TestMeter7");
- Counter<int> c = meter.CreateCounter<int>("counter1", "hat", "Fooz!!");
+ using Meter meter = new Meter("TestMeter7", null, new TagList() { { "Mk1", "Mv1" }, { "Mk2", "Mv2" } });
+ Counter<int> c = meter.CreateCounter<int>("counter1", "hat", "Fooz!!", new TagList() { { "Ck1", "Cv1" }, { "Ck2", "Cv2" } });
EventWrittenEventArgs[] events, events2;
using (MetricsEventListener listener = new MetricsEventListener(_output, MetricsEventListener.TimeSeriesValues, isShared: true, IntervalSecs, 10, 12, "TestMeter7"))
[OuterLoop("Slow and has lots of console spew")]
public void MultipleListeners_SharedSessionRejectsListenerWithDifferentInterval()
{
- using Meter meter = new Meter("TestMeter7");
+ using Meter meter = new Meter("TestMeter7", null, new TagList() { { "Mk1", null }, { "Mk2", null } }, new object());
Counter<int> c = meter.CreateCounter<int>("counter1", "hat", "Fooz!!");
int counterState = 3;
- ObservableCounter<int> oc = meter.CreateObservableCounter<int>("observableCounter1", () => { counterState += 7; return counterState; }, "MB", "Size of universe");
+ ObservableCounter<int> oc = meter.CreateObservableCounter<int>("observableCounter1", () => { counterState += 7; return counterState; }, "MB", "Size of universe", new TagList() { { "Ck1", null }, { "Ck2", "" } });
int gaugeState = 0;
ObservableGauge<int> og = meter.CreateObservableGauge<int>("observableGauge1", () => { gaugeState += 9; return gaugeState; }, "12394923 asd [],;/", "junk!");
- Histogram<int> h = meter.CreateHistogram<int>("histogram1", "a unit", "the description");
+ Histogram<int> h = meter.CreateHistogram<int>("histogram1", "a unit", "the description", new TagList() { { "hk1", "hv1" }, { "hk2", "hv2" }, { "hk3", "hv3" } });
UpDownCounter<int> udc = meter.CreateUpDownCounter<int>("upDownCounter1", "udc unit", "udc description");
int upDownCounterState = 0;
ObservableUpDownCounter<int> oudc = meter.CreateObservableUpDownCounter<int>("observableUpDownCounter1", () => { upDownCounterState += 11; return upDownCounterState; }, "oudc unit", "oudc description");
[OuterLoop("Slow and has lots of console spew")]
public void MultipleListeners_DisposeMeterBeforeSecondListener()
{
- using Meter meterA = new Meter("TestMeter8");
- using Meter meterB = new Meter("TestMeter9");
+ using Meter meterA = new Meter("TestMeter8", null, null, new object());
+ using Meter meterB = new Meter("TestMeter9", null, new TagList() { { "Mk1", "Mv1" }, { "Mk2", "Mv2" } });
Counter<int> c = meterA.CreateCounter<int>("counter1", "hat", "Fooz!!");
int counterState = 3;
- ObservableCounter<int> oc = meterA.CreateObservableCounter<int>("observableCounter1", () => { counterState += 7; return counterState; }, "MB", "Size of universe");
+ ObservableCounter<int> oc = meterA.CreateObservableCounter<int>("observableCounter1", () => { counterState += 7; return counterState; }, "MB", "Size of universe", new TagList() { { "Ck1", "Cv1" }, { "Ck2", "Cv2" } });
int gaugeState = 0;
ObservableGauge<int> og = meterA.CreateObservableGauge<int>("observableGauge1", () => { gaugeState += 9; return gaugeState; }, "12394923 asd [],;/", "junk!");
- Histogram<int> h = meterB.CreateHistogram<int>("histogram1", "a unit", "the description");
+ Histogram<int> h = meterB.CreateHistogram<int>("histogram1", "a unit", "the description", new TagList() { { "hk1", "hv1" }, { "hk2", "hv2" } });
UpDownCounter<int> udc = meterA.CreateUpDownCounter<int>("upDownCounter1", "udc unit", "udc description");
int upDownCounterState = 0;
ObservableUpDownCounter<int> oudc = meterA.CreateObservableUpDownCounter<int>("observableUpDownCounter1", () => { upDownCounterState += 11; return upDownCounterState; }, "oudc unit", "oudc description");
events = listener.Events.ToArray();
}
- AssertBeginInstrumentReportingEventsPresent(events, c, oc, og, h, udc, oudc, h); // only h occurs twice because meterA is disposed before listener2 is created
+ AssertBeginInstrumentReportingEventsPresent(events, c, oc, og, h, udc, oudc, h); // only h occurs twice because meterA is disposed before listener2 is created
AssertBeginInstrumentReportingEventsPresent(events2, h);
AssertInitialEnumerationCompleteEventPresent(events, 2);
AssertInitialEnumerationCompleteEventPresent(events2);
[OuterLoop("Slow and has lots of console spew")]
public void MultipleListeners_DisposeMetersDuringAndAfterSecondListener()
{
- using Meter meterA = new Meter("TestMeter8");
- using Meter meterB = new Meter("TestMeter9");
- Counter<int> c = meterA.CreateCounter<int>("counter1", "hat", "Fooz!!");
+ using Meter meterA = new Meter("TestMeter8", null, new TagList() { { "1Mk1", "1Mv1" }, { "1Mk2", "Mv2" } });
+ using Meter meterB = new Meter("TestMeter9", null, new TagList() { { "2Mk1", "2Mv1" } }, new object());
+ Counter<int> c = meterA.CreateCounter<int>("counter1", "hat", "Fooz!!", new TagList() { { "Ck1", "Cv1" } });
int counterState = 3;
ObservableCounter<int> oc = meterA.CreateObservableCounter<int>("observableCounter1", () => { counterState += 7; return counterState; }, "MB", "Size of universe");
int gaugeState = 0;
ObservableGauge<int> og = meterA.CreateObservableGauge<int>("observableGauge1", () => { gaugeState += 9; return gaugeState; }, "12394923 asd [],;/", "junk!");
Histogram<int> h = meterB.CreateHistogram<int>("histogram1", "a unit", "the description");
- UpDownCounter<int> udc = meterA.CreateUpDownCounter<int>("upDownCounter1", "udc unit", "udc description");
+ UpDownCounter<int> udc = meterA.CreateUpDownCounter<int>("upDownCounter1", "udc unit", "udc description", new TagList() { { "udCk1", "udCv1" }, { "udCk2", "udCv2" } });
int upDownCounterState = 0;
ObservableUpDownCounter<int> oudc = meterA.CreateObservableUpDownCounter<int>("observableUpDownCounter1", () => { upDownCounterState += 11; return upDownCounterState; }, "oudc unit", "oudc description");
[OuterLoop("Slow and has lots of console spew")]
public void MultipleListeners_PublishingInstruments()
{
- using Meter meterA = new Meter("TestMeter10");
- using Meter meterB = new Meter("TestMeter11");
- Counter<int> c = meterA.CreateCounter<int>("counter1", "hat", "Fooz!!");
+ using Meter meterA = new Meter("TestMeter10", null, new TagList() { { "Mk1", "Mv1" }, { "Mk2", "Mv2"}, { "Mk3", null }});
+ using Meter meterB = new Meter("TestMeter11", null, null, new object());
+ Counter<int> c = meterA.CreateCounter<int>("counter1", "hat", "Fooz!!", new TagList() { { "Ck1", "Cv1" } });
int counterState = 3;
ObservableCounter<int> oc = meterA.CreateObservableCounter<int>("observableCounter1", () => { counterState += 7; return counterState; }, "MB", "Size of universe");
int gaugeState = 0;
[OuterLoop("Slow and has lots of console spew")]
public void EventSourcePublishesTimeSeriesWithEmptyMetadata()
{
- using Meter meter = new Meter("TestMeter1");
+ using Meter meter = new Meter("TestMeter1", null, new TagList() { { "Mk1", "Mv1" }, { "Mk2", "Mv2" } }, new object());
Counter<int> c = meter.CreateCounter<int>("counter1");
int counterState = 3;
ObservableCounter<int> oc = meter.CreateObservableCounter<int>("observableCounter1", () => { counterState += 7; return counterState; });
public void EventSourcePublishesTimeSeriesWithMetadata()
{
using Meter meter = new Meter("TestMeter2");
- Counter<int> c = meter.CreateCounter<int>("counter1", "hat", "Fooz!!");
+ Counter<int> c = meter.CreateCounter<int>("counter1", "hat", "Fooz!!", new TagList() { { "Ck1", "Cv1" }, { "Ck2", "Cv2" } });
int counterState = 3;
- ObservableCounter<int> oc = meter.CreateObservableCounter<int>("observableCounter1", () => { counterState += 7; return counterState; } , "MB", "Size of universe");
+ ObservableCounter<int> oc = meter.CreateObservableCounter<int>("observableCounter1", () => { counterState += 7; return counterState; } , "MB", "Size of universe", new TagList() { { "oCk1", "oCv1" } });
int gaugeState = 0;
- ObservableGauge<int> og = meter.CreateObservableGauge<int>("observableGauge1", () => { gaugeState += 9; return gaugeState; }, "12394923 asd [],;/", "junk!");
+ ObservableGauge<int> og = meter.CreateObservableGauge<int>("observableGauge1", () => { gaugeState += 9; return gaugeState; }, "12394923 asd [],;/", "junk!", new TagList() { { "ogk1", null } });
Histogram<int> h = meter.CreateHistogram<int>("histogram1", "a unit", "the description");
- UpDownCounter<int> udc = meter.CreateUpDownCounter<int>("upDownCounter1", "udc unit", "udc description");
+ UpDownCounter<int> udc = meter.CreateUpDownCounter<int>("upDownCounter1", "udc unit", "udc description", new TagList() { { "udCk1", "udCv1" }, { "udCk2", "udCv2" } });
int upDownCounterState = 0;
ObservableUpDownCounter<int> oudc = meter.CreateObservableUpDownCounter<int>("observableUpDownCounter1", () => { upDownCounterState += 11; return upDownCounterState; }, "oudc unit", "oudc description");
listener.WaitForCollectionStop(s_waitForEventTimeout, 1);
// Instruments are created after the EventSource was already monitoring
- c = meter.CreateCounter<int>("counter1");
+ c = meter.CreateCounter<int>("counter1", null, null, new TagList() { { "Ck1", "Cv1" }, { "Ck2", "Cv2" } });
int counterState = 3;
oc = meter.CreateObservableCounter<int>("observableCounter1", () => { counterState += 7; return counterState; });
int gaugeState = 0;
og = meter.CreateObservableGauge<int>("observableGauge1", () => { gaugeState += 9; return gaugeState; });
h = meter.CreateHistogram<int>("histogram1");
- udc = meter.CreateUpDownCounter<int>("upDownCounter1");
+ udc = meter.CreateUpDownCounter<int>("upDownCounter1", null, null, new TagList() { { "udCk1", "udCv1" } });
int upDownCounterState = 0;
oudc = meter.CreateObservableUpDownCounter<int>("observableUpDownCounter1", () => { upDownCounterState += 11; return upDownCounterState; });
[ActiveIssue("https://github.com/dotnet/runtime/issues/79749", TargetFrameworkMonikers.NetFramework)]
public void EventSourceFiltersInstruments()
{
- using Meter meterA = new Meter("TestMeterA");
- using Meter meterB = new Meter("TestMeterB");
- using Meter meterC = new Meter("TestMeterC");
+ object scope = new object();
+ using Meter meterA = new Meter("TestMeterA", null, new TagList() { { "1Mk1", null } }, scope);
+ using Meter meterB = new Meter("TestMeterB", null, new TagList() { { "2Mk1", "" }}, scope);
+ using Meter meterC = new Meter("TestMeterC", null, new TagList() { { "3Mk1", "Mv1" }, { "3Mk2", "Mv2" } }, scope);
Counter<int> c1a = meterA.CreateCounter<int>("counter1");
Counter<int> c2a = meterA.CreateCounter<int>("counter2");
Counter<int> c3a = meterA.CreateCounter<int>("counter3");
[OuterLoop("Slow and has lots of console spew")]
public void EventSourcePublishesMissingDataPoints()
{
- using Meter meter = new Meter("TestMeter6");
- Counter<int> c = meter.CreateCounter<int>("counter1");
+ using Meter meter = new Meter("TestMeter6", null, new TagList() { { "Mk1", "Mv1" }, { "Mk2", "Mv2" } }, new object());
+ Counter<int> c = meter.CreateCounter<int>("counter1", null, null, new TagList() { { "Ck1", "Cv1" }, { "Ck2", "Cv2" } });
int counterState = 3;
int counterCollectInterval = 0;
ObservableCounter<int> oc = meter.CreateObservableCounter<int>("observableCounter1", () =>
[OuterLoop("Slow and has lots of console spew")]
public void EventSourcePublishesEndEventsOnMeterDispose()
{
- using Meter meterA = new Meter("TestMeter8");
- using Meter meterB = new Meter("TestMeter9");
+ object scope = new object();
+ using Meter meterA = new Meter("TestMeter8", null, new TagList() { { "Mk1", "Mv1" }, { "Mk2", null } }, scope);
+ using Meter meterB = new Meter("TestMeter9", null, new TagList() { { "Mk1", null }, { "Mk2", "Mv2" } }, scope);
Counter<int> c = meterA.CreateCounter<int>("counter1", "hat", "Fooz!!");
int counterState = 3;
ObservableCounter<int> oc = meterA.CreateObservableCounter<int>("observableCounter1", () => { counterState += 7; return counterState; }, "MB", "Size of universe");
int gaugeState = 0;
ObservableGauge<int> og = meterA.CreateObservableGauge<int>("observableGauge1", () => { gaugeState += 9; return gaugeState; }, "12394923 asd [],;/", "junk!");
- Histogram<int> h = meterB.CreateHistogram<int>("histogram1", "a unit", "the description");
+ Histogram<int> h = meterB.CreateHistogram<int>("histogram1", "a unit", "the description", new TagList() { { "hk1", "hv1" }, { "hk2", "hv2" }, { "hk3", "hv3" } });
UpDownCounter<int> udc = meterA.CreateUpDownCounter<int>("upDownCounter1", "udc unit", "udc description");
int upDownCounterState = 0;
ObservableUpDownCounter<int> oudc = meterA.CreateObservableUpDownCounter<int>("observableUpDownCounter1", () => { upDownCounterState += 11; return upDownCounterState; }, "oudc unit", "oudc description");
[OuterLoop("Slow and has lots of console spew")]
public void EventSourcePublishesInstruments()
{
- using Meter meterA = new Meter("TestMeter10");
- using Meter meterB = new Meter("TestMeter11");
+ object scope = new object();
+
+ using Meter meterA = new Meter("TestMeter10", null, null, scope);
+ using Meter meterB = new Meter("TestMeter11", null, new TagList() { { "Mk1", "Mv1" }, { "Mk2", null } }, scope);
Counter<int> c = meterA.CreateCounter<int>("counter1", "hat", "Fooz!!");
int counterState = 3;
- ObservableCounter<int> oc = meterA.CreateObservableCounter<int>("observableCounter1", () => { counterState += 7; return counterState; }, "MB", "Size of universe");
+ ObservableCounter<int> oc = meterA.CreateObservableCounter<int>("observableCounter1", () => { counterState += 7; return counterState; }, "MB", "Size of universe",
+ new TagList() { { "ock1", "ocv1" }, { "ock2", "ocv2" }, { "ock3", "ocv3" } });
int gaugeState = 0;
- ObservableGauge<int> og = meterA.CreateObservableGauge<int>("observableGauge1", () => { gaugeState += 9; return gaugeState; }, "12394923 asd [],;/", "junk!");
- Histogram<int> h = meterB.CreateHistogram<int>("histogram1", "a unit", "the description");
- UpDownCounter<int> udc = meterA.CreateUpDownCounter<int>("upDownCounter1", "udc unit", "udc description");
+ ObservableGauge<int> og = meterA.CreateObservableGauge<int>("observableGauge1", () => { gaugeState += 9; return gaugeState; }, "12394923 asd [],;/", "junk!",
+ new TagList() { { "ogk1", "ogv1" } });
+ Histogram<int> h = meterB.CreateHistogram<int>("histogram1", "a unit", "the description", new TagList() { { "hk1", "hv1" }, { "hk2", "" }, {"hk3", null } });
+ UpDownCounter<int> udc = meterA.CreateUpDownCounter<int>("upDownCounter1", "udc unit", "udc description", new TagList() { { "udk1", "udv1" } });
int upDownCounterState = 0;
ObservableUpDownCounter<int> oudc = meterA.CreateObservableUpDownCounter<int>("observableUpDownCounter1", () => { upDownCounterState += 11; return upDownCounterState; }, "oudc unit", "oudc description");
[OuterLoop("Slow and has lots of console spew")]
public void EventSourceEnforcesHistogramLimitAndNotMaxTimeSeries()
{
- using Meter meter = new Meter("TestMeter17");
- Histogram<int> h = meter.CreateHistogram<int>("histogram1");
-
+ using Meter meter = new Meter("TestMeter17", null, new TagList() { { "Mk1", "Mv1" }, { "Mk2", "Mv2" } });
+ Histogram<int> h = meter.CreateHistogram<int>("histogram1", null, null, new TagList() { { "hk1", "hv1" }, { "hk2", "hv2" } });
EventWrittenEventArgs[] events;
// MaxTimeSeries = 3, MaxHistograms = 2
AssertCollectStartStopEventsPresent(events, IntervalSecs, 3);
}
+ private static string FormatScopeHash(object? scope) =>
+ scope is null ? string.Empty : RuntimeHelpers.GetHashCode(scope).ToString(CultureInfo.InvariantCulture);
+
+ private static string FormatTags(IEnumerable<KeyValuePair<string, object?>>? tags)
+ {
+ if (tags is null)
+ {
+ return string.Empty;
+ }
+
+ StringBuilder sb = new StringBuilder();
+ bool first = true;
+ foreach (KeyValuePair<string, object?> tag in tags)
+ {
+ if (first)
+ {
+ first = false;
+ }
+ else
+ {
+ sb.Append(',');
+ }
+
+ sb.Append(tag.Key).Append('=');
+
+ if (tag.Value is not null)
+ {
+ sb.Append(tag.Value.ToString());
+ }
+ }
+ return sb.ToString();
+ }
+
private void AssertBeginInstrumentReportingEventsPresent(EventWrittenEventArgs[] events, params Instrument[] expectedInstruments)
{
var beginReportEvents = events.Where(e => e.EventName == "BeginInstrumentReporting").Select(e =>
InstrumentName = e.Payload[3].ToString(),
InstrumentType = e.Payload[4].ToString(),
Unit = e.Payload[5].ToString(),
- Description = e.Payload[6].ToString()
+ Description = e.Payload[6].ToString(),
+ InstrumentTags = e.Payload[7].ToString(),
+ MeterTags = e.Payload[8].ToString(),
+ ScopeHash = e.Payload[9].ToString()
}).ToArray();
foreach(Instrument i in expectedInstruments)
Assert.Equal(i.GetType().Name, e.InstrumentType);
Assert.Equal(i.Unit ?? "", e.Unit);
Assert.Equal(i.Description ?? "", e.Description);
+ Assert.Equal(FormatTags(i.Tags), e.InstrumentTags);
+ Assert.Equal(FormatTags(i.Meter.Tags), e.MeterTags);
+ Assert.Equal(FormatScopeHash(i.Meter.Scope), e.ScopeHash);
}
Assert.Equal(expectedInstruments.Length, beginReportEvents.Length);
InstrumentName = e.Payload[3].ToString(),
InstrumentType = e.Payload[4].ToString(),
Unit = e.Payload[5].ToString(),
- Description = e.Payload[6].ToString()
+ Description = e.Payload[6].ToString(),
+ InstrumentTags = e.Payload[7].ToString(),
+ MeterTags = e.Payload[8].ToString(),
+ ScopeHash = e.Payload[9].ToString()
}).ToArray();
foreach (Instrument i in expectedInstruments)
Assert.Equal(i.GetType().Name, e.InstrumentType);
Assert.Equal(i.Unit ?? "", e.Unit);
Assert.Equal(i.Description ?? "", e.Description);
+ Assert.Equal(FormatTags(i.Tags), e.InstrumentTags);
+ Assert.Equal(FormatTags(i.Meter.Tags), e.MeterTags);
+ Assert.Equal(FormatScopeHash(i.Meter.Scope), e.ScopeHash);
}
Assert.Equal(expectedInstruments.Length, beginReportEvents.Length);
InstrumentName = e.Payload[3].ToString(),
InstrumentType = e.Payload[4].ToString(),
Unit = e.Payload[5].ToString(),
- Description = e.Payload[6].ToString()
+ Description = e.Payload[6].ToString(),
+ InstrumentTags = e.Payload[7].ToString(),
+ MeterTags = e.Payload[8].ToString(),
+ ScopeHash = e.Payload[9].ToString()
}).ToArray();
foreach (Instrument i in expectedInstruments)
Assert.Equal(i.GetType().Name, e.InstrumentType);
Assert.Equal(i.Unit ?? "", e.Unit);
Assert.Equal(i.Description ?? "", e.Description);
+ Assert.Equal(FormatTags(i.Tags), e.InstrumentTags);
+ Assert.Equal(FormatTags(i.Meter.Tags), e.MeterTags);
+ Assert.Equal(FormatScopeHash(i.Meter.Scope), e.ScopeHash);
}
Assert.Equal(expectedInstruments.Length, publishEvents.Length);
{
_output.WriteLine($" {eventData.PayloadNames[i]}: {eventData.Payload[i]}");
}
-
+
}
_autoResetEvent.Set();
}