Monitoring Docker

Configuration

Config file layout and override settings

Collectord’s configuration files control how it behaves overall, what data it forwards to Splunk, how it talks to Splunk, and the defaults for each data pipeline (logs, metrics, events). This page shows how to override them, with files of your own or environment variables.

Collectord’s defaults live in 001-general.conf, mounted at /config/001-general.conf inside the image. You don’t edit that file directly. Instead, you drop additional .conf files into the same /config directory. Collectord reads everything matching *.conf in alphabetical order, and later files override earlier ones.

For per-container behavior, use annotations on the containers themselves: multi-line join rules, stripping terminal colors, dropping noisy lines, field extraction, value masking, application-log paths.

To reduce log volume, run your own scripts, choose how fields are spelled or raise one subsystem’s log level, see Collectord.

Overriding configuration by embedding configuration files

The cleanest way to customize a deployment is to bake a small override file into your own image. Put in only the keys you want to change: everything else inherits from 001-general.conf. For example, save the following as 002-conf.conf to accept the license, point Collectord at your Splunk HEC, and route logs and metrics to dedicated indexes:

002-conf.conf ini
 1# accepting license
 2[general]
 3acceptLicense = true
 4
 5# Configuring Splunk output
 6[output.splunk]
 7url = https://hec.example.com:8088/services/collector/event/1.0
 8token = B5A79AAD-D822-46CC-80D1-819F80D7BFB0
 9insecure = true
10
11# Overriding default indices
12[input.system_stats]
13index = docker_stats
14
15[input.mount_stats]
16index = docker_stats
17
18[input.disk_stats]
19index = docker_stats
20
21[input.net_stats]
22index = docker_stats
23
24[input.net_socket_table]
25index = docker_stats
26
27[input.proc_stats]
28index = docker_stats
29
30[input.files]
31index = docker_logs
32
33[input.app_logs]
34index = docker_logs
35
36[input.journald]
37index = docker_logs
38
39[input.files::logs]
40index = docker_logs
41
42[input.docker_events]
43index = docker_logs

Wrap it in a Dockerfile that extends the base Collectord image:

Dockerfile Dockerfile
1FROM registry.outcold.solutions/outcoldsolutions/collectorfordocker:26.10.1
2
3COPY 002-conf.conf /config/002-conf.conf

Build the image:

bash
1docker build -t example.com/collectorfordocker:26.10.1 .

Then run it the same way as the stock image: the installation guide has the full docker run command.

Overriding configuration with the environment variables

You don’t have to build a custom image: you can pass every setting through an environment variable instead. That suits quick experiments, ephemeral hosts, and an orchestrator that already manages env vars. The format is:

bash
1--env "COLLECTOR__<ANYUNIQUENAME>=<section>__<key>=<value>"

The same overrides as the file above, expressed as env vars:

bash
 1--env "COLLECTOR__ACCEPTLICENSE=general__acceptLicense=true" \
 2--env "COLLECTOR__SPLUNK_URL=output.splunk__url=https://hec.example.com:8088/services/collector/event/1.0" \
 3--env "COLLECTOR__SPLUNK_TOKEN=output.splunk__token=B5A79AAD-D822-46CC-80D1-819F80D7BFB0"  \
 4--env "COLLECTOR__SPLUNK_INSECURE=output.splunk__insecure=true"  \
 5--env "COLLECTOR__STATS_INDEX=input.system_stats__index=docker_stats" \
 6--env "COLLECTOR__MOUNTSTATS_INDEX=input.mount_stats__index=docker_stats" \
 7--env "COLLECTOR__DISKSTATS_INDEX=input.disk_stats__index=docker_stats" \
 8--env "COLLECTOR__NETSTATS_INDEX=input.net_stats__index=docker_stats" \
 9--env "COLLECTOR__NETSOCKET_INDEX=input.net_socket_table__index=docker_stats" \
10--env "COLLECTOR__PROCSTATS_INDEX=input.proc_stats__index=docker_stats" \
11--env "COLLECTOR__CONTAINERLOGS_INDEX=input.files__index=docker_logs" \
12--env "COLLECTOR__APPLICATIONLOGS_INDEX=input.app_logs__index=docker_logs" \
13--env "COLLECTOR__JOURNALD_INDEX=input.journald__index=docker_logs" \
14--env "COLLECTOR__HOSTLOGS_INDEX=input.files::logs__index=docker_logs" \
15--env "COLLECTOR__EVENTS_INDEX=input.docker_events__index=docker_logs"

[input.files::syslog] ships off. If you turn it on (see the next section), give it the same index as [input.journald].

Host logs: the journal or the syslog files

Collectord reads the host’s own logs from two places:

  • the systemd journal ([input.journald]);
  • the *.log files under /var/log ([input.files::logs]).

It no longer reads /var/log/syslog or /var/log/messages ([input.files::syslog], off by default). Where rsyslog runs beside journald, as on the RHEL family, Amazon Linux 2 and Ubuntu, rsyslog writes those files from the journal, so reading both sent every line to Splunk twice. For the same reason, [input.files::logs] leaves out the files rsyslog writes per facility on Debian and Ubuntu: auth.log, kern.log, mail.log and the like.

Before 26.10, [input.files::syslog] was on, so Collectord read /var/log/syslog and /var/log/messages beside the journal.

The journal’s entries also carry more than a syslog line does: the systemd unit, priority, facility and command name, and a timestamp with its time zone.

