Skip to main content

Linux Datasets

Linux datasets define collection rules for Linux devices (dataset type linux). Most collector types, including file log collection, are configured through the dataset creation wizard — see Management; the connection event and script execution collectors below are configured via device YAML. For the dataset and profile model, see Overview.

Datasets do not run over agentless SSH

A Linux device collecting agentless over SSH runs inventory collection only — every dataset assigned to it is skipped, including the collectors on this page. Assign datasets to Linux devices running the VirtualMetric Agent. See Linux for the two deployment modes.

Collector Types​

  • Linux System Events (linux_host_log_collector): File path input for the system log source.
  • Linux Audit Events (linux_audit_report_log_collector): File path input for the audit log source.
  • Linux Firewall Events (linux_firewall_log_collector): File path input for the firewall log source.
  • Linux TCP Connections (linux_tcp_connection_collector): Established TCP connections with process attribution and destination geolocation.
  • Linux Remote Connections (linux_remote_connection_collector): Remote login sessions (SSH and console) from host session records.
  • Linux Script Execution (linux_execute_collector): Runs a script or executable and collects its standard output as log events.
  • Linux Metrics (linux_metrics_collector): The host's performance, sampled on an interval — CPU, memory, swap, volumes, block devices, network interfaces, and the busiest processes — as ECS metric documents.
  • Linux Suricata Stats (linux_suricata_stats_collector): The engine counters of a Suricata IDS/IPS sensor on the host, read from its command socket on an interval, as ECS metric documents.
  • Linux WireGuard Interfaces (linux_wireguard_interface_collector): The WireGuard interfaces on the host, read on an interval as ECS metric documents. See WireGuard.
  • Linux WireGuard Peers (linux_wireguard_peer_collector): The peers of the host's WireGuard interfaces — endpoint, last handshake, and bytes received and sent — read on an interval as ECS metric documents. See WireGuard.
  • Linux Certificates (linux_certificate_collector): The certificates in the host's certificate files, read on an interval as an inventory, each marked added, changed, unchanged or removed. See Linux Certificates.
  • Linux Docker Containers (linux_docker_container_collector): The containers of a Docker engine, running or not, read on an interval as an inventory, each marked added, changed, unchanged or removed. See Linux Docker.
  • Linux Docker Logs (linux_docker_log_collector): The lines the containers of a Docker engine write to their standard output and error, with each container's name, image and labels. See Linux Docker.
  • Kubernetes Pod Logs (linux_kubernetes_pod_log_collector): Container logs written by the kubelet under /var/log/pods, decoded as CRI and filtered by namespace, pod label, or owner kind.
  • Kubernetes Metrics (linux_kubernetes_metrics_collector): Node, pod, and container usage and status read from the kubelet, with optional cluster-object and cAdvisor series.

Connection Event Collectors​

The TCP connection (linux_tcp_connection_collector) and remote connection (linux_remote_connection_collector) collectors capture host network activity as ECS events. The TCP collector reports established TCP connections with process attribution and destination geolocation. The remote connection collector reports remote login sessions (SSH, derived from pts* devices) and local console sessions (tty*) from the host session records. Both accept only a pipeline_name property for routing; collection cadence, connection caching, and country-level geolocation are handled automatically.

note

These collectors are configured via device YAML files under config/devices/ — they are not available in the dataset creation wizard.

Enabling TCP and remote connection collection on a Linux device, routing both to a pipeline...

devices:
- id: 123458
name: linux-host
type: linux
status: true
definitions:
- name: linux_tcp_connection_collector
status: true
properties:
pipeline_name: my-pipeline
- name: linux_remote_connection_collector
status: true
properties:
pipeline_name: my-pipeline

Each established TCP connection is emitted as an ECS event with process and destination geo...

{
"@timestamp": "2026-07-24T10:15:03.472Z",
"event": {
"dataset": "linux.tcp_connection",
"category": ["network"],
"type": ["connection", "start"],
"action": "established"
},
"host": { "name": "linux-host", "ip": ["10.0.0.12"] },
"network": { "transport": "tcp", "type": "ipv4" },
"source": { "ip": "10.0.0.12", "port": 52344 },
"destination": {
"ip": "140.82.112.3",
"port": 443,
"geo": { "country_iso_code": "US", "country_name": "United States" }
},
"process": { "name": "curl", "pid": 4821 }
}

A remote login session is emitted with the authenticated user and session type...

{
"@timestamp": "2026-07-24T10:12:55.000Z",
"event": {
"dataset": "linux.remote_connection",
"category": ["authentication", "session"],
"type": ["start"],
"action": "SSH"
},
"message": "admin@10.0.0.5",
"host": { "name": "linux-host", "ip": ["10.0.0.12"] },
"network": { "transport": "tcp" },
"user": { "name": "admin" },
"source": {
"ip": "10.0.0.5",
"geo": { "country_iso_code": "US", "country_name": "United States" }
}
}

Script Execution​

The linux_execute_collector runs a script or executable on the Linux host and collects its standard output as log events. Each execution is defined as an input with its own interpreter, arguments, schedule, and pipeline routing, so a single dataset can run multiple scripts.

note

This collector is configured via device YAML files under config/devices/. Scripts must be placed in the agent's user/scripts (operator-owned, survives upgrades) or package/scripts (product-shipped) directory; the path property is a file name only.

Input properties​

Each entry under inputs: defines one script execution. Inputs share the standard dataset input frame (id, name, status) plus the following properties:

FieldRequiredTypeDefaultDescription
pathYstring—Script or executable file name (not a path). Resolved under the agent's scripts directories. Absolute paths and .. traversal are rejected.
interpreterNstring—Interpreter that runs the script. Linux: sh, bash, or exe. Windows: ps1, cmd, or exe. exe runs path directly. There is no implicit default; if unset (or unrecognized), shell is used instead.
shellNstring—Custom interpreter for the fall-through case (e.g. python3 or an executable path). On Windows with interpreter: ps1, selects the PowerShell edition: pwsh (7+), powershell (5.1), or unset (auto).
argsNlist—Arguments passed to the script or executable.
environmentNmap—KEY: VALUE pairs appended to the inherited process environment.
working_directoryNstringinheritWorking directory for the child process.
timeoutNint120Maximum run time in seconds. A non-positive value falls back to 120. On timeout, the entire child process group is terminated.
max_bytesNint0Cap on captured output in bytes. 0 means unbounded.
emit_on_errorNbooleanfalseWhen true, a non-zero exit code still emits the captured stdout. A timeout or a failure to start never emits, regardless of this setting.
execution_policy_bypassNbooleanfalseWindows ps1 only. Adds -ExecutionPolicy Bypass to the PowerShell invocation.
cronNstring—Per-input schedule (cron expression). An empty value or "0" runs the script on every collection cycle.
max_retriesNint1Number of times a failed run is retried on subsequent collection cycles.
skippableNbooleantrueWhen true, missed schedule slots collapse into a single run. When false, each missed slot is replayed.
pipeline_nameNstring—Route the output to a specific preprocessing pipeline by name.
ignore_timeNbooleantrueSkip time-based filtering on the emitted events.

Output​

