public void DoubleObserverSendsAggregateToRegisteredProcessor() { var testProcessor = new TestMetricProcessor(); var meter = MeterFactory.Create(testProcessor).GetMeter("library1") as MeterSdk; var testObserver = meter.CreateDoubleObserver("testObserver", TestCallbackDouble); meter.Collect(); Assert.Equal(2, testProcessor.doubleMetrics.Count); Assert.Equal(2, testProcessor.doubleMetrics.Count(m => m.MetricName == "testObserver")); Assert.Single(testProcessor.doubleMetrics.Where(m => (m.Data as SumData <double>).Sum == 30.5)); Assert.Single(testProcessor.doubleMetrics.Where(m => (m.Data as SumData <double>).Sum == 300.5)); }
public void CounterSendsAggregateToRegisteredProcessor() { var testProcessor = new TestMetricProcessor(); var meter = MeterFactory.Create(testProcessor).GetMeter("library1") as MeterSdk; var testCounter = meter.CreateInt64Counter("testCounter"); var labels1 = new List <KeyValuePair <string, string> >(); labels1.Add(new KeyValuePair <string, string>("dim1", "value1")); var labels2 = new List <KeyValuePair <string, string> >(); labels2.Add(new KeyValuePair <string, string>("dim1", "value2")); var labels3 = new List <KeyValuePair <string, string> >(); labels3.Add(new KeyValuePair <string, string>("dim1", "value3")); var context = default(SpanContext); testCounter.Add(context, 100, meter.GetLabelSet(labels1)); testCounter.Add(context, 10, meter.GetLabelSet(labels1)); var boundCounterLabel2 = testCounter.Bind(labels2); boundCounterLabel2.Add(context, 200); testCounter.Add(context, 200, meter.GetLabelSet(labels3)); testCounter.Add(context, 10, meter.GetLabelSet(labels3)); meter.Collect(); Assert.Equal(3, testProcessor.longMetrics.Count); Assert.Equal(3, testProcessor.longMetrics.Count(m => m.MetricName == "testCounter")); Assert.Single(testProcessor.longMetrics.Where(m => (m.Data as SumData <long>).Sum == 110)); Assert.Single(testProcessor.longMetrics.Where(m => (m.Data as SumData <long>).Sum == 200)); Assert.Single(testProcessor.longMetrics.Where(m => (m.Data as SumData <long>).Sum == 210)); }
public void MeasureSendsAggregateToRegisteredProcessor() { var testProcessor = new TestMetricProcessor(); var meter = MeterFactory.Create(testProcessor).GetMeter("library1") as MeterSdk; var testMeasure = meter.CreateInt64Measure("testMeasure"); var labels1 = new List <KeyValuePair <string, string> >(); labels1.Add(new KeyValuePair <string, string>("dim1", "value1")); var labels2 = new List <KeyValuePair <string, string> >(); labels2.Add(new KeyValuePair <string, string>("dim1", "value2")); var context = default(SpanContext); testMeasure.Record(context, 100, meter.GetLabelSet(labels1)); testMeasure.Record(context, 10, meter.GetLabelSet(labels1)); testMeasure.Record(context, 1, meter.GetLabelSet(labels1)); testMeasure.Record(context, 200, meter.GetLabelSet(labels2)); testMeasure.Record(context, 20, meter.GetLabelSet(labels2)); meter.Collect(); Assert.Equal(2, testProcessor.longMetrics.Count); Assert.Equal(2, testProcessor.longMetrics.Count(m => m.MetricName == "testMeasure")); Assert.Single(testProcessor.longMetrics.Where(m => (m.Data as SummaryData <long>).Sum == 111)); Assert.Single(testProcessor.longMetrics.Where(m => (m.Data as SummaryData <long>).Count == 3)); Assert.Single(testProcessor.longMetrics.Where(m => (m.Data as SummaryData <long>).Min == 1)); Assert.Single(testProcessor.longMetrics.Where(m => (m.Data as SummaryData <long>).Max == 100)); Assert.Single(testProcessor.longMetrics.Where(m => (m.Data as SummaryData <long>).Sum == 220)); Assert.Single(testProcessor.longMetrics.Where(m => (m.Data as SummaryData <long>).Count == 2)); Assert.Single(testProcessor.longMetrics.Where(m => (m.Data as SummaryData <long>).Min == 20)); Assert.Single(testProcessor.longMetrics.Where(m => (m.Data as SummaryData <long>).Max == 200)); }
public void LongCounterBoundInstrumentsStatusUpdatedCorrectlySingleThread() { var testProcessor = new TestMetricProcessor(); var meter = MeterFactory.Create(testProcessor).GetMeter("library1") as MeterSdk; var testCounter = meter.CreateInt64Counter("testCounter") as CounterMetricSdkBase <long>; var labels1 = new List <KeyValuePair <string, string> >(); labels1.Add(new KeyValuePair <string, string>("dim1", "value1")); var ls1 = meter.GetLabelSet(labels1); var labels2 = new List <KeyValuePair <string, string> >(); labels2.Add(new KeyValuePair <string, string>("dim1", "value2")); var ls2 = meter.GetLabelSet(labels2); var labels3 = new List <KeyValuePair <string, string> >(); labels3.Add(new KeyValuePair <string, string>("dim1", "value3")); var ls3 = meter.GetLabelSet(labels3); var context = default(SpanContext); // We have ls1, ls2, ls3 // ls1 and ls3 are not bound so they should removed when no usage for a Collect cycle. // ls2 is bound by user. testCounter.Add(context, 100, ls1); testCounter.Add(context, 10, ls1); // initial status for temp bound instruments are UpdatePending. Assert.Equal(RecordStatus.UpdatePending, testCounter.GetAllBoundInstruments()[ls1].Status); var boundCounterLabel2 = testCounter.Bind(ls2); boundCounterLabel2.Add(context, 200); // initial/forever status for user bound instruments are Bound. Assert.Equal(RecordStatus.Bound, testCounter.GetAllBoundInstruments()[ls2].Status); testCounter.Add(context, 200, ls3); testCounter.Add(context, 10, ls3); // initial status for temp bound instruments are UpdatePending. Assert.Equal(RecordStatus.UpdatePending, testCounter.GetAllBoundInstruments()[ls3].Status); // This collect should mark ls1, ls3 as NoPendingUpdate, leave ls2 untouched. meter.Collect(); // Validate collect() has marked records correctly. Assert.Equal(RecordStatus.NoPendingUpdate, testCounter.GetAllBoundInstruments()[ls1].Status); Assert.Equal(RecordStatus.NoPendingUpdate, testCounter.GetAllBoundInstruments()[ls3].Status); Assert.Equal(RecordStatus.Bound, testCounter.GetAllBoundInstruments()[ls2].Status); // Use ls1 again, so that it'll be promoted to UpdatePending testCounter.Add(context, 100, ls1); // This collect should mark ls1 as NoPendingUpdate, leave ls2 untouched. // And ls3 as CandidateForRemoval, as it was not used since last Collect meter.Collect(); // Validate collect() has marked records correctly. Assert.Equal(RecordStatus.NoPendingUpdate, testCounter.GetAllBoundInstruments()[ls1].Status); Assert.Equal(RecordStatus.CandidateForRemoval, testCounter.GetAllBoundInstruments()[ls3].Status); Assert.Equal(RecordStatus.Bound, testCounter.GetAllBoundInstruments()[ls2].Status); // This collect should mark // ls1 as CandidateForRemoval as it was not used since last Collect // leave ls2 untouched. // ls3 should be physically removed as it remained CandidateForRemoval during an entire Collect cycle. meter.Collect(); Assert.Equal(RecordStatus.CandidateForRemoval, testCounter.GetAllBoundInstruments()[ls1].Status); Assert.Equal(RecordStatus.Bound, testCounter.GetAllBoundInstruments()[ls2].Status); Assert.False(testCounter.GetAllBoundInstruments().ContainsKey(ls3)); }
public void DoubleCounterBoundInstrumentsStatusUpdatedCorrectlyMultiThread() { var testProcessor = new TestMetricProcessor(); var meter = MeterFactory.Create(testProcessor).GetMeter("library1") as MeterSdk; var testCounter = meter.CreateDoubleCounter("testCounter") as CounterMetricSdkBase <double>; var labels1 = new List <KeyValuePair <string, string> >(); labels1.Add(new KeyValuePair <string, string>("dim1", "value1")); var ls1 = meter.GetLabelSet(labels1); var context = default(SpanContext); // Call metric update with ls1 so that ls1 wont be brand new labelset when doing multi-thread test. testCounter.Add(context, 100.0, ls1); testCounter.Add(context, 10.0, ls1); // This collect should mark ls1 NoPendingUpdate meter.Collect(); Assert.Single(testProcessor.doubleMetrics.Where(m => (m.Data as SumData <double>).Sum == 110.0)); // Validate collect() has marked records correctly. Assert.Equal(RecordStatus.NoPendingUpdate, testCounter.GetAllBoundInstruments()[ls1].Status); // Another collect(). This collect should mark ls1 as CandidateForRemoval. meter.Collect(); Assert.Equal(RecordStatus.CandidateForRemoval, testCounter.GetAllBoundInstruments()[ls1].Status); // Call Collect() and update with ls1 parallelly to validate no update is lost, as ls1 is marked // candidate for removal after above step. var mre = new ManualResetEvent(false); var argsForMeterCollect = new ArgsToThread { mreToBlockStartOfThread = mre, callback = () => meter.Collect() }; var argsForCounterAdd = new ArgsToThread { mreToBlockStartOfThread = mre, callback = () => testCounter.Add(context, 100.0, ls1) }; var collectThread = new Thread(ThreadMethod); var updateThread = new Thread(ThreadMethod); collectThread.Start(argsForMeterCollect); updateThread.Start(argsForCounterAdd); // Attempt to start both threads. // TODO: // Instead of this, evaluate if a different testing approach is needed. // One or more thread doing Updates in parallel. // One thread doing occasional Collect. // At the end, validate that no metric update is lost. mre.Set(); collectThread.Join(); updateThread.Join(); // Validate that the exported record doesn't miss any update. // The Add(100) value must have already been exported, or must be exported in the next Collect(). meter.Collect(); double sum = 0; foreach (var exportedData in testProcessor.doubleMetrics) { sum += (exportedData.Data as SumData <double>).Sum; } // 210 = 110 from initial update, 100 from the multi-thread test case. Assert.Equal(210.0, sum); }