A host without systemd (Alpine, for one) has no journal. There, collectord verify reports x input(journald): FAILED, and Collectord logs a journald input: could not locate journald path warning when it starts.

On such a host, read the syslog files instead: /var/log/syslog or /var/log/messages, and the auth.log that Debian and Ubuntu keep authentication in. Turn [input.files::syslog] on and [input.journald] off:

002-conf.conf ini
1[input.files::syslog]
2disabled = false
3
4[input.journald]
5disabled = true

Or with environment variables:

bash
1--env "COLLECTOR__SYSLOG_DISABLED=input.files::syslog__disabled=false" \
2--env "COLLECTOR__JOURNALD_DISABLED=input.journald__disabled=true"

Two more cases to know about:

  • The host relays other hosts’ syslog. Lines rsyslog receives over the network never reach the local journal. If rsyslog writes them to files of their own, add an [input.files::<name>] section for those files. If it mixes them into /var/log/syslog or /var/log/messages, turn [input.files::syslog] on as well, and the host’s own lines arrive twice.
  • The journal is kept only in memory. Where there is no /var/log/journal directory, journald keeps the journal under /run/log/journal. Collectord reads it there, but whatever it has not sent yet when the host reboots is gone with it. To keep it, make the journal persistent: mkdir -p /var/log/journal && systemd-tmpfiles --create --prefix /var/log/journal && journalctl --flush.

Attaching EC2 Metadata

On EC2, every event can carry instance-level context, such as the instance ID, instance type and availability zone. To add it, point Collectord at the EC2 metadata service. Each entry maps a field name to a path from Instance Metadata and User Data:

ini
1# Include EC2 Metadata (see list of possible fields https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html)
2# Should be in format ec2Metadata.{desired_field_name} = {url path to read the value}
3# ec2Metadata.ec2_instance_id = /latest/meta-data/instance-id
4# ec2Metadata.ec2_instance_type = /latest/meta-data/instance-type

With environment variables, the same two fields look like this:

bash
1...
2--env "COLLECTOR__EC2_INSTANCE_ID=general__ec2Metadata.ec2_instance_id=/latest/meta-data/instance-id" \
3--env "COLLECTOR__EC2_INSTANCE_TYPE=general__ec2Metadata.ec2_instance_type=/latest/meta-data/instance-type" \
4...

Placeholders in index and sources

Static index names work fine for a single host. Once you forward from a fleet, you’ll often want logs grouped by cluster, environment, or container. Use any metadata field as a placeholder in index, source, and sourcetype.

For example, to route each cluster’s logs to its own index:

ini
1[input.files]
2
3index = docker_{{docker_cluster}}

Or build a structured source path that combines cluster and container. That helps when a single index holds logs from many hosts and you want Splunk’s source-based filtering to do the heavy lifting:

ini
1[input.files]
2
3source = /{{docker_cluster}}/{{docker_container_name}}

License server endpoint (static IPs for egress-restricted networks)

Collectord checks in with the Outcold-hosted license server on a schedule and reports telemetry to the same host. The default endpoint, license.outcold.solutions, sits behind AWS API Gateway and CloudFront, so it resolves to a large, frequently changing range of IP addresses. That’s fine for most hosts. It’s a problem where outbound traffic has to pass a firewall with a strict allow-list.

Available since Collectord version 26.04.2

Starting in 26.04.2, we also publish license-static.outcold.solutions, a parallel endpoint backed by AWS Global Accelerator. It serves the same license and telemetry traffic from two stable anycast IPv4 addresses, so the allow-list stays small and doesn’t drift over time:

  • 166.117.80.67
  • 99.83.183.50

The original license.outcold.solutions endpoint is unchanged. If your host can already reach it, there’s nothing you need to do: switch over only if you need the static IPs.

To use the static-IP endpoint, override the two URLs under [general] in an override .conf file:

002-conf.conf ini
1[general]
2licenseEndpoint = https://license-static.outcold.solutions/license/
3telemetryEndpoint = https://license-static.outcold.solutions/telemetry/

Or the same change as environment variables on the docker run command line:

bash
1--env "COLLECTOR__LICENSEENDPOINT=general__licenseEndpoint=https://license-static.outcold.solutions/license/" \
2--env "COLLECTOR__TELEMETRYENDPOINT=general__telemetryEndpoint=https://license-static.outcold.solutions/telemetry/"

Then allow-list the two IPs above for outbound tcp/443. The static-IP endpoint runs the same backend as the default one, so the license behavior is identical: only the hostname and the front door differ.

FIPS-compliant images

Since version 26.04, we publish FIPS 140-compliant images alongside the regular images, with a -fips suffix:

registry.outcold.solutions/outcoldsolutions/collectorfordocker:26.10.1-fips

By default, these images use FIPS-certified cryptographic algorithms, but still fall back to non-approved algorithms when needed. To enforce FIPS 140 mode strictly, set the environment variable GODEBUG=fips140=only. Collectord then crashes if any code attempts to use an algorithm that isn’t FIPS 140-compliant.

Collectord logs its FIPS state at startup and includes it in the output of collectord diag and collectord verify.

See FIPS 140-3 Compliance for details on the Go implementation.

