Example #1
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);
        }
Example #2
0
 internal static void AddMetrics(
     this OtlpCollector.ExportMetricsServiceRequest request,
     OtlpResource.Resource processResource,
     in Batch <Metric> metrics)
Example #3
0
        public void TestGaugeToOtlpMetric(string name, string description, string unit, long?longValue, double?doubleValue)
        {
            var metrics = new List <Metric>();

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

            if (longValue.HasValue)
            {
                meter.CreateObservableGauge(name, () => longValue.Value, unit, description);
            }
            else
            {
                meter.CreateObservableGauge(name, () => doubleValue.Value, unit, description);
            }

            provider.ForceFlush();

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

            var request = new OtlpCollector.ExportMetricsServiceRequest();

            request.AddMetrics(ResourceBuilder.CreateEmpty().Build().ToOtlpResource(), batch);

            var resourceMetric = request.ResourceMetrics.Single();
            var instrumentationLibraryMetrics = resourceMetric.InstrumentationLibraryMetrics.Single();
            var actual = instrumentationLibraryMetrics.Metrics.Single();

            Assert.Equal(name, actual.Name);
            Assert.Equal(description ?? string.Empty, actual.Description);
            Assert.Equal(unit ?? string.Empty, actual.Unit);

            Assert.Equal(OtlpMetrics.Metric.DataOneofCase.Gauge, actual.DataCase);

            Assert.NotNull(actual.Gauge);
            Assert.Null(actual.Sum);
            Assert.Null(actual.Histogram);
            Assert.Null(actual.ExponentialHistogram);
            Assert.Null(actual.Summary);

            Assert.Single(actual.Gauge.DataPoints);
            var dataPoint = actual.Gauge.DataPoints.First();

            Assert.True(dataPoint.StartTimeUnixNano > 0);
            Assert.True(dataPoint.TimeUnixNano > 0);

            if (longValue.HasValue)
            {
                Assert.Equal(OtlpMetrics.NumberDataPoint.ValueOneofCase.AsInt, dataPoint.ValueCase);
                Assert.Equal(longValue, dataPoint.AsInt);
            }
            else
            {
                Assert.Equal(OtlpMetrics.NumberDataPoint.ValueOneofCase.AsDouble, dataPoint.ValueCase);
                Assert.Equal(doubleValue, dataPoint.AsDouble);
            }

            Assert.Empty(dataPoint.Attributes);

            Assert.Empty(dataPoint.Exemplars);

#pragma warning disable CS0612 // Type or member is obsolete
            Assert.Null(actual.IntGauge);
            Assert.Null(actual.IntSum);
            Assert.Null(actual.IntHistogram);
            Assert.Empty(dataPoint.Labels);
#pragma warning restore CS0612 // Type or member is obsolete
        }
