示例#1
0
        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));
        }
示例#2
0
        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));
        }
示例#3
0
        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);
        }