Reference 001-general.conf

  1# The image's /config/001-general.conf. Set a value with an environment variable,
  2# COLLECTOR__<ANYNAME>=<section>__<key>=<value>, for example
  3#   COLLECTOR__LOGLEVEL=general__logLevel=debug
  4# or in a .conf file of your own mounted in /config/, named to sort after this one.
  5
  6[general]
  7
  8# Please review license https://www.outcoldsolutions.com/legal/license-agreement/
  9# and accept license by changing the value to *true*
 10acceptLicense = false
 11
 12# The read positions and internal state, in the image's /data/ volume (the working directory is /).
 13# Moving it, or a container started without the same volume, forwards the logs again.
 14dataPath = ./data/
 15
 16# log level (trace, debug, info, warn, error, fatal)
 17logLevel = info
 18
 19# How Collectord spells the fields it composes: _ (the default) or .; the monitoring apps read both
 20# fieldsSeparator = _
 21
 22# host:port of the http server (empty: none), serving /healthz and /readyz, and
 23# /metrics/prometheus and /metrics/json with httpServerEndpoints.metrics = true
 24httpServerBinding =
 25
 26# telemetry report endpoint, set it to empty string to disable telemetry
 27telemetryEndpoint = https://license.outcold.solutions/telemetry/
 28
 29licenseEndpoint = https://license.outcold.solutions/license/
 30licenseServerProxyUrl =
 31
 32# user:password
 33licenseServerProxyBasicAuth =
 34
 35license =
 36
 37# empty: the host name the Docker daemon reports
 38hostname =
 39
 40# splunk, or devnull to send nothing
 41defaultOutput = splunk
 42
 43# The index type of every input below that sets no indexType: events, metrics (a Splunk metrics
 44# index) or both, to compare the dashboards before switching
 45defaultIndexType = events
 46
 47fileInputBufferSize = 8kb
 48fileInputLineMaxSize = 1mb
 49
 50# Indexed fields added to every event, named to match ^[a-z][_a-z0-9]*$
 51# ; fields.my_environment = dev
 52
 53# EC2 instance metadata as fields: ec2Metadata.<field> = <metadata path>
 54# ec2Metadata.ec2_instance_id = /latest/meta-data/instance-id
 55# ec2Metadata.ec2_instance_type = /latest/meta-data/instance-type
 56
 57# Read the container labels under <subdomain>.collectord.io/ instead of collectord.io/, the prefix
 58# of every label this file names; every Collectord reads collectord.collectord.io/ too
 59annotationsSubdomain =
 60
 61# A cap on the logs forwarded a second, such as 512Kb (metrics are not capped). Each log input
 62# below takes thruputPerSecond (a container's in [input.files], a volume's in [input.app_logs]),
 63# tooOldEvents and tooNewEvents of its own too
 64thruputPerSecond =
 65
 66# Drop the events older than this, such as 168h, or this far in the future, such as 1h
 67tooOldEvents =
 68tooNewEvents =
 69
 70# Skip the gzipped files (by name or leading bytes) in [input.files::<name>] and the application logs
 71autoSkipGzipFiles = true
 72
 73# The events for an output other than the pipeline's own (process stats a container's labels send
 74# elsewhere, the metricsOutput copies of indexType = both) go asynchronously: a slow output drops
 75# them instead of holding back the rest. false holds the pipeline back.
 76; multioutput.async = true
 77# Events buffered per output of each pipeline; past it and the output's queue they are dropped
 78# (multioutput_dropped_events)
 79; multioutput.asyncBufferSize = 100
 80
 81[license.client]
 82# A license on a web server, or served by a Collectord license server
 83url =
 84basicAuth =
 85insecure = false
 86capath =
 87caname =
 88proxyUrl =
 89# user:password
 90proxyBasicAuth =
 91
 92
 93[input.collectord_metrics]
 94
 95disabled = false
 96type = docker_prometheus
 97interval = 1m
 98output =
 99index =