Example #4
0
        public void TestHistogramToOltpMetric(string name, string description, string unit, long?longValue, double?doubleValue, AggregationTemporality aggregationTemporality, params object[] keysValues)
        {
            var metrics = new List <Metric>();

            var metricReader = new BaseExportingMetricReader(new InMemoryExporter <Metric>(metrics));

            metricReader.Temporality = aggregationTemporality;

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

            var attributes = ToAttributes(keysValues).ToArray();

            if (longValue.HasValue)
            {
                var histogram = meter.CreateHistogram <long>(name, unit, description);
                histogram.Record(longValue.Value, attributes);
            }
            else
            {
                var histogram = meter.CreateHistogram <double>(name, unit, description);
                histogram.Record(doubleValue.Value, attributes);
            }

            provider.ForceFlush();

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

            var request = new OtlpCollector.ExportMetricsServiceRequest();

            request.AddMetrics(ResourceBuilder.CreateEmpty().Build().ToOtlpResource(), batch);

            var resourceMetric = request.ResourceMetrics.Single();
            var instrumentationLibraryMetrics = resourceMetric.InstrumentationLibraryMetrics.Single();
            var actual = instrumentationLibraryMetrics.Metrics.Single();

            Assert.Equal(name, actual.Name);
            Assert.Equal(description ?? string.Empty, actual.Description);
            Assert.Equal(unit ?? string.Empty, actual.Unit);

            Assert.Equal(OtlpMetrics.Metric.DataOneofCase.Histogram, actual.DataCase);

            Assert.Null(actual.Gauge);
            Assert.Null(actual.Sum);
            Assert.NotNull(actual.Histogram);
            Assert.Null(actual.ExponentialHistogram);
            Assert.Null(actual.Summary);

            var otlpAggregationTemporality = aggregationTemporality == AggregationTemporality.Cumulative
                ? OtlpMetrics.AggregationTemporality.Cumulative
                : OtlpMetrics.AggregationTemporality.Delta;

            Assert.Equal(otlpAggregationTemporality, actual.Histogram.AggregationTemporality);

            Assert.Single(actual.Histogram.DataPoints);
            var dataPoint = actual.Histogram.DataPoints.First();

            Assert.True(dataPoint.StartTimeUnixNano > 0);
            Assert.True(dataPoint.TimeUnixNano > 0);

            Assert.Equal(1UL, dataPoint.Count);

            if (longValue.HasValue)
            {
                Assert.Equal((double)longValue, dataPoint.Sum);
            }
            else
            {
                Assert.Equal(doubleValue, dataPoint.Sum);
            }

            int bucketIndex;

            for (bucketIndex = 0; bucketIndex < dataPoint.ExplicitBounds.Count; ++bucketIndex)
            {
                if (dataPoint.Sum <= dataPoint.ExplicitBounds[bucketIndex])
                {
                    break;
                }

                Assert.Equal(0UL, dataPoint.BucketCounts[bucketIndex]);
            }

            Assert.Equal(1UL, dataPoint.BucketCounts[bucketIndex]);

            if (attributes.Length > 0)
            {
                OtlpTestHelpers.AssertOtlpAttributes(attributes, dataPoint.Attributes);
            }
            else
            {
                Assert.Empty(dataPoint.Attributes);
            }

            Assert.Empty(dataPoint.Exemplars);

#pragma warning disable CS0612 // Type or member is obsolete
            Assert.Null(actual.IntGauge);
            Assert.Null(actual.IntSum);
            Assert.Null(actual.IntHistogram);
            Assert.Empty(dataPoint.Labels);
#pragma warning restore CS0612 // Type or member is obsolete
        }
        public void ToOtlpResourceMetricsTest(bool includeServiceNameInResource)
        {
            using var exporter = new OtlpMetricsExporter(
                      new OtlpExporterOptions(),
                      new NoopMetricsServiceClient());

            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 tags = new KeyValuePair <string, object>[]
            {
                new KeyValuePair <string, object>("key1", "value1"),
                new KeyValuePair <string, object>("key2", "value2"),
            };

            var processor = new PullMetricProcessor(new TestExporter <MetricItem>(RunTest), true);

            using var provider = Sdk.CreateMeterProviderBuilder()
                                 .SetResourceBuilder(resourceBuilder)
                                 .AddSource("TestMeter")
                                 .AddMetricProcessor(processor)
                                 .Build();

            exporter.ParentProvider = provider;

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

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

            counter.Add(100, tags);

            var testCompleted = false;

            // Invokes the TestExporter which will invoke RunTest
            processor.PullRequest();

            Assert.True(testCompleted);

            void RunTest(Batch <MetricItem> metricItem)
            {
                var request = new OtlpCollector.ExportMetricsServiceRequest();

                request.AddBatch(exporter.ProcessResource, metricItem);

                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("TestMeter", instrumentationLibraryMetrics.InstrumentationLibrary.Name);
                Assert.Equal("0.0.1", instrumentationLibraryMetrics.InstrumentationLibrary.Version);

                Assert.Single(instrumentationLibraryMetrics.Metrics);

                foreach (var metric in instrumentationLibraryMetrics.Metrics)
                {
                    Assert.Equal(string.Empty, metric.Description);
                    Assert.Equal(string.Empty, metric.Unit);
                    Assert.Equal("counter", metric.Name);

                    Assert.Equal(OtlpMetrics.Metric.DataOneofCase.Sum, metric.DataCase);
                    Assert.True(metric.Sum.IsMonotonic);
                    Assert.Equal(OtlpMetrics.AggregationTemporality.Delta, metric.Sum.AggregationTemporality);

                    Assert.Single(metric.Sum.DataPoints);
                    var dataPoint = metric.Sum.DataPoints.First();
                    Assert.True(dataPoint.StartTimeUnixNano > 0);
                    Assert.True(dataPoint.TimeUnixNano > 0);
                    Assert.Equal(OtlpMetrics.NumberDataPoint.ValueOneofCase.AsInt, dataPoint.ValueCase);
                    Assert.Equal(100, dataPoint.AsInt);

#pragma warning disable CS0612 // Type or member is obsolete
                    Assert.Empty(dataPoint.Labels);
#pragma warning restore CS0612 // Type or member is obsolete
                    OtlpTestHelpers.AssertOtlpAttributes(tags.ToList(), dataPoint.Attributes);

                    Assert.Empty(dataPoint.Exemplars);
                }

                testCompleted = true;
            }
        }
 public OtlpCollector.ExportMetricsServiceResponse Export(OtlpCollector.ExportMetricsServiceRequest request, GrpcCore.Metadata headers = null, DateTime?deadline = null, CancellationToken cancellationToken = default)
 {
     return(null);
 }
