diff --git a/src/Generators/Microsoft.Gen.Metrics/Emitter.cs b/src/Generators/Microsoft.Gen.Metrics/Emitter.cs index d6b0decec0d..0e6e7da0091 100644 --- a/src/Generators/Microsoft.Gen.Metrics/Emitter.cs +++ b/src/Generators/Microsoft.Gen.Metrics/Emitter.cs @@ -297,7 +297,7 @@ private void GenTagList(MetricMethod metricMethod) foreach (var tagName in metricMethod.TagKeys) { var paramName = GetSanitizedParamName(tagName); - OutLn($"new global::System.Collections.Generic.KeyValuePair(\"{paramName}\", {paramName}),"); + OutLn($"new global::System.Collections.Generic.KeyValuePair(\"{tagName}\", {paramName}),"); } } else diff --git a/src/Libraries/Microsoft.AspNetCore.HeaderParsing/Metric.cs b/src/Libraries/Microsoft.AspNetCore.HeaderParsing/Metric.cs index 944fa08970f..5237c8a528f 100644 --- a/src/Libraries/Microsoft.AspNetCore.HeaderParsing/Metric.cs +++ b/src/Libraries/Microsoft.AspNetCore.HeaderParsing/Metric.cs @@ -8,9 +8,9 @@ namespace Microsoft.AspNetCore.HeaderParsing; internal static partial class Metric { - [Counter("HeaderName", "Kind", Name = @"HeaderParsing.ParsingErrors")] + [Counter("aspnetcore.header_parsing.header.name", "error.type", Name = "aspnetcore.header_parsing.parse_errors")] public static partial ParsingErrorCounter CreateParsingErrorCounter(Meter meter); - [Counter("HeaderName", "Type", Name = @"HeaderParsing.CacheAccess")] + [Counter("aspnetcore.header_parsing.header.name", "aspnetcore.header_parsing.cache_access.type", Name = "aspnetcore.header_parsing.cache_accesses")] public static partial CacheAccessCounter CreateCacheAccessCounter(Meter meter); } diff --git a/src/Libraries/Microsoft.Extensions.Diagnostics.HealthChecks.Common/Metric.cs b/src/Libraries/Microsoft.Extensions.Diagnostics.HealthChecks.Common/Metric.cs index e366c714bbe..b59531bf859 100644 --- a/src/Libraries/Microsoft.Extensions.Diagnostics.HealthChecks.Common/Metric.cs +++ b/src/Libraries/Microsoft.Extensions.Diagnostics.HealthChecks.Common/Metric.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics.Metrics; -using System.Globalization; using Microsoft.Extensions.Diagnostics.Metrics; using Microsoft.Extensions.EnumStrings; @@ -12,14 +11,14 @@ namespace Microsoft.Extensions.Diagnostics.HealthChecks; internal static partial class Metric { - [Counter("healthy", "status", Name = @"R9\\HealthCheck\\Report")] + [Counter("dotnet.health_check.status", Name = "dotnet.health_check.reports")] public static partial HealthCheckReportCounter CreateHealthCheckReportCounter(Meter meter); - [Counter("name", "status", Name = @"R9\\HealthCheck\\UnhealthyHealthCheck")] + [Counter("dotnet.health_check.name", "dotnet.health_check.status", Name = "dotnet.health_check.unhealthy_checks")] public static partial UnhealthyHealthCheckCounter CreateUnhealthyHealthCheckCounter(Meter meter); - public static void RecordMetric(this HealthCheckReportCounter counterMetric, bool isHealthy, HealthStatus status) - => counterMetric.Add(1, isHealthy.ToString(CultureInfo.InvariantCulture), status.ToInvariantString()); + public static void RecordMetric(this HealthCheckReportCounter counterMetric, HealthStatus status) + => counterMetric.Add(1, status.ToInvariantString()); public static void RecordMetric(this UnhealthyHealthCheckCounter counterMetric, string name, HealthStatus status) => counterMetric.Add(1, name, status.ToInvariantString()); diff --git a/src/Libraries/Microsoft.Extensions.Diagnostics.HealthChecks.Common/TelemetryHealthCheckPublisher.cs b/src/Libraries/Microsoft.Extensions.Diagnostics.HealthChecks.Common/TelemetryHealthCheckPublisher.cs index 217bef39e8f..16bbfc97c6e 100644 --- a/src/Libraries/Microsoft.Extensions.Diagnostics.HealthChecks.Common/TelemetryHealthCheckPublisher.cs +++ b/src/Libraries/Microsoft.Extensions.Diagnostics.HealthChecks.Common/TelemetryHealthCheckPublisher.cs @@ -49,8 +49,6 @@ public Task PublishAsync(HealthReport report, CancellationToken cancellationToke { Log.Healthy(_logger, report.Status); } - - _metrics.HealthCheckReportCounter.RecordMetric(true, report.Status); } else { @@ -79,10 +77,10 @@ public Task PublishAsync(HealthReport report, CancellationToken cancellationToke Log.Unhealthy(_logger, report.Status, stringBuilder); PoolFactory.SharedStringBuilderPool.Return(stringBuilder); - - _metrics.HealthCheckReportCounter.RecordMetric(false, report.Status); } + _metrics.HealthCheckReportCounter.RecordMetric(report.Status); + return Task.CompletedTask; } } diff --git a/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/Linux/LinuxUtilizationProvider.cs b/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/Linux/LinuxUtilizationProvider.cs index 679d5a1c3bf..b2c2f259216 100644 --- a/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/Linux/LinuxUtilizationProvider.cs +++ b/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/Linux/LinuxUtilizationProvider.cs @@ -9,7 +9,9 @@ namespace Microsoft.Extensions.Diagnostics.ResourceMonitoring.Linux; internal sealed class LinuxUtilizationProvider : ISnapshotProvider { - private const float Hundred = 100.0f; + private const double One = 1.0; + private const long Hundred = 100L; + private readonly object _cpuLocker = new(); private readonly object _memoryLocker = new(); private readonly LinuxUtilizationParser _parser; @@ -48,7 +50,7 @@ public LinuxUtilizationProvider(IOptions options, Lin var hostCpus = _parser.GetHostCpuCount(); var availableCpus = _parser.GetCgroupLimitedCpus(); - _scale = hostCpus * Hundred / availableCpus; + _scale = hostCpus / availableCpus; _scaleForTrackerApi = hostCpus / availableCpus; #pragma warning disable CA2000 // Dispose objects before losing scope @@ -58,13 +60,13 @@ public LinuxUtilizationProvider(IOptions options, Lin var meter = meterFactory.Create("Microsoft.Extensions.Diagnostics.ResourceMonitoring"); #pragma warning restore CA2000 // Dispose objects before losing scope - _ = meter.CreateObservableGauge(name: ResourceUtilizationCounters.CpuConsumptionPercentage, observeValue: CpuPercentage); - _ = meter.CreateObservableGauge(name: ResourceUtilizationCounters.MemoryConsumptionPercentage, observeValue: MemoryPercentage); + _ = meter.CreateObservableGauge(name: ResourceUtilizationInstruments.CpuUtilization, observeValue: CpuUtilization, unit: "1"); + _ = meter.CreateObservableGauge(name: ResourceUtilizationInstruments.MemoryUtilization, observeValue: MemoryUtilization, unit: "1"); Resources = new SystemResources(1, hostCpus, _totalMemoryInBytes, hostMemory); } - public double CpuPercentage() + public double CpuUtilization() { var now = _timeProvider.GetUtcNow(); bool needUpdate = false; @@ -91,7 +93,7 @@ public double CpuPercentage() if (deltaHost > 0 && deltaCgroup > 0) { - var percentage = Math.Min(Hundred, deltaCgroup / deltaHost * _scale); + var percentage = Math.Min(One, deltaCgroup / deltaHost * _scale); _cpuPercentage = percentage; _refreshAfterCpu = now.Add(_cpuRefreshInterval); @@ -105,7 +107,7 @@ public double CpuPercentage() return _cpuPercentage; } - public double MemoryPercentage() + public double MemoryUtilization() { var now = _timeProvider.GetUtcNow(); bool needUpdate = false; @@ -126,7 +128,7 @@ public double MemoryPercentage() { if (now >= _refreshAfterMemory) { - var memoryPercentage = Math.Min(Hundred, (double)memoryUsed / _totalMemoryInBytes * Hundred); + var memoryPercentage = Math.Min(One, (double)memoryUsed / _totalMemoryInBytes); _memoryPercentage = memoryPercentage; _refreshAfterMemory = now.Add(_memoryRefreshInterval); @@ -149,9 +151,9 @@ public Snapshot GetSnapshot() var memoryUsed = _parser.GetMemoryUsageInBytes(); return new Snapshot( - totalTimeSinceStart: TimeSpan.FromTicks(hostTime / (long)Hundred), + totalTimeSinceStart: TimeSpan.FromTicks(hostTime / Hundred), kernelTimeSinceStart: TimeSpan.Zero, - userTimeSinceStart: TimeSpan.FromTicks((long)(cgroupTime / (long)Hundred * _scaleForTrackerApi)), + userTimeSinceStart: TimeSpan.FromTicks((long)(cgroupTime / Hundred * _scaleForTrackerApi)), memoryUsageInBytes: memoryUsed); } } diff --git a/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/Microsoft.Extensions.Diagnostics.ResourceMonitoring.csproj b/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/Microsoft.Extensions.Diagnostics.ResourceMonitoring.csproj index 333067cd272..5801f144a17 100644 --- a/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/Microsoft.Extensions.Diagnostics.ResourceMonitoring.csproj +++ b/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/Microsoft.Extensions.Diagnostics.ResourceMonitoring.csproj @@ -42,8 +42,6 @@ - - diff --git a/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/Microsoft.Extensions.Diagnostics.ResourceMonitoring.json b/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/Microsoft.Extensions.Diagnostics.ResourceMonitoring.json index 3bb53fbb05d..f20b3d49685 100644 --- a/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/Microsoft.Extensions.Diagnostics.ResourceMonitoring.json +++ b/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/Microsoft.Extensions.Diagnostics.ResourceMonitoring.json @@ -133,20 +133,6 @@ } ] }, - { - "Type": "static class Microsoft.Extensions.Diagnostics.ResourceMonitoring.ResourceUtilizationCounters", - "Stage": "Stable", - "Properties": [ - { - "Member": "static string Microsoft.Extensions.Diagnostics.ResourceMonitoring.ResourceUtilizationCounters.CpuConsumptionPercentage { get; }", - "Stage": "Stable" - }, - { - "Member": "static string Microsoft.Extensions.Diagnostics.ResourceMonitoring.ResourceUtilizationCounters.MemoryConsumptionPercentage { get; }", - "Stage": "Stable" - } - ] - }, { "Type": "readonly struct Microsoft.Extensions.Diagnostics.ResourceMonitoring.SystemResources", "Stage": "Stable", diff --git a/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/ResourceMonitoringOptions.Linux.cs b/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/ResourceMonitoringOptions.Linux.cs index 5ec54ef4d57..cb6038826f9 100644 --- a/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/ResourceMonitoringOptions.Linux.cs +++ b/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/ResourceMonitoringOptions.Linux.cs @@ -13,7 +13,7 @@ public partial class ResourceMonitoringOptions internal static readonly TimeSpan DefaultRefreshInterval = TimeSpan.FromSeconds(5); /// - /// Gets or sets the default interval used for refreshing values reported by . + /// Gets or sets the default interval used for refreshing values reported by "process.cpu.utilization" metrics. /// /// /// The default value is 5 seconds. @@ -26,7 +26,7 @@ public partial class ResourceMonitoringOptions public TimeSpan CpuConsumptionRefreshInterval { get; set; } = DefaultRefreshInterval; /// - /// Gets or sets the default interval used for refreshing values reported by . + /// Gets or sets the default interval used for refreshing values reported by "dotnet.process.memory.virtual.utilization" metrics. /// /// /// The default value is 5 seconds. diff --git a/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/ResourceUtilizationCounters.cs b/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/ResourceUtilizationInstruments.cs similarity index 68% rename from src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/ResourceUtilizationCounters.cs rename to src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/ResourceUtilizationInstruments.cs index f873bef44d6..da38092353b 100644 --- a/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/ResourceUtilizationCounters.cs +++ b/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/ResourceUtilizationInstruments.cs @@ -7,24 +7,24 @@ namespace Microsoft.Extensions.Diagnostics.ResourceMonitoring; /// Represents the names of instruments published by this package. /// /// -/// These counters are currently only published on Linux. +/// These metrics are currently only published on Linux. /// /// -public static class ResourceUtilizationCounters +internal static class ResourceUtilizationInstruments { /// - /// Gets the CPU consumption of the running application in percentages. + /// Gets the CPU consumption of the running application in range [0, 1]. /// /// /// The type of an instrument is . /// - public static string CpuConsumptionPercentage => "cpu_consumption_percentage"; + public const string CpuUtilization = "process.cpu.utilization"; /// - /// Gets the memory consumption of the running application in percentages. + /// Gets the memory consumption of the running application in range [0, 1]. /// /// /// The type of an instrument is . /// - public static string MemoryConsumptionPercentage => "memory_consumption_percentage"; + public const string MemoryUtilization = "dotnet.process.memory.virtual.utilization"; } diff --git a/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/Windows/WindowsCounters.cs b/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/Windows/WindowsCounters.cs index 5f87b9dfc19..fed46d64795 100644 --- a/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/Windows/WindowsCounters.cs +++ b/src/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring/Windows/WindowsCounters.cs @@ -1,6 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Collections.Generic; +using System.Diagnostics; using System.Diagnostics.Metrics; using Microsoft.Extensions.Diagnostics.ResourceMonitoring.Windows.Network; @@ -8,8 +10,12 @@ namespace Microsoft.Extensions.Diagnostics.ResourceMonitoring.Windows; internal sealed class WindowsCounters { + private readonly TcpTableInfo _tcpTableInfo; + public WindowsCounters(IMeterFactory meterFactory, TcpTableInfo tcpTableInfo) { + _tcpTableInfo = tcpTableInfo; + #pragma warning disable CA2000 // Dispose objects before losing scope // We don't dispose the meter because IMeterFactory handles that // An issue on analyzer side: https://github.com/dotnet/roslyn-analyzers/issues/6912 @@ -17,196 +23,63 @@ public WindowsCounters(IMeterFactory meterFactory, TcpTableInfo tcpTableInfo) var meter = meterFactory.Create("Microsoft.Extensions.Diagnostics.ResourceMonitoring"); #pragma warning restore CA2000 // Dispose objects before losing scope - _ = meter.CreateObservableGauge( - "ipv4_tcp_connection_closed_count", - () => - { - var snapshot = tcpTableInfo.GetIPv4CachingSnapshot(); - return snapshot.ClosedCount; - }); - - _ = meter.CreateObservableGauge( - "ipv4_tcp_connection_listen_count", - () => - { - var snapshot = tcpTableInfo.GetIPv4CachingSnapshot(); - return snapshot.ListenCount; - }); - - _ = meter.CreateObservableGauge( - "ipv4_tcp_connection_syn_sent_count", - () => - { - var snapshot = tcpTableInfo.GetIPv4CachingSnapshot(); - return snapshot.SynSentCount; - }); - - _ = meter.CreateObservableGauge( - "ipv4_tcp_connection_syn_received_count", - () => - { - var snapshot = tcpTableInfo.GetIPv4CachingSnapshot(); - return snapshot.SynRcvdCount; - }); - - _ = meter.CreateObservableGauge( - "ipv4_tcp_connection_established_count", - () => - { - var snapshot = tcpTableInfo.GetIPv4CachingSnapshot(); - return snapshot.EstabCount; - }); - - _ = meter.CreateObservableGauge( - "ipv4_tcp_connection_fin_wait_1_count", - () => - { - var snapshot = tcpTableInfo.GetIPv4CachingSnapshot(); - return snapshot.FinWait1Count; - }); - - _ = meter.CreateObservableGauge( - "ipv4_tcp_connection_fin_wait_2_count", - () => - { - var snapshot = tcpTableInfo.GetIPv4CachingSnapshot(); - return snapshot.FinWait2Count; - }); - - _ = meter.CreateObservableGauge( - "ipv4_tcp_connection_close_wait_count", - () => - { - var snapshot = tcpTableInfo.GetIPv4CachingSnapshot(); - return snapshot.CloseWaitCount; - }); - - _ = meter.CreateObservableGauge( - "ipv4_tcp_connection_closing_count", - () => - { - var snapshot = tcpTableInfo.GetIPv4CachingSnapshot(); - return snapshot.ClosingCount; - }); - - _ = meter.CreateObservableGauge( - "ipv4_tcp_connection_last_ack_count", - () => - { - var snapshot = tcpTableInfo.GetIPv4CachingSnapshot(); - return snapshot.LastAckCount; - }); - - _ = meter.CreateObservableGauge( - "ipv4_tcp_connection_time_wait_count", - () => - { - var snapshot = tcpTableInfo.GetIPv4CachingSnapshot(); - return snapshot.TimeWaitCount; - }); - - _ = meter.CreateObservableGauge( - "ipv4_tcp_connection_delete_tcb_count", - () => - { - var snapshot = tcpTableInfo.GetIPv4CachingSnapshot(); - return snapshot.DeleteTcbCount; - }); - - _ = meter.CreateObservableGauge( - "ipv6_tcp_connection_closed_count", - () => - { - var snapshot = tcpTableInfo.GetIPv6CachingSnapshot(); - return snapshot.ClosedCount; - }); - - _ = meter.CreateObservableGauge( - "ipv6_tcp_connection_listen_count", - () => - { - var snapshot = tcpTableInfo.GetIPv6CachingSnapshot(); - return snapshot.ListenCount; - }); - - _ = meter.CreateObservableGauge( - "ipv6_tcp_connection_syn_sent_count", - () => - { - var snapshot = tcpTableInfo.GetIPv6CachingSnapshot(); - return snapshot.SynSentCount; - }); - - _ = meter.CreateObservableGauge( - "ipv6_tcp_connection_syn_received_count", - () => - { - var snapshot = tcpTableInfo.GetIPv6CachingSnapshot(); - return snapshot.SynRcvdCount; - }); - - _ = meter.CreateObservableGauge( - "ipv6_tcp_connection_established_count", - () => - { - var snapshot = tcpTableInfo.GetIPv6CachingSnapshot(); - return snapshot.EstabCount; - }); - - _ = meter.CreateObservableGauge( - "ipv6_tcp_connection_fin_wait_1_count", - () => - { - var snapshot = tcpTableInfo.GetIPv6CachingSnapshot(); - return snapshot.FinWait1Count; - }); - - _ = meter.CreateObservableGauge( - "ipv6_tcp_connection_fin_wait_2_count", - () => - { - var snapshot = tcpTableInfo.GetIPv6CachingSnapshot(); - return snapshot.FinWait2Count; - }); - - _ = meter.CreateObservableGauge( - "ipv6_tcp_connection_close_wait_count", - () => - { - var snapshot = tcpTableInfo.GetIPv6CachingSnapshot(); - return snapshot.CloseWaitCount; - }); - - _ = meter.CreateObservableGauge( - "ipv6_tcp_connection_closing_count", - () => - { - var snapshot = tcpTableInfo.GetIPv6CachingSnapshot(); - return snapshot.ClosingCount; - }); - - _ = meter.CreateObservableGauge( - "ipv6_tcp_connection_last_ack_count", - () => - { - var snapshot = tcpTableInfo.GetIPv6CachingSnapshot(); - return snapshot.LastAckCount; - }); - - _ = meter.CreateObservableGauge( - "ipv6_tcp_connection_time_wait_count", - () => - { - var snapshot = tcpTableInfo.GetIPv6CachingSnapshot(); - return snapshot.TimeWaitCount; - }); + var tcpTag = new KeyValuePair("network.transport", "tcp"); + var commonTags = new TagList + { + tcpTag + }; + + // The metric is aligned with + // https://github.com/open-telemetry/semantic-conventions/blob/main/docs/system/system-metrics.md#metric-systemnetworkconnections + + _ = meter.CreateObservableUpDownCounter( + "system.network.connections", + GetMeasurements, + unit: "{connection}", + description: null, + tags: commonTags); + } - _ = meter.CreateObservableGauge( - "ipv6_tcp_connection_delete_tcb_count", - () => - { - var snapshot = tcpTableInfo.GetIPv6CachingSnapshot(); - return snapshot.DeleteTcbCount; - }); + private IEnumerable> GetMeasurements() + { + const string NetworkStateKey = "system.network.state"; + + // These are covered in https://github.com/open-telemetry/semantic-conventions/blob/main/docs/rpc/rpc-metrics.md#attributes: + var tcpVersionFourTag = new KeyValuePair("network.type", "ipv4"); + var tcpVersionSixTag = new KeyValuePair("network.type", "ipv6"); + + var measurements = new List>(24); + + // IPv4: + var snapshotV4 = _tcpTableInfo.GetIPv4CachingSnapshot(); + measurements.Add(new Measurement(snapshotV4.ClosedCount, new TagList { tcpVersionFourTag, new(NetworkStateKey, "closed") })); + measurements.Add(new Measurement(snapshotV4.ListenCount, new TagList { tcpVersionFourTag, new(NetworkStateKey, "listen") })); + measurements.Add(new Measurement(snapshotV4.SynSentCount, new TagList { tcpVersionFourTag, new(NetworkStateKey, "syn_sent") })); + measurements.Add(new Measurement(snapshotV4.SynRcvdCount, new TagList { tcpVersionFourTag, new(NetworkStateKey, "syn_recv") })); + measurements.Add(new Measurement(snapshotV4.EstabCount, new TagList { tcpVersionFourTag, new(NetworkStateKey, "established") })); + measurements.Add(new Measurement(snapshotV4.FinWait1Count, new TagList { tcpVersionFourTag, new(NetworkStateKey, "fin_wait_1") })); + measurements.Add(new Measurement(snapshotV4.FinWait2Count, new TagList { tcpVersionFourTag, new(NetworkStateKey, "fin_wait_2") })); + measurements.Add(new Measurement(snapshotV4.CloseWaitCount, new TagList { tcpVersionFourTag, new(NetworkStateKey, "close_wait") })); + measurements.Add(new Measurement(snapshotV4.ClosingCount, new TagList { tcpVersionFourTag, new(NetworkStateKey, "closing") })); + measurements.Add(new Measurement(snapshotV4.LastAckCount, new TagList { tcpVersionFourTag, new(NetworkStateKey, "last_ack") })); + measurements.Add(new Measurement(snapshotV4.TimeWaitCount, new TagList { tcpVersionFourTag, new(NetworkStateKey, "time_wait") })); + measurements.Add(new Measurement(snapshotV4.DeleteTcbCount, new TagList { tcpVersionFourTag, new(NetworkStateKey, "delete") })); + + // IPv6: + var snapshotV6 = _tcpTableInfo.GetIPv6CachingSnapshot(); + measurements.Add(new Measurement(snapshotV6.ClosedCount, new TagList { tcpVersionSixTag, new(NetworkStateKey, "closed") })); + measurements.Add(new Measurement(snapshotV6.ListenCount, new TagList { tcpVersionSixTag, new(NetworkStateKey, "listen") })); + measurements.Add(new Measurement(snapshotV6.SynSentCount, new TagList { tcpVersionSixTag, new(NetworkStateKey, "syn_sent") })); + measurements.Add(new Measurement(snapshotV6.SynRcvdCount, new TagList { tcpVersionSixTag, new(NetworkStateKey, "syn_recv") })); + measurements.Add(new Measurement(snapshotV6.EstabCount, new TagList { tcpVersionSixTag, new(NetworkStateKey, "established") })); + measurements.Add(new Measurement(snapshotV6.FinWait1Count, new TagList { tcpVersionSixTag, new(NetworkStateKey, "fin_wait_1") })); + measurements.Add(new Measurement(snapshotV6.FinWait2Count, new TagList { tcpVersionSixTag, new(NetworkStateKey, "fin_wait_2") })); + measurements.Add(new Measurement(snapshotV6.CloseWaitCount, new TagList { tcpVersionSixTag, new(NetworkStateKey, "close_wait") })); + measurements.Add(new Measurement(snapshotV6.ClosingCount, new TagList { tcpVersionSixTag, new(NetworkStateKey, "closing") })); + measurements.Add(new Measurement(snapshotV6.LastAckCount, new TagList { tcpVersionSixTag, new(NetworkStateKey, "last_ack") })); + measurements.Add(new Measurement(snapshotV6.TimeWaitCount, new TagList { tcpVersionSixTag, new(NetworkStateKey, "time_wait") })); + measurements.Add(new Measurement(snapshotV6.DeleteTcbCount, new TagList { tcpVersionSixTag, new(NetworkStateKey, "delete") })); + + return measurements; } } diff --git a/src/Libraries/Microsoft.Extensions.Resilience/Resilience/Internal/ResilienceMetricsEnricher.cs b/src/Libraries/Microsoft.Extensions.Resilience/Resilience/Internal/ResilienceMetricsEnricher.cs index c0621654715..ee5d9990322 100644 --- a/src/Libraries/Microsoft.Extensions.Resilience/Resilience/Internal/ResilienceMetricsEnricher.cs +++ b/src/Libraries/Microsoft.Extensions.Resilience/Resilience/Internal/ResilienceMetricsEnricher.cs @@ -34,16 +34,12 @@ public override void Enrich(in EnrichmentContext if (_exceptionSummarizer is not null && outcome?.Exception is Exception e) { - context.Tags.Add(new(ResilienceTagNames.FailureSource, e.Source)); - context.Tags.Add(new(ResilienceTagNames.FailureReason, e.GetType().Name)); - context.Tags.Add(new(ResilienceTagNames.FailureSummary, _exceptionSummarizer.Summarize(e).ToString())); + context.Tags.Add(new(ResilienceTagNames.ErrorType, _exceptionSummarizer.Summarize(e).ToString())); } else if (outcome is not null && outcome.Value.Result is object result && _faultFactories.TryGetValue(result.GetType(), out var factory)) { var failureContext = factory(result); - context.Tags.Add(new(ResilienceTagNames.FailureSource, failureContext.FailureSource)); - context.Tags.Add(new(ResilienceTagNames.FailureReason, failureContext.FailureReason)); - context.Tags.Add(new(ResilienceTagNames.FailureSummary, failureContext.AdditionalInformation)); + context.Tags.Add(new(ResilienceTagNames.ErrorType, failureContext.AdditionalInformation)); } if ((context.TelemetryEvent.Context.GetRequestMetadata() ?? _outgoingRequestContext?.RequestMetadata) is RequestMetadata requestMetadata) diff --git a/src/Libraries/Microsoft.Extensions.Resilience/Resilience/Internal/ResilienceTagNames.cs b/src/Libraries/Microsoft.Extensions.Resilience/Resilience/Internal/ResilienceTagNames.cs index 158f77e362e..587a044dae9 100644 --- a/src/Libraries/Microsoft.Extensions.Resilience/Resilience/Internal/ResilienceTagNames.cs +++ b/src/Libraries/Microsoft.Extensions.Resilience/Resilience/Internal/ResilienceTagNames.cs @@ -5,13 +5,9 @@ namespace Microsoft.Extensions.Resilience.Internal; internal static class ResilienceTagNames { - public const string FailureSource = "failure-source"; + public const string ErrorType = "error.type"; - public const string FailureReason = "failure-reason"; + public const string DependencyName = "request.dependency.name"; - public const string FailureSummary = "failure-summary"; - - public const string DependencyName = "dep-name"; - - public const string RequestName = "req-name"; + public const string RequestName = "request.name"; } diff --git a/test/Libraries/Microsoft.AspNetCore.HeaderParsing.Tests/HeaderParsingFeatureTests.cs b/test/Libraries/Microsoft.AspNetCore.HeaderParsing.Tests/HeaderParsingFeatureTests.cs index b8d53275e70..ce23cb2dfb0 100644 --- a/test/Libraries/Microsoft.AspNetCore.HeaderParsing.Tests/HeaderParsingFeatureTests.cs +++ b/test/Libraries/Microsoft.AspNetCore.HeaderParsing.Tests/HeaderParsingFeatureTests.cs @@ -135,7 +135,7 @@ public void TryParse_returns_false_on_error() { using var meter = new Meter(nameof(TryParse_returns_false_on_error)); var metrics = GetMockedMetrics(meter); - using var metricCollector = new MetricCollector(meter, @"HeaderParsing.ParsingErrors"); + using var metricCollector = new MetricCollector(meter, "aspnetcore.header_parsing.parse_errors"); Context.Request.Headers["Date"] = "Not a date."; var feature = new HeaderParsingFeature(Registry, _logger, metrics) { Context = Context }; @@ -147,10 +147,11 @@ public void TryParse_returns_false_on_error() Assert.Equal("Can't parse header 'Date' due to 'Unable to parse date time offset value.'.", _logger.Collector.LatestRecord.Message); - var latest = metricCollector.LastMeasurement!; + var latest = metricCollector.LastMeasurement; + Assert.NotNull(latest); latest.Value.Should().Be(1); - latest.Tags["HeaderName"].Should().Be("Date"); - latest.Tags["Kind"].Should().Be("Unable to parse date time offset value."); + latest.Tags["aspnetcore.header_parsing.header.name"].Should().Be("Date"); + latest.Tags["error.type"].Should().Be("Unable to parse date time offset value."); } [Fact] @@ -190,7 +191,7 @@ public void CachingWorks() { using var meter = new Meter(nameof(CachingWorks)); var metrics = GetMockedMetrics(meter); - using var metricCollector = new MetricCollector(meter, @"HeaderParsing.CacheAccess"); + using var metricCollector = new MetricCollector(meter, "aspnetcore.header_parsing.cache_accesses"); Context.Request.Headers[HeaderNames.CacheControl] = "max-age=604800"; @@ -204,10 +205,11 @@ public void CachingWorks() Assert.Same(value1, value2); Assert.Same(value1, value3); - var latest = metricCollector.LastMeasurement!; + var latest = metricCollector.LastMeasurement; + Assert.NotNull(latest); latest.Value.Should().Be(1); - latest.Tags["HeaderName"].Should().Be(HeaderNames.CacheControl); - latest.Tags["Type"].Should().Be("Hit"); + latest.Tags["aspnetcore.header_parsing.header.name"].Should().Be(HeaderNames.CacheControl); + latest.Tags["aspnetcore.header_parsing.cache_access.type"].Should().Be("Hit"); } private static HeaderParsingMetrics GetMockedMetrics(Meter meter) diff --git a/test/Libraries/Microsoft.Extensions.Diagnostics.HealthChecks.Common.Tests/TelemetryHealthChecksPublisherTests.cs b/test/Libraries/Microsoft.Extensions.Diagnostics.HealthChecks.Common.Tests/TelemetryHealthChecksPublisherTests.cs index ad1c5226e35..9bf8fa6f06c 100644 --- a/test/Libraries/Microsoft.Extensions.Diagnostics.HealthChecks.Common.Tests/TelemetryHealthChecksPublisherTests.cs +++ b/test/Libraries/Microsoft.Extensions.Diagnostics.HealthChecks.Common.Tests/TelemetryHealthChecksPublisherTests.cs @@ -17,10 +17,10 @@ namespace Microsoft.Extensions.Diagnostics.HealthChecks.Test; public class TelemetryHealthChecksPublisherTests { - private const string HealthReportMetricName = @"R9\HealthCheck\Report"; - private const string UnhealthyHealthCheckMetricName = @"R9\HealthCheck\UnhealthyHealthCheck"; + private const string HealthReportMetricName = "dotnet.health_check.reports"; + private const string UnhealthyHealthCheckMetricName = "dotnet.health_check.unhealthy_checks"; - public static TheoryData, bool, int, string, LogLevel, string, string> PublishAsyncArgs => new() + public static TheoryData, bool, int, string, LogLevel, string> PublishAsyncArgs => new() { { new List { HealthStatus.Healthy }, @@ -28,7 +28,6 @@ public class TelemetryHealthChecksPublisherTests 1, "Process reporting healthy: Healthy.", LogLevel.Debug, - bool.TrueString, HealthStatus.Healthy.ToString() }, { @@ -37,7 +36,6 @@ public class TelemetryHealthChecksPublisherTests 1, "Process reporting unhealthy: Degraded. Health check entries are id0: {status: Degraded, description: desc0}", LogLevel.Warning, - bool.FalseString, HealthStatus.Degraded.ToString() }, { @@ -46,7 +44,6 @@ public class TelemetryHealthChecksPublisherTests 1, "Process reporting unhealthy: Unhealthy. Health check entries are id0: {status: Unhealthy, description: desc0}", LogLevel.Warning, - bool.FalseString, HealthStatus.Unhealthy.ToString() }, { @@ -55,7 +52,6 @@ public class TelemetryHealthChecksPublisherTests 0, "Process reporting healthy: Healthy.", LogLevel.Debug, - bool.TrueString, HealthStatus.Healthy.ToString() }, { @@ -64,7 +60,6 @@ public class TelemetryHealthChecksPublisherTests 1, "Process reporting unhealthy: Unhealthy. Health check entries are id0: {status: Healthy, description: desc0}, id1: {status: Unhealthy, description: desc1}", LogLevel.Warning, - bool.FalseString, HealthStatus.Unhealthy.ToString() }, { @@ -74,7 +69,6 @@ public class TelemetryHealthChecksPublisherTests "Process reporting unhealthy: Unhealthy. Health check entries are " + "id0: {status: Healthy, description: desc0}, id1: {status: Degraded, description: desc1}, id2: {status: Unhealthy, description: desc2}", LogLevel.Warning, - bool.FalseString, HealthStatus.Unhealthy.ToString() }, }; @@ -87,7 +81,6 @@ public async Task PublishAsync( int expectedLogCount, string expectedLogMessage, LogLevel expectedLogLevel, - string expectedMetricHealthy, string expectedMetricStatus) { using var meter = new Meter(nameof(PublishAsync)); @@ -113,11 +106,12 @@ public async Task PublishAsync( Assert.Equal(expectedLogLevel, collector.LatestRecord.Level); } - var latest = healthyMetricCollector.LastMeasurement!; + var latest = healthyMetricCollector.LastMeasurement; + + Assert.NotNull(latest); latest.Value.Should().Be(1); - latest.Tags["healthy"].Should().Be(expectedMetricHealthy); - latest.Tags["status"].Should().Be(expectedMetricStatus); + latest.Tags.Should().ContainKey("dotnet.health_check.status").WhoseValue.Should().Be(expectedMetricStatus); var unhealthyCounters = unhealthyMetricCollector.GetMeasurementSnapshot(); @@ -145,8 +139,8 @@ private static long GetValue(IReadOnlyCollection> cou { foreach (var counter in counters) { - if (counter!.Tags["name"]?.ToString() == healthy && - counter!.Tags["status"]?.ToString() == status) + if (counter!.Tags["dotnet.health_check.name"]?.ToString() == healthy && + counter!.Tags["dotnet.health_check.status"]?.ToString() == status) { return counter.Value; } diff --git a/test/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring.Tests/Linux/AcceptanceTest.cs b/test/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring.Tests/Linux/AcceptanceTest.cs index ce49066f3f5..6ff29196f7e 100644 --- a/test/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring.Tests/Linux/AcceptanceTest.cs +++ b/test/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring.Tests/Linux/AcceptanceTest.cs @@ -157,8 +157,8 @@ public Task ResourceUtilizationTracker_Reports_The_Same_Values_As_One_Can_Observ listener.InstrumentPublished = (i, m) => { - if (i.Name == ResourceUtilizationCounters.CpuConsumptionPercentage - || i.Name == ResourceUtilizationCounters.MemoryConsumptionPercentage) + if (i.Name == ResourceUtilizationInstruments.CpuUtilization + || i.Name == ResourceUtilizationInstruments.MemoryUtilization) { m.EnableMeasurementEvents(i); } @@ -166,11 +166,11 @@ public Task ResourceUtilizationTracker_Reports_The_Same_Values_As_One_Can_Observ listener.SetMeasurementEventCallback((m, f, _, _) => { - if (m.Name == ResourceUtilizationCounters.CpuConsumptionPercentage) + if (m.Name == ResourceUtilizationInstruments.CpuUtilization) { cpuFromGauge = f; } - else if (m.Name == ResourceUtilizationCounters.MemoryConsumptionPercentage) + else if (m.Name == ResourceUtilizationInstruments.MemoryUtilization) { memoryFromGauge = f; } diff --git a/test/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring.Tests/Linux/LinuxCountersTests.cs b/test/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring.Tests/Linux/LinuxCountersTests.cs index 3e75a1da2c2..2a0c286d0ea 100644 --- a/test/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring.Tests/Linux/LinuxCountersTests.cs +++ b/test/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring.Tests/Linux/LinuxCountersTests.cs @@ -44,7 +44,10 @@ public void LinuxCounters_Registers_Instruments() { InstrumentPublished = (instrument, listener) => { - listener.EnableMeasurementEvents(instrument); + if (ReferenceEquals(meter, instrument.Meter)) + { + listener.EnableMeasurementEvents(instrument); + } } }; @@ -61,9 +64,9 @@ public void LinuxCounters_Registers_Instruments() listener.RecordObservableInstruments(); Assert.Equal(2, samples.Count); - Assert.Equal(ResourceUtilizationCounters.CpuConsumptionPercentage, samples[0].instrument.Name); + Assert.Equal(ResourceUtilizationInstruments.CpuUtilization, samples[0].instrument.Name); Assert.Equal(double.NaN, samples[0].value); - Assert.Equal(ResourceUtilizationCounters.MemoryConsumptionPercentage, samples[1].instrument.Name); - Assert.Equal(50, samples[1].value); + Assert.Equal(ResourceUtilizationInstruments.MemoryUtilization, samples[1].instrument.Name); + Assert.Equal(0.5, samples[1].value); } } diff --git a/test/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring.Tests/ResourceUtilizationCountersTests.cs b/test/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring.Tests/ResourceUtilizationCountersTests.cs deleted file mode 100644 index 5cfa3003cb7..00000000000 --- a/test/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring.Tests/ResourceUtilizationCountersTests.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Xunit; - -namespace Microsoft.Extensions.Diagnostics.ResourceMonitoring.Test; - -public class ResourceUtilizationCountersTests -{ - [Fact] - public void ExpectedStrings() - { - Assert.Equal("cpu_consumption_percentage", ResourceUtilizationCounters.CpuConsumptionPercentage); - Assert.Equal("memory_consumption_percentage", ResourceUtilizationCounters.MemoryConsumptionPercentage); - } -} diff --git a/test/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring.Tests/Windows/WindowsCountersTests.cs b/test/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring.Tests/Windows/WindowsCountersTests.cs index 09948f43f38..cbd1ecee25c 100644 --- a/test/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring.Tests/Windows/WindowsCountersTests.cs +++ b/test/Libraries/Microsoft.Extensions.Diagnostics.ResourceMonitoring.Tests/Windows/WindowsCountersTests.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Generic; using System.Diagnostics.Metrics; -using System.Linq; using FluentAssertions; using Microsoft.Extensions.Diagnostics.ResourceMonitoring.Windows.Network; using Moq; @@ -54,54 +53,8 @@ public void WindowsCounters_Registers_Instruments() listener.Start(); listener.RecordObservableInstruments(); samples.Count.Should().Be(24); - samples.First().instrument.Name.Should().Be("ipv4_tcp_connection_closed_count"); - samples.First().value.Should().Be(1); - samples.Skip(1).First().instrument.Name.Should().Be("ipv4_tcp_connection_listen_count"); - samples.Skip(1).First().value.Should().Be(1); - samples.Skip(2).First().instrument.Name.Should().Be("ipv4_tcp_connection_syn_sent_count"); - samples.Skip(2).First().value.Should().Be(1); - samples.Skip(3).First().instrument.Name.Should().Be("ipv4_tcp_connection_syn_received_count"); - samples.Skip(3).First().value.Should().Be(1); - samples.Skip(4).First().instrument.Name.Should().Be("ipv4_tcp_connection_established_count"); - samples.Skip(4).First().value.Should().Be(1); - samples.Skip(5).First().instrument.Name.Should().Be("ipv4_tcp_connection_fin_wait_1_count"); - samples.Skip(5).First().value.Should().Be(1); - samples.Skip(6).First().instrument.Name.Should().Be("ipv4_tcp_connection_fin_wait_2_count"); - samples.Skip(6).First().value.Should().Be(1); - samples.Skip(7).First().instrument.Name.Should().Be("ipv4_tcp_connection_close_wait_count"); - samples.Skip(7).First().value.Should().Be(1); - samples.Skip(8).First().instrument.Name.Should().Be("ipv4_tcp_connection_closing_count"); - samples.Skip(8).First().value.Should().Be(1); - samples.Skip(9).First().instrument.Name.Should().Be("ipv4_tcp_connection_last_ack_count"); - samples.Skip(9).First().value.Should().Be(1); - samples.Skip(10).First().instrument.Name.Should().Be("ipv4_tcp_connection_time_wait_count"); - samples.Skip(10).First().value.Should().Be(1); - samples.Skip(11).First().instrument.Name.Should().Be("ipv4_tcp_connection_delete_tcb_count"); - samples.Skip(11).First().value.Should().Be(1); - samples.Skip(12).First().instrument.Name.Should().Be("ipv6_tcp_connection_closed_count"); - samples.Skip(12).First().value.Should().Be(1); - samples.Skip(13).First().instrument.Name.Should().Be("ipv6_tcp_connection_listen_count"); - samples.Skip(13).First().value.Should().Be(1); - samples.Skip(14).First().instrument.Name.Should().Be("ipv6_tcp_connection_syn_sent_count"); - samples.Skip(14).First().value.Should().Be(1); - samples.Skip(15).First().instrument.Name.Should().Be("ipv6_tcp_connection_syn_received_count"); - samples.Skip(15).First().value.Should().Be(1); - samples.Skip(16).First().instrument.Name.Should().Be("ipv6_tcp_connection_established_count"); - samples.Skip(16).First().value.Should().Be(1); - samples.Skip(17).First().instrument.Name.Should().Be("ipv6_tcp_connection_fin_wait_1_count"); - samples.Skip(17).First().value.Should().Be(1); - samples.Skip(18).First().instrument.Name.Should().Be("ipv6_tcp_connection_fin_wait_2_count"); - samples.Skip(18).First().value.Should().Be(1); - samples.Skip(19).First().instrument.Name.Should().Be("ipv6_tcp_connection_close_wait_count"); - samples.Skip(19).First().value.Should().Be(1); - samples.Skip(20).First().instrument.Name.Should().Be("ipv6_tcp_connection_closing_count"); - samples.Skip(20).First().value.Should().Be(1); - samples.Skip(21).First().instrument.Name.Should().Be("ipv6_tcp_connection_last_ack_count"); - samples.Skip(21).First().value.Should().Be(1); - samples.Skip(22).First().instrument.Name.Should().Be("ipv6_tcp_connection_time_wait_count"); - samples.Skip(22).First().value.Should().Be(1); - samples.Skip(23).First().instrument.Name.Should().Be("ipv6_tcp_connection_delete_tcb_count"); - samples.Skip(23).First().value.Should().Be(1); + samples.Should().AllSatisfy(x => x.instrument.Name.Should().Be("system.network.connections")); + samples.Should().AllSatisfy(x => x.value.Should().Be(1)); } [Fact] @@ -126,7 +79,10 @@ public void WindowsCounters_Got_Unsuccessful() { InstrumentPublished = (instrument, listener) => { - listener.EnableMeasurementEvents(instrument); + if (instrument.Meter == meter) + { + listener.EnableMeasurementEvents(instrument); + } } }; diff --git a/test/Libraries/Microsoft.Extensions.Http.Resilience.Tests/Resilience/HttpClientBuilderExtensionsTests.Resilience.cs b/test/Libraries/Microsoft.Extensions.Http.Resilience.Tests/Resilience/HttpClientBuilderExtensionsTests.Resilience.cs index bcdd3784c33..ebf5f52c117 100644 --- a/test/Libraries/Microsoft.Extensions.Http.Resilience.Tests/Resilience/HttpClientBuilderExtensionsTests.Resilience.cs +++ b/test/Libraries/Microsoft.Extensions.Http.Resilience.Tests/Resilience/HttpClientBuilderExtensionsTests.Resilience.cs @@ -10,7 +10,6 @@ using FluentAssertions; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Diagnostics.Metrics.Testing; -using Microsoft.Extensions.Http.Diagnostics; using Microsoft.Extensions.Http.Resilience.Internal; using Microsoft.Extensions.Http.Resilience.Test.Helpers; using Microsoft.Extensions.Options; @@ -71,13 +70,13 @@ public async Task AddResilienceHandler_OnPipelineDisposed_EnsureCalled() context.OnPipelineDisposed(() => onPipelineDisposedCalled = true); }); - var serviceProvider = services.BuildServiceProvider(); - - var client = serviceProvider.GetRequiredService().CreateClient("client"); - using var request = new HttpRequestMessage(HttpMethod.Get, "https://dummy"); + using (var serviceProvider = services.BuildServiceProvider()) + { + var client = serviceProvider.GetRequiredService().CreateClient("client"); + using var request = new HttpRequestMessage(HttpMethod.Get, "https://dummy"); - await client.GetStringAsync("https://dummy"); - serviceProvider.Dispose(); + await client.GetStringAsync("https://dummy"); + } onPipelineDisposedCalled.Should().BeTrue(); } @@ -117,15 +116,14 @@ public async Task AddResilienceHandler_EnsureFailureResultContext() options.Retry.Delay = TimeSpan.Zero; }); - var client = services.BuildServiceProvider().GetRequiredService().CreateClient("client"); + using var serviceProvider = services.BuildServiceProvider(); + var client = serviceProvider.GetRequiredService().CreateClient("client"); using var request = new HttpRequestMessage(HttpMethod.Get, "https://dummy"); using var response = await client.SendAsync(request); var lookup = enricher.Tags.ToLookup(t => t.Key, t => t.Value); - lookup["failure-reason"].Should().Contain("500"); - lookup["failure-summary"].Should().Contain("InternalServerError"); - lookup["failure-source"].Should().Contain(TelemetryConstants.Unknown); + lookup["error.type"].Should().Contain("InternalServerError"); } [Fact] diff --git a/test/Libraries/Microsoft.Extensions.Resilience.Tests/Resilience/FailureResultContextTests.cs b/test/Libraries/Microsoft.Extensions.Resilience.Tests/Resilience/FailureResultContextTests.cs new file mode 100644 index 00000000000..a280c306c75 --- /dev/null +++ b/test/Libraries/Microsoft.Extensions.Resilience.Tests/Resilience/FailureResultContextTests.cs @@ -0,0 +1,21 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using FluentAssertions; +using Microsoft.Extensions.Http.Diagnostics; +using Xunit; + +namespace Microsoft.Extensions.Resilience.Test.Resilience; + +public class FailureResultContextTests +{ + [Fact] + public void ContextFactory_CreateTheObject() + { + var context = FailureResultContext.Create(); + + context.FailureSource.Should().Be(TelemetryConstants.Unknown); + context.AdditionalInformation.Should().Be(TelemetryConstants.Unknown); + context.FailureReason.Should().Be(TelemetryConstants.Unknown); + } +} diff --git a/test/Libraries/Microsoft.Extensions.Resilience.Tests/Resilience/ResilienceMetricsEnricherTests.cs b/test/Libraries/Microsoft.Extensions.Resilience.Tests/Resilience/ResilienceMetricsEnricherTests.cs index df5c60f0c27..e02ca8b5242 100644 --- a/test/Libraries/Microsoft.Extensions.Resilience.Tests/Resilience/ResilienceMetricsEnricherTests.cs +++ b/test/Libraries/Microsoft.Extensions.Resilience.Tests/Resilience/ResilienceMetricsEnricherTests.cs @@ -42,9 +42,7 @@ public void AddResilienceEnricher_Exception_EnsureDimensions() CreateSut().Enrich(CreateEnrichmentContext(Outcome.FromException(new InvalidOperationException { Source = "my-source" }))); - Tags["failure-reason"].Should().Be("InvalidOperationException"); - Tags["failure-summary"].Should().Be("type:desc:details"); - Tags["failure-source"].Should().Be("my-source"); + Tags.Should().ContainKey("error.type").WhoseValue.Should().Be("type:desc:details"); } [Fact] @@ -54,9 +52,7 @@ public void AddResilienceEnricher_ExceptionWithNoSummarizer_EnsureNoDimensions() CreateSut().Enrich(CreateEnrichmentContext(Outcome.FromException(new InvalidOperationException { Source = "my-source" }))); - Tags.Should().NotContainKey("failure-reason"); - Tags.Should().NotContainKey("failure-summary"); - Tags.Should().NotContainKey("failure-source"); + Tags.Should().NotContainKey("error.type"); } [Fact] @@ -66,9 +62,7 @@ public void AddResilienceEnricher_Outcome_EnsureDimensions() CreateSut().Enrich(CreateEnrichmentContext(Outcome.FromResult("string-result"))); - Tags["failure-source"].Should().Be("my-source"); - Tags["failure-reason"].Should().Be("my-reason"); - Tags["failure-summary"].Should().Be("string-result"); + Tags.Should().ContainKey("error.type").WhoseValue.Should().Be("string-result"); } [Fact] @@ -78,8 +72,8 @@ public void AddResilienceEnricher_RequestMetadata_EnsureDimensions() Outcome.FromResult("string-result"), context => context.SetRequestMetadata(new RequestMetadata { RequestName = "my-req", DependencyName = "my-dep" }))); - Tags["dep-name"].Should().Be("my-dep"); - Tags["req-name"].Should().Be("my-req"); + Tags.Should().ContainKey("request.dependency.name").WhoseValue.Should().Be("my-dep"); + Tags.Should().ContainKey("request.name").WhoseValue.Should().Be("my-req"); } [Fact] @@ -90,8 +84,8 @@ public void AddResilienceEnricher_RequestMetadataFromOutgoingRequestContext_Ensu CreateSut().Enrich(CreateEnrichmentContext()); - Tags["dep-name"].Should().Be("my-dep"); - Tags["req-name"].Should().Be("my-req"); + Tags.Should().ContainKey("request.dependency.name").WhoseValue.Should().Be("my-dep"); + Tags.Should().ContainKey("request.name").WhoseValue.Should().Be("my-req"); } private EnrichmentContext CreateEnrichmentContext(Outcome? outcome = null, Action? configure = null)