예제 #1
0
        public void ViewToDropSingleInstrument()
        {
            using var meter = new Meter("ViewToDropSingleInstrumentTest");
            var exportedItems = new List <Metric>();

            using var meterProvider = Sdk.CreateMeterProviderBuilder()
                                      .AddMeter(meter.Name)
                                      .AddView("counterNotInteresting", new MetricStreamConfiguration()
            {
                Aggregation = Aggregation.Drop
            })
                                      .AddInMemoryExporter(exportedItems)
                                      .Build();

            // Expecting one metric stream.
            var counterInteresting    = meter.CreateCounter <long>("counterInteresting");
            var counterNotInteresting = meter.CreateCounter <long>("counterNotInteresting");

            counterInteresting.Add(10);
            counterNotInteresting.Add(10);

            meterProvider.ForceFlush(MaxTimeToAllowForFlush);
            Assert.Single(exportedItems);
            var metric = exportedItems[0];

            Assert.Equal("counterInteresting", metric.Name);
        }
예제 #2
0
        public void ViewToDropMultipleInstruments()
        {
            using var meter = new Meter(Utils.GetCurrentMethodName());
            var exportedItems = new List <Metric>();

            using var meterProvider = Sdk.CreateMeterProviderBuilder()
                                      .AddMeter(meter.Name)
                                      .AddView("server*", MetricStreamConfiguration.Drop)
                                      .AddInMemoryExporter(exportedItems)
                                      .Build();

            // Expecting two client metric streams as both server* are dropped.
            var serverRequests   = meter.CreateCounter <long>("server.requests");
            var serverExceptions = meter.CreateCounter <long>("server.exceptions");
            var clientRequests   = meter.CreateCounter <long>("client.requests");
            var clientExceptions = meter.CreateCounter <long>("client.exceptions");

            serverRequests.Add(10);
            serverExceptions.Add(10);
            clientRequests.Add(10);
            clientExceptions.Add(10);

            meterProvider.ForceFlush(MaxTimeToAllowForFlush);
            Assert.Equal(2, exportedItems.Count);
            Assert.Equal("client.requests", exportedItems[0].Name);
            Assert.Equal("client.exceptions", exportedItems[1].Name);
        }
예제 #3
0
        public void ViewToRenameMetricWildCardMatch()
        {
            using var meter1 = new Meter("ViewToRenameMetricWildCardMatchTest");
            var exportedItems = new List <Metric>();

            using var meterProvider = Sdk.CreateMeterProviderBuilder()
                                      .AddMeter(meter1.Name)
                                      .AddView("counter*", "renamed")
                                      .AddInMemoryExporter(exportedItems)
                                      .Build();

            // Expecting one metric stream.
            var counter1 = meter1.CreateCounter <long>("counterA");

            counter1.Add(10);
            var counter2 = meter1.CreateCounter <long>("counterB");

            counter2.Add(10);
            var counter3 = meter1.CreateCounter <long>("counterC");

            counter3.Add(10);
            meterProvider.ForceFlush(MaxTimeToAllowForFlush);

            // counter* matches all 3 instruments which all
            // becomes "renamed" and only 1st one is exported.
            Assert.Single(exportedItems);
            var metric = exportedItems[0];

            Assert.Equal("renamed", metric.Name);
        }
