public void DefaultTags_AreSynchronizedWithFrozenWhenAdded() { var options = new MetricSourceOptions(); options.DefaultTags.Add("name", "value"); Assert.True(options.DefaultTagsFrozen.TryGetValue("name", out var value) && value == "value"); }
public void Constructor_CanOverrideDefaultTags() { var options = new MetricSourceOptions(); options.DefaultTags.Clear(); options.DefaultTags[StringTag.Name] = "default_value"; // create a metric and make sure the tags on its readings // do not have the default tag value var source = new MetricSource(options); var metric = CreateTaggedMetric(source, StringTag); UpdateMetric(metric, "value"); var readings = metric.GetReadings(DateTime.UtcNow).ToList(); Assert.NotEmpty(readings); var reading = readings[0]; Assert.Collection( reading.Tags, tag => { var transformedKey = options.TagNameTransformer(StringTag.Name); var transformedValue = options.TagValueTransformer(transformedKey, "value"); Assert.Equal(transformedKey, tag.Key); Assert.Equal(transformedValue, tag.Value); }); }
/// <summary> /// Instantiates the base class. /// </summary> protected MetricBase(string name, string unit, string description, MetricSourceOptions options, ImmutableDictionary <string, string> tags = null) { if (name == null) { throw new ArgumentNullException(nameof(name)); } if (options == null) { throw new ArgumentNullException(nameof(options)); } name = options.MetricNameTransformer(name); if (!options.MetricNameValidator(name)) { throw new ArgumentException(name + " is not a valid metric name.", nameof(name)); } var tagBuilder = options.DefaultTagsFrozen.ToBuilder(); if (tags != null) { foreach (var tag in tags) { tagBuilder[tag.Key] = tag.Value; } } Name = name; Unit = unit; Description = description; Tags = tagBuilder.ToImmutable(); }
public void GetReadings_HasDefaultTags() { var options = new MetricSourceOptions { DefaultTags = { ["host"] = Environment.MachineName } }; var source = new MetricSource(options); var metric = CreateMetric(source); UpdateMetric(metric); var readings = metric.GetReadings(DateTime.UtcNow).ToList(); Assert.NotEmpty(readings); var reading = readings[0]; Assert.Collection( reading.Tags, tag => { var transformedKey = options.TagNameTransformer("host"); var transformedValue = options.TagValueTransformer(transformedKey, Environment.MachineName); Assert.Equal(transformedKey, tag.Key); Assert.Equal(transformedValue, tag.Value); }); }
/// <summary> /// Constructs a new instance of <see cref="ProcessMetricSource" />. /// </summary> public ProcessMetricSource(MetricSourceOptions options) : base(options) { _processorTime = AddSamplingGauge("dotnet.cpu.processortime", "seconds", "Total processor time"); _virtualMemory = AddSamplingGauge("dotnet.mem.virtual", "bytes", "Virtual memory for the process"); _pagedMemory = AddSamplingGauge("dotnet.mem.paged", "bytes", "Paged memory for the process"); _threadCount = AddSamplingGauge("dotnet.cpu.threads", "threads", "Threads for the process"); }
/// <summary> /// Constructs a new instance of <see cref="AspNetMetricSource" />. /// </summary> public AspNetMetricSource(IDiagnosticsCollector diagnosticsCollector, MetricSourceOptions options) : base(options) { const string MicrosoftAspNetCoreHostingEventSourceName = "Microsoft.AspNetCore.Hosting"; diagnosticsCollector.AddSource( new EventPipeProvider( MicrosoftAspNetCoreHostingEventSourceName, EventLevel.Informational, arguments: new Dictionary <string, string>() { { "EventCounterIntervalSec", "5" } } ) ); void AddCounterCallback(string eventName, string name, string unit, string description) { var counter = AddCounter(name, unit, description); diagnosticsCollector.AddCounterCallback(MicrosoftAspNetCoreHostingEventSourceName, eventName, counter.Increment); } void AddGaugeCallback(string eventName, string name, string unit, string description) { var gauge = AddSamplingGauge(name, unit, description); diagnosticsCollector.AddGaugeCallback(MicrosoftAspNetCoreHostingEventSourceName, eventName, gauge.Record); } AddCounterCallback("requests-per-sec", "dotnet.kestrel.requests.per_sec", "requests/sec", "Requests per second"); AddGaugeCallback("total-requests", "dotnet.kestrel.requests.total", "requests", "Total requests"); AddGaugeCallback("current-requests", "dotnet.kestrel.requests.current", "requests", "Currently executing requests"); AddGaugeCallback("failed-requests", "dotnet.kestrel.requests.failed", "requests", "Failed requests"); }
public AppMetricSource(MetricSourceOptions options) : base(options) { _rng = new Random(); _requests = AddCounter("request.hits", "requests", "Number of requests to the application, split by route", new MetricTag <string>("route")); _errors = AddCounter("request.errors", "requests", "Number of errors in the application, split by route and status code", new MetricTag <string>("route"), new MetricTag <int>("status_code")); _randomNumber = AddSamplingGauge("random", "number", "A random number"); _randomNumberByType = AddSamplingGauge("random.by_type", "number", "A random number, split by an enum", new MetricTag <RandomNumberType>("type")); }
public void DefaultTags_HasTransformedHost() { var options = new MetricSourceOptions { TagValueTransformer = (_, __) => "qwertyYTREWQ" }; Assert.True(options.DefaultTags.TryGetValue("host", out var value) && value == "qwertyYTREWQ"); }
public void DefaultTags_FailedTagNameValidation() { var options = new MetricSourceOptions { TagNameValidator = _ => false }; Assert.Throws <ArgumentException>("key", () => options.DefaultTags.Add("name", "value")); }
public void DefaultTags_TagNamesAreTransformed() { var options = new MetricSourceOptions { TagNameTransformer = v => v.ToUpper() }; options.DefaultTags.Add("name", "value"); Assert.True(options.DefaultTags.ContainsKey("NAME")); }
public void DefaultTags_TagValuesAreTransformed() { var options = new MetricSourceOptions { TagValueTransformer = (n, v) => v.ToString().ToUpper() }; options.DefaultTags.Add("name", "value"); Assert.True(options.DefaultTags.TryGetValue("name", out var value) && value == "VALUE"); }
public void Constructor_FailedMetricNameValidation_Tagged() { var options = new MetricSourceOptions { MetricNameValidator = _ => false }; var source = new MetricSource(options); Assert.Throws <ArgumentException>("name", () => CreateTaggedMetric(source, StringTag)); }
public void Constructor_FailedTagValueValidation() { var options = new MetricSourceOptions { TagValueValidator = _ => false }; var source = new MetricSource(options); var metric = CreateTaggedMetric(source, StringTag); Assert.Throws <ArgumentException>("value", () => UpdateMetric(metric, "test")); }
public virtual void GetReadings_Resets() { var options = new MetricSourceOptions(); var source = new MetricSource(options); var c = CreateMetric(source); UpdateMetric(c); var readings = c.GetReadings(DateTime.UtcNow); Assert.NotEmpty(readings); readings = c.GetReadings(DateTime.UtcNow); Assert.Empty(readings); }
/// <summary> /// Constructs a new instance of <see cref="RuntimeMetricSource" />. /// </summary> public RuntimeMetricSource(IDiagnosticsCollector diagnosticsCollector, MetricSourceOptions options) : base(options) { const string SystemRuntimeEventSourceName = "System.Runtime"; diagnosticsCollector.AddSource( new EventPipeProvider( SystemRuntimeEventSourceName, EventLevel.Informational, arguments: new Dictionary <string, string>() { { "EventCounterIntervalSec", "5" } } ) ); void AddCounterCallback(string eventName, string name, string unit, string description) { var counter = AddCounter(name, unit, description); diagnosticsCollector.AddCounterCallback(SystemRuntimeEventSourceName, eventName, counter.Increment); Add(counter); } void AddGaugeCallback(string eventName, string name, string unit, string description) { var gauge = AddSamplingGauge(name, unit, description); diagnosticsCollector.AddGaugeCallback(SystemRuntimeEventSourceName, eventName, gauge.Record); Add(gauge); } AddGaugeCallback("cpu-usage", "dotnet.cpu.usage", "percent", "% CPU usage"); AddGaugeCallback("working-set", "dotnet.mem.working_set", "bytes", "Working set for the process"); // GC AddCounterCallback("gen-0-gc-count", "dotnet.mem.collections.gen0", "collections", "Number of gen-0 collections"); AddCounterCallback("gen-1-gc-count", "dotnet.mem.collections.gen1", "collections", "Number of gen-1 collections"); AddCounterCallback("gen-2-gc-count", "dotnet.mem.collections.gen2", "collections", "Number of gen-2 collections"); AddGaugeCallback("gen-0-size", "dotnet.mem.size.gen0", "bytes", "Total number of bytes in gen-0"); AddGaugeCallback("gen-1-size", "dotnet.mem.size.gen1", "bytes", "Total number of bytes in gen-1"); AddGaugeCallback("gen-2-size", "dotnet.mem.size.gen2", "bytes", "Total number of bytes in gen-2"); AddGaugeCallback("gc-heap-size", "dotnet.mem.size.heap", "bytes", "Total number of bytes across all heaps"); AddGaugeCallback("loh-size", "dotnet.mem.size.loh", "bytes", "Total number of bytes in the LOH"); AddCounterCallback("alloc-rate", "dotnet.mem.allocation_rate", "bytes/sec", "Allocation Rate (Bytes / sec)"); // thread pool AddGaugeCallback("threadpool-thread-count", "dotnet.threadpool.count", "threads", "Number of threads in the threadpool"); AddGaugeCallback("threadpool-queue-length", "dotnet.threadpool.queue_length", "workitems", "Number of work items queued to the threadpool"); AddGaugeCallback("active-timer-count", "dotnet.timers.count", "timers", "Number of active timers"); }
public virtual void GetMetadata_ReturnsData() { var options = new MetricSourceOptions(); var source = new MetricSource(options); var metric = CreateMetric(source); var metadata = metric.GetMetadata(); Assert.Collection( metadata, metadata => { Assert.Equal(metric.Name, metadata.Metric); Assert.Equal(MetadataNames.Rate, metadata.Name); switch (metric.MetricType) { case MetricType.Counter: case MetricType.CumulativeCounter: Assert.Equal("counter", metadata.Value); break; case MetricType.Gauge: Assert.Equal("gauge", metadata.Value); break; } }, metadata => { Assert.Equal(metric.Name, metadata.Metric); Assert.Equal(MetadataNames.Description, metadata.Name); Assert.Equal(metric.Description, metadata.Value); }, metadata => { Assert.Equal(metric.Name, metadata.Metric); Assert.Equal(MetadataNames.Unit, metadata.Name); Assert.Equal(metric.Unit, metadata.Value); } ); }
/// <summary> /// Used by derived classes to pass the name, description and unit for a tag. /// </summary> protected TaggedMetricFactory(string name, string description, string unit, MetricSourceOptions options) { if (name == null) { throw new ArgumentNullException(nameof(name)); } if (options == null) { throw new ArgumentNullException(nameof(options)); } name = options.MetricNameTransformer(name); if (!options.MetricNameValidator(name)) { throw new ArgumentException(name + " is not a valid metric name.", nameof(name)); } Name = name; Description = description; Unit = unit; Options = options; }
/// <summary> /// Initializes a new snapshot counter. The counter will call <paramref name="getCountFunc"/> at each reporting interval in order to get the current /// value. /// </summary> internal SnapshotCounter(Func <long?> getCountFunc, string name, string unit, string description, MetricSourceOptions options, ImmutableDictionary <string, string> tags = null) : base(name, unit, description, options, tags) { _getCountFunc = getCountFunc ?? throw new ArgumentNullException("getCountFunc"); }
/// <summary> /// Instantiates a new cumulative counter. /// </summary> public CumulativeCounter(string name, string unit, string description, MetricSourceOptions options, ImmutableDictionary <string, string> tags = null) : base(name, unit, description, options, tags) { }
public TagDictionary(MetricSourceOptions options) { _options = options; }
/// <summary> /// Constructs a new instance of <see cref="GarbageCollectorMetricSource" />. /// </summary> public GarbageCollectorMetricSource(MetricSourceOptions options) : base(options) { _gen0 = AddSamplingGauge("dotnet.mem.collections.gen0", "collections", "Number of gen-0 collections"); _gen1 = AddSamplingGauge("dotnet.mem.collections.gen1", "collections", "Number of gen-1 collections"); _gen2 = AddSamplingGauge("dotnet.mem.collections.gen2", "collections", "Number of gen-2 collections"); }
/// <summary> /// Instantiates a new event gauge. /// </summary> internal EventGauge(string name, string unit, string description, MetricSourceOptions options, ImmutableDictionary <string, string> tags = null) : base(name, unit, description, options, tags) { }
/// <summary> /// Instantiates a new <see cref="AggregateGauge"/>. /// </summary> public AggregateGauge(IEnumerable <GaugeAggregator> aggregators, string name, string unit, string description, MetricSourceOptions options, ImmutableDictionary <string, string> tags = null) : base(name, unit, description, options, tags) { var strategy = new GaugeAggregatorStrategy(aggregators.ToImmutableArray()); // denormalize these for one less level of indirection _percentiles = strategy.Percentiles; _suffixes = strategy.Suffixes; _trackMean = strategy.TrackMean; _specialCaseMin = strategy.SpecialCaseMin; _specialCaseMax = strategy.SpecialCaseMax; _specialCaseLast = strategy.SpecialCaseLast; _reportCount = strategy.ReportCount; // setup heap, if required. if (strategy.UseList) { _list = new List <double>(); } _snapshot = new double[_suffixes.Length]; _snapshotReportingMode = SnapshotReportingMode.None; }