-
Notifications
You must be signed in to change notification settings - Fork 772
/
Copy pathWindowsNetworkMetrics.cs
82 lines (69 loc) · 5.65 KB
/
WindowsNetworkMetrics.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
// 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.Shared.Instruments;
namespace Microsoft.Extensions.Diagnostics.ResourceMonitoring.Windows.Network;
internal sealed class WindowsNetworkMetrics
{
private readonly ITcpStateInfoProvider _tcpStateInfoProvider;
public WindowsNetworkMetrics(IMeterFactory meterFactory, ITcpStateInfoProvider tcpStateInfoProvider)
{
_tcpStateInfoProvider = tcpStateInfoProvider;
#pragma warning disable CA2000 // Dispose objects before losing scope
// We don't dispose the meter because IMeterFactory handles that
// Is's a false-positive, see: https://github.com/dotnet/roslyn-analyzers/issues/6912.
// Related documentation: https://github.com/dotnet/docs/pull/37170
var meter = meterFactory.Create(ResourceUtilizationInstruments.MeterName);
#pragma warning restore CA2000 // Dispose objects before losing scope
KeyValuePair<string, object?> tcpTag = new("network.transport", "tcp");
TagList commonTags = new() { tcpTag };
// The metric is aligned with
// https://github.com/open-telemetry/semantic-conventions/blob/main/docs/system/system-metrics.md#metric-systemnetworkconnections
_ = meter.CreateObservableUpDownCounter(
ResourceUtilizationInstruments.SystemNetworkConnections,
GetMeasurements,
unit: "{connection}",
description: null,
tags: commonTags);
}
private IEnumerable<Measurement<long>> GetMeasurements()
{
const string NetworkTypeKey = "network.type";
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:
KeyValuePair<string, object?> tcpVersionFourTag = new(NetworkTypeKey, "ipv4");
KeyValuePair<string, object?> tcpVersionSixTag = new(NetworkTypeKey, "ipv6");
List<Measurement<long>> measurements = new(24);
// IPv4:
TcpStateInfo stateV4 = _tcpStateInfoProvider.GetpIpV4TcpStateInfo();
measurements.Add(new Measurement<long>(stateV4.ClosedCount, new TagList { tcpVersionFourTag, new(NetworkStateKey, "close") }));
measurements.Add(new Measurement<long>(stateV4.ListenCount, new TagList { tcpVersionFourTag, new(NetworkStateKey, "listen") }));
measurements.Add(new Measurement<long>(stateV4.SynSentCount, new TagList { tcpVersionFourTag, new(NetworkStateKey, "syn_sent") }));
measurements.Add(new Measurement<long>(stateV4.SynRcvdCount, new TagList { tcpVersionFourTag, new(NetworkStateKey, "syn_recv") }));
measurements.Add(new Measurement<long>(stateV4.EstabCount, new TagList { tcpVersionFourTag, new(NetworkStateKey, "established") }));
measurements.Add(new Measurement<long>(stateV4.FinWait1Count, new TagList { tcpVersionFourTag, new(NetworkStateKey, "fin_wait_1") }));
measurements.Add(new Measurement<long>(stateV4.FinWait2Count, new TagList { tcpVersionFourTag, new(NetworkStateKey, "fin_wait_2") }));
measurements.Add(new Measurement<long>(stateV4.CloseWaitCount, new TagList { tcpVersionFourTag, new(NetworkStateKey, "close_wait") }));
measurements.Add(new Measurement<long>(stateV4.ClosingCount, new TagList { tcpVersionFourTag, new(NetworkStateKey, "closing") }));
measurements.Add(new Measurement<long>(stateV4.LastAckCount, new TagList { tcpVersionFourTag, new(NetworkStateKey, "last_ack") }));
measurements.Add(new Measurement<long>(stateV4.TimeWaitCount, new TagList { tcpVersionFourTag, new(NetworkStateKey, "time_wait") }));
measurements.Add(new Measurement<long>(stateV4.DeleteTcbCount, new TagList { tcpVersionFourTag, new(NetworkStateKey, "delete") }));
// IPv6:
TcpStateInfo stateV6 = _tcpStateInfoProvider.GetpIpV6TcpStateInfo();
measurements.Add(new Measurement<long>(stateV6.ClosedCount, new TagList { tcpVersionSixTag, new(NetworkStateKey, "close") }));
measurements.Add(new Measurement<long>(stateV6.ListenCount, new TagList { tcpVersionSixTag, new(NetworkStateKey, "listen") }));
measurements.Add(new Measurement<long>(stateV6.SynSentCount, new TagList { tcpVersionSixTag, new(NetworkStateKey, "syn_sent") }));
measurements.Add(new Measurement<long>(stateV6.SynRcvdCount, new TagList { tcpVersionSixTag, new(NetworkStateKey, "syn_recv") }));
measurements.Add(new Measurement<long>(stateV6.EstabCount, new TagList { tcpVersionSixTag, new(NetworkStateKey, "established") }));
measurements.Add(new Measurement<long>(stateV6.FinWait1Count, new TagList { tcpVersionSixTag, new(NetworkStateKey, "fin_wait_1") }));
measurements.Add(new Measurement<long>(stateV6.FinWait2Count, new TagList { tcpVersionSixTag, new(NetworkStateKey, "fin_wait_2") }));
measurements.Add(new Measurement<long>(stateV6.CloseWaitCount, new TagList { tcpVersionSixTag, new(NetworkStateKey, "close_wait") }));
measurements.Add(new Measurement<long>(stateV6.ClosingCount, new TagList { tcpVersionSixTag, new(NetworkStateKey, "closing") }));
measurements.Add(new Measurement<long>(stateV6.LastAckCount, new TagList { tcpVersionSixTag, new(NetworkStateKey, "last_ack") }));
measurements.Add(new Measurement<long>(stateV6.TimeWaitCount, new TagList { tcpVersionSixTag, new(NetworkStateKey, "time_wait") }));
measurements.Add(new Measurement<long>(stateV6.DeleteTcbCount, new TagList { tcpVersionSixTag, new(NetworkStateKey, "delete") }));
return measurements;
}
}