WinNetFlow
WinNetFlow collects per-process L4 network flow metrics on Windows by consuming
TCP/UDP events from the Microsoft-Windows-TCPIP ETW provider. The measurement
core field and endpoint-role schema is compatible with the Linux
ebpf-net/netflow collector, so host-level network dashboards can reuse the
same src/dst, client/server, conn_side and traffic fields.
It also consumes Microsoft-Windows-HttpService events to collect HTTP request
metrics (httpflow, enabled by default) for HTTP.sys based web services such as
IIS, HttpListener and ASP.NET Core, with a schema compatible with the Linux
ebpf-net/httpflow collector.
Configuration¶
Requirements¶
- OS: Windows 10 / Windows Server 2016 or later (64-bit)
- The collector must run with administrator privileges (required to create a real-time ETW session)
- Independent from the eBPF collector; only one should be enabled per host
Copy winnetflow.conf.sample from the conf.d/samples directory of
your DataKit installation and rename it to winnetflow.conf. Example:
[[inputs.winnetflow]]
# Flow aggregation and report interval.
interval = "60s"
# Optional ETW session tuning. Buffer size is in KB; unsafe values are
# clamped to documented limits and a 256 MiB per-session memory budget.
# etw_buffer_size_kb = 64
# etw_min_buffers = 8
# etw_max_buffers = 256
# Max flows tracked per interval; excess new flows are dropped and counted.
# max_flows = 65536
# Collect L7 HTTP request metrics from the HTTP.sys ETW provider (IIS,
# HttpListener and other HTTP.sys clients) as the "httpflow" measurement.
# enable_httpflow = true
# Max in-flight HTTP requests tracked; excess new requests are dropped and
# counted in the periodic summary.
# max_http_requests = 65536
# Max request path length collected; longer paths are truncated and flagged.
# httpflow_path_limit = 256
[inputs.winnetflow.tags]
# some_tag = "some_value"
After configuration, restart DataKit.
You can enable the collector via a ConfigMap or ENV_DATAKIT_INPUTS.
Parameters can also be adjusted via environment variables (the collector
must be added to ENV_DEFAULT_ENABLED_INPUTS):
-
ENV_INPUT_WINNETFLOW_INTERVAL
Collect interval
Type: Duration
input.conf:
intervalDefault: 10s
-
ENV_INPUT_WINNETFLOW_ETW_BUFFER_SIZE_K_B
ETW session buffer size in KB (4-1024).
Type: Int
input.conf:
etw_buffer_size_k_bExample: 64
-
ENV_INPUT_WINNETFLOW_ETW_MIN_BUFFERS
Minimum number of ETW session buffers (2-4096).
Type: Int
input.conf:
etw_min_buffersExample: 8
-
ENV_INPUT_WINNETFLOW_ETW_MAX_BUFFERS
Maximum ETW buffers, also limited to a 256 MiB session budget.
Type: Int
input.conf:
etw_max_buffersExample: 256
-
ENV_INPUT_WINNETFLOW_MAX_FLOWS
Maximum concurrent flows tracked per interval; excess flows are dropped and counted.
Type: Int
input.conf:
max_flowsExample: 65536
-
ENV_INPUT_WINNETFLOW_ENABLE_HTTP_FLOW
Enable L7 httpflow collection from the HTTP.sys ETW provider.
Type: Boolean
input.conf:
enable_http_flowExample: true
-
ENV_INPUT_WINNETFLOW_MAX_HTTP_REQUESTS
Maximum concurrent in-flight HTTP requests tracked; excess requests are dropped and counted.
Type: Int
input.conf:
max_http_requestsExample: 65536
-
ENV_INPUT_WINNETFLOW_HTTP_FLOW_PATH_LIMIT
Maximum collected request path length; longer paths are truncated and flagged.
Type: Int
input.conf:
http_flow_path_limitExample: 256
-
ENV_INPUT_WINNETFLOW_TAGS
Customize tags. If there is a tag with the same name in the configuration file, it will be overwritten
Type: String
input.conf:
tagsExample:
'tag1=value1,tag2=value2'
Measurements¶
All collected data is tagged with the host tag by default (the DataKit host
name). Additional tags can be set via [inputs.winnetflow.tags]:
| Tags & Fields | Description |
|---|---|
| client_ip ( tag) |
Client endpoint IP address. |
| client_ip_type ( tag) |
Client IP type: private, loopback, multicast or other. |
| client_port ( tag) |
Client endpoint port. |
| conn_side ( tag) |
Local connection role: client or server. |
| direction ( tag) |
Flow direction: incoming or outgoing. |
| dst_ip ( tag) |
Destination IP address. |
| dst_ip_type ( tag) |
Destination IP type: private, loopback, multicast or other. |
| dst_nat_ip ( tag) |
Destination NAT IP; N/A because Windows ETW does not expose NAT translation. |
| dst_nat_port ( tag) |
Destination NAT port; N/A because Windows ETW does not expose NAT translation. |
| dst_port ( tag) |
Destination port. |
| family ( tag) |
IP family: IPv4 or IPv6. |
| pid ( tag) |
Process ID owning the connection. |
| process_name ( tag) |
Process name owning the connection. |
| server_ip ( tag) |
Server endpoint IP address. |
| server_ip_type ( tag) |
Server IP type: private, loopback, multicast or other. |
| server_port ( tag) |
Server endpoint port. |
| src_ip ( tag) |
Source IP address. |
| src_ip_type ( tag) |
Source IP type: private, loopback, multicast or other. |
| src_port ( tag) |
Source port. |
| transport ( tag) |
Transport protocol: tcp or udp. |
| bytes_read | Bytes read on this flow during the interval. Type: int | (gauge) Unit: digital,B |
| bytes_written | Bytes written on this flow during the interval. Type: int | (gauge) Unit: digital,B |
| client_sent | Bytes sent by the client during the interval. Type: int | (gauge) Unit: digital,B |
| packets_read | Packets read on this flow during the interval (approximate on Windows). Type: int | (gauge) Unit: count |
| packets_written | Packets/messages written during the interval; always 0 for TCP because TCPIP send events do not expose a packet count, and approximated by message count for UDP. Type: int | (gauge) Unit: count |
| retransmits | TCP retransmissions on this flow during the interval. Type: int | (gauge) Unit: count |
| rtt | Average smoothed TCP RTT in microseconds. Type: int | (gauge) Unit: time,μs |
| rtt_var | Average TCP RTT variance in microseconds. Type: int | (gauge) Unit: time,μs |
| server_sent | Bytes sent by the server during the interval. Type: int | (gauge) Unit: digital,B |
| tcp_close_wait | TCP transitions into CLOSE_WAIT state during the interval. Type: int | (gauge) Unit: count |
| tcp_closed | TCP connections closed during the interval. Type: int | (gauge) Unit: count |
| tcp_connect_attempts | TCP active connect attempts during the interval. Type: int | (gauge) Unit: count |
| tcp_connect_failures | TCP active connect failures during the interval. Type: int | (gauge) Unit: count |
| tcp_established | TCP connections established during the interval. Type: int | (gauge) Unit: count |
| tcp_last_ack | TCP transitions into LAST_ACK state during the interval. Type: int | (gauge) Unit: count |
| tcp_time_wait | TCP transitions into TIME_WAIT state during the interval. Type: int | (gauge) Unit: count |
| Tags & Fields | Description |
|---|---|
| client_ip ( tag) |
Client endpoint IP address. |
| client_ip_type ( tag) |
Client IP type: private, loopback, multicast or other. |
| client_port ( tag) |
Client endpoint port. |
| conn_side ( tag) |
Local connection role, always server for HTTP.sys. |
| direction ( tag) |
Flow direction, always incoming for the HTTP.sys server side. |
| dst_ip ( tag) |
Client IP address (remote endpoint). |
| dst_ip_type ( tag) |
Client destination IP type: private, loopback, multicast or other. |
| dst_nat_ip ( tag) |
Destination NAT IP; N/A because Windows ETW does not expose NAT translation. |
| dst_nat_port ( tag) |
Destination NAT port; N/A because Windows ETW does not expose NAT translation. |
| dst_port ( tag) |
Client port. |
| family ( tag) |
IP family: IPv4 or IPv6. |
| pid ( tag) |
Server process ID reported by HTTP.sys on the response event. |
| process_name ( tag) |
Server process name resolved from the HTTP.sys response event PID (for example, w3wp.exe). |
| server_ip ( tag) |
Server endpoint IP address. |
| server_ip_type ( tag) |
Server IP type: private, loopback, multicast or other. |
| server_port ( tag) |
Server endpoint port. |
| src_ip ( tag) |
Server IP address (local endpoint). |
| src_ip_type ( tag) |
Server source IP type: private, loopback, multicast or other. |
| src_port ( tag) |
Server port. |
| transport ( tag) |
Transport protocol, always tcp. |
| bytes_read | Bytes read on this flow during the interval (always 0; HTTP.sys does not expose request body sizes). Type: int | (gauge) Unit: digital,B |
| bytes_written | Bytes written on this flow during the interval (populated for cache-served responses). Type: int | (gauge) Unit: digital,B |
| client_sent | Bytes sent by the HTTP client; always 0 because HTTP.sys does not expose request body sizes. Type: int | (gauge) Unit: digital,B |
| count | Number of HTTP requests in this group during the interval. Type: int | (gauge) Unit: count |
| http_version | HTTP version; empty because HTTP.sys events do not carry it. Type: string | (string) Unit: N/A |
| latency | Average request processing time (receive to send complete) in nanoseconds. Type: int | (gauge) Unit: time,ns |
| method | HTTP method (GET/POST/...). Type: string | (string) Unit: N/A |
| path | Request path. Type: string | (string) Unit: N/A |
| server_sent | Bytes sent by the HTTP server during the interval. Type: int | (gauge) Unit: digital,B |
| status_code | HTTP response status code. Type: int | (gauge) Unit: N/A |
| truncated | Request path reached the configured length limit and was truncated. Type: bool | (gauge) Unit: bool |
Known limitations¶
- TCP send events carry no packet count;
packets_writtenis only populated for UDP (message count used as an approximation of packets); - UDP has no connection semantics; direction is inferred heuristically from
bound sockets on non-ephemeral ports (
incomingwhen the local port matches,outgoingotherwise); - TCP connections that already exist when collection starts are attributed as incoming when their local endpoint matches a TCP listener snapshot, and as outgoing otherwise. The listener snapshot refreshes every 30 seconds.
- Windows ETW does not expose network namespaces, Kubernetes endpoint metadata,
DNS domains or NAT translation.
dst_nat_ipanddst_nat_portare emitted asN/A; Kubernetes and namespace tags must come from separately configured global tags where applicable. - Under extreme load a real-time ETW session may drop events; the collector logs session statistics (decoded/dropped/parse errors/lost counters) roughly every 10 minutes and warns when anomalies are detected.
- The number of flows tracked per interval is capped (default 65536, configurable
via
max_flows); new flows beyond the cap are dropped and counted asflows_skipped. httpflowonly covers HTTP traffic that goes through HTTP.sys (IIS, HttpListener, ASP.NET Core, ...); self-hosted socket HTTP servers (e.g. some Go/Node services) are not captured.- HTTP.sys events do not carry the HTTP version or request body size;
http_versionis always empty andbytes_readis always 0.bytes_writtenis only available for cache-served responses (event 16). - HTTP process attribution is best effort. The connection event PID belongs to
the client and is intentionally ignored; the collector resolves the server
PID as soon as HTTP.sys reports a response.
process_namecan beunknownif the server exits before Windows allows its name to be resolved. - In-flight HTTP request tracking is capped (default 65536, configurable via
max_http_requests); excess requests are dropped and counted in the periodic summary. URL query strings are excluded to avoid collecting secrets and unbounded metric cardinality. Request paths longer thanhttpflow_path_limit(default 256) are truncated and flagged withtruncated.