예제 #4
0
        public void ViewConflict_TwoIdenticalInstruments_TwoViews_DifferentTags()
        {
            var exportedItems = new List <Metric>();

            using var meter = new Meter($"{Utils.GetCurrentMethodName()}");
            var meterProviderBuilder = Sdk.CreateMeterProviderBuilder()
                                       .AddMeter(meter.Name)
                                       .AddView((instrument) =>
            {
                return(new MetricStreamConfiguration {
                    TagKeys = new[] { "key1" }
                });
            })
                                       .AddView((instrument) =>
            {
                return(new MetricStreamConfiguration {
                    TagKeys = new[] { "key2" }
                });
            })
                                       .AddInMemoryExporter(exportedItems);

            using var meterProvider = meterProviderBuilder.Build();

            var instrument1 = meter.CreateCounter <long>("name");
            var instrument2 = meter.CreateCounter <long>("name");

            var tags = new KeyValuePair <string, object>[]
            {
                new("key1", "value"),
                new("key2", "value"),
            };

            instrument1.Add(10, tags);
            instrument2.Add(10, tags);

            meterProvider.ForceFlush(MaxTimeToAllowForFlush);

            Assert.Equal(2, exportedItems.Count);
            var metric1 = new List <Metric>()
            {
                exportedItems[0]
            };
            var metric2 = new List <Metric>()
            {
                exportedItems[1]
            };
            var tag1 = new List <KeyValuePair <string, object> > {
                tags[0]
            };
            var tag2 = new List <KeyValuePair <string, object> > {
                tags[1]
            };

            Assert.Equal("name", exportedItems[0].Name);
            Assert.Equal("name", exportedItems[1].Name);
            Assert.Equal(20, GetLongSum(metric1));
            Assert.Equal(20, GetLongSum(metric2));
            CheckTagsForNthMetricPoint(metric1, tag1, 1);
            CheckTagsForNthMetricPoint(metric2, tag2, 1);
        }
        public void StreamNamesDuplicatesAreNotAllowedTest(AggregationTemporality temporality)
        {
            var metricItems    = new List <Metric>();
            int metricCount    = 0;
            var metricExporter = new TestExporter <Metric>(ProcessExport);

            void ProcessExport(Batch <Metric> batch)
            {
                foreach (var metric in batch)
                {
                    metricCount++;
                }
            }

            var metricReader = new BaseExportingMetricReader(metricExporter)
            {
                PreferredAggregationTemporality = temporality,
            };

            using var meter1        = new Meter("TestDuplicateMetricName1");
            using var meter2        = new Meter("TestDuplicateMetricName2");
            using var meterProvider = Sdk.CreateMeterProviderBuilder()
                                      .AddMeter("TestDuplicateMetricName1")
                                      .AddMeter("TestDuplicateMetricName2")
                                      .AddReader(metricReader)
                                      .Build();

            // Expecting one metric stream.
            var counterLong = meter1.CreateCounter <long>("name1");

            counterLong.Add(10);
            metricReader.Collect();
            Assert.Equal(1, metricCount);

            // The following will be ignored as
            // metric of same name exists.
            // Metric stream will remain one.
            var anotherCounterSameName = meter1.CreateCounter <long>("name1");

            anotherCounterSameName.Add(10);
            metricCount = 0;
            metricReader.Collect();
            Assert.Equal(1, metricCount);

            // The following will also be ignored
            // as the name is same.
            // (the Meter name is not part of stream name)
            var anotherCounterSameNameDiffMeter = meter2.CreateCounter <long>("name1");

            anotherCounterSameNameDiffMeter.Add(10);
            metricCount = 0;
            metricReader.Collect();
            Assert.Equal(1, metricCount);
        }
 public JoinRequestMessageHandler(NetworkServerConfiguration configuration,
                                  IConcentratorDeduplication concentratorDeduplication,
                                  ILoRaDeviceRegistry deviceRegistry,
                                  ILogger <JoinRequestMessageHandler> logger,
                                  Meter meter)
 {
     this.configuration             = configuration;
     this.concentratorDeduplication = concentratorDeduplication;
     this.deviceRegistry            = deviceRegistry;
     this.joinRequestCounter        = meter?.CreateCounter <int>(MetricRegistry.JoinRequests);
     this.logger                  = logger;
     this.receiveWindowHits       = meter?.CreateCounter <int>(MetricRegistry.ReceiveWindowHits);
     this.receiveWindowMisses     = meter?.CreateCounter <int>(MetricRegistry.ReceiveWindowMisses);
     this.unhandledExceptionCount = meter?.CreateCounter <int>(MetricRegistry.UnhandledExceptions);
 }
예제 #7
0
        public void MultithreadedLongCounterTest()
        {
            var exportedItems = new List <Metric>();

            using var meter = new Meter(Utils.GetCurrentMethodName());
            var counterLong = meter.CreateCounter <long>("mycounter");

            using var meterProvider = Sdk.CreateMeterProviderBuilder()
                                      .AddMeter(meter.Name)
                                      .AddReader(new BaseExportingMetricReader(new InMemoryExporter <Metric>(exportedItems))
            {
                Temporality = AggregationTemporality.Cumulative,
            })
                                      .Build();

            // setup args to threads.
            var mreToBlockUpdateThreads      = new ManualResetEvent(false);
            var mreToEnsureAllThreadsStarted = new ManualResetEvent(false);

            var argToThread = new UpdateThreadArguments <long>();

            argToThread.DeltaValueUpdatedByEachCall = deltaLongValueUpdatedByEachCall;
            argToThread.Counter                    = counterLong;
            argToThread.ThreadsStartedCount        = 0;
            argToThread.MreToBlockUpdateThread     = mreToBlockUpdateThreads;
            argToThread.MreToEnsureAllThreadsStart = mreToEnsureAllThreadsStarted;

            Thread[] t = new Thread[numberOfThreads];
            for (int i = 0; i < numberOfThreads; i++)
            {
                t[i] = new Thread(CounterUpdateThread <long>);
                t[i].Start(argToThread);
            }

            // Block until all threads started.
            mreToEnsureAllThreadsStarted.WaitOne();

            Stopwatch sw = Stopwatch.StartNew();

            // unblock all the threads.
            // (i.e let them start counter.Add)
            mreToBlockUpdateThreads.Set();

            for (int i = 0; i < numberOfThreads; i++)
            {
                // wait for all threads to complete
                t[i].Join();
            }

            var timeTakenInMilliseconds = sw.ElapsedMilliseconds;

            this.output.WriteLine($"Took {timeTakenInMilliseconds} msecs. Total threads: {numberOfThreads}, each thread doing {numberOfMetricUpdateByEachThread} recordings.");

            meterProvider.ForceFlush(MaxTimeToAllowForFlush);

            var sumReceived = GetLongSum(exportedItems);
            var expectedSum = deltaLongValueUpdatedByEachCall * numberOfMetricUpdateByEachThread * numberOfThreads;

            Assert.Equal(expectedSum, sumReceived);
        }
