Exemplo n.º 1
0
        public void CreatingLabelledMetric_AfterObservingLabelledData_DoesNotExportUnlabelled()
        {
            var registry = new DefaultCollectorRegistry();
            var factory  = Metrics.WithCustomRegistry(registry);

            var gauge     = factory.CreateGauge("gauge", "", "labelname");
            var counter   = factory.CreateCounter("counter", "", "labelname");
            var summary   = factory.CreateSummary("summary", "", "labelname");
            var histogram = factory.CreateHistogram("histogram", "", null, "labelname");

            // Touch some labelled metrics.
            gauge.Labels("labelvalue").Inc();
            counter.Labels("labelvalue").Inc();
            summary.Labels("labelvalue").Observe(123);
            histogram.Labels("labelvalue").Observe(123);

            // Without touching any unlabelled metrics, there should be only labelled output.
            var exported = registry.CollectAll().ToArray();

            // There is a family for each of the above, in each family we expect to see 1 metric (for the labelled case).
            Assert.AreEqual(4, exported.Length);

            foreach (var family in exported)
            {
                Assert.AreEqual(1, family.metric.Count, $"Family {family.type} had unexpected metric count.");
            }
        }
        public void TestResponsesTotalRecordsFailureViaLabel()
        {
            string metricName = "test";
            DefaultCollectorRegistry registry = GetEmptyRegistry();
            string totalMetricName            = string.Format("{0}_responses_total", metricName);

            try
            {
                Metrics.Instrument(metricName, () =>
                {
                    throw new ApplicationException("Simulate error during request");
                });
                Assert.Fail("Metrics.Instrument should not swallow exceptions");
            }
            catch (ApplicationException)
            {
            }

            var family = registry.CollectAll().First(x => x.name == totalMetricName);
            var metric = family.metric[0];
            var label  = metric.label.Find(l => l.name == "success");

            Assert.IsNotNull(label, "success label not found");
            Assert.AreEqual("0", label.value);
        }
        public void CreatingUnlabelledMetric_WithInitialValueSuppression_ExportsNothingByDefault()
        {
            var registry = new DefaultCollectorRegistry();
            var factory  = Metrics.WithCustomRegistry(registry);

            var gauge = factory.CreateGauge("gauge", "", new GaugeConfiguration
            {
                SuppressInitialValue = true
            });
            var counter = factory.CreateCounter("counter", "", new CounterConfiguration
            {
                SuppressInitialValue = true
            });
            var summary = factory.CreateSummary("summary", "", new SummaryConfiguration
            {
                SuppressInitialValue = true
            });
            var histogram = factory.CreateHistogram("histogram", "", new HistogramConfiguration
            {
                SuppressInitialValue = true
            });

            var exported = registry.CollectAll().ToArray();

            // There is a family for each of the above, in each family we expect to see 0 metrics.
            Assert.AreEqual(4, exported.Length);

            foreach (var family in exported)
            {
                Assert.AreEqual(0, family.metric.Count, $"Family {family.type} had unexpected metric count.");
            }
        }
        public void CreatingLabelledMetric_WithoutObservingAnyData_ExportsImmediately()
        {
            var registry = new DefaultCollectorRegistry();
            var factory  = Metrics.WithCustomRegistry(registry);

            var gauge = factory.CreateGauge("gauge", "", new GaugeConfiguration
            {
                LabelNames = new[] { "foo" }
            }).WithLabels("bar");
            var counter = factory.CreateCounter("counter", "", new CounterConfiguration
            {
                LabelNames = new[] { "foo" }
            }).WithLabels("bar");
            var summary = factory.CreateSummary("summary", "", new SummaryConfiguration
            {
                LabelNames = new[] { "foo" }
            }).WithLabels("bar");
            var histogram = factory.CreateHistogram("histogram", "", new HistogramConfiguration
            {
                LabelNames = new[] { "foo" }
            }).WithLabels("bar");

            // Without touching any metrics, there should be output for all because default config publishes immediately.
            var exported = registry.CollectAll().ToArray();

            // There is a family for each of the above, in each family we expect to see 1 metrics.
            Assert.AreEqual(4, exported.Length);

            foreach (var family in exported)
            {
                Assert.AreEqual(1, family.metric.Count, $"Family {family.type} had unexpected metric count.");
            }
        }
        private DefaultCollectorRegistry GetEmptyRegistry()
        {
            DefaultCollectorRegistry registry = DefaultCollectorRegistry.Instance;

            registry.Clear();
            Assert.IsFalse(registry.CollectAll().Any());
            return(registry);
        }
        private void TestHistogramIsCreated(string name, Action instrument)
        {
            DefaultCollectorRegistry registry = GetEmptyRegistry();

            instrument();
            var histogram = registry.CollectAll().First(x => x.name == string.Format("{0}_request_duration_seconds", name));

            Assert.IsTrue(histogram.metric.Count > 0);
        }
        private void TestCounterIsIncremented(string name, Action instrument)
        {
            DefaultCollectorRegistry registry = GetEmptyRegistry();

            instrument();
            var counter = registry.CollectAll().First(x => x.name == name);

            Assert.AreEqual(1, counter.metric.Count);
        }
        private static ICollectorRegistry CreateCollectorRegistry(IServiceProvider serviceProvider)
        {
            var circuitBreakerManager = serviceProvider.GetService <ICircuitBreakerManager>();

            var collectorRegistry = new DefaultCollectorRegistry();

            collectorRegistry.GetOrAdd(new CircuitBreakerStateCollector(circuitBreakerManager));

            return(collectorRegistry);
        }
        private void TestCurrentRequestCounterIsIncrementedAndDecremented(string name, Action <Action> instrument)
        {
            string fullName = string.Format("{0}_current_requests", name);
            DefaultCollectorRegistry registry = GetEmptyRegistry();

            instrument(() =>
            {
                Assert.AreEqual(1, registry.CollectAll().First(x => x.name == fullName).metric[0].gauge.value);
            });
            Assert.AreEqual(0, registry.CollectAll().First(x => x.name == fullName).metric[0].gauge.value);
        }
        public void OnNext_RequestObserver_With_Null_Action_Value_And_Null_Controller_Value()
        {
            // Arrange
            var observer = new AspNetCoreDiagnosticListenerObserver();

            var registry = new DefaultCollectorRegistry();
            var factory  = Metrics.WithCustomRegistry(registry);

            var listener = new DiagnosticListener("TestListener2");

            listener.Subscribe(observer);



            var context = new DefaultHttpContext();

            context.Request.Method      = "GET";
            context.Request.Path        = new PathString("/api/test2");
            context.Response.StatusCode = 200;

            var httpConnectionFeature = new HttpConnectionFeature
            {
                ConnectionId = "12345"
            };

            context.Features.Set <IHttpConnectionFeature>(httpConnectionFeature);

            var routeData = new RouteData();

            routeData.Values.Add("controller", null);
            routeData.Values.Add("action", null);

            // Act
            var activity = new Activity("Microsoft.AspNetCore.Hosting.HttpRequestIn");

            listener.StartActivity(activity, new { HttpContext = context });
            listener.Write("Microsoft.AspNetCore.Mvc.AfterAction", new { httpContext = context, routeData });
            listener.StopActivity(activity, new { HttpContext = context });


            // Assert
            var requestCounter = (Counter)observer.GetType().GetField("_requestCounter",
                                                                      BindingFlags.Instance | BindingFlags.NonPublic).GetValue(observer);
            var requestSummary = (Summary)observer.GetType().GetField("_requestSummary",
                                                                      BindingFlags.Instance | BindingFlags.NonPublic).GetValue(observer);

            var counterMetrics = requestCounter.Collect();
            var summaryMetrics = requestSummary.Collect();



            Assert.IsTrue(counterMetrics.First().metric.Any(p => p.label[1].value == "/api/test2"));
            Assert.IsNotNull(summaryMetrics.First().metric[0].summary);
        }