Example #7
0
 public ExportRequestContent(OtlpCollector.ExportMetricsServiceRequest exportRequest)
 {
     this.exportRequest       = exportRequest;
     this.Headers.ContentType = ProtobufMediaTypeHeader;
 }
        public void TestCounterToOtlpMetric(string name, string description, string unit, long?longValue, double?doubleValue, MetricReaderTemporalityPreference aggregationTemporality, bool isMonotonic, params object[] keysValues)
        {
            var metrics = new List <Metric>();

            using var meter    = new Meter(Utils.GetCurrentMethodName());
            using var provider = Sdk.CreateMeterProviderBuilder()
                                 .AddMeter(meter.Name)
                                 .AddInMemoryExporter(metrics, metricReaderOptions =>
            {
                metricReaderOptions.TemporalityPreference = aggregationTemporality;
            })
                                 .Build();

            var attributes = ToAttributes(keysValues).ToArray();

            if (longValue.HasValue)
            {
                var counter = meter.CreateCounter <long>(name, unit, description);
                counter.Add(longValue.Value, attributes);
            }
            else
            {
                var counter = meter.CreateCounter <double>(name, unit, description);
                counter.Add(doubleValue.Value, attributes);
            }

            provider.ForceFlush();

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

            var request = new OtlpCollector.ExportMetricsServiceRequest();

            request.AddMetrics(ResourceBuilder.CreateEmpty().Build().ToOtlpResource(), batch);

            var resourceMetric = request.ResourceMetrics.Single();
            var scopeMetrics   = resourceMetric.ScopeMetrics.Single();
            var actual         = scopeMetrics.Metrics.Single();

            Assert.Equal(name, actual.Name);
            Assert.Equal(description ?? string.Empty, actual.Description);
            Assert.Equal(unit ?? string.Empty, actual.Unit);

            Assert.Equal(OtlpMetrics.Metric.DataOneofCase.Sum, actual.DataCase);

            Assert.Null(actual.Gauge);
            Assert.NotNull(actual.Sum);
            Assert.Null(actual.Histogram);
            Assert.Null(actual.ExponentialHistogram);
            Assert.Null(actual.Summary);

            Assert.Equal(isMonotonic, actual.Sum.IsMonotonic);

            var otlpAggregationTemporality = aggregationTemporality == MetricReaderTemporalityPreference.Cumulative
                ? OtlpMetrics.AggregationTemporality.Cumulative
                : OtlpMetrics.AggregationTemporality.Delta;

            Assert.Equal(otlpAggregationTemporality, actual.Sum.AggregationTemporality);

            Assert.Single(actual.Sum.DataPoints);
            var dataPoint = actual.Sum.DataPoints.First();

            Assert.True(dataPoint.StartTimeUnixNano > 0);
            Assert.True(dataPoint.TimeUnixNano > 0);

            if (longValue.HasValue)
            {
                Assert.Equal(OtlpMetrics.NumberDataPoint.ValueOneofCase.AsInt, dataPoint.ValueCase);
                Assert.Equal(longValue, dataPoint.AsInt);
            }
            else
            {
                Assert.Equal(OtlpMetrics.NumberDataPoint.ValueOneofCase.AsDouble, dataPoint.ValueCase);
                Assert.Equal(doubleValue, dataPoint.AsDouble);
            }

            if (attributes.Length > 0)
            {
                OtlpTestHelpers.AssertOtlpAttributes(attributes, dataPoint.Attributes);
            }
            else
            {
                Assert.Empty(dataPoint.Attributes);
            }

            Assert.Empty(dataPoint.Exemplars);
        }
        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 tags = new KeyValuePair <string, object>[]
            {
                new KeyValuePair <string, object>("key1", "value1"),
                new KeyValuePair <string, object>("key2", "value2"),
            };

            using var meter = new Meter($"{Utils.GetCurrentMethodName()}.{includeServiceNameInResource}", "0.0.1");

            var exportedItems = new List <Metric>();

            using var provider = Sdk.CreateMeterProviderBuilder()
                                 .SetResourceBuilder(resourceBuilder)
                                 .AddMeter(meter.Name)
                                 .AddReader(new BaseExportingMetricReader(new InMemoryExporter <Metric>(exportedItems))
            {
                PreferredAggregationTemporality = AggregationTemporality.Delta
            })
                                 .Build();

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

            counter.Add(100, tags);

            var testCompleted = false;

            provider.ForceFlush();

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

            RunTest(batch);

            Assert.True(testCompleted);

            void RunTest(Batch <Metric> metrics)
            {
                var request = new OtlpCollector.ExportMetricsServiceRequest();

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

                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);

                Assert.Single(instrumentationLibraryMetrics.Metrics);

                foreach (var metric in instrumentationLibraryMetrics.Metrics)
                {
                    Assert.Equal(string.Empty, metric.Description);
                    Assert.Equal(string.Empty, metric.Unit);
                    Assert.Equal("counter", metric.Name);

                    Assert.Equal(OtlpMetrics.Metric.DataOneofCase.Sum, metric.DataCase);
                    Assert.True(metric.Sum.IsMonotonic);
                    Assert.Equal(OtlpMetrics.AggregationTemporality.Delta, metric.Sum.AggregationTemporality);

                    Assert.Single(metric.Sum.DataPoints);
                    var dataPoint = metric.Sum.DataPoints.First();
                    Assert.True(dataPoint.StartTimeUnixNano > 0);
                    Assert.True(dataPoint.TimeUnixNano > 0);
                    Assert.Equal(OtlpMetrics.NumberDataPoint.ValueOneofCase.AsInt, dataPoint.ValueCase);
                    Assert.Equal(100, dataPoint.AsInt);

#pragma warning disable CS0612 // Type or member is obsolete
                    Assert.Empty(dataPoint.Labels);
#pragma warning restore CS0612 // Type or member is obsolete
                    OtlpTestHelpers.AssertOtlpAttributes(tags.ToList(), dataPoint.Attributes);

                    Assert.Empty(dataPoint.Exemplars);
                }

                testCompleted = true;
            }
        }