예제 #8
0
        private void ApplicationInsights_Metrics_Collection_Raises_Counter_Metrics <T>(T[] metricValues, double[] expectedReportedValues)
            where T : struct
        {
            // arrange
            const string gateway = "foogateway";

            using var meter = new Meter("LoRaWan", "1.0");
            var counter = meter.CreateCounter <T>(CounterMetric.Name);

            // act
            applicationInsightsMetricExporter.Start();
            foreach (var val in metricValues)
            {
                counter.Add(val, KeyValuePair.Create(MetricRegistry.ConcentratorIdTagName, (object)gateway));
            }

            // assert
            foreach (var expectedReportedValue in expectedReportedValues)
            {
                this.trackValueMock.Verify(me => me.Invoke(It.Is <Metric>(m => m.Identifier.MetricNamespace == MetricRegistry.Namespace &&
                                                                          m.Identifier.MetricId == CounterMetric.Name),
                                                           expectedReportedValue,
                                                           new[] { gateway }),
                                           Times.Once);
            }
        }
예제 #9
0
        public void InMemoryExporterShouldDeepCopyMetricPoints()
        {
            var metrics = new List <Metric>();

            using var meter         = new Meter(Utils.GetCurrentMethodName());
            using var meterProvider = Sdk.CreateMeterProviderBuilder()
                                      .AddMeter(meter.Name)
                                      .AddReader(new BaseExportingMetricReader(new InMemoryExporter <Metric>(metrics))
            {
                PreferredAggregationTemporality = AggregationTemporality.Delta,
            })
                                      .Build();

            var counter = meter.CreateCounter <long>("meter");

            // Emit 10 for the MetricPoint with a single key-vaue pair: ("tag1", "value1")
            counter.Add(10, new KeyValuePair <string, object>("tag1", "value1"));

            meterProvider.ForceFlush();

            var metric = metrics[0]; // Only one Metric object is added to the collection at this point
            var metricPointsEnumerator = metric.GetMetricPoints().GetEnumerator();

            Assert.True(metricPointsEnumerator.MoveNext()); // One MetricPoint is emitted for the Metric
            ref var metricPointForFirstExport = ref metricPointsEnumerator.Current;
예제 #10
0
        public void ExportOnlyWhenPointChanged(AggregationTemporality temporality)
        {
            using var meter = new Meter($"{Utils.GetCurrentMethodName()}.{temporality}");

            var exportedItems = new List <Metric>();

            using var meterProvider = Sdk.CreateMeterProviderBuilder()
                                      .AddMeter(meter.Name)
                                      .AddReader(
                      new BaseExportingMetricReader(new InMemoryExporter <Metric>(exportedItems))
            {
                Temporality = temporality,
            })
                                      .Build();

            var counter = meter.CreateCounter <long>("meter");

            counter.Add(10, new KeyValuePair <string, object>("tag1", "value1"));
            meterProvider.ForceFlush();
            Assert.Single(exportedItems);

            exportedItems.Clear();
            meterProvider.ForceFlush();
            if (temporality == AggregationTemporality.Cumulative)
            {
                Assert.Single(exportedItems);
            }
            else
            {
                Assert.Empty(exportedItems);
            }
        }
        public void ValidateMetricTelemetryItem()
        {
            var metrics = new List <Metric>();

            using var meter    = new Meter(nameof(ValidateMetricTelemetryItem));
            using var provider = Sdk.CreateMeterProviderBuilder()
                                 .AddMeter(meter.Name)
                                 .AddInMemoryExporter(metrics)
                                 .Build();

            var doubleCounter = meter.CreateCounter <double>("TestDoubleCounter");

            doubleCounter.Add(123.45);
            provider.ForceFlush();

            var telemetryItems = MetricHelper.OtelToAzureMonitorMetrics(new Batch <Metric>(metrics.ToArray(), 1), "testRoleName", "testRoleInstance", "00000000-0000-0000-0000-000000000000");

            Assert.Single(telemetryItems);
            Assert.Equal("MetricData", telemetryItems[0].Data.BaseType);
            Assert.Equal("00000000-0000-0000-0000-000000000000", telemetryItems[0].InstrumentationKey);
            Assert.Equal("testRoleName", telemetryItems[0].Tags[ContextTagKeys.AiCloudRole.ToString()]);
            Assert.Equal("testRoleInstance", telemetryItems[0].Tags[ContextTagKeys.AiCloudRoleInstance.ToString()]);

            var metricsData = (MetricsData)telemetryItems[0].Data.BaseData;

            Assert.Equal(2, metricsData.Version);
            Assert.Equal("TestDoubleCounter", metricsData.Metrics.First().Name);
            Assert.Equal(123.45, metricsData.Metrics.First().Value);
            Assert.Equal(DataPointType.Aggregation, metricsData.Metrics.First().DataPointType);
            Assert.Equal(1, metricsData.Properties.Count);
            Assert.Equal("60000", metricsData.Properties["_MS.AggregationIntervalMs"]);
        }
예제 #12
0
        public void ViewToProduceMultipleStreamsWithDuplicatesFromInstrument()
        {
            using var meter1 = new Meter("ViewToProduceMultipleStreamsWithDuplicatesFromInstrumentTest");
            var exportedItems = new List <Metric>();

            using var meterProvider = Sdk.CreateMeterProviderBuilder()
                                      .AddMeter(meter1.Name)
                                      .AddView("name1", "renamedStream1")
                                      .AddView("name1", "renamedStream2")
                                      .AddView("name1", "renamedStream2")
                                      .AddInMemoryExporter(exportedItems)
                                      .Build();

            // Expecting two metric stream.
            // the .AddView("name1", "renamedStream2")
            // won't produce new Metric as the name
            // conflicts.
            var counterLong = meter1.CreateCounter <long>("name1");

            counterLong.Add(10);
            meterProvider.ForceFlush(MaxTimeToAllowForFlush);
            Assert.Equal(2, exportedItems.Count);
            Assert.Equal("renamedStream1", exportedItems[0].Name);
            Assert.Equal("renamedStream2", exportedItems[1].Name);
        }
예제 #13
0
        public void AddViewWithInvalidHistogramBoundsIgnored(double[] boundaries)
        {
            var exportedItems = new List <Metric>();

            using var meter1 = new Meter("AddViewWithInvalidHistogramBoundsIgnored");

            var counter1 = meter1.CreateCounter <long>("counter1");

            using (var provider = Sdk.CreateMeterProviderBuilder()
                                  .AddMeter(meter1.Name)
                                  .AddView((instrument) =>
            {
                return(instrument.Name == counter1.Name
                        ? new ExplicitBucketHistogramConfiguration()
                {
                    Boundaries = boundaries
                }
                        : null);
            })
                                  .AddInMemoryExporter(exportedItems)
                                  .Build())
            {
                counter1.Add(1);
            }

            // Counter is aggregated with default configuration
            // as the View config is ignored due to invalid histogram bounds.
            Assert.Single(exportedItems);
        }
예제 #14
0
        public void ValidateOneDimension(MetricType metricType)
        {
            var metrics = new List <Metric>();

            using var meter    = new Meter(nameof(ValidateOneDimension));
            using var provider = Sdk.CreateMeterProviderBuilder()
                                 .AddMeter(meter.Name)
                                 .AddInMemoryExporter(metrics)
                                 .Build();

            var    dataPointType = DataPointType.Aggregation;
            string name          = null;

            if (metricType == MetricType.DoubleSum)
            {
                name = "TestDoubleCounter";
                var doubleCounter = meter.CreateCounter <double>(name);
                doubleCounter.Add(123.45, new KeyValuePair <string, object>("tag", "value"));
            }
            else if (metricType == MetricType.DoubleGauge)
            {
                name = "TestGauge";
                meter.CreateObservableGauge(
                    name,
                    () => new List <Measurement <double> >()
                {
                    new(123.45, new KeyValuePair <string, object>("tag", "value")),
                });
예제 #15
0
        public void AddViewsWithAndWithoutExceptionInUserCallback()
        {
            var exportedItems = new List <Metric>();

            using var meter1        = new Meter("AddViewWithExceptionInUserCallback");
            using var meterProvider = Sdk.CreateMeterProviderBuilder()
                                      .AddMeter(meter1.Name)
                                      .AddView((instrument) => { throw new Exception("bad"); })
                                      .AddView((instrument) => { return(new MetricStreamConfiguration()
                {
                    Name = "newname"
                }); })
                                      .AddInMemoryExporter(exportedItems)
                                      .Build();

            using (var inMemoryEventListener = new InMemoryEventListener(OpenTelemetrySdkEventSource.Log))
            {
                var counter1 = meter1.CreateCounter <long>("counter1");
                counter1.Add(1);
                Assert.Single(inMemoryEventListener.Events.Where((e) => e.EventId == 41));
            }

            meterProvider.ForceFlush(MaxTimeToAllowForFlush);

            // Counter is still reported with 2nd View
            // even if 1st View is ignored due to View exception.
            Assert.Single(exportedItems);
            Assert.Equal("newname", exportedItems[0].Name);
        }
예제 #16
0
        public void ViewToProduceMultipleStreamsWithDuplicatesFromInstrument()
        {
            using var meter = new Meter(Utils.GetCurrentMethodName());
            var exportedItems = new List <Metric>();

            using var meterProvider = Sdk.CreateMeterProviderBuilder()
                                      .AddMeter(meter.Name)
                                      .AddView("name1", "renamedStream1")
                                      .AddView("name1", "renamedStream2")
                                      .AddView("name1", "renamedStream2")
                                      .AddInMemoryExporter(exportedItems)
                                      .Build();

            // Expecting three metric stream.
            // the second .AddView("name1", "renamedStream2")
            // produces a conflicting metric stream.
            var counterLong = meter.CreateCounter <long>("name1");

            counterLong.Add(10);
            meterProvider.ForceFlush(MaxTimeToAllowForFlush);
            Assert.Equal(3, exportedItems.Count);
            Assert.Equal("renamedStream1", exportedItems[0].Name);
            Assert.Equal("renamedStream2", exportedItems[1].Name);
            Assert.Equal("renamedStream2", exportedItems[2].Name);
        }
예제 #17
0
        public void AddViewWithExceptionInUserCallbackNoDefault()
        {
            var exportedItems = new List <Metric>();

            using var meter1        = new Meter("AddViewWithExceptionInUserCallback");
            using var meterProvider = Sdk.CreateMeterProviderBuilder()
                                      .AddMeter(meter1.Name)
                                      .AddView((instrument) => { throw new Exception("bad"); })
                                      .AddView("*", MetricStreamConfiguration.Drop)
                                      .AddInMemoryExporter(exportedItems)
                                      .Build();

            using (var inMemoryEventListener = new InMemoryEventListener(OpenTelemetrySdkEventSource.Log))
            {
                var counter1 = meter1.CreateCounter <long>("counter1");
                counter1.Add(1);
                Assert.Single(inMemoryEventListener.Events.Where((e) => e.EventId == 41));
            }

            meterProvider.ForceFlush(MaxTimeToAllowForFlush);

            // Counter is not reported.
            // as the View is ignored due to View exception.
            // and Default is suppressed with * -> Drop
            Assert.Empty(exportedItems);
        }
예제 #18
0
        public void GaugeOneDimension()
        {
            var buffer  = new byte[85000];
            var metrics = new List <Metric>();

            using var meter    = new Meter(Utils.GetCurrentMethodName());
            using var provider = Sdk.CreateMeterProviderBuilder()
                                 .AddMeter(meter.Name)
                                 .AddInMemoryExporter(metrics)
                                 .Build();

            var counter = meter.CreateCounter <long>("test_counter");

            counter.Add(123, new KeyValuePair <string, object>("tagKey", "tagValue"));

            provider.ForceFlush();

            var cursor = PrometheusSerializer.WriteMetric(buffer, 0, metrics[0]);

            Assert.Matches(
                ("^"
                 + "# TYPE test_counter counter\n"
                 + "test_counter{tagKey='tagValue'} 123 \\d+\n"
                 + "$").Replace('\'', '"'),
                Encoding.UTF8.GetString(buffer, 0, cursor));
        }
        public void InMemoryExporterShouldDeepCopyMetricPoints()
        {
            var meter = new Meter("InMemoryExporterTests", "1.0");

            var exportedItems = new List <Metric>();

            using var inMemoryReader = new BaseExportingMetricReader(new InMemoryExporter <Metric>(exportedItems))
                  {
                      PreferredAggregationTemporality = AggregationTemporality.Delta,
                  };

            using var meterProvider = Sdk.CreateMeterProviderBuilder()
                                      .AddMeter("InMemoryExporterTests")
                                      .AddReader(inMemoryReader)
                                      .Build();

            var counter = meter.CreateCounter <long>("meter");

            // Emit 10 for the MetricPoint with a single key-vaue pair: ("tag1", "value1")
            counter.Add(10, new KeyValuePair <string, object>("tag1", "value1"));

            // Pull metric data from AggregatorStore
            inMemoryReader.Collect();

            var metric = exportedItems[0]; // Only one Metric object is added to the collection at this point
            var metricPointsEnumerator = metric.GetMetricPoints().GetEnumerator();

            Assert.True(metricPointsEnumerator.MoveNext()); // One MetricPoint is emitted for the Metric
            ref var metricPointForFirstExport = ref metricPointsEnumerator.Current;
예제 #20
0
        public async Task PrometheusExporterMiddlewareIntegration()
        {
            var host = await new HostBuilder()
                       .ConfigureWebHost(webBuilder => webBuilder
                                         .UseTestServer()
                                         .UseStartup <Startup>())
                       .StartAsync();

            var tags = new KeyValuePair <string, object>[]
            {
                new KeyValuePair <string, object>("key1", "value1"),
                new KeyValuePair <string, object>("key2", "value2"),
            };

            using var meter = new Meter(MeterName, "0.0.1");

            var counter = meter.CreateCounter <double>("counter_double");

            counter.Add(100.18D, tags);
            counter.Add(0.99D, tags);

            using var response = await host.GetTestClient().GetAsync("/metrics").ConfigureAwait(false);

            Assert.Equal(HttpStatusCode.OK, response.StatusCode);

            string content = await response.Content.ReadAsStringAsync().ConfigureAwait(false);

            Assert.Equal(
                $"# TYPE counter_double counter\ncounter_double{{key1=\"value1\",key2=\"value2\"}} 101.17 1633041000000\n",
                content);

            await host.StopAsync().ConfigureAwait(false);
        }
예제 #21
0
        private static string WriteLongSum(Meter meter, KeyValuePair <string, object>[] tags, string tagsExpected)
        {
            var counter = meter.CreateCounter <int>("counter_int", description: "Prometheus help text goes here \n escaping.");

            counter.Add(100, tags);

            return($"# HELP counter_int Prometheus help text goes here \\n escaping.\n# TYPE counter_int counter\ncounter_int{tagsExpected} 100 1633041000000\n");
        }
예제 #22
0
 public LnsProtocolMessageProcessor(IBasicsStationConfigurationService basicsStationConfigurationService,
                                    WebSocketWriterRegistry <StationEui, string> socketWriterRegistry,
                                    IDownstreamMessageSender downstreamMessageSender,
                                    IMessageDispatcher messageDispatcher,
                                    ILogger <LnsProtocolMessageProcessor> logger,
                                    RegistryMetricTagBag registryMetricTagBag,
                                    Meter meter)
 {
     this.basicsStationConfigurationService = basicsStationConfigurationService;
     this.socketWriterRegistry    = socketWriterRegistry;
     this.downstreamMessageSender = downstreamMessageSender;
     this.messageDispatcher       = messageDispatcher;
     this.logger = logger;
     this.registryMetricTagBag    = registryMetricTagBag;
     this.joinRequestCounter      = meter?.CreateCounter <int>(MetricRegistry.JoinRequests);
     this.uplinkMessageCounter    = meter?.CreateCounter <int>(MetricRegistry.D2CMessagesReceived);
     this.unhandledExceptionCount = meter?.CreateCounter <int>(MetricRegistry.UnhandledExceptions);
 }
예제 #23
0
        private static string WriteDoubleSum(Meter meter, KeyValuePair <string, object>[] tags, string tagsExpected)
        {
            var counter = meter.CreateCounter <double>("counter_double");

            counter.Add(100.18D, tags);
            counter.Add(0.99D, tags);

            return($"# TYPE counter_double counter\ncounter_double{tagsExpected} 101.17 1633041000000\n");
        }
예제 #24
0
        public void ToOtlpResourceMetricsTest(bool includeServiceNameInResource)
        {
            var resourceBuilder = ResourceBuilder.CreateEmpty();

            if (includeServiceNameInResource)
            {
                resourceBuilder.AddAttributes(
                    new List <KeyValuePair <string, object> >
                {
                    new KeyValuePair <string, object>(ResourceSemanticConventions.AttributeServiceName, "service-name"),
                    new KeyValuePair <string, object>(ResourceSemanticConventions.AttributeServiceNamespace, "ns1"),
                });
            }

            var metrics = new List <Metric>();

            using var meter    = new Meter($"{Utils.GetCurrentMethodName()}.{includeServiceNameInResource}", "0.0.1");
            using var provider = Sdk.CreateMeterProviderBuilder()
                                 .SetResourceBuilder(resourceBuilder)
                                 .AddMeter(meter.Name)
                                 .AddInMemoryExporter(metrics)
                                 .Build();

            var counter = meter.CreateCounter <int>("counter");

            counter.Add(100);

            provider.ForceFlush();

            var batch = new Batch <Metric>(metrics.ToArray(), metrics.Count);

            var request = new OtlpCollector.ExportMetricsServiceRequest();

            request.AddMetrics(resourceBuilder.Build().ToOtlpResource(), batch);

            Assert.Single(request.ResourceMetrics);
            var resourceMetric = request.ResourceMetrics.First();
            var oltpResource   = resourceMetric.Resource;

            if (includeServiceNameInResource)
            {
                Assert.Contains(oltpResource.Attributes, (kvp) => kvp.Key == ResourceSemanticConventions.AttributeServiceName && kvp.Value.StringValue == "service-name");
                Assert.Contains(oltpResource.Attributes, (kvp) => kvp.Key == ResourceSemanticConventions.AttributeServiceNamespace && kvp.Value.StringValue == "ns1");
            }
            else
            {
                Assert.Contains(oltpResource.Attributes, (kvp) => kvp.Key == ResourceSemanticConventions.AttributeServiceName && kvp.Value.ToString().Contains("unknown_service:"));
            }

            Assert.Single(resourceMetric.InstrumentationLibraryMetrics);
            var instrumentationLibraryMetrics = resourceMetric.InstrumentationLibraryMetrics.First();

            Assert.Equal(string.Empty, instrumentationLibraryMetrics.SchemaUrl);
            Assert.Equal(meter.Name, instrumentationLibraryMetrics.InstrumentationLibrary.Name);
            Assert.Equal("0.0.1", instrumentationLibraryMetrics.InstrumentationLibrary.Version);
        }
예제 #25
0
        public void ViewConflict_OneInstrument_DifferentDescription()
        {
            var exportedItems = new List <Metric>();

            using var meter = new Meter($"{Utils.GetCurrentMethodName()}");
            var meterProviderBuilder = Sdk.CreateMeterProviderBuilder()
                                       .AddMeter(meter.Name)
                                       .AddView("instrumentName", new MetricStreamConfiguration()
            {
                Description = "newDescription1"
            })
                                       .AddView("instrumentName", new MetricStreamConfiguration()
            {
                Description = "newDescription2"
            })
                                       .AddInMemoryExporter(exportedItems);

            using var meterProvider = meterProviderBuilder.Build();

            var instrument = meter.CreateCounter <long>("instrumentName", "instrumentUnit", "instrumentDescription");

            instrument.Add(10);

            meterProvider.ForceFlush(MaxTimeToAllowForFlush);
            Assert.Equal(2, exportedItems.Count);

            var metric1 = exportedItems[0];
            var metric2 = exportedItems[1];

            Assert.Equal("newDescription1", metric1.Description);
            Assert.Equal("newDescription2", metric2.Description);

            List <MetricPoint> metric1MetricPoints = new List <MetricPoint>();

            foreach (ref readonly var mp in metric1.GetMetricPoints())
            {
                metric1MetricPoints.Add(mp);
            }

            Assert.Single(metric1MetricPoints);
            var metricPoint1 = metric1MetricPoints[0];

            Assert.Equal(10, metricPoint1.GetSumLong());

            List <MetricPoint> metric2MetricPoints = new List <MetricPoint>();

            foreach (ref readonly var mp in metric2.GetMetricPoints())
            {
                metric2MetricPoints.Add(mp);
            }

            Assert.Single(metric2MetricPoints);
            var metricPoint2 = metric2MetricPoints[0];

            Assert.Equal(10, metricPoint2.GetSumLong());
        }
예제 #26
0
 public CupsProtocolMessageProcessor(IBasicsStationConfigurationService basicsStationConfigurationService,
                                     LoRaDeviceAPIServiceBase deviceAPIServiceBase,
                                     ILogger <CupsProtocolMessageProcessor> logger,
                                     Meter?meter)
 {
     this.basicsStationConfigurationService = basicsStationConfigurationService;
     this.deviceAPIServiceBase = deviceAPIServiceBase;
     this.logger = logger;
     this.unhandledExceptionCount = meter?.CreateCounter <int>(MetricRegistry.UnhandledExceptions);
 }
예제 #27
0
        public void DuplicateInstrumentNamesFromSameMeterAreNotAllowed(AggregationTemporality temporality, bool hasView)
        {
            var metricItems    = new List <Metric>();
            var metricExporter = new InMemoryExporter <Metric>(metricItems);

            var metricReader = new BaseExportingMetricReader(metricExporter)
            {
                PreferredAggregationTemporality = temporality,
            };

            using var meter = new Meter($"{Utils.GetCurrentMethodName()}.{temporality}");
            var meterProviderBuilder = Sdk.CreateMeterProviderBuilder()
                                       .AddMeter(meter.Name)
                                       .AddReader(metricReader);

            if (hasView)
            {
                meterProviderBuilder.AddView("name1", new MetricStreamConfiguration()
                {
                    Description = "description"
                });
            }

            using var meterProvider = meterProviderBuilder.Build();

            // Expecting one metric stream.
            var counterLong = meter.CreateCounter <long>("name1");

            counterLong.Add(10);
            metricReader.Collect();
            Assert.Single(metricItems);

            // The following will be ignored as
            // metric of same name exists.
            // Metric stream will remain one.
            var anotherCounterSameName = meter.CreateCounter <long>("name1");

            anotherCounterSameName.Add(10);
            counterLong.Add(10);
            metricItems.Clear();
            metricReader.Collect();
            Assert.Single(metricItems);
        }
예제 #28
0
        public void TestMetricPointCap(AggregationTemporality temporality)
        {
            var metricItems      = new List <Metric>();
            int metricPointCount = 0;
            var metricExporter   = new TestExporter <Metric>(ProcessExport);

            void ProcessExport(Batch <Metric> batch)
            {
                foreach (var metric in batch)
                {
                    foreach (ref var metricPoint in metric.GetMetricPoints())
                    {
                        metricPointCount++;
                    }
                }
            }

            var metricReader = new BaseExportingMetricReader(metricExporter)
            {
                PreferredAggregationTemporality = temporality,
            };

            using var meter = new Meter("TestPointCapMeter");
            var counterLong = meter.CreateCounter <long>("mycounterCapTest");

            using var meterProvider = Sdk.CreateMeterProviderBuilder()
                                      .AddMeter("TestPointCapMeter")
                                      .AddReader(metricReader)
                                      .Build();

            // Make one Add with no tags.
            // as currently we reserve 0th index
            // for no tag point!
            // This may be changed later.
            counterLong.Add(10);
            for (int i = 0; i < AggregatorStore.MaxMetricPoints + 1; i++)
            {
                counterLong.Add(10, new KeyValuePair <string, object>("key", "value" + i));
            }

            metricReader.Collect();
            Assert.Equal(AggregatorStore.MaxMetricPoints, metricPointCount);

            metricPointCount = 0;
            metricReader.Collect();
            Assert.Equal(AggregatorStore.MaxMetricPoints, metricPointCount);

            // These updates would be dropped.
            counterLong.Add(10, new KeyValuePair <string, object>("key", "valueA"));
            counterLong.Add(10, new KeyValuePair <string, object>("key", "valueB"));
            counterLong.Add(10, new KeyValuePair <string, object>("key", "valueC"));
            metricPointCount = 0;
            metricReader.Collect();
            Assert.Equal(AggregatorStore.MaxMetricPoints, metricPointCount);
        }
예제 #29
0
        public void TestInstrumentDisposal(AggregationTemporality temporality)
        {
            var metricItems    = new List <Metric>();
            var metricExporter = new InMemoryExporter <Metric>(metricItems);
            var metricReader   = new BaseExportingMetricReader(metricExporter)
            {
                PreferredAggregationTemporality = temporality,
            };

            var meter1   = new Meter($"{Utils.GetCurrentMethodName()}.{temporality}.1");
            var meter2   = new Meter($"{Utils.GetCurrentMethodName()}.{temporality}.2");
            var counter1 = meter1.CreateCounter <long>("counterFromMeter1");
            var counter2 = meter2.CreateCounter <long>("counterFromMeter2");

            using var meterProvider = Sdk.CreateMeterProviderBuilder()
                                      .AddMeter(meter1.Name)
                                      .AddMeter(meter2.Name)
                                      .AddReader(metricReader)
                                      .Build();

            counter1.Add(10, new KeyValuePair <string, object>("key", "value"));
            counter2.Add(10, new KeyValuePair <string, object>("key", "value"));

            metricReader.Collect();
            Assert.Equal(2, metricItems.Count);
            metricItems.Clear();

            counter1.Add(10, new KeyValuePair <string, object>("key", "value"));
            counter2.Add(10, new KeyValuePair <string, object>("key", "value"));
            meter1.Dispose();

            metricReader.Collect();
            Assert.Equal(2, metricItems.Count);
            metricItems.Clear();

            counter1.Add(10, new KeyValuePair <string, object>("key", "value"));
            counter2.Add(10, new KeyValuePair <string, object>("key", "value"));
            metricReader.Collect();
            Assert.Single(metricItems);
            metricItems.Clear();

            counter1.Add(10, new KeyValuePair <string, object>("key", "value"));
            counter2.Add(10, new KeyValuePair <string, object>("key", "value"));
            meter2.Dispose();

            metricReader.Collect();
            Assert.Single(metricItems);
            metricItems.Clear();

            counter1.Add(10, new KeyValuePair <string, object>("key", "value"));
            counter2.Add(10, new KeyValuePair <string, object>("key", "value"));
            metricReader.Collect();
            Assert.Empty(metricItems);
        }
예제 #30
0
        private void MultithreadedCounterTest <T>(T deltaValueUpdatedByEachCall)
            where T : struct, IComparable
        {
            var metricItems  = new List <Metric>();
            var metricReader = new BaseExportingMetricReader(new InMemoryExporter <Metric>(metricItems));

            using var meter         = new Meter($"{Utils.GetCurrentMethodName()}.{typeof(T).Name}.{deltaValueUpdatedByEachCall}");
            using var meterProvider = Sdk.CreateMeterProviderBuilder()
                                      .AddMeter(meter.Name)
                                      .AddReader(metricReader)
                                      .Build();

            var argToThread = new UpdateThreadArguments <T>
            {
                ValuesToRecord             = new T[] { deltaValueUpdatedByEachCall },
                Instrument                 = meter.CreateCounter <T>("counter"),
                MreToBlockUpdateThread     = new ManualResetEvent(false),
                MreToEnsureAllThreadsStart = new ManualResetEvent(false),
            };

            Thread[] t = new Thread[numberOfThreads];
            for (int i = 0; i < numberOfThreads; i++)
            {
                t[i] = new Thread(CounterUpdateThread <T>);
                t[i].Start(argToThread);
            }

            argToThread.MreToEnsureAllThreadsStart.WaitOne();
            Stopwatch sw = Stopwatch.StartNew();

            argToThread.MreToBlockUpdateThread.Set();

            for (int i = 0; i < numberOfThreads; i++)
            {
                t[i].Join();
            }

            this.output.WriteLine($"Took {sw.ElapsedMilliseconds} msecs. Total threads: {numberOfThreads}, each thread doing {numberOfMetricUpdateByEachThread} recordings.");

            metricReader.Collect();

            if (typeof(T) == typeof(long))
            {
                var sumReceived = GetLongSum(metricItems);
                var expectedSum = deltaLongValueUpdatedByEachCall * numberOfMetricUpdateByEachThread * numberOfThreads;
                Assert.Equal(expectedSum, sumReceived);
            }
            else if (typeof(T) == typeof(double))
            {
                var sumReceived = GetDoubleSum(metricItems);
                var expectedSum = deltaDoubleValueUpdatedByEachCall * numberOfMetricUpdateByEachThread * numberOfThreads;
                Assert.Equal(expectedSum, sumReceived, 2);
            }
        }