Exemplo n.º 11
0
        public void custom_registry()
        {
            var myRegistry = new DefaultCollectorRegistry();
            var counter1   = Metrics.WithCustomRegistry(myRegistry).CreateCounter("counter1", "help1"); //registered on a custom registry

            var counter2 = Metrics.CreateCounter("counter1", "help1");                                  //created on different registry - same name is hence permitted

            counter1.Inc(3);
            counter2.Inc(4);

            Assert.Equal(3, myRegistry.CollectAll().ToArray()[0].metric[0].counter.value);                        //counter1 == 3
            Assert.Equal(4, DefaultCollectorRegistry.Instance.CollectAll().ToArray()[0].metric[0].counter.value); //counter2 == 4
        }
        public void TestRequestDurationRecordsSuccessViaLabel()
        {
            string metricName                 = "test";
            string durationMetricName         = string.Format("{0}_request_duration_seconds", metricName);
            DefaultCollectorRegistry registry = GetEmptyRegistry();

            Metrics.Instrument(metricName, () => { });

            var family = registry.CollectAll().First(x => x.name == durationMetricName);
            var metric = family.metric[1];
            var label  = metric.label.Find(l => l.name == "success");

            Assert.IsNotNull(label, "success label not found");
            Assert.AreEqual("1", label.value);
        }
        public void TestResponsesTotalRecordsSuccessViaLabel()
        {
            string metricName = "test";

            Metrics.Instrument(metricName, () => { });

            DefaultCollectorRegistry registry = GetEmptyRegistry();
            string totalMetricName            = string.Format("{0}_responses_total", metricName);

            Metrics.Instrument(metricName, () => { });

            var family = registry.CollectAll().First(x => x.name == totalMetricName);
            var metric = family.metric[0];
            var label  = metric.label.Find(l => l.name == "success");

            Assert.IsNotNull(label, "success label not found");
            Assert.AreEqual("1", label.value);
        }
        public void StartCollecting_Allows_Multiple_Collectors_For_Non_Default_Registries()
        {
#if PROMV2
            var registry1 = new DefaultCollectorRegistry();
            var registry2 = new DefaultCollectorRegistry();
#elif PROMV3
            var registry1 = Metrics.NewCustomRegistry();
            var registry2 = Metrics.NewCustomRegistry();
#endif

            using (DotNetRuntimeStatsBuilder.Customize().StartCollecting())
            {
                using (DotNetRuntimeStatsBuilder.Customize().StartCollecting(registry1))
                {
                    using (DotNetRuntimeStatsBuilder.Customize().StartCollecting(registry2))
                    {
                    }
                }
            }
        }