100
101# An indexType here or in the stats and Prometheus inputs below overrides [general]
102# defaultIndexType. Set metricsIndex or [output.splunk] defaultMetricsIndex: the HEC token's default
103# index is normally an events index. metricsOutput: an output whose token can write it.
104metricsIndex =
105metricsOutput =
106
107# Regular expressions on the metric name: with a whitelist, only the matching metrics are sent
108whitelist.1 = ^file_input_open$
109whitelist.2 = ^file_input_read_bytes$
110whitelist.3 = ^docker_handlers$
111whitelist.4 = ^pipe$
112whitelist.5 = ^pipelines_num$
113whitelist.6 = ^splunk_post_bytes_sum.*$
114whitelist.7 = ^splunk_post_events_count_sum.*$
115whitelist.8 = ^splunk_post_failed_requests$
116whitelist.9 = ^splunk_post_message_max_lag_seconds_bucket.*$
117whitelist.10 = ^splunk_post_requests_seconds_sum.*$
118whitelist.11 = ^splunk_post_retries_required_sum.*$
119
120[general.docker]
121
122url = unix:///rootfs/run/docker.sock
123
124# Docker's data root under /rootfs; with another data root, set [input.files] path to its
125# containers/ too
126dockerRootFolder = /rootfs/var/lib/docker/
127
128# per Docker API request
129timeout = 1m
130
131# A container's cgroup path, Docker's (Amazon ECS's included) and Podman's layouts: a container
132# whose cgroup it does not match gets no stats, and its processes count as the host's
133containersCgroupFilter = ^/([^/\s]+/)*(((docker-|docker/|ecs/([0-9a-f]{32}|[0-9a-f\-]{36})/)[0-9a-f]{64}(\.scope)?)|(libpod-(payload-)?[0-9a-f]{64}(\.scope)?(/container)?))$
134
135# auto: v1.44, or the newest an older daemon serves (down to v1.24); `collectord verify` shows it
136apiVersion = auto
137
138# Rootless Podman: each user's API socket this pattern finds, monitored beside url (empty: none).
139# A socket needs the user's podman.socket and a session or lingering; users who log in after
140# Collectord starts are seen only with --volume /:/rootfs:ro,rslave. Their volume logs are not read.
141rootlessURL.podman = unix:///rootfs/run/user/*/podman/podman.sock
142
143# The containers one user's rootless engines may have followed: that many running or created, and
144# that many exited; past it no more are followed (a warning says so)
145rootlessMaxContainers = 500
146
147[input.system_stats]
148
149disabled.host = false
150disabled.cgroup = false
151pathCgroups = /rootfs/sys/fs/cgroup
152pathProc = /rootfs/proc
153statsInterval = 30s
154type.host = docker_stats_v2_host
155type.cgroup = docker_stats_v2_cgroup
156index.host =
157index.cgroup =
158metricsIndex.host =
159metricsIndex.cgroup =
160metricsOutput.host =
161metricsOutput.cgroup =
162output.host =
163output.cgroup =
164
165
166[input.mount_stats]
167
168disabled = false
169statsInterval = 30s
170
171# root: the filesystem holding dockerRootFolder alone; auto: every real filesystem of the host,
172# one event each at its shortest mount point, the mount table reread every interval (a filesystem
173# mounted after the container started is seen only with --volume /:/rootfs:ro,rslave)
174mounts = root
175
176# with mounts = auto: a regular expression the filesystem type must match, and one the mount
177# point must not (empty: the defaults). autofs mounts are never read: it would keep them mounted
178include =
179exclude =
180
181type = docker_mount_stats
182index =
183metricsIndex =
184metricsOutput =
185output =
186
187
188[input.disk_stats]
189
190disabled = false
191statsInterval = 30s
192type = docker_disk_stats
193index =
194metricsIndex =
195metricsOutput =
196output =
197
198
199[input.proc_stats]
200
201disabled = false
202pathProc = /rootfs/proc
203statsInterval = 30s
204type = docker_proc_stats_v2
205index.host =
206index.cgroup =
207metricsIndex =
208metricsOutput =
209
210# kernel threads too: often over 100 of them, rarely of use, all indexed
211includeSystemThreads = false
212
213output.host =
214output.cgroup =
215
216
217[input.net_stats]
218
219disabled = false
220pathProc = /rootfs/proc
221statsInterval = 30s
222type = docker_net_stats_v2
223index =
224metricsIndex =
225metricsOutput =
226output =
227
228
229[input.net_socket_table]
230
231disabled = false
232pathProc = /rootfs/proc
233statsInterval = 30s
234type = docker_net_socket_table
235index =
236output =
237
238# one event per group of connections sharing a state and address pair, not one per connection
239group = true
240
241
242# The containers' stdout and stderr
243[input.files]
244
245disabled = false
246path = /rootfs/var/lib/docker/containers/
247
248# how often a file read to its end is checked for more
249pollingInterval = 250ms
250
251# how often path is searched for new files
252walkingInterval = 5s
253
254# add the file offset to the events
255verboseFields = false
256
257type = docker_logs
258index =
259
260# Docker splits a long line into parts: join them back into one event
261joinPartialEvents = true
262
263# Strip terminal colors from every container's lines; a container's
264# collectord.io/logs-escapeterminalsequences=true label does it for that container alone
265stripTerminalEscapeSequences = false
266# what is stripped: colors and a few other sequences, not every escape sequence
267stripTerminalEscapeSequencesRegex = (\x1b\[\d{1,3}(;\d{1,3})*m)|(\x07)|(\x1b]\d+(\s\d)?;[^\x07]+\x07)|(.*\x1b\[K)
268
269# the percent of lines forwarded: 20 sends 20%, -1 all of them
270samplingPercent = -1
271
272# hash-based sampling: a regular expression with a named group `key`
273samplingKey =
274
275output =
276thruputPerSecond =
277tooOldEvents =
278tooNewEvents =
279
280# Group each stream's repeated lines into one event per run that counts them. Off unless true,
281# or a container's collectord.io/logs-repeat-enabled label says so.
282repeatEnabled = false
283# How long a run is held before its event goes out, up to 10m (a crash resends up to that much)
284# repeatMaxSpan = 1m
285# Add every line's time to a run's event (collectord_repeat_offsets, milliseconds from its own)
286# repeatOffsets = false
287# What each stream may remember: distinct lines, lines one event stands for, and bytes
288# repeatMaxKeys = 256
289# repeatMaxCount = 1000
290# repeatMaxBytes = 256KB
291
292# Fold each stream's lines of one pattern past foldMaxPerMinute into one summary a minute.
293# Lossy: folded lines are not sent. Off unless true, or a container's
294# collectord.io/logs-fold-enabled label says so.
295foldEnabled = false
296# Lines of one pattern a minute sent before the rest fold
297# foldMaxPerMinute = 60
298# Lines never folded (a regular expression; empty: the default)
299# foldKeep = (?i)error|exception|fatal|panic
300# What each stream may keep a minute: its patterns and summaries
301# foldMaxBytes = 256KB
302
303# Report each stream's top patterns every interval, as events of their own. Off unless true,
304# or a container's collectord.io/logs-patterns-enabled label says so.
305patternsEnabled = false
306# How often a report goes out, from 1m to 24h
307# patternsInterval = 15m
308# How many patterns a report carries, up to 100
309# patternsTop = 20
310# What each stream's patterns may keep; past it a new one takes the place of the lightest
311# patternsMaxBytes = 256KB
312# The report events' type (empty: this section's type with _patterns after it)
313# patternsType =
314
315
316# The log files on the volumes a container's collectord.io/volume.<n>-logs-name labels name
317[input.app_logs]
318
319disabled = false
320
321# where the host's / is mounted: a volume's host path is read under it
322root = /rootfs
323
324syncInterval = 5s
325glob = *.log*
326pollingInterval = 250ms
327walkingInterval = 5s
328verboseFields = false
329type = docker_logs
330index =
331
332# a line this does not match continues the event before it
333eventPatternRegex = ^[^\s]
334eventPatternMaxInterval = 100ms
335eventPatternMaxWait = 1s
336eventPatternMaxSize = 100kb
337
338samplingPercent = -1
339samplingKey =
340output =
341thruputPerSecond =
342tooOldEvents =
343tooNewEvents =
344
345# How long a stopped container's volume logs are read on, their files held open, before they are
346# let go
347maxHoldAfterClose = 1800s
348
349# Group each file's repeated lines into one event per run that counts them. Off unless true,
350# or a container's collectord.io/volume.<n>-logs-repeat-enabled label says so.
351repeatEnabled = false
352# How long a run is held before its event goes out, up to 10m (a crash resends up to that much)
353# repeatMaxSpan = 1m
354# Add every line's time to a run's event (collectord_repeat_offsets, milliseconds from its own)
355# repeatOffsets = false
356# What each stream may remember: distinct lines, lines one event stands for, and bytes
357# repeatMaxKeys = 256
358# repeatMaxCount = 1000
359# repeatMaxBytes = 256KB
360
361# Fold each file's lines of one pattern past foldMaxPerMinute into one summary a minute.
362# Lossy: folded lines are not sent. Off unless true, or a container's
363# collectord.io/volume.<n>-logs-fold-enabled label says so.
364foldEnabled = false
365# Lines of one pattern a minute sent before the rest fold
366# foldMaxPerMinute = 60
367# Lines never folded (a regular expression; empty: the default)
368# foldKeep = (?i)error|exception|fatal|panic
369# What each file may keep a minute: its patterns and summaries
370# foldMaxBytes = 256KB
371
372# Report each file's top patterns every interval, as events of their own. Off unless true,
373# or a container's collectord.io/volume.<n>-logs-patterns-enabled label says so.
374patternsEnabled = false
375# How often a report goes out, from 1m to 24h
376# patternsInterval = 15m
377# How many patterns a report carries, up to 100
378# patternsTop = 20
379# What each file's patterns may keep; past it a new one takes the place of the lightest
380# patternsMaxBytes = 256KB
381# The report events' type (empty: this section's type with _patterns after it)
382# patternsType =
383
384
385# The host's syslog, messages and auth.log. Off: rsyslog writes them from the journal
386# [input.journald] reads, so every line would arrive twice. On a host without journald, turn this
387# on and journald off.
388[input.files::syslog]
389
390disabled = true
391path = /rootfs/var/log/
392match = ^(syslog|messages|auth\.log)(.[\d\-]+)?$
393recursive = false
394pollingInterval = 250ms
395walkingInterval = 5s
396verboseFields = false
397type = docker_host_logs
398index =
399extraction = ^(?P<timestamp>[A-Za-z]+\s+\d+\s\d+:\d+:\d+|\d{4}-\d{2}-\d{2}T\S+)\s(?P<syslog_hostname>[^\s]+)\s(?P<syslog_component>[^:\[]+)(\[(?P<syslog_pid>\d+)\])?: (.+)$
400
401# the extracted fields naming the process that wrote a line, which groups its lines apart
402extractionWriterFields = syslog_hostname, syslog_component, syslog_pid
403
404timestampField = timestamp
405
406# a Go layout of the reference time `Mon Jan 2 15:04:05 -0700 MST 2006`; @syslog reads RFC 3339
407# and the traditional `Jan 2 15:04:05`
408timestampFormat = @syslog
409
410# take the month and day from today when the format has none
411timestampSetMonth = false
412timestampSetDay = false
413
414# the time zone when the format has none
415timestampLocation = Local
416
417samplingPercent = -1
418samplingKey =
419output =
420thruputPerSecond =
421tooOldEvents =
422tooNewEvents =
423
424# whitelist.0 = ^regexp$
425# blacklist.0 = ^regexp$
426
427# Lines matching thruputExempt.<n> pass every thruput cap and sampling; with one set, a spent
428# cap drops the other lines instead of pausing this input
429# thruputExempt.0 = ^regexp$
430
431# Group each file's repeated lines into one event per run that counts them. Off unless true.
432repeatEnabled = false
433# How long a run is held before its event goes out, up to 10m (a crash resends up to that much)
434# repeatMaxSpan = 1m
435# Add every line's time to a run's event (collectord_repeat_offsets, milliseconds from its own)
436# repeatOffsets = false
437# What each stream may remember: distinct lines, lines one event stands for, and bytes
438# repeatMaxKeys = 256
439# repeatMaxCount = 1000
440# repeatMaxBytes = 256KB
441
442# Fold each file's lines of one pattern past foldMaxPerMinute into one summary a minute.
443# Lossy: folded lines are not sent. Off unless true.
444foldEnabled = false
445# Lines of one pattern a minute sent before the rest fold
446# foldMaxPerMinute = 60
447# Lines never folded (a regular expression; empty: the default)
448# foldKeep = (?i)error|exception|fatal|panic
449# What each file may keep a minute: its patterns and summaries
450# foldMaxBytes = 256KB
451
452# Report each file's top patterns every interval, as events of their own. Off unless true.
453patternsEnabled = false
454# How often a report goes out, from 1m to 24h
455# patternsInterval = 15m
456# How many patterns a report carries, up to 100
457# patternsTop = 20
458# What each file's patterns may keep; past it a new one takes the place of the lightest
459# patternsMaxBytes = 256KB
460# The report events' type (empty: this section's type with _patterns after it)
461# patternsType =
462
463
464[input.files::logs]
465
466disabled = false
467path = /rootfs/var/log/
468match = ^(([\w\-.]+\.log(.[\d\-]+)?)|(docker))$
469
470# the files rsyslog writes from the journal on Debian and Ubuntu, which [input.journald] reads
471exclude = ^(auth|cron|daemon|kern|lpr|mail|user|ufw)\.log(.[\d\-]+)?$
472
473pollingInterval = 250ms
474walkingInterval = 5s
475verboseFields = false
476type = docker_host_logs
477index =
478extraction =
479timestampField =
480
481# a Go layout of the reference time `Mon Jan 2 15:04:05 -0700 MST 2006`
482timestampFormat =
483
484# the time zone when the format has none
485timestampLocation =
486
487samplingPercent = -1
488samplingKey =
489output =
490thruputPerSecond =
491tooOldEvents =
492tooNewEvents =
493
494# whitelist.0 = ^regexp$
495# blacklist.0 = ^regexp$
496
497# Lines matching thruputExempt.<n> pass every thruput cap and sampling; with one set, a spent
498# cap drops the other lines instead of pausing this input
499# thruputExempt.0 = ^regexp$
500
501# Group each file's repeated lines into one event per run that counts them. Off unless true.
502repeatEnabled = false
503# How long a run is held before its event goes out, up to 10m (a crash resends up to that much)
504# repeatMaxSpan = 1m
505# Add every line's time to a run's event (collectord_repeat_offsets, milliseconds from its own)
506# repeatOffsets = false
507# What each stream may remember: distinct lines, lines one event stands for, and bytes
508# repeatMaxKeys = 256
509# repeatMaxCount = 1000
510# repeatMaxBytes = 256KB
511
512# Fold each file's lines of one pattern past foldMaxPerMinute into one summary a minute.
513# Lossy: folded lines are not sent. Off unless true.
514foldEnabled = false
515# Lines of one pattern a minute sent before the rest fold
516# foldMaxPerMinute = 60
517# Lines never folded (a regular expression; empty: the default)
518# foldKeep = (?i)error|exception|fatal|panic
519# What each file may keep a minute: its patterns and summaries
520# foldMaxBytes = 256KB
521
522# Report each file's top patterns every interval, as events of their own. Off unless true.
523patternsEnabled = false
524# How often a report goes out, from 1m to 24h
525# patternsInterval = 15m
526# How many patterns a report carries, up to 100
527# patternsTop = 20
528# What each file's patterns may keep; past it a new one takes the place of the lightest
529# patternsMaxBytes = 256KB
530# The report events' type (empty: this section's type with _patterns after it)
531# patternsType =
532
533
534[input.journald]
535
536disabled = false
537path.persistent = /rootfs/var/log/journal/
538path.volatile = /rootfs/run/log/journal/
539
540# how often the journal read to its end is checked for more
541pollingInterval = 250ms
542
543type = docker_host_logs
544index =
545samplingPercent = -1
546samplingKey =
547
548# reopen the journal this often, to let go of the files journald deleted
549reopenInterval = 1h
550
551output =
552thruputPerSecond =
553tooOldEvents =
554tooNewEvents =
555
556# whitelist.0 = ^regexp$
557# blacklist.0 = ^regexp$
558
559# Lines matching thruputExempt.<n> pass every thruput cap and sampling; with one set, a spent
560# cap drops the other lines instead of pausing this input
561# thruputExempt.0 = ^regexp$
562
563# Group each writer's repeated lines (unit, identifier, command, process, priority and facility
564# tell writers apart) into one event per run that counts them. Off unless true.
565repeatEnabled = false
566# How long a run is held before its event goes out, up to 10m (a crash resends up to that much)
567# repeatMaxSpan = 1m
568# Add every line's time to a run's event (collectord_repeat_offsets, milliseconds from its own)
569# repeatOffsets = false
570# What the journal, all its writers together, may remember: distinct lines, lines one event stands for, and bytes
571# repeatMaxKeys = 256
572# repeatMaxCount = 1000
573# repeatMaxBytes = 256KB
574
575# Fold each writer's lines of one pattern past foldMaxPerMinute into one summary a minute.
576# Lossy: folded lines are not sent. Off unless true.
577foldEnabled = false
578# Lines of one pattern a minute sent before the rest fold
579# foldMaxPerMinute = 60
580# Lines never folded (a regular expression; empty: the default)
581# foldKeep = (?i)error|exception|fatal|panic
582# What the journal, all its writers together, may keep a minute: its patterns and summaries
583# foldMaxBytes = 256KB
584
585# Report the journal's top patterns, of all its writers together, every interval, as events of
586# their own. Off unless true.
587patternsEnabled = false
588# How often a report goes out, from 1m to 24h
589# patternsInterval = 15m
590# How many patterns a report carries, up to 100
591# patternsTop = 20
592# What the journal's patterns may keep; past it a new one takes the place of the lightest
593# patternsMaxBytes = 256KB
594# The report events' type (empty: this section's type with _patterns after it)
595# patternsType =
596
597
598[input.docker_events]
599
600disabled = false
601
602type = docker_events
603index =
604output =
605
606
607[input.docker_api::containers]
608
609disabled = false
610path = /containers/json
611inspectPath = /containers/{{.Id}}/json
612interval = 5m
613query = all=1
614apiVersion =
615type = docker_objects
616index =
617output =
618
619
620[input.docker_api::images]
621
622disabled = false
623path = /images/json
624inspectPath = /images/{{.Id}}/json
625interval = 5m
626query = all=0
627apiVersion =
628type = docker_objects
629index =
630output =
631
632[input.docker_api::system]
633
634disabled = false
635path = /system/df
636listPath.Volumes = Volumes
637interval = 5m
638apiVersion =
639type = docker_objects
640index =
641output =
642
643# Docker Swarm services, tasks and nodes, read on managers only. swarmRole = leader: the Swarm
644# leader alone (while it is drained, also the first ready manager that is not); manager: every
645# manager, each sending the same records. A drained node runs no stack task: with the managers
646# drained, run Collectord on them with docker run, or no host sends these records.
647[input.docker_api::swarm_services]
648
649disabled = false
650path = /services
651query = status=true
652interval = 1m
653apiVersion =
654swarmRole = leader
655type = docker_objects
656index =
657output =
658
659# With swarmTasks = notRunning a task Swarm wants running but is not is sent on every read, a
660# stopped task once, and a running task never; empty sends every task on every read
661[input.docker_api::swarm_tasks]
662
663disabled = false
664path = /tasks
665interval = 1m
666apiVersion =
667swarmRole = leader
668swarmTasks = notRunning
669type = docker_objects
670index =
671output =
672
673[input.docker_api::swarm_nodes]
674
675disabled = false
676path = /nodes
677interval = 1m
678apiVersion =
679swarmRole = leader
680type = docker_objects
681index =
682output =
683
684# Scrape the containers whose collectord.io/prometheus.<n>-port label names a port
685[input.prometheus_auto]
686
687disabled = false
688type = docker_prometheus
689index =
690metricsIndex =
691metricsOutput =
692
693# a container's collectord.io/prometheus.<n>-interval label overrides it
694interval = 60s
695
696includeHelp = false
697timeout = 30s
698output =
699
700# The Authorization header of the containers whose collectord.io/prometheus.<n>-authorizationkey
701# label is <key>:
702# authorization.<key> = Bearer <token>
703
704
705# Run an executable every interval and send what it prints, one [input.script::<name>] section
706# each. It runs without a shell, as root unless user says, with a fixed environment (PATH,
707# LANG=C, HOME, the COLLECTORD_* variables, then env.<n>), never Collectord's, and only while it
708# and every directory above it are owned by root and writable by no one else. A change to these
709# sections takes a restart. The image has no shell or tools: with root = /rootfs the script runs
710# chrooted in the host's /, with its tools, and command, user and workingDirectory are the host's.
711; [input.script::uptime]
712; disabled = false
713; command = /opt/scripts/uptime.sh
714; arg.1 = --format
715; arg.2 = json
716; env.1 = TZ=UTC
717; interval = 5m
718; startDelay = 0s
719# runs never overlap, so it may be longer than interval
720; timeout = 60s
721# event: all of the output is one event; lines: one event per line; prometheus: see below
722; format = event
723# with format = lines, a line this does not match continues the event before it
724; eventPattern =
725# a name or uid, optionally :group or :gid; empty runs as root
726; user = nobody
727; root = /rootfs
728; workingDirectory = /
729# a run printing more, or past timeout, is stopped: format = lines sends the complete lines
730# before it, the others nothing
731; maxOutputSize = 1MB
732# the events' sourcetype (default is the section's name) and source (default is command)
733; type = docker_uptime
734; source =
735; index =
736; output =
737
738# With format = prometheus a script prints a Prometheus text exposition (what node_exporter's
739# textfile collector reads): a sample is an event, or with indexType = metrics or both a
740# metrics-index record; a counter's event carries its rise since the last run.
741; [input.script::backup_metrics]
742; disabled = false
743; command = /opt/scripts/backup-metrics.sh
744; root = /rootfs
745; interval = 1m
746; user = nobody
747; format = prometheus
748; indexType = metrics
749; metricsIndex =
750; metricsOutput =
751; whitelist.1 = ^backup_
752; blacklist.1 =
753; includeHelp = false
754; type = docker_backup
755
756
757[output.splunk]
758
759url =
760# several HEC URLs, all with the same path:
761# urls.0 = https://server1:8088/services/collector/event/1.0
762# urls.1 = https://server1:8088/services/collector/event/1.0
763# urls.2 = https://server1:8088/services/collector/event/1.0
764
765# how a URL is picked from several, at first and after each failure (connection or HTTP 5xx):
766# urlSelection = random|round-robin|random-with-round-robin
767# random picks at random, at first and after each failure; random-with-round-robin and round-robin
768# take the next URL after a failure, so the instances on a failed URL can all move to the same one
769urlSelection = random
770
771token =
772insecure = false
773#minTLSVersion = TLSv1.2
774#maxTLSVersion = TLSv1.3
775
776caPath =
777caName =
778clientCertPath =
779clientKeyPath =
780
781# a batch goes out at batchSize, at events, or after frequency
782frequency = 5s
783batchSize = 768K
784# 0: no limit
785events = 50
786
787proxyUrl =
788
789# user:password
790proxyBasicAuth =
791
792# Splunk acknowledgement url (.../services/collector/ack)
793ackUrl =
794# with several urls, ackUrls.<n> in the same order, so a payload is acknowledged where it went:
795# ackUrls.0 = https://server1:8088/services/collector/ack
796# ackUrls.1 = https://server1:8088/services/collector/ack
797# ackUrls.2 = https://server1:8088/services/collector/ack
798
799ackEnabled = false
800ackTimeout = 3m
801
802# per request, connecting and reading the response included
803timeout = 30s
804
805# a client per index, so events with an incorrect index do not block the other pipelines
806dedicatedClientPerIndex = true
807
808# RedirectToDefault, Drop or Retry
809incorrectIndexBehavior = RedirectToDefault
810
811# gzip compression level (nocompression, default, 1...9)
812compressionLevel = default
813
814# more threads for over 4k events a second
815threads = 2
816# roundrobin, or weighted (beta)
817threadsAlgorithm = weighted
818
819# Most connections to one HEC host (unset: 8 per thread; 0: no limit); not applied through a
820# SOCKS5 proxyUrl
821; maxConnsPerHost = 16
822
823# indexed fields to leave out of the events
824# excludeFields.docker_container_ip = true
825
826# With fieldsSeparator = ., also send every built-in field under its underscore name (events only)
827# duplicateFieldsWithUnderscore = false
828
829# Drop the events that name no index, instead of sending them to the HEC token's default index
830; requireExplicitIndex = true
831
832# The metrics index of every input with indexType = metrics or both and no metricsIndex of its
833# own; unset, the HEC token's default index
834; defaultMetricsIndex = docker_metrics
835
836# Truncate messages longer than this
837; maximumMessageLength = 1M
838
839# A unique event_id on the events read from log files
840; includeEventID = false
841
842# Events queued for the output: more rides out longer network trouble, at the cost of memory
843queueSize = 1024
844
845# Digits of the timestamps' fraction: 3, milliseconds (the default); 6, microseconds; 9, nanoseconds
846; timestampPrecision = 3
847
848# Joins a container's lines into events: a line patternRegex does not match continues the one
849# before. maxInterval, maxWait, maxSize and gapBased also time the host logs' and the scripts'
850# eventPattern.
851[pipe.join]
852
853disabled = false
854maxInterval = 100ms
855maxWait = 1s
856maxSize = 100K
857
858# Measure maxInterval and maxWait from the last line instead of the event's first: a source
859# printing a line just under the gap then holds its event (and its acknowledgement) until maxSize
860gapBased = false
861
862patternRegex = ^[^\s]
863
864
865# (deprecated: use container labels) patternRegex for the containers whose fields match every
866# matchRegex.<field>
867# [pipe.join::my_app]
868#; matchRegex.docker_container_image = my_app
869#; matchRegex.stream = stdout
870#; patternRegex = ^\[\d+
871
872# Log lines no thruput cap holds back and no sampling drops, in the container and volume logs of
873# the containers whose fields match every matchRegex.<field> (none: every container; stream:
874# stdout or stderr; a label never matches). Over its cap such a container drops its other lines
875# instead of pausing.
876; [pipe.thruput_exempt::payments-audit]
877; matchRegex.docker_container_name = ^payments$
878; patternRegex = ^AUDIT
879
880# Replace rules for the logs and events (not the stats or Prometheus samples), to remove sensitive
881# data before it is sent; this one masks password=TEST as password=********
882; [pipe.replace::name]
883; patternRegex = (password=)([^\s]+)
884; replace = $1********
885
886# Count the events and bytes leaving every pipeline (pipeline_events, pipeline_bytes) by these
887# labels; maxSeries bounds the combinations. Add both names to the whitelist above to forward them.
888; [pipe.eventcount]
889; labels = index, sourcetype, output
890; fields =
891; maxSeries = 1000
892
893# Report low entropy
894; [diagnostics::node-entropy]
895; settings.path = /rootfs/proc/sys/kernel/random/entropy_avail
896; settings.interval = 1h
897; settings.threshold = 800
898
899# Report a pending reboot
900[diagnostics::node-reboot-required]
901settings.path = /rootfs/run/reboot-required*
902settings.interval = 1h
903
904# Report the CPU vulnerabilities the kernel says the host is open to
905[diagnostics::cpu-vulnerabilities]
906settings.path = /rootfs/sys/devices/system/cpu/vulnerabilities/*
907settings.interval = 1h