Captured stdout is converted to log events one line at a time:

  • Trailing line terminators are trimmed once; if nothing remains, no events are emitted (an empty or whitespace-only run produces nothing).
  • The remaining output is split on newlines, producing one event per line. A trailing carriage return on each line is stripped, so CRLF output is handled.
  • Interior blank lines are preserved; only trailing blank lines from a final newline are dropped.
  • stderr is never emitted as events. The exit code is logged and gates emit_on_error.

Example​

Running a health-check shell script every five minutes and routing its output to a pipeline...

devices:
- id: 123459
name: linux-host
type: linux
status: true
definitions:
- name: linux_execute_collector
status: true
inputs:
- id: 3001
name: Disk Health
status: true
properties:
path: disk-health.sh
interpreter: bash
args:
- "--all"
cron: "*/5 * * * *"
timeout: 30
pipeline_name: my-pipeline

Each line of standard output becomes a separate log event...

{ "message": "/dev/sda1 usage 62%" }
{ "message": "/dev/sdb1 usage 41%" }

File Log Collection​

The linux_file_log_collector collects lines from arbitrary log files on Linux hosts. It supports glob path expansion, lookback-based backfill, multiline parsing, include/exclude filtering, character-set decoding, and per-pipeline routing. The path syntax uses Linux-style paths (e.g. /var/log/myapp/*.log).

note

File log datasets can be created through the dataset creation wizard (Linux File Logs) or configured via device YAML files under config/devices/ using the schema below.

Device-level property​

FieldRequiredTypeDefaultDescription
file_log_concurrencyNint8Maximum number of inputs processed in parallel per device. A zero or negative value resolves to 8.

Input properties​

Each entry under inputs: defines one file log source. Inputs share the standard dataset input frame (id, name, status) plus the following properties:

FieldRequiredTypeDefaultDescription
pathYstring—File path or glob pattern. Supports wildcards (e.g. /var/log/myapp/*.log, C:\Logs\*\app-*.log).
start_dateNint300Lookback window in seconds: only files modified within this window are read. A negative value (e.g. -1) disables time-based filtering. 0 is not a way to narrow the window — it resolves to the 300 default.
ignore_cacheNbooleanfalseSkip the persisted file-position cache (re-read from the start).
ignore_old_dateNbooleanfalseSkip old-date filtering.
ignore_retentionNbooleanfalseSkip retention filtering.
ignore_timeNbooleanfalseSkip time-based filtering.
date_formatNstring—Custom timestamp layout using Java-style tokens (e.g. yyyy-MM-dd HH:mm:ss). Used to extract an event timestamp from each line.
line_parserNobject | string—Multiline detection rules. See Line parser.
filter_modeNstringexcludeinclude or exclude. Synonyms: inclusive/allow (include), exclusive/deny (exclude).
filter_rulesNarray—Include/exclude rules. See Filter rules. Alias: filters.
encodingNstring | int—Character encoding for the file. Accepts an alias (e.g. utf-8, windows-1252) or a numeric decoder ID. See Encoding aliases.
pipeline_nameNstring—Route matched lines to a specific preprocessing pipeline by name.

Line parser​

line_parser controls how multi-line log entries are reassembled. It accepts either an object or a bare string shorthand.

Accepted type values:

ValueAliasesBehavior
regex1A regex pattern detects where a new entry begins.
newlinenew_line, 2Each raw line is a separate entry.
stringprefix, 3Lines beginning with a literal string mark a new entry.

Object fields:

FieldRequiredTypeDescription
typeNstring | intOne of the values above. If omitted and regex is set, regex is assumed.
regexNstringPattern used by regex, or the literal prefix used by string/prefix. Compiled with Go's RE2 engine, which does not support lookarounds or backreferences.
valueNstringAlias for regex.
date_basedNbooleanMerge continuation lines using date boundaries detected via date_format.
has_spaceNbooleanTreat leading whitespace on a line as a continuation of the previous entry.

A bare string at line_parser: is treated as type: regex with that pattern:

line_parser: '^\d{4}-\d{2}-\d{2}'

Filter rules​

filter_rules is an array of include/exclude rules applied to the content of each record, after line parsing. The effect of each match (keep or drop) is determined by filter_mode. These rules select content; the files themselves are selected by path.

Each rule accepts:

FieldRequiredTypeDescription
typeNstring | intregex (1) or string (2). If omitted, inferred from which field is set.
regexNstringRegex pattern matched against the record. Compiled with a .NET-compatible engine, so lookarounds and backreferences are available — unlike line_parser.regex, which uses RE2.
sourceNstringLiteral text matched against the record, with optional leading and trailing wildcards. Not a file path — use path to select files.
valueNstringAlias for source.

A bare array of regex strings is also accepted and is equivalent to type: regex for each entry.

A string rule matches its text literally: regex metacharacters carry no special meaning, so *[error]* looks for the six characters [error] rather than a character class. Wildcards are positional and only recognized at the ends:

sourceMatches a record that
*text*contains text
text*starts with text
*textends with text
textcontains text

An interior * is matched as a literal asterisk and reported in the Console Logs — use type: regex for pattern matching. A source that is empty once its wildcards are removed matches nothing.

A rule the reader cannot use — an invalid regex, or a string rule with an empty literal — is reported and then discounted. When no rule in the set is usable, filtering is inactive and no record is dropped, including under filter_mode: include.

Encoding aliases​

encoding accepts a numeric decoder ID or one of the following aliases. Dashes, underscores, dots, and spaces are ignored during alias lookup, so utf-8, utf_8, and UTF 8 all resolve identically.

Alias(es)ID
utf81
utf8bom2
utf16be3
utf16le4
utf16bebom5
utf16lebom6
gbk11
latin1, iso8859115
windows1250, cp125050
windows1251, cp125151
windows1252, cp125252
windows1256, cp125656

The EBCDIC code pages (IDs 40--42) end lines with NEL (0x15), not LF, so they are not split into lines correctly. No alias maps to them.

Upgrading

Earlier versions accepted encoding but did not apply it to plain-text log files, which were read as raw bytes. A UTF-16 or code-page source therefore arrived garbled. If you compensated downstream, for example with a processor that strips NUL bytes or re-encodes the text, remove that workaround when you upgrade. The file is now decoded correctly, and the workaround will corrupt the correctly decoded text.

Example​

Collecting a rotating application log on Linux with regex-based multiline detection and an include filter for errors and warnings...

devices:
- id: 123457
name: app-linux
type: linux
status: true
properties:
file_log_concurrency: 2
definitions:
- name: linux_file_log_collector
status: true
inputs:
- id: 1001
name: Application Logs
status: true
properties:
path: /var/log/myapp/*.log
start_date: 300
date_format: yyyy-MM-dd HH:mm:ss
line_parser:
type: regex
regex: '^\d{4}-\d{2}-\d{2}'
date_based: true
filter_mode: include
filter_rules:
- type: regex
regex: '^(ERROR|WARN)'
encoding: utf-8
pipeline_name: my-pipeline

Linux Metrics​

The linux_metrics_collector samples the host's performance on the agent at a fixed interval: CPU, memory, swap, volumes, block devices, network interfaces, and the busiest processes. It reads them from /proc, df, and ps.

note

Linux Metrics datasets can be created through the dataset creation wizard (Linux Metrics, under the Linux category) or configured via device YAML files under config/devices/. Like every dataset on this page, it runs only on Linux devices with the VirtualMetric Agent, not on devices collecting agentless over SSH.

Wizard fields​

The Dataset configuration step asks for:

FieldRequiredBehavior
Interval (seconds)NLeave empty to read every 60 seconds. At least 10.
Parts to readYAt least one part must be ticked. All seven are ticked by default, and with every part ticked, all of them are read.
Pre-processing pipelineNThe pipeline the dataset's records enter, as on every dataset.

The wizard writes interval only when one is entered, and items only when a part is left out. An untouched dataset therefore follows the agent's defaults.

Properties​

FieldRequiredTypeDefaultDescription
intervalNint60Seconds between readings. At least 10. A restart or a failover keeps the schedule: the next reading is due one interval after the last. The rate baseline is not kept, so the rate parts start again with the second reading.
itemsNstring[]every partThe parts to read, as listed below.
pipeline_nameNstring—Route the dataset's records to a specific preprocessing pipeline by name.
PartConsole labelOne document per
cpuCPU usagereading
memoryMemory usagereading
swapSwap usagereading
filesystemFile system usagevolume
diskioDisk I/Oblock device
networkNetwork trafficnetwork interface
processesBusiest processesbusy process

The busiest processes are the 25 that use the most CPU and the 25 with the most resident memory.

Rate parts start with the second reading

Most of what the kernel reports are counters since boot, so a rate is measured between two readings. The first reading after the agent starts, or after a part is added to items, has nothing to measure against: it writes only the gauges (memory, swap, and filesystem). The rate parts (cpu, diskio, network, and processes) start with the second reading, one interval later. A disk, interface, or process that appears between two readings is measured from the next one.

Output​

Each reading writes ECS metric documents with event.dataset set to linux.<part> — for example linux.cpu or linux.network.

Example​

Reading every part except the busiest processes, every 30 seconds...

devices:
- id: 123462
name: linux-host
type: linux
status: true
definitions:
- name: linux_metrics_collector
status: true
properties:
interval: 30
items:
- cpu
- memory
- swap
- filesystem
- diskio
- network
pipeline_name: my-pipeline

Suricata Stats​

The linux_suricata_stats_collector reads the engine counters of a Suricata IDS/IPS sensor running on the host:

  • packets captured and dropped;
  • the decoder, flow, TCP, defrag, and app-layer counters;
  • alerts;
  • memory in use.

On its interval the agent asks Suricata's command socket for dump-counters. It writes one ECS metric document for the engine's totals and one for each Suricata thread: the workers (W#01-eth0, ...), the flow manager (FM#01), and Global, which holds the counters no thread owns.

note

This dataset is configured via device YAML files under config/devices/. Like every dataset on this page, it runs only on Linux devices with the VirtualMetric Agent. One Suricata sensor is read per host: if a device is assigned more than one dataset of this type, only the first is read.

Sensor setup​

Nothing has to be set up on the sensor. The dataset relies on two Suricata defaults in suricata.yaml:

unix-command:
enabled: auto # packaged Suricata puts the socket at /var/run/suricata/suricata-command.socket
stats:
enabled: yes

Suricata creates the socket with mode 0660, in a directory it creates with mode 0750, both owned by the user Suricata runs as. The agent's user must be that user, root, or a member of that user's group.

Properties​

FieldRequiredTypeDefaultDescription
socketNstring/var/run/suricata/suricata-command.socketThe command socket. Set it whenever the sensor's socket is elsewhere: when unix-command.filename is set in suricata.yaml, or when Suricata was built with a different state directory — a source build with the default prefix uses /usr/local/var/run/suricata/suricata-command.socket.
timeoutNint10Seconds one reading may take, connecting included. At most 60.
intervalNint60Seconds between readings. At least 10, as for every Linux metrics dataset; a smaller value falls back to the default.
pipeline_nameNstring—Route the dataset's records to a specific preprocessing pipeline by name.

Output​

Every document carries definition id 16150 and event.dataset linux.suricata_stats, with the same event.* and host.* fields as the host's other metrics documents.

  • linux.suricata_stats.thread is total for the totals document and the thread's name otherwise.
  • The counters sit under linux.suricata_stats by Suricata's own names — for example linux.suricata_stats.capture.kernel_packets, linux.suricata_stats.decoder.pkts, linux.suricata_stats.detect.alert, and linux.suricata_stats.flow.memuse.
  • The totals document also has linux.suricata_stats.uptime, in seconds.
Values are written as Suricata keeps them, with no rates

Most counters count from Suricata's start; some are current figures, such as flow.memuse and tcp.memuse. The socket does not say which is which, so a rate is a query's or a pipeline's job. This differs from the host metrics datasets, which write a *_per_sec value beside each counter.

When the sensor cannot be read, the reading writes nothing, logs why, and is retried after the interval. The causes are no Suricata on the host, the command socket turned off, stats are disabled in the config, or stats not yet synchronized just after Suricata starts.

Suricata's EVE events (alerts, flows, DNS, HTTP, TLS) are logs, not counters. Collect them with a file log dataset on eve.json, which is read as JSON lines.

Example​

Reading the counters of the host's Suricata sensor every 60 seconds from its default command socket...

devices:
- id: 123460
name: linux-suricata
type: linux
status: true
definitions:
- name: linux_suricata_stats_collector
status: true
properties:
socket: /var/run/suricata/suricata-command.socket
timeout: 10
interval: 60
pipeline_name: my-pipeline

WireGuard​

The linux_wireguard_interface_collector and linux_wireguard_peer_collector read the WireGuard interfaces on the host and their peers, as wg show does — what Telegraf's wireguard input reports. WireGuard logs almost nothing by design: which peer connected from where, and when it last shook hands, is known only by asking the interface. These datasets ask it on an interval and write the answer.

The agent reads the kernel's own interfaces and those of a userspace implementation, such as wireguard-go or boringtun. An interface and a peer are two schemas, so they are two datasets. A device may be assigned either or both, and the two read the host in one listing when they are due together.

note

WireGuard datasets can be created through the dataset creation wizard (Linux WireGuard Interfaces and Linux WireGuard Peers, under the Linux category) or configured via device YAML files under config/devices/. Like every dataset on this page, they run only on Linux devices with the VirtualMetric Agent. Windows and macOS have WireGuard datasets of their own; Solaris and AIX have none.

DatasetCollectorevent.datasetDefinition idOne record per
Linux WireGuard Interfaceslinux_wireguard_interface_collectorlinux.wireguard_interface20150interface
Linux WireGuard Peerslinux_wireguard_peer_collectorlinux.wireguard_peer20151peer of each interface

The agent has to be allowed to administer the network (CAP_NET_ADMIN), which it is when it runs as root. An agent that is not allowed is told operation not permitted: the datasets write nothing for that reading and log why. A host without WireGuard, or with no interface, writes nothing, and that is no error.

Wizard fields​

The Dataset configuration step asks for:

FieldRequiredBehavior
Interval (seconds)NLeave empty to read every 60 seconds. At least 10.
Pre-processing pipelineNThe pipeline the dataset's records enter, as on every dataset.

Below them, the Filters section has the Network interfaces group, with Include interfaces and Exclude interfaces. It has no Skip container networking interfaces switch: none of the interfaces that switch leaves out is a WireGuard interface. On a Linux WireGuard Peers dataset, Use the filter of another dataset offers the tenant's Linux WireGuard Interfaces datasets. See Management for how filters work.

Properties​

Both datasets take the same properties:

FieldRequiredTypeDefaultDescription
intervalNint60Seconds between readings. At least 10, as for every Linux metrics dataset.
filterNobject—Which interfaces it reads, by their names, under the interface scope the network interface datasets also use: filter.interface.include and filter.interface.exclude. With none, it reads every interface. The Peers dataset reads the peers of the interfaces its own filter keeps, and may follow a Linux WireGuard Interfaces dataset's filter instead.
pipeline_nameNstring—Route the dataset's records to a specific preprocessing pipeline by name.

A listing is given 10 seconds. The kernel answers at once, but a userspace implementation that does not answer holds a listing for as long as it likes: one that outlives its 10 seconds is left to end, and no other is started until it has.

Output​

Every document carries the same event.* and host.* fields as the host's other metrics documents, with event.kind metric and event.category network.

Linux WireGuard Interfaces writes one document per interface, in the order of their names. Its fields are under linux.wireguard_interface:

FieldDescription
nameThe interface's name, such as wg0.
typeWhere the interface runs: linux_kernel for the kernel's own, userspace for an implementation such as wireguard-go or boringtun.
public_keyThe interface's public key. Left out for an interface that has no key yet.
listen_portThe UDP port it listens on, 0 when it has none.
firewall_markIts firewall mark, 0 when it has none.
peer_countHow many peers it has.
received_bytes, sent_bytesIts peers' received_bytes and sent_bytes, summed: WireGuard counts per peer.
received_bytes_per_sec, sent_bytes_per_secWhat was received and sent per second since the dataset's last delivered reading. See the rates below.

Linux WireGuard Peers writes one document per peer of each interface, in the order of the interfaces' names and of the peers' public keys. Its fields are under linux.wireguard_peer:

FieldDescription
interfaceThe name of the interface the peer belongs to.
public_keyThe peer's public key.
allowed_ipsThe addresses the peer may send from, as a list of CIDR ranges.
endpointWhere the peer was last heard from, or where it is configured to be, as address:port. Left out for a peer never heard from and configured nowhere.
last_handshakeWhen the last handshake was made, in UTC.
seconds_since_handshakeHow long before the reading the last handshake was made.
received_bytes, sent_bytesThe bytes received from the peer and sent to it since the interface came up.
received_bytes_per_sec, sent_bytes_per_secWhat was received from the peer and sent to it per second since the dataset's last delivered reading. See the rates below.
persistent_keepaliveThe keepalive interval in seconds, 0 when none is sent.
protocol_versionThe WireGuard protocol version. Left out when the implementation does not say it.

The endpoint is also the document's source.address, source.ip, and source.port, with network.transport udp. A peer that roams answers from another address in the next reading, so its endpoint and source change.

last_handshake and seconds_since_handshake are left out for a peer no handshake was made with since the interface came up. WireGuard shakes hands again every two minutes or so while a tunnel carries traffic, so a peer whose handshake is older than a few minutes is idle or gone.

Private and preshared keys are never written

The kernel answers an interface's private key and a peer's preshared key to whoever may ask for an interface. The agent leaves both behind: no document holds either.

Rates are measured between two delivered readings

received_bytes and sent_bytes count from when the interface came up. received_bytes_per_sec and sent_bytes_per_sec are what was received and sent since the dataset's last delivered reading, per second, to two decimals; none on a first reading, for a new interface or peer, or for a counter that went back.

Migrating from Telegraf​

  • Telegraf's wireguard input writes a wireguard_device and a wireguard_peer measurement. They correspond to the Linux WireGuard Interfaces and Linux WireGuard Peers datasets here, which can be assigned separately.
  • The interfaces a Telegraf wireguard input lists in devices are the datasets' filter.interface.include. With none, every interface is read, as in Telegraf.

Example​

Reading the host's WireGuard interfaces every five minutes, and the peers of wg0 every minute...

devices:
- id: 123463
name: linux-wireguard
type: linux
status: true
definitions:
- name: linux_wireguard_interface_collector
status: true
properties:
interval: 300
pipeline_name: my-pipeline
- name: linux_wireguard_peer_collector
status: true
properties:
interval: 60
filter:
interface:
include: ["wg0"]
pipeline_name: my-pipeline

Each peer is written with its endpoint as the document's source...

{
"@timestamp": "2026-10-03T10:15:00Z",
"event": {
"kind": "metric",
"module": "linux",
"dataset": "linux.wireguard_peer",
"category": ["network"],
"type": ["info"]
},
"host": { "name": "linux-wireguard" },
"linux": {
"wireguard_peer": {
"interface": "wg0",
"public_key": "xTIBA5rboUvnH4htodjb6e697QjLERt1NAB4mZqp8Dg=",
"allowed_ips": ["10.8.0.2/32"],
"endpoint": "198.51.100.24:51820",
"last_handshake": "2026-10-03T10:14:30Z",
"seconds_since_handshake": 30,
"received_bytes": 1843120,
"sent_bytes": 9921044,
"persistent_keepalive": 25,
"protocol_version": 1
}
},
"source": { "address": "198.51.100.24", "ip": "198.51.100.24", "port": 51820 },
"network": { "transport": "udp" }
}

Linux Certificates​

The linux_certificate_collector reads the certificates in the host's certificate files on the agent, as an inventory: one record per certificate and file. The certificate a service presents over the network is in every result of a TLS Check and an HTTP Check instead, under tls.server.x509.*, with the certificate of its chain that expires first.

Two things go unseen without it:

  • A server certificate expiring on a host no check reaches. It is a record whose days_left runs low.
  • A root added to the host's trust store, which is how TLS interception is planted (MITRE ATT&CK T1553.004, Install Root Certificate). It is a record marked added.
note

Linux Certificates datasets can be created through the dataset creation wizard (Linux Certificates, under the Linux category) or configured via device YAML files under config/devices/. Like every dataset on this page, it runs only on Linux devices with the VirtualMetric Agent.

DatasetCollectorevent.datasetDefinition idOne record per
Linux Certificateslinux_certificate_collectorlinux.certificate2121certificate and file

Wizard fields​

The Dataset configuration step asks for:

FieldRequiredBehavior
Interval (seconds)NLeave empty to read every 3600 seconds. At least 10.
Certificate pathsNOne path per line. Leave empty to read /etc/ssl, /etc/pki and /etc/letsencrypt/live, which the empty field shows; paths you enter replace these. The editor refuses a path that is not absolute, one in /proc, /sys, /dev or /run, and one that holds a comma. A path is cleaned before it is checked, so /tmp/../proc/1 is refused as /proc/1 is.
Pre-processing pipelineNThe pipeline the dataset's records enter, as on every dataset.

Properties​

FieldRequiredTypeDefaultDescription
intervalNint3600Seconds between readings. At least 10. A restart or a failover resumes from the dataset's last reading.
certificate_pathsNstring[]/etc/ssl, /etc/pki, /etc/letsencrypt/liveWhere to read certificates, a list or one comma-separated text. Each path is absolute, and is a file, a directory, or a glob of either (/etc/haproxy/certs/*.pem). A directory is walked, at most 16 directories below it, for its .pem, .crt, .cer, .cert and .der files. A file a path names itself is read whatever it is called. /proc, /sys, /dev and /run are never read.
keystore_pathsNstring[]—The PKCS #12 and JKS keystores to read, a list or one comma-separated text, named as certificate_paths names files: a directory is walked for its .p12, .pfx, .jks, .keystore and .truststore files; a file a path names is read whatever it is called ($JAVA_HOME/lib/security/cacerts). See Keystores.
keystore_passwordNstring—The keystores' password, one for all: plain text, ${ENV_VAR}, or $secret{...}. A reference keeps it out of the dataset's settings.
pipeline_nameNstring—Route the dataset's records to a specific preprocessing pipeline by name.

How the files are read​

  • Only certificates are read. A file is read whole and only its CERTIFICATE blocks are decoded: a private key in the same file is passed over.
  • A certificate that does not parse is still written, by its fingerprints and its file, with error.message saying why. A certificate planted in a trust store must not go unseen because it is malformed.
  • A bundle is written as each certificate it holds, in the file's order, and a certificate it holds twice is written once. A file with no PEM block is read as DER.
  • A trust store's directory is made of symbolic links. A link to a file is read, under the name it was found by. A link to a directory is entered only where a path names it, and its files are then written under the path as it was given, with where each really is in file.target_path. A file that several paths or links lead to is read once, where it was found first.
  • A distribution keeps its roots both as one bundle and as a directory of single certificates, so each root is written once per file that holds it.
  • A path that leads nowhere on the host is passed over, such as /etc/pki on Debian. The dataset is unread, with a warning, only when none of its paths or keystores can be read.
  • A file that cannot be read does not have its certificates marked removed. A file larger than 4 MiB, and a file, a directory or a path the agent cannot read, are passed over with a warning, and so is a directory a glob cannot list. What the last reading read of them is kept, and compared with again once they can be read. A file that is gone has its certificates removed.
  • A reading lists at most 10,000 certificates, and logs a warning when it stops there. Such a reading has not looked at everything, so it marks no certificate removed.

Output​

Each reading writes ECS inventory documents with event.kind set to state and event.dataset set to linux.certificate, one per certificate and file. The file is written as ECS's file: file.path, file.name, file.directory and file.extension, and file.target_path when the file was found through a symbolic link. The certificate's fields are under linux.certificate:

FieldDescription
subject.distinguished_name, subject.common_nameThe subject's whole name, and its common name as a list of one.
issuer.distinguished_name, issuer.common_nameThe issuer's, the same way.
serial_numberUpper-case hex, without leading zeros.
not_before, not_afterRFC 3339, in UTC.
days_leftThe whole days the certificate has left at the reading, rounded down: one that expired an hour ago has -1.
version_number3, or 1 for the oldest roots.
signature_algorithmFor example SHA256-RSA, ECDSA-SHA384, or SHA1-RSA.
public_key_algorithm, public_key_sizeRSA, ECDSA or Ed25519, and the key's size in bits.
public_key_curve, public_key_exponentAn elliptic key's curve (P-256), an RSA key's exponent (65537).
alternative_namesThe DNS names, then the IP addresses, the e-mail addresses, and the URIs.
key_usageFor example digital_signature, key_encipherment, cert_sign, or crl_sign.
extended_key_usageFor example server_auth, client_auth, or code_signing, and any other by its object identifier.
is_caWhether its basic constraints say it is a CA's. A version 1 root has none, and says false.
self_signedWhether it names itself as its issuer. The signature is not verified.
hash.sha1, hash.sha256Its fingerprints, in upper-case hex.
chain.trustedWhether its chain verifies against the host's trust store at the reading. See Chain Verification.
chain.statusWhen chain.trusted is false, why: unknown_authority, expired, not_yet_valid, not_authorized_to_sign, name_constraints, incompatible_usage, too_many_intermediates, insecure_algorithm, unhandled_critical_extension, no_trust_store, or error.
keystore.typeOn a keystore's certificate: pkcs12 or jks. See Keystores.
keystore.aliasOn a keystore's certificate: the entry's alias, a PKCS #12 bag's friendly name or a JKS entry's alias. Left out when it has none.
keystore.trustedOn a keystore's certificate: whether the keystore holds it as a trusted certificate, a JKS trusted-certificate entry or a PKCS #12 bag Java marks as one. A Java trust store's roots say true.
has_private_keyOn a keystore's certificate: whether the keystore holds the certificate's private key. The rest of a chain says false.

From a dataset's second reading on, event.action marks each certificate added, changed, unchanged or removed:

  • A certificate is known by its file and its fingerprint, so a renewed certificate is the old one removed and the new one added, never one changed.
  • days_left is left out of what a reading compares, so a day passing changes no certificate.
  • Changing certificate_paths or keystore_paths starts a fresh baseline: the first reading after the change marks nothing, rather than writing every certificate the dataset no longer reads as removed.

Solaris, AIX and macOS have certificate datasets of their own: see Solaris, AIX, and macOS Datasets.

Keystores​

The dataset reads the keystores keystore_paths names: PKCS #12 (.p12, .pfx, which OpenSSL, Windows' certificate export and Java write) and Java's JKS (.jks, .keystore, .truststore, and a cacerts named by its path). They are told apart by what they hold, not by their names. Each certificate a keystore holds is a record of the file, as a bundle's are, with the file's fields and keystore.type, keystore.alias, keystore.trusted and has_private_key, described under Output above.

  • A key is never decrypted. A PKCS #12 file's certificates are read, and the MAC that protects the file is checked, with the password; its keys are only matched to their certificates. A JKS file's private-key entries give their certificate chains without their keys.
  • A wrong password is the keystore's error, not the reading's. A keystore that refuses the password, is no keystore the dataset reads (JCEKS, BKS, an IBM .kdb), or cannot be read is passed over with a warning, and what the last reading read of it is kept, as an unreadable file's is. So is every keystore when the password's reference cannot be resolved.
  • A certificate a keystore holds twice, under two aliases, is written once, with the first alias.
  • One password is the dataset's, for all its keystores: keystores of different passwords are read by different devices' datasets, or not at all.

Chain Verification​

Every certificate says whether its chain verifies against the host's trust store at the reading: chain.trusted, and when it is false, chain.status, why. The certificate authorities the same reading found are its intermediates, so a server certificate whose chain a store or a bundle holds verifies whether the trust store holds the intermediate or not. Every usage is accepted, a client's or a code signing certificate's as a server's; no name is checked, and revocation is not checked. This holds for every host's certificate dataset:

  • Linux, Solaris and AIX verify against the roots of the host's trust store files: Linux's /etc/ssl/certs/ca-certificates.crt and its kin, /etc/certs on Solaris, /var/ssl on AIX.
  • Windows verifies with its own verifier, which may fetch an issuer the machine does not hold and installs a root of Microsoft's programme into AuthRoot when a chain reaches one. A certificate of the Disallowed store has no chain.
  • macOS verifies with Apple's verifier, which evaluates every chain as a TLS server's: a certificate that is not for TLS servers may say false with error.
  • A chain is verified only by an agent on the host. A Solaris, AIX or macOS host the Director reads over SSH writes no chain, since the Director's trust store is not the host's.
chain.statusWhy the chain does not verify
unknown_authorityNo chain reaches a root the host trusts: a self-signed certificate the trust store does not hold, or an issuer the reading and the trust store lack.
expired, not_yet_validThe certificate is out of its dates, or (expired) an issuer of its chain is out of its.
not_authorized_to_signAn issuer that is no certificate authority.
name_constraintsAn issuer's name constraints refuse its names.
incompatible_usageAn issuer may not issue for the certificate's usage.
too_many_intermediatesA chain longer than an issuer allows.
insecure_algorithmA SHA-1 or MD5 signature on a certificate other than a root.
unhandled_critical_extensionA critical extension the verifier does not know.
no_trust_storeThe host's trust store could not be read.
errorAny other failure.

chain is compared like the certificate's other fields: a certificate whose chain stops verifying (it expired, its root left the trust store) is changed. A certificate that does not parse is not verified.

Example​

Reading the usual certificate directories and an HAProxy certificate directory every hour...

devices:
- id: 123461
name: linux-host
type: linux
status: true
definitions:
- name: linux_certificate_collector
status: true
properties:
certificate_paths:
- /etc/ssl
- /etc/pki
- /etc/letsencrypt/live
- /etc/haproxy/certs/*.pem
interval: 3600
pipeline_name: my-pipeline

Linux Docker​

The linux_docker_container_collector and linux_docker_log_collector read the containers of a Docker engine and what they write — what Telegraf's docker and docker_log inputs read. Edge servers, CI runners and small deployments run their workloads in Docker or Docker Compose and keep none of their logs under /var/log, and the host's own datasets see a container only as processes. Kubernetes Pod Logs reads a Kubernetes node's containers only.

The agent speaks to the engine's API: through its socket, /var/run/docker.sock, or over TCP. A container and a line it writes are two schemas, so they are two datasets, and a device may be assigned either or both.

The containers dataset also answers what a security team asks first about a container: is it privileged, which capabilities were added, which host paths it mounts — a writable mount of /var/run/docker.sock administers the engine — and which ports it publishes.

note

Linux Docker datasets can be created through the dataset creation wizard (Linux Docker Containers and Linux Docker Logs, under the Linux category) or configured via device YAML files under config/devices/. Like every dataset on this page, they run only on Linux devices with the VirtualMetric Agent. Windows, macOS, Solaris and AIX have no Docker dataset.

DatasetCollectorevent.datasetDefinition idOne record per
Linux Docker Containerslinux_docker_container_collectorlinux.docker_container22100container, running or not
Linux Docker Logslinux_docker_log_collectorlinux.docker_log39line a container writes to its standard output or error
Speaking to the engine is administering it

The agent has to be allowed to speak to the engine: it runs as root, or as a member of the docker group. Either way it can administer the engine and every container it runs. An engine reached over TCP without TLS lets anyone who can reach it do as much, which is why Docker serves its API over TCP with --tlsverify.

Wizard fields​

The Dataset configuration step asks, on both datasets, for the engine:

FieldRequiredBehavior
Docker endpointNThe engine's socket, as unix:///path or the path alone, or an engine reached over TCP, as tcp://host:port or https://host:port. Leave empty for unix:///var/run/docker.sock.
CA certificate pathNFor a TCP engine: the CA file on the agent's host the engine's certificate is checked against. Leave empty to use the host's trust store.
Certificate path, Private key pathNFor a TCP engine run with --tlsverify: the certificate the agent presents and its key, files on the agent's host. Each requires the other.
Skip certificate verificationNSpeak TLS and accept whatever certificate the engine presents.
Pre-processing pipelineNThe pipeline the dataset's records enter, as on every dataset.

A TLS setting is refused on a socket endpoint. Linux Docker Containers also asks for Interval (seconds): leave it empty to read every 300 seconds, at least 10. Linux Docker Logs also asks for Lookback window: leave it empty for the default 300 seconds, or enter -1 to read a container's whole log.

Below them, the Filters section has the Containers group: Include containers and Exclude containers by name, Include images and Exclude images, and Include labels and Exclude labels. On a Linux Docker Logs dataset, Use the filter of another dataset offers the tenant's Linux Docker Containers datasets. See Management for how filters work.

Properties​

FieldRequiredTypeDefaultDescription
endpointNstringunix:///var/run/docker.sockThe engine: its socket, unix:///path or the path alone, or one reached over TCP, tcp://host:port or https://host:port. A TCP endpoint without a port is reached on 2375, or on 2376 over TLS, as the docker client reaches one.
ca_path, cert_path, key_pathNstring—TLS to an engine reached over TCP, as a docker client given --tlsverify speaks it: the CA the engine's certificate is checked against (the host's own roots when none is named), and the certificate and key the agent presents. They are files on the agent's host. Naming any of them, or insecure_skip_verify, speaks TLS to a tcp:// endpoint. A certificate needs its key. A socket takes none of them.
insecure_skip_verifyNbooleanfalseAccept whatever certificate the engine presents.
filterNobject—Which containers it reads, under the container scope: include and exclude by name, images and exclude_images, labels and exclude_labels. With none, it reads every container. The logs dataset may follow a Linux Docker Containers dataset's filter instead.
pipeline_nameNstring—Route the dataset's records to a specific preprocessing pipeline by name.
intervalNint300linux_docker_container_collector only: seconds between readings. At least 10. Not hourly, as the host's inventory is: containers come and go in minutes.
start_dateNint300linux_docker_log_collector only: how far back, in seconds, a container's log is read the first time it is read. -1 reads its whole log.

The filter's container name is the name without the slash the engine puts before it. An image pattern is matched against the image the container was created from (nginx:1.27) and its name without a tag or digest (nginx). Each also as the other engine writes it: nginx keeps a container Podman runs from docker.io/library/nginx:1.27. A label pattern is key=value, either side with wildcards, or a key alone for the label whatever its value; labels are matched by their real names, dots included. Each pair of lists is matched on its own, and a container is read only when it passes all three.

Linux Docker Containers​

The containers dataset is read on its interval: the engine lists its containers, and each the filter keeps is inspected. It writes one ECS inventory document per container, running or not, in the order of their names, with container.runtime set to docker. What ECS names sits under container; the rest sits under docker.container, where Metricbeat's docker module writes it.

FieldDescription
container.id, container.nameThe container's id and name.
container.image.name, container.image.tagThe image as the container was created from it: nginx:1.27 is nginx and 1.27. Podman writes a Docker Hub image's whole name (docker.io/library/nginx). A reference that names neither a tag nor a digest is latest, as Docker reads it, and one by digest has no tag.
container.image.hash.allThe digests a registry knows the image by, or the image's own id for an image no registry served.
container.labelsThe container's labels, with the dots in their names written as underscores, as Beats write them: com.docker.compose.project is com_docker_compose_project. The filter still matches the labels by their real names.
container.runtimedocker.
docker.container.commandThe program and its arguments, as docker ps --no-trunc writes them.
docker.container.statecreated, running, paused, restarting, removing, exited, or dead.
docker.container.healthstarting, healthy, or unhealthy. Left out for a container without a health check.
docker.container.exit_code, docker.container.finished_atSet on a stopped container.
docker.container.restart_countHow many times the engine restarted it by its restart policy.
docker.container.created, docker.container.started_atWhen it was created, and when it last started.
docker.container.portsThe ports it publishes on the host, as {container_port, protocol, host_ip, host_port}. A port it only exposes is not one.
docker.container.mountsIts mounts, as {type, source, destination, read_only}, type being bind, volume, or tmpfs.
docker.container.network_modeIts network mode.
docker.container.privileged, docker.container.cap_addWhat it may do on the host beyond a container's defaults. Capabilities are named as docker run --cap-add names them, such as NET_ADMIN.

From the dataset's second reading on, event.action marks each container added, changed or unchanged, and a container removed since is written once more, as it was, removed:

  • A container restarted, stopped, or started is changed. Nothing in its fields moves while it does not change.
  • An engine that cannot be read writes nothing and marks nothing removed, and is logged once while it lasts. A container whose inspection fails is not marked removed either.
  • Changing the filter or the engine starts a fresh baseline: the first reading after either changes marks nothing, rather than writing every container the dataset no longer reads as removed.

Linux Docker Logs​

The logs dataset follows each container the filter keeps and writes one record per line, with message, the container's container.* fields, and docker.log.stream, stdout or stderr. A container started with a terminal (docker run -t) writes one stream, so its lines are all stdout.

  • A restart of the agent, or of the engine, neither loses a line nor writes one twice. The agent keeps a position per container on its disk, in the reader cache it keeps the file logs' and Kubernetes pod logs' positions in, and reads on from there. That holds for what the engine still has: lines its log driver rotated away while the agent was stopped are gone before the agent can read them.
  • A new container is read from start_date seconds back — 300 by default, -1 for its whole log. So is every container when the dataset is first assigned.
  • Running containers are followed as they write, and a stopped one is read to its end once. A container started and stopped between two cycles is still read, but a --rm container that comes and goes between two cycles leaves no log.
  • Log drivers. The engine reads json-file, local, and journald logs back directly, and the other drivers' (syslog, gelf, fluentd, …) from the local copy Docker keeps of them by default since 20.10. A container on the none driver, or whose copy is turned off, has its log refused: that is logged once, and not asked for again while the engine lists the container. A log whose reading fails otherwise is retried from its position after 30 seconds, then twice as long each time, up to 10 minutes.
  • On Docker 20.10, a line over 16 KiB read back from local or the dual-logging copy joins the next. Docker 20.10's local store loses such a line's ending when it reads it back, so docker logs shows it joined with the next line, and so does the agent. Docker 24 and later read it back whole.
  • An engine that cannot be reached is logged once while it lasts. Once it answers, its containers are followed again from their positions, including what they wrote meanwhile that the engine still keeps.

Not covered: Windows containers, and the containers' resource use (CPU, memory, I/O) beyond what the inventory holds. Podman's Docker-compatible API is read the same way, through its socket (unix:///run/podman/podman.sock, after systemctl enable --now podman.socket) or podman system service tcp://…. Tried with Podman 5.8.7, not rootless or with journald.

Example​

Reading the containers of the host's engine every five minutes, leaving out BuildKit's, and their logs, leaving out BuildKit's and those of any container labelled logging=off...

devices:
- id: 123464
name: linux-docker
type: linux
status: true
definitions:
- name: linux_docker_container_collector
status: true
properties:
interval: 300
filter:
container:
exclude_images: ["moby/buildkit*"]
pipeline_name: my-pipeline
- name: linux_docker_log_collector
status: true
properties:
start_date: 300
filter:
container:
exclude_images: ["moby/buildkit*"]
exclude_labels: ["logging=off"]
pipeline_name: my-pipeline

An engine reached over TCP with TLS, as docker --tlsverify speaks to it...

properties:
endpoint: tcp://docker-host:2376
ca_path: /etc/vmetric/docker/ca.pem
cert_path: /etc/vmetric/docker/cert.pem
key_path: /etc/vmetric/docker/key.pem

Kubernetes Pod Logs​

The linux_kubernetes_pod_log_collector reads the container log files the kubelet writes under /var/log/pods on the node. Each matched file is decoded as CRI, and its path is parsed into the namespace, pod name, pod UID, and container name that identify it — no Kubernetes API call is involved in that step. Namespace filtering works from the parsed path alone; label and owner-kind filtering additionally consult a pod watcher.

note

Kubernetes pod log datasets can be created through the dataset creation wizard (Kubernetes Pod Logs, under the Linux category) or configured via device YAML files under config/devices/. They can be assigned only to Linux devices.

The agent must be able to read /var/log/pods on the node, so a containerized agent needs that path mounted. The decoder property is fixed to cri and cannot be changed, which is why the wizard does not offer a decoder selector for this type.

Input properties​

Each entry under inputs: defines one pod log source. Inputs share the standard dataset input frame (id, name, status) plus the following properties:

FieldRequiredTypeDefaultDescription
pathNstring/var/log/pods/*/*/*.logGlob or comma-separated globs matching pod log files. The kubelet layout is <root>/<namespace>_<pod>_<uid>/<container>/<N>.log. An empty or unset value falls back to the default.
exclude_pathsNstring—Glob or comma-separated globs pruned from the path match set. A different dialect than path: each pattern is matched against the whole path, ** is not supported, * never crosses /, and the pattern must mirror the full segment depth of path (e.g. /var/log/pods/*/sidecar/*.log). A malformed pattern excludes nothing rather than everything.
namespacesNstring—Comma-separated namespace allowlist, evaluated from the parsed path. Empty means every namespace is eligible.
exclude_namespacesNstringkube-system,kube-node-lease,kube-publicComma-separated namespace denylist. Evaluated after namespaces and always wins, so a namespace in both lists is excluded. Set it to an empty value to collect the system namespaces.
label_selectorNstring—Pod-label filter in the Kubernetes label-selector grammar: equality (key=value), inequality (key!=value), existence (key, !key), and set-based (key in (v1,v2), key notin (v1,v2)), combined with AND. Requires API access. An unparseable value disables label filtering for that input and is reported once.
exclude_owner_kindsNstring—Comma-separated list of controlling owner-reference kinds to exclude, e.g. DaemonSet, Job, StatefulSet. Case-insensitive. Requires API access.
unparsed_pathsNstringcollectWhat to do with a matched file whose path does not parse into a pod identity. collect reads the file anyway, skipping the four filters above for that file; drop skips the file. Any other value resolves to collect.
api_serverNstringin-clusterAPI server URL, used only when label_selector or exclude_owner_kinds is set. Must be an absolute https:// URL. When empty, it is derived from KUBERNETES_SERVICE_HOST and KUBERNETES_SERVICE_PORT.
token_pathNstring/var/run/secrets/kubernetes.io/serviceaccount/tokenService account token file. Same gate as api_server.
ca_pathNstring/var/run/secrets/kubernetes.io/serviceaccount/ca.crtCA certificate file used to verify the API server. Same gate as api_server.
start_dateNint300Lookback window in seconds: only files modified within this window are read. A negative value (e.g. -1) disables time-based filtering. 0 resolves to the 300 default.
pipeline_nameNstring—Route decoded lines to a specific preprocessing pipeline by name.

The reader properties are the same as file log collection — ignore_cache, ignore_old_date, ignore_time, ignore_retention, date_format, line_parser, filter_mode, filter_rules, and encoding — and the device-level file_log_concurrency applies here too. See File Log Collection for their semantics.

Filters degrade to collection, not exclusion

label_selector and exclude_owner_kinds need a synchronized pod watcher. When the watcher cannot be built, has not synchronized yet, or has no record of the pod, the file is collected rather than excluded, and the condition is reported once. The API server URL is derived from environment variables the kubelet injects into pods, so an agent running as a host process outside a pod has no in-cluster API access and these two filters are inert. namespaces and exclude_namespaces are unaffected — they never consult the watcher.

Reaching the API server requires a service account with list and watch on pods.

Output​

The emitted record's source field carries the parsed identity as <namespace>/<pod>/<pod-uid>/<container>; a file whose path did not parse keeps its raw file path instead. Structured k8s.* fields are not added by this collector — to attach them, route the records through the Kubernetes processor, which looks the pod up in the cluster and writes k8s.namespace, k8s.pod, k8s.deployment, and k8s.node.

Example​

Collecting application pod logs while excluding the system namespaces and DaemonSet-owned pods...

devices:
- id: 123460
name: k8s-node-1
type: linux
status: true
definitions:
- name: linux_kubernetes_pod_log_collector
status: true
inputs:
- id: 4001
name: Application Pods
status: true
properties:
path: /var/log/pods/*/*/*.log
exclude_namespaces: kube-system,kube-node-lease,kube-public
label_selector: app=web,tier!=debug
exclude_owner_kinds: DaemonSet
unparsed_paths: drop
start_date: 300
pipeline_name: my-pipeline

Each decoded container log line becomes a record carrying the pod identity parsed from its path...

{
"message": "listening on :8080",
"source": "prod/web-1/8f3c2b1a-5d6e-4f70-9a2b-1c3d4e5f6a7b/web"
}

Kubernetes Metrics​

The linux_kubernetes_metrics_collector reads node, pod, and container usage and status from the kubelet on the node, and can optionally add cluster-object counts from the API server and a curated set of cAdvisor series. Each metric sample is emitted as its own record.

note

Kubernetes metrics datasets can be created through the dataset creation wizard (Kubernetes Metrics, under the Linux category) or configured via device YAML files under config/devices/. They can be assigned only to Linux devices.

Input properties​

Each entry under inputs: defines one metrics source. Inputs share the standard dataset input frame (id, name, status) plus the following properties:

FieldRequiredTypeDefaultDescription
kubelet_urlNstringhttps://127.0.0.1:10250Kubelet base URL. Must use https; an http URL is rejected before the request is made.
token_pathNstring—Service account token file presented to the kubelet as a bearer token. See the caution below — there is no in-cluster fallback on this path.
ca_pathNstring—CA certificate file used to verify the kubelet. Ignored while insecure_skip_verify is true.
insecure_skip_verifyNbooleantrueSkip TLS verification of the kubelet certificate. Set it to false to verify against ca_path. Applies to the kubelet endpoints only, never to the API server.
node_nameNstringthe device nameNode name stamped onto every record and used to scope the pod watcher.
collect_cluster_objectsNbooleanfalseAlso read deployment, daemonset, statefulset, job, cronjob, service, and namespace counts from the API server.
scrape_cadvisorNbooleanfalseAlso scrape the kubelet cAdvisor endpoint for a curated set of container CPU, filesystem, and network series.
namespacesNstring—Comma-separated namespaces whose series this input sends. Empty sends every namespace. Wizard: Namespaces.
exclude_namespacesNstring—Comma-separated namespaces whose series are not sent. Checked after namespaces, and it always wins. No default, unlike Kubernetes Pod Logs' kube-system,kube-node-lease,kube-public: this dataset has always sent kube-system, and an input that sets neither property still does. Wizard: Exclude namespaces.
api_serverNstringin-clusterAPI server URL used by the pod watcher and by collect_cluster_objects. Derived from KUBERNETES_SERVICE_HOST and KUBERNETES_SERVICE_PORT when empty.
pipeline_nameNstring—Route emitted metrics to a specific preprocessing pipeline by name.

retention is read at the definition level and falls back to the device retention.

Namespace names match exactly and are case-sensitive, as on Kubernetes Pod Logs. The node's own series belong to no namespace and are always sent. Cluster objects are judged by their namespace, and cAdvisor samples by their namespace label before the 50,000-sample cap on each cAdvisor scrape counts them. A sample with no namespace label is sent.

token_path is effectively required

The kubelet endpoints apply no in-cluster default for token_path: when it is empty, no authorization header is sent at all. On a cluster with the usual kubelet authentication that means every request is rejected and the dataset emits nothing but a single reported warning. Set token_path explicitly. The in-cluster defaults do apply to api_server, which is a separate path used only by the watcher and by collect_cluster_objects.

node_name must match the Kubernetes node

When node_name is unset it falls back to the device name. If that does not equal the node name in Kubernetes, the pod watcher matches nothing and no pod or container status metrics are produced, while usage metrics continue to arrive — a partial result rather than a visible failure.

The token needs nodes/stats for the kubelet endpoints, and list plus watch on pods for the status metrics. collect_cluster_objects additionally needs list on deployments, daemonsets, and statefulsets (apps/v1), jobs and cronjobs (batch/v1), and services and namespaces (core/v1).

Cluster objects are collected per node, with no leader election

collect_cluster_objects reads cluster-wide counts. Nothing elects a single reporter, so enabling it on the datasets of several nodes multiplies every cluster-object series by the number of nodes that have it on. Enable it on exactly one node dataset per cluster.

Each source degrades independently: a kubelet, watcher, cluster-object, or cAdvisor failure is reported once and yields no records from that source, while the others continue. A cAdvisor scrape is capped at 50,000 records; beyond that the excess is discarded and reported.

Output​

Each sample is emitted as a metric record:

FieldDescription
metric.nameMetric name, e.g. pod_cpu_usage_nanocores.
metric.valueNumeric value.
metric.typegauge or counter.
metric.sourceOrigin of the sample: kubelet_summary, cadvisor, kube_api, or watcher.
k8s.namespace, k8s.pod, k8s.container, k8s.node, k8s.kind, k8s.nameIdentity of the object the sample describes. Empty fields are omitted.
@timestampSample time.

Example​

Collecting kubelet metrics from one node with verification enabled, adding cluster objects on this node only...

devices:
- id: 123461
name: k8s-node-1
type: linux
status: true
definitions:
- name: linux_kubernetes_metrics_collector
status: true
inputs:
- id: 5001
name: Node Metrics
status: true
properties:
kubelet_url: https://127.0.0.1:10250
token_path: /var/run/secrets/kubernetes.io/serviceaccount/token
ca_path: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
insecure_skip_verify: false
node_name: k8s-node-1
collect_cluster_objects: true
scrape_cadvisor: true
pipeline_name: my-pipeline

Every sample is emitted as its own record, carrying the object it describes...

{
"metric": {
"name": "pod_cpu_usage_nanocores",
"value": 42,
"type": "gauge",
"source": "kubelet_summary"
},
"k8s": { "namespace": "default", "pod": "web-1", "node": "k8s-node-1" },
"@timestamp": "2026-08-25T10:15:03.472Z"
}