Exemplo n.º 15
0
        public void CreatingLabelledMetric_WithoutObservingAnyData_DoesNotExportUnlabelled()
        {
            var registry = new DefaultCollectorRegistry();
            var factory  = Metrics.WithCustomRegistry(registry);

            var gauge     = factory.CreateGauge("gauge", "", "labelname");
            var counter   = factory.CreateCounter("counter", "", "labelname");
            var summary   = factory.CreateSummary("summary", "", "labelname");
            var histogram = factory.CreateHistogram("histogram", "", null, "labelname");

            // Without touching any metrics, there should be no output.
            var exported = registry.CollectAll().ToArray();

            // There is a family for each of the above, in each family we expect to see 0 metrics.
            Assert.AreEqual(4, exported.Length);

            foreach (var family in exported)
            {
                Assert.AreEqual(0, family.metric.Count, $"Family {family.type} had unexpected metric count.");
            }
        }
        public void TestRequestCounterIsDecrementedOnException()
        {
            const string             name     = "request_counter_dec_on_exception";
            DefaultCollectorRegistry registry = GetEmptyRegistry();

            try
            {
                Metrics.Instrument(name, () =>
                {
                    throw new ApplicationException("Simulate exception during request.");
                });
            }
            catch (ApplicationException)
            {
                var family = registry.CollectAll().First(x => x.name == string.Format("{0}_current_requests", name));
                Assert.AreEqual(0, family.metric[0].gauge.value);
                return;
            }

            Assert.Fail("Metrics.Instrument should not swallow exceptions");
        }
        public void CreatingUnlabelledMetric_WithInitialValueSuppression_ExportsAfterValueChange()
        {
            var registry = new DefaultCollectorRegistry();
            var factory  = Metrics.WithCustomRegistry(registry);

            var gauge = factory.CreateGauge("gauge", "", new GaugeConfiguration
            {
                SuppressInitialValue = true
            });
            var counter = factory.CreateCounter("counter", "", new CounterConfiguration
            {
                SuppressInitialValue = true
            });
            var summary = factory.CreateSummary("summary", "", new SummaryConfiguration
            {
                SuppressInitialValue = true
            });
            var histogram = factory.CreateHistogram("histogram", "", new HistogramConfiguration
            {
                SuppressInitialValue = true
            });

            gauge.Set(123);
            counter.Inc();
            summary.Observe(123);
            histogram.Observe(31);

            // Without touching any metrics, there should be output for all because default config publishes immediately.
            var exported = registry.CollectAll().ToArray();

            // There is a family for each of the above, in each family we expect to see 1 metric.
            Assert.AreEqual(4, exported.Length);

            foreach (var family in exported)
            {
                Assert.AreEqual(1, family.metric.Count, $"Family {family.type} had unexpected metric count.");
            }
        }
        private async Task Assert_Expected_Stats_Are_Present_In_Registry(
#if PROMV2
            DefaultCollectorRegistry registry
Exemplo n.º 19
0
        public DefaultCollectorRegistry ReadMetrics(string resourceId)
        {
            var reg           = new DefaultCollectorRegistry();
            var metricFactory = new MetricFactory(reg);

            var    now    = DateTime.UtcNow.AddMinutes(-1);
            string prefix = "azure"; // fallback prefix

            var resourceGroupMatch = Regex.Match(resourceId, "resourceGroups/(.+)/providers");
            var resourceGroup      = resourceGroupMatch.Groups[1].Value;
            var labels             = new List <string>()
            {
                "resource_group"
            };
            var labelValues = new List <string>()
            {
                resourceGroup
            };

            if (resourceId.Contains("Microsoft.Web/certificates"))
            {
                var certificate = _azure.AppServices.AppServiceCertificates.GetById(resourceId);
//                var certificate = _azure.AppServices.AppServiceCertificates.List().SingleOrDefault(cert => cert.Id == resourceId);
//                _azure.AppServices.AppServiceCertificates.List().
                prefix = "certificate";
                metricFactory.CreateGauge(prefix + "_expires_in", "Certificate will expire in X days", labels.ToArray())
                .Labels(labelValues.ToArray()).Set((certificate.ExpirationDate - DateTime.UtcNow).TotalDays);
                metricFactory.CreateGauge(prefix + "_expired", "Certificate is expired", labels.ToArray())
                .Labels(labelValues.ToArray()).Set(((certificate.ExpirationDate - DateTime.UtcNow).TotalDays < 0) ? 1 : 0);
                metricFactory.CreateGauge(prefix + "_lifetime", "Had a lifetime of X days", labels.ToArray())
                .Labels(labelValues.ToArray()).Set((certificate.ExpirationDate - certificate.IssueDate).TotalDays);
                // certificate.Inner.
                var kvStatus = 0; // Not in keyvault
                if (!String.IsNullOrEmpty(certificate.Inner.KeyVaultId))
                {
                    if (certificate.Inner.KeyVaultSecretStatus == Microsoft.Azure.Management.AppService.Fluent.Models.KeyVaultSecretStatus.Succeeded)
                    {
                        kvStatus = 1; // Ok
                    }
                    else
                    {
                        kvStatus = 2; // ???
                    }
                }
                metricFactory.CreateGauge(prefix + "_keyvault_status", "Keyvault status", labels.ToArray())
                .Labels(labelValues.ToArray()).Set(kvStatus);
                return(reg);
            }

            var before       = now.AddMinutes(-1);
            var periodString = "startTime eq " + before.ToString("s", System.Globalization.CultureInfo.InvariantCulture) +
                               " and endTime eq " + now.ToString("s", System.Globalization.CultureInfo.InvariantCulture);

            try
            {
                var filter = "";
                if (resourceId.Contains("Microsoft.Web/sites"))
                {
                    prefix = "webapp";
                }
                else if (resourceId.Contains("Microsoft.Web/serverfarms/"))
                {
                    prefix = "appplan";
                }
                else if (resourceId.Contains("Microsoft.Sql/servers/") && resourceId.Contains("/databases/"))
                {
                    prefix = "database";
                }
                else if (resourceId.Contains("Microsoft.Compute/virtualMachines"))
                {
                    prefix = "vm";
                }
                else if (resourceId.Contains("Microsoft.Storage"))
                {
                    prefix = "storage";
                }
                else if (resourceId.Contains("ApiManagement"))
                {
                    prefix = "apim";
                }

                if (resourceId.Contains("Microsoft.Web") && false)
                {
                    filter = "$filter=(name.value eq 'AverageResponseTime'" +
                             " or name.value eq 'Requests'" +
                             " or name.value eq 'CpuTime'" +
                             " or name.value eq 'Http2xx'" +
                             " or name.value eq 'Http4xx'" +
                             " or name.value eq 'Http5xx'" +
                             " or name.value eq 'BytesReceived'" +
                             " or name.value eq 'BytesSent'" +
                             " or name.value eq 'MemoryWorkingSet'" +
                             ")" +
                             " and (aggregationType eq 'Total' or aggregationType eq 'Maximum' or aggregationType eq 'Minimum' or aggregationType eq 'Average' or aggregationType eq 'Count')" +
                             " and " + periodString +
                             " and timeGrain eq duration'PT1M'";
                }
                else   // if (resourceId.Contains("Microsoft.Sql"))
                {
                    var sqlInfoMatch = Regex.Match(resourceId, "servers/(\\w+)/databases/(\\w+)");
                    if (sqlInfoMatch.Groups[1].Success)
                    {
                        labels.Add("server");
                        labelValues.Add(sqlInfoMatch.Groups[1].Value);
                    }
                    if (sqlInfoMatch.Groups[2].Success)
                    {
                        labels.Add("database");
                        labelValues.Add(sqlInfoMatch.Groups[2].Value);
                    }
                    //var resourceGroup = resourceGroupMatch.Groups[1].Value;
                    string metricFilter;
                    if (metricDefCache.ContainsKey(resourceId))
                    {
                        metricFilter = metricDefCache[resourceId];
                        Console.WriteLine("FROM CACHE");
                    }
                    else
                    {
                        var defs = new List <String>();
                        var metricDefinitions = _monitorClient.MetricDefinitions.List(resourceId);
                        foreach (var mDef in metricDefinitions)
                        {
                            defs.Add($"name.value eq '{mDef.Name.Value}'");
                        }
                        if (defs.Count == 0)
                        {
                            Console.WriteLine("Failed to get metric defs!!!");
                            return(null);
                        }
                        metricFilter = String.Join(" or ", defs);
                        metricDefCache.Add(resourceId, metricFilter);
                    }
                    filter = "$filter=(" +
                             metricFilter +
                             ")" +
                             " and (aggregationType eq 'Total' or aggregationType eq 'Maximum' or aggregationType eq 'Minimum' or aggregationType eq 'Average' or aggregationType eq 'Count')" +
                             " and " + periodString +
                             " and timeGrain eq duration'PT1M'";
                }


                var metrics = _monitorClient.Metrics.List(resourceId, filter);

                foreach (var metric in metrics)
                {
                    var    localLabels      = new List <String>(labels);
                    var    localLabelValues = new List <String>(labelValues);
                    string metricName       = metric.Name.Value.Trim();
                    if (Regex.Match(metricName, "^Http\\d").Success)
                    {
                        metricName = "Http";
                        localLabels.Add("status_code");
                        localLabelValues.Add(metric.Name.Value.Substring(4));
                    }

                    var name = prefix + "_"
                               + Regex.Replace(metricName, "(?<=.)([A-Z])", "_$0", RegexOptions.Compiled).ToLower().Trim()
                               + "_" + metric.Unit.ToString().ToLower().Trim();
                    name = name.Replace("percent_percent", "percent"); // Fix double pct ... hackish
                    name = name.Replace("bytes_bytes", "bytes");
                    name = name.Replace(" ", "_");
                    name = name.Replace("/", "_");
                    name = name.Replace("__", "_");
                    name = name.Replace("c_p_u", "cpu");
                    Console.WriteLine("Metric: {0} ({1} {2} {3})", metric.Name.Value, metricName, String.Join(",", localLabels), String.Join(",", localLabelValues));
                    Console.WriteLine("Metric: {0}", name);
                    if (metric.Data.Any())
                    {
                        metricFactory.CreateGauge(name + "_total", "", localLabels.ToArray())
                        .Labels(localLabelValues.ToArray()).Set(metric.Data.Last().Total.GetValueOrDefault());
                        metricFactory.CreateGauge(name + "_average", "", localLabels.ToArray())
                        .Labels(localLabelValues.ToArray()).Set(metric.Data.Last().Average.GetValueOrDefault());
                        metricFactory.CreateGauge(name + "_minimum", "", localLabels.ToArray())
                        .Labels(localLabelValues.ToArray()).Set(metric.Data.Last().Minimum.GetValueOrDefault());
                        metricFactory.CreateGauge(name + "_maximum", "", localLabels.ToArray())
                        .Labels(localLabelValues.ToArray()).Set(metric.Data.Last().Maximum.GetValueOrDefault());
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Outer exception: {0}", ex.ToString());
                return(null);
            }

            return(reg);
        }