| File: System\Net\Http\SocketsHttpHandler\Metrics\ConnectionMetrics.cs | Web Access |
| Project: src\runtime\src\libraries\System.Net.Http\src\System.Net.Http.csproj (System.Net.Http) |
// 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; namespace System.Net.Http.Metrics { internal sealed class ConnectionMetrics { private readonly SocketsHttpHandlerMetrics _metrics; private readonly bool _openConnectionsEnabled; private readonly object _protocolVersionTag; private readonly object _schemeTag; private readonly object _hostTag; private readonly object _portTag; private readonly object? _peerAddressTag; private bool _currentlyIdle; public ConnectionMetrics(SocketsHttpHandlerMetrics metrics, string protocolVersion, string scheme, string host, int port, string? peerAddress) { _metrics = metrics; _openConnectionsEnabled = _metrics.OpenConnections.Enabled; _protocolVersionTag = protocolVersion; _schemeTag = scheme; _hostTag = host; _portTag = DiagnosticsHelper.GetBoxedInt32(port); _peerAddressTag = peerAddress; } // TagList is a huge struct, so we avoid storing it in a field to reduce the amount we allocate on the heap. private TagList GetTags() { TagList tags = default; tags.Add("network.protocol.version", _protocolVersionTag); tags.Add("url.scheme", _schemeTag); tags.Add("server.address", _hostTag); tags.Add("server.port", _portTag); if (_peerAddressTag is not null) { tags.Add("network.peer.address", _peerAddressTag); } return tags; } private static KeyValuePair<string, object?> GetStateTag(bool idle) => new KeyValuePair<string, object?>("http.connection.state", idle ? "idle" : "active"); public void ConnectionEstablished() { if (_openConnectionsEnabled) { _currentlyIdle = true; TagList tags = GetTags(); tags.Add(GetStateTag(idle: true)); _metrics.OpenConnections.Add(1, tags); } } public void ConnectionClosed(long durationMs) { TagList tags = GetTags(); if (_metrics.ConnectionDuration.Enabled) { _metrics.ConnectionDuration.Record(durationMs / 1000d, tags); } if (_openConnectionsEnabled) { tags.Add(GetStateTag(idle: _currentlyIdle)); _metrics.OpenConnections.Add(-1, tags); } } public void IdleStateChanged(bool idle) { if (_openConnectionsEnabled && _currentlyIdle != idle) { _currentlyIdle = idle; TagList tags = GetTags(); tags.Add(GetStateTag(idle: !idle)); _metrics.OpenConnections.Add(-1, tags); tags[tags.Count - 1] = GetStateTag(idle: idle); _metrics.OpenConnections.Add(1, tags); } } } }