Local listening processes discovery
Kind: net_listeners
Overview
Netdata can automatically discover services running on the local host by inspecting the kernel's listening sockets. This is the discoverer that powers Netdata's "zero-config" experience for most database, cache, web-server, and exporter monitoring — if the service is listening on a known port and runs as a recognisable process, Netdata picks it up and starts collecting metrics without you writing any configuration.
This page covers net_listeners-specific setup. For the broader Service Discovery model and the shared template-helper reference, see Service Discovery.
How it works
Each discovery cycle, the discoverer:
- Reads the kernel's TCP/UDP listening-socket table via the bundled
local-listenershelper, which reads Linux procfs socket and process data. - Builds one target per
(protocol, IP, port, process)tuple, exposing.Protocol,.IPAddress,.Port,.Comm(process basename),.Cmdline(full command line), and.Address(the convenienceIPAddress:Port). - Caches each target for 10 minutes so a brief disappearance (process restart) does not churn collector jobs.
- Runs the
services:rules against each target. The stock conf carries ~100 curated rules covering the bulk of go.d modules (databases, web servers, caches, message queues, exporters). - Reconciles disappeared listeners — when a process stops listening, its target is removed and the corresponding collector job stops on the next reconcile.
Limitations
- Only local listeners are visible. Discovering services on other hosts requires another discoverer (
http,snmp,k8s, or a custom one). - The discoverer needs to read kernel socket information. On Linux this works for processes owned by other users only when Netdata can read the appropriate
/proc/<pid>/netfiles; the Netdata installer configures this via thelocal-listenerssetuid helper. - The bundled
local-listenershelper is currently built for Linux. A missing or non-executable helper makes both normal discovery and the DynCfg operational test fail. - Containerised services in
hostnetworking appear as listeners and are picked up here, not by the Docker discoverer. Services in private container networks must be discovered by the Docker discoverer instead. - The discoverer does not introspect process runtime — anything beyond port/
comm/cmdline(e.g. config-file path, version, runtime URL prefix) must be inferred via service rules or known by convention.
Setup
You can configure the net_listeners discoverer in two ways:
| Method | Best for | How to |
|---|---|---|
| UI | Fast setup without editing files | Go to Collectors -> go.d -> ServiceDiscovery -> net_listeners, then add a discovery pipeline. |
| File | File-based configuration or automation | Edit /etc/netdata/go.d/sd/net_listeners.conf and define the discoverer: and services: blocks. |
Prerequisites
Discovery is enabled by default
The stock conf at /etc/netdata/go.d/sd/net_listeners.conf ships with disabled: no and a curated set of rules. To turn discovery off, set disabled: yes at the top of the file.
Trust the curated stock rules
The stock rule set covers most commonly-monitored services out of the box (Apache, Nginx, MySQL, PostgreSQL, Redis, RabbitMQ, MongoDB, Elasticsearch, etc.). Most users do not need to author their own rules — start by enabling the relevant collector module and let the stock rules find local instances.
Configuration
Options
The configuration file has two top-level blocks: discoverer: (the options below) and services: (rules that turn discovered listeners into collector jobs — see Service Rules).
After editing the file, restart the Netdata Agent to load the updated discovery pipeline.
| Option | Description | Default | Required |
|---|---|---|---|
| interval | How often to re-scan the listening-socket table. | 2m | no |
| timeout | Maximum time to wait for the local-listeners helper to return. | 5s | no |
via UI
- Open the Netdata Dynamic Configuration UI.
- Go to
Collectors -> go.d -> ServiceDiscovery -> net_listeners. - Add a new discovery pipeline and give it a name.
- Fill in the discoverer-specific settings and the service rules.
- Save the discovery pipeline.
via File
Define the discovery pipeline in /etc/netdata/go.d/sd/net_listeners.conf.
The file has two top-level blocks: discoverer: (the options above) and services: (rules that turn discovered targets into collector jobs — see Service Rules).
After editing the file, restart the Netdata Agent to load the updated discovery pipeline.
Examples
Default — keep stock rules
Most users should not need to touch this file. The stock conf carries ~100 curated rules. Set disabled: yes if you want to disable local-listener discovery entirely.
disabled: no
discoverer:
net_listeners: { }
# services rules ship in the stock conf — the snippet below is illustrative only
services:
- id: redis
match: '{{ or (eq .Port "6379") (eq .Comm "redis-server") }}'
config_template: |
name: local
address: redis://@{{.Address}}
Faster scan interval
Bump the scan rate to once per minute. Useful for very dynamic environments where services come and go often (e.g. ephemeral test runners).
disabled: no
discoverer:
net_listeners:
interval: 1m
services: [ ]
Service Rules
A services: rule turns each discovered listener into one or more collector jobs. The stock conf carries ~100 curated rules — most rules match on a (.Port, .Comm) pair (or just .Comm / .Cmdline for services with non-default ports), and most templates use name: local plus the canonical .Address to point the collector at the listener.
The shared rule model — function reference (match, glob, sprig, regexFind, trimPrefix, promPort), config_template rendering rules, and the missingkey=error failure semantics — lives on the Service Discovery hub page. The notes below are net_listeners-specific.
How rules are evaluated
Quick reference — see Rule evaluation semantics on the hub page for the full model.
- Match by .Port AND .Comm where possible — The idiomatic stock pattern is
{{ and (eq .Port "PORT") (eq .Comm "PROCESS") }}— porty + processy. This avoids picking up the wrong process on the right port (e.g. an HTTP exporter listening on:80is not Apache). - For services with non-standard ports, use .Cmdline + glob — Some services (Logstash, RabbitMQ, ZooKeeper, Tomcat, …) listen on default ports but identify themselves through their command line, not their
.Comm(which is a genericjava,python, …). Stock rules for these useglob .Cmdline "*tomcat*"orglob .Cmdline "*rabbitmq*". - Use
match "sp"for variant patterns — When you want to match any of several short patterns, simple-patterns (match "sp" .Comm "mysqld mariadbd") is shorter than nestedor (eq ...) (eq ...). See the hub page for matcher types. - Module inference from rule id — For
net_listeners, setid: <module-name>so the rendered job inherits the module name automatically. The stock conf does this throughout (id: nginx,id: postgres, …). - The
exportercatch-all rule usespromPort— The last rule in the stock conf catches Prometheus exporters by port using thepromPorthelper, which maps a port number to a known exporter module name (or empty if unknown). Keep this rule at the bottom — it overlaps with everything above it.
Template Variables
Available inside both match expressions and config_template bodies for net_listeners targets.
| Variable | Type | Description |
|---|---|---|
.Protocol | string | Protocol — TCP, UDP, TCP6, UDP6. |
.IPAddress | string | Listening IP address (e.g. 127.0.0.1, 0.0.0.0, ::). |
.Port | string | Listening port. Stock rules typically gate on this with eq .Port "PORT". |
.Comm | string | Process basename (comm field — kernel-truncated to 15 chars). Examples: nginx, mysqld, redis-server. Best for native daemons. |
.Cmdline | string | Full process command line. Use glob .Cmdline "*pattern*" or regexFind (from sprig) to match interpreters that hide the real service name behind java/python/node (e.g. RabbitMQ, Logstash, ZooKeeper, Spigot). |
.Address | string | Convenience IPAddress:Port — used in nearly every stock rule template. |
Examples
Each example shows one or more entries from the services: array. The full curated rule set lives in the stock conf; the snippets below illustrate the common patterns.
Port + Comm (idiomatic)
The most common stock-rule shape. Match the canonical port AND the canonical process name.
- id: redis
match: '{{ or (eq .Port "6379") (eq .Comm "redis-server") }}'
config_template: |
name: local
address: redis://@{{.Address}}
Comm + Cmdline glob (for interpreted services)
When the process is java/python/node and the real service name lives in the command line.
- id: rabbitmq
match: '{{ or (eq .Port "15672") (glob .Cmdline "*rabbitmq*") }}'
config_template: |
name: local
url: http://{{.Address}}
username: guest
password: guest
collect_queues_metrics: no
Multiple jobs from one target (sequence output)
When one running service should produce multiple collector jobs — for example, MySQL exposing both a Unix-socket DSN and a TCP DSN. The rendered YAML is a top-level sequence; each item becomes a separate job.
- id: mysql
match: '{{ or (eq .Port "3306") (eq .Comm "mysqld" "mariadbd") }}'
config_template: |
- name: local
dsn: netdata@unix(/var/run/mysqld/mysqld.sock)/
- name: local
dsn: netdata@tcp({{.Address}})/
Prometheus-exporter catch-all (promPort)
The last rule in the stock conf catches generic Prometheus exporters by port. promPort .Port returns the well-known module name for that port, or empty. The rule is bottom-most because it overlaps with every preceding curated rule.
- id: exporter
match: '{{ or (and (not (empty (promPort .Port))) (not (eq .Comm "docker-proxy"))) (glob .Comm "*exporter*") }}'
config_template: |
{{ $name := promPort .Port -}}
{{ if empty $name -}}
{{ $name = printf "%s_%s" .Comm .Port -}}
{{ end -}}
module: prometheus
name: {{$name}}_local
url: http://{{.Address}}/metrics
Verify discovery worked
After enabling the discoverer, confirm it is finding listeners and producing jobs.
Test a candidate configuration without applying it
A DynCfg test runs the same installed nd-run and local-listeners path once, with the production flags and configured timeout, then parses the complete snapshot and discards it. Success proves that this one helper invocation and parse worked on the local host at that instant.
The test does not start discovery, cache or publish targets, evaluate services: rules, create collector jobs, or prove that a generated job can connect to its service. It requires no permissions beyond normal local-listener discovery. Work and buffered output scale with the host's socket/process inventory; caller cancellation and timeout bound elapsed time, not the number of inspected entries.
Confirm listeners are being scanned
Watch the agent log for discoverer=net_listeners messages. With systemd:
journalctl _SYSTEMD_INVOCATION_ID="$(systemctl show --value --property=InvocationID netdata)" --namespace=netdata --grep "discoverer=net_listeners"
On a healthy host you should see periodic scan activity. If the log shows local-listeners exec failures, the helper binary is missing or not executable.
Confirm the local-listeners helper sees your service
Run the helper manually to see what targets it would emit:
sudo /usr/libexec/netdata/plugins.d/local-listeners
If your service does not appear in the helper output, the kernel's listening-socket table is the place to debug — ss -tlnp and ss -ulnp should show it.
Confirm jobs are being created
In the Netdata UI go to Collectors -> go.d -> <module> for the module your listener should map to. Stock-rule jobs are typically named local.
Troubleshooting
A locally-running service is not picked up
Check, in order:
- Is the service actually listening (
ss -tlnp | grep <name>)? - Does the stock conf have a rule for it? See
/etc/netdata/go.d/sd/net_listeners.conf. - Is the service on a non-standard port? Stock rules typically gate on the canonical port. Add a rule keyed on
.Commor.Cmdlinefor non-default ports. - Is the process name truncated past 15 chars?
.Commis kernel-truncated; use.Cmdlineinstead.
Wrong module picked
The stock exporter catch-all rule (last in the file) is greedy by design — anything on a known Prometheus port gets the prometheus module. Add a more specific rule above it if you want a different module to win.
Generated jobs fail to start
The discoverer creates jobs but does not run them. Common causes: the rendered template assumes credentials the local service rejects (e.g. RabbitMQ default guest:guest); a rule renders the wrong port or protocol; or the service has TLS but the template uses HTTP.
Do you have any feedback for this page? If so, you can open a new issue on our netdata/learn repository.