29
29
#include "we_util.h"
30
30
#include "we_metric.h"
31
31
32
+ #include <iphlpapi.h>
33
+
34
+ const char * TCP_STATE_STRINGS [] = {
35
+ "ESTABLISHED" , "SYN_SENT" , "SYN_RECV" , "FIN_WAIT1" , "FIN_WAIT2" , "TIME_WAIT" ,
36
+ "CLOSE" , "CLOSE_WAIT" , "LAST_ACK" , "LISTEN" , "CLOSING" , "DELETE_TCB" , "UNKNOWN"
37
+ };
38
+
39
+ static inline int windows_state_to_index (int state )
40
+ {
41
+ switch (state ) {
42
+ case MIB_TCP_STATE_ESTAB :
43
+ return 0 ;
44
+ case MIB_TCP_STATE_SYN_SENT :
45
+ return 1 ;
46
+ case MIB_TCP_STATE_SYN_RCVD :
47
+ return 2 ;
48
+ case MIB_TCP_STATE_FIN_WAIT1 :
49
+ return 3 ;
50
+ case MIB_TCP_STATE_FIN_WAIT2 :
51
+ return 4 ;
52
+ case MIB_TCP_STATE_TIME_WAIT :
53
+ return 5 ;
54
+ /* MIB_TCP_STATE_CLOSED is 1 */
55
+ case MIB_TCP_STATE_CLOSE_WAIT :
56
+ return 7 ;
57
+ case MIB_TCP_STATE_LAST_ACK :
58
+ return 8 ;
59
+ case MIB_TCP_STATE_LISTEN :
60
+ return 9 ;
61
+ case MIB_TCP_STATE_CLOSING :
62
+ return 10 ;
63
+ case MIB_TCP_STATE_DELETE_TCB :
64
+ return 11 ;
65
+ default :
66
+ return 12 ;
67
+ }
68
+ }
69
+
70
+ static int we_tcp_get_state_metrics (struct flb_we * ctx , const char * af_label )
71
+ {
72
+ PMIB_TCPTABLE2 tcp_table = NULL ;
73
+ ULONG buffer_size = 0 ;
74
+ DWORD result ;
75
+ DWORD idx = 0 ;
76
+ int state_index ;
77
+ int i = 0 ;
78
+ const char * state_label ;
79
+ uint64_t timestamp = cfl_time_now ();
80
+ int af_family = (strcmp (af_label , "ipv4" ) == 0 ) ? AF_INET : AF_INET6 ;
81
+ unsigned int state_counts [13 ] = {0 };
82
+ const char * labels [2 ];
83
+
84
+ result = GetExtendedTcpTable (NULL , & buffer_size , FALSE, af_family , TCP_TABLE_OWNER_PID_ALL , 0 );
85
+ if (result != ERROR_INSUFFICIENT_BUFFER ) {
86
+ flb_plg_error (ctx -> ins , "TCP state metrics: error getting buffer size: %lu" , result );
87
+ return -1 ;
88
+ }
89
+
90
+ tcp_table = (PMIB_TCPTABLE2 )flb_malloc (buffer_size );
91
+ if (tcp_table == NULL ) {
92
+ flb_plg_error (ctx -> ins , "TCP state metrics: could not allocate buffer" );
93
+ return -1 ;
94
+ }
95
+
96
+ result = GetExtendedTcpTable (tcp_table , & buffer_size , FALSE, af_family , TCP_TABLE_OWNER_PID_ALL , 0 );
97
+ if (result != NO_ERROR ) {
98
+ flb_plg_error (ctx -> ins , "TCP state metrics: error getting table: %lu" , result );
99
+ flb_free (tcp_table );
100
+ return -1 ;
101
+ }
102
+
103
+ for (idx = 0 ; idx < tcp_table -> dwNumEntries ; idx ++ ) {
104
+ state_index = windows_state_to_index (tcp_table -> table [idx ].dwState );
105
+ state_counts [state_index ]++ ;
106
+ }
107
+
108
+ flb_free (tcp_table );
109
+
110
+ for (i = 0 ; i < 13 ; i ++ ) {
111
+ if (state_counts [i ] > 0 ) {
112
+ state_label = TCP_STATE_STRINGS [i ];
113
+ labels [0 ] = af_label ;
114
+ labels [1 ] = state_label ;
115
+ cmt_gauge_set (ctx -> wmi_tcp -> connections_state , timestamp ,
116
+ (double )state_counts [i ], 2 , (char * * )labels );
117
+ }
118
+ }
119
+
120
+ return 0 ;
121
+ }
122
+
32
123
int we_wmi_tcp_init (struct flb_we * ctx )
33
124
{
34
125
ctx -> wmi_tcp = flb_calloc (1 , sizeof (struct we_wmi_tcp_counters ));
@@ -40,12 +131,22 @@ int we_wmi_tcp_init(struct flb_we *ctx)
40
131
41
132
struct cmt_gauge * g ;
42
133
struct cmt_counter * c ;
43
- char * label = "af" ;
134
+ char * wmi_label [] = {"af" };
135
+ char * state_labels [] = {"af" , "state" };
136
+
137
+ g = cmt_gauge_create (ctx -> cmt , "windows" , "tcp" ,
138
+ "connections_state" ,
139
+ "Number of connections in a given state." ,
140
+ 2 , state_labels );
141
+ if (!g ) {
142
+ return -1 ;
143
+ }
144
+ ctx -> wmi_tcp -> connections_state = g ;
44
145
45
146
c = cmt_counter_create (ctx -> cmt , "windows" , "tcp" ,
46
147
"connection_failures_total" ,
47
148
"Total number of connection failures." ,
48
- 1 , & label );
149
+ 1 , wmi_label );
49
150
if (!c ) {
50
151
return -1 ;
51
152
}
@@ -54,7 +155,7 @@ int we_wmi_tcp_init(struct flb_we *ctx)
54
155
g = cmt_gauge_create (ctx -> cmt , "windows" , "tcp" ,
55
156
"connections_active" ,
56
157
"Number of active TCP connections." ,
57
- 1 , & label );
158
+ 1 , wmi_label );
58
159
if (!g ) {
59
160
return -1 ;
60
161
}
@@ -63,7 +164,7 @@ int we_wmi_tcp_init(struct flb_we *ctx)
63
164
c = cmt_counter_create (ctx -> cmt , "windows" , "tcp" ,
64
165
"connections_established_total" ,
65
166
"Total number of TCP connections established." ,
66
- 1 , & label );
167
+ 1 , wmi_label );
67
168
if (!c ) {
68
169
return -1 ;
69
170
}
@@ -72,7 +173,7 @@ int we_wmi_tcp_init(struct flb_we *ctx)
72
173
c = cmt_counter_create (ctx -> cmt , "windows" , "tcp" ,
73
174
"connections_passive_total" ,
74
175
"Total number of passive TCP connections." ,
75
- 1 , & label );
176
+ 1 , wmi_label );
76
177
if (!c ) {
77
178
return -1 ;
78
179
}
@@ -81,7 +182,7 @@ int we_wmi_tcp_init(struct flb_we *ctx)
81
182
c = cmt_counter_create (ctx -> cmt , "windows" , "tcp" ,
82
183
"connections_reset_total" ,
83
184
"Total number of reset TCP connections." ,
84
- 1 , & label );
185
+ 1 , wmi_label );
85
186
if (!c ) {
86
187
return -1 ;
87
188
}
@@ -90,7 +191,7 @@ int we_wmi_tcp_init(struct flb_we *ctx)
90
191
g = cmt_gauge_create (ctx -> cmt , "windows" , "tcp" ,
91
192
"segments_total" ,
92
193
"Total TCP segments sent or received per second." ,
93
- 1 , & label );
194
+ 1 , wmi_label );
94
195
if (!g ) {
95
196
return -1 ;
96
197
}
@@ -99,7 +200,7 @@ int we_wmi_tcp_init(struct flb_we *ctx)
99
200
g = cmt_gauge_create (ctx -> cmt , "windows" , "tcp" ,
100
201
"segments_total" ,
101
202
"TCP segments received per second." ,
102
- 1 , & label );
203
+ 1 , wmi_label );
103
204
if (!g ) {
104
205
return -1 ;
105
206
}
@@ -108,7 +209,7 @@ int we_wmi_tcp_init(struct flb_we *ctx)
108
209
g = cmt_gauge_create (ctx -> cmt , "windows" , "tcp" ,
109
210
"segments_retransmitted_total" ,
110
211
"TCP segments retransmitted per second." ,
111
- 1 , & label );
212
+ 1 , wmi_label );
112
213
if (!g ) {
113
214
return -1 ;
114
215
}
@@ -117,7 +218,7 @@ int we_wmi_tcp_init(struct flb_we *ctx)
117
218
g = cmt_gauge_create (ctx -> cmt , "windows" , "tcp" ,
118
219
"segments_sent_total" ,
119
220
"TCP segments sent per second." ,
120
- 1 , & label );
221
+ 1 , wmi_label );
121
222
if (!g ) {
122
223
return -1 ;
123
224
}
@@ -175,6 +276,10 @@ int we_wmi_tcp_update(struct flb_we *ctx)
175
276
return -1 ;
176
277
}
177
278
279
+ /* Collect the new state-based metrics first. This does not require WMI coinitialization. */
280
+ we_tcp_get_state_metrics (ctx , ipv4_label );
281
+ we_tcp_get_state_metrics (ctx , ipv6_label );
282
+
178
283
if (FAILED (we_wmi_coinitialize (ctx ))) {
179
284
return -1 ;
180
285
}
0 commit comments