docs: improve snmp profile format documentation (#21223)
Ilya Mashchenko committed
Oct 28, 2025 at 12:45 UTC
fa8aae90ea0a8354d41c96519ee9c96e704e7fdd
1 file changed
+144
-26
src/go/plugin/go.d/collector/snmp/profile-format.md
+144
-26
@@ -26,7 +26,7 @@ When Netdata connects to an SNMP device, the collector:
26
27
1. Reads the device’s **sysObjectID** and **sysDescr**.
28
2. Evaluates all available profiles.
29
-3. Applies every profile whose [selector](#1-selector) matches.
29
+3. Applies all profiles whose [selectors](#1-selector) match (multiple profiles can apply simultaneously).
30
4. Uses the combined configuration to:
31
- Collect [scalar metrics](#scalar-metrics-single-values) (single values like uptime or temperature).
32
- Collect [table metrics](#table-metrics-multiple-rows) (multi-row values like per-interface traffic).
@@ -151,15 +151,15 @@ static_tags: <static tags>
151
virtual_metrics: <calculated metrics>
152
```
153
154
-| Section | Purpose |
155
-|-------------------------------------------|-----------------------------------------------------------|
156
-| [**selector**](#1-selector) | Defines which devices the profile applies to. |
157
-| [**extends**](#2-extends) | Inherits and merges other base profiles. |
158
-| [**metadata**](#3-metadata) | Collects device-level information (host labels). |
159
-| [**metrics**](#4-metrics) | Defines which OIDs to collect and how to chart them. |
160
-| [**metric_tags**](#5-metric_tags) | Defines global dynamic tags collected once per device. |
161
-| [**static_tags**](#6-static_tags) | Defines fixed tags applied to all metrics. |
162
-| [**virtual_metrics**](#7-virtual_metrics) | Defines calculated or aggregated metrics based on others. |
154
+| Section | Purpose |
155
+|-------------------------------------------|------------------------------------------------------------------------------------|
156
+| [**selector**](#1-selector) | Defines which devices the profile applies to. |
157
+| [**extends**](#2-extends) | Inherits and merges other base profiles. |
158
+| [**metadata**](#3-metadata) | Collects device-level information (host labels). |
159
+| [**metrics**](#4-metrics) | Defines which OIDs to collect and how to chart them. |
160
+| [**metric_tags**](#5-metric_tags) | Defines global dynamic tags collected once per device and attached to all metrics. |
161
+| [**static_tags**](#6-static_tags) | Defines fixed tags applied to all metrics. |
162
+| [**virtual_metrics**](#7-virtual_metrics) | Defines calculated or aggregated metrics based on others. |
163
164
### 1. selector
165
@@ -240,7 +240,9 @@ It always follows the structure `metadata → device → fields`, where each fie
240
Each field can be:
241
242
- **Static** — `value:` is a fixed string.
243
-- **Dynamic** — `symbol:` reads the value from an SNMP OID.
243
+- **Dynamic** — the value is read from one or more SNMP OIDs using either:
244
+ - `symbol` — a single OID to read from.
245
+ - `symbols` — an ordered list of OIDs to try, **first non-empty wins**.
246
247
```yaml
248
metadata:
@@ -248,23 +250,21 @@ metadata:
250
fields:
251
vendor:
252
value: "Cisco" # static label
253
+
254
model:
252
- symbol: # dynamic label from SNMP
253
- OID: 1.3.6.1.2.1.47.1.1.1.1.2.1
254
- name: entPhysicalModelName
255
+ symbols: # dynamic label with fallback
256
+ - OID: 1.3.6.1.4.1.9.3.6.3.0
257
+ name: ciscoModelA
258
+ - OID: 1.3.6.1.2.1.47.1.1.1.1.13.1
259
+ name: entPhysicalModelName
260
```
261
257
-:::info
258
-
259
-You can define multiple symbols for fallback — the first valid one will be used.
260
-
261
-:::
262
-
262
**How it works**:
263
264
- `vendor` is set statically to `"Cisco"`.
266
-- `model` is collected from `entPhysicalModelName`.
267
-- These values appear as **device (virtual node) host labels** in the UI. They are **not** per-metric tags.
265
+- `model` is collected dynamically. The collector tries the listed OIDs **in order** and uses the **first** one that returns a non-empty value.
266
+- These values appear as **device (virtual node) host labels** in the Netdata UI.
267
+- They are **not per-metric tags** and are applied to the device itself, not individual charts.
268
269
:::tip
270
@@ -342,6 +342,57 @@ See also
342
343
:::
344
345
+#### Underscore-prefixed metrics
346
+
347
+Metric names that start with an underscore (e.g., `_ifHCInOctets`) are **private**: they’re collected but **not** propagated to the SNMP collector output. Use them as internal building blocks (typically as inputs for [virtual_metrics](#7-virtual_metrics)) so the final metric set remains clean. After virtual metrics are computed, the collector drops underscored metrics from the exported set.
348
+
349
+```yaml
350
+# IF-MIB::ifXTable
351
+metrics:
352
+ - MIB: IF-MIB
353
+ table:
354
+ OID: 1.3.6.1.2.1.31.1.1
355
+ name: ifXTable
356
+ symbols:
357
+ - { OID: 1.3.6.1.2.1.31.1.1.1.6, name: _ifHCInOctets, scale_factor: 8 }
358
+ - { OID: 1.3.6.1.2.1.31.1.1.1.10, name: _ifHCOutOctets, scale_factor: 8 }
359
+
360
+virtual_metrics:
361
+ - name: ifTraffic
362
+ per_row: true
363
+ group_by: ["interface"]
364
+ sources:
365
+ - { metric: _ifHCInOctets, table: ifXTable, as: in }
366
+ - { metric: _ifHCOutOctets, table: ifXTable, as: out }
367
+```
368
+
369
+#### Multiple symbol fallbacks
370
+
371
+You can express “try this OID, otherwise try that OID” by declaring **multiple metrics with the same** `symbol.name`, each pointing to a different OID. At runtime the collector **GETs** all declared scalar OIDs, marks missing ones, and **emits** the metric from whichever OID returns data. Missing OIDs are skipped cleanly.
372
+
373
+```yaml
374
+metrics:
375
+ - MIB: HOST-RESOURCES-MIB
376
+ symbol:
377
+ OID: 1.3.6.1.2.1.25.1.1.0
378
+ name: systemUptime
379
+ scale_factor: 0.01
380
+ chart_meta:
381
+ description: Time since the system was last rebooted or powered on.
382
+ family: 'System/Uptime'
383
+ unit: "s"
384
+
385
+ - MIB: HOST-RESOURCES-MIB
386
+ symbol:
387
+ OID: 1.3.6.1.2.1.1.3.0
388
+ name: systemUptime
389
+ scale_factor: 0.01
390
+ chart_meta:
391
+ description: Time since the system was last rebooted or powered on.
392
+ family: 'System/Uptime'
393
+ unit: "s"
394
+```
395
+
396
### 5. metric_tags
397
398
The `metric_tags` section defines **global dynamic tags** — values collected once from the device and applied to **every metric** in the profile.
@@ -378,6 +429,64 @@ See [**Tag Transformation**](#tag-transformation) for supported transformations
429
430
:::
431
432
+#### Underscore-prefixed tags
433
+
434
+Tag names that start with an underscore (e.g., `_if_type`) are **emitted as labels** but are **ignored for chart-ID composition** by the SNMP collector that consumes these metrics. Use underscore tags to keep chart IDs short when another tag already guarantees uniqueness (for example, `interface`). (You still get the underscore-tag value as a chart label.)
435
+
436
+```yaml
437
+metrics:
438
+ - MIB: IF-MIB
439
+ table:
440
+ OID: 1.3.6.1.2.1.31.1.1
441
+ name: ifXTable
442
+ symbols:
443
+ - OID: 1.3.6.1.2.1.31.1.1.1.6
444
+ name: ifHCInOctets
445
+ chart_meta:
446
+ description: Traffic
447
+ family: 'Network/Interface/Traffic/In'
448
+ unit: "bit/s"
449
+ scale_factor: 8
450
+ metric_tags:
451
+ - tag: interface
452
+ symbol: { OID: 1.3.6.1.2.1.31.1.1.1.1, name: ifName }
453
+ - tag: _if_type
454
+ table: ifTable
455
+ symbol: { OID: 1.3.6.1.2.1.2.2.1.3, name: ifType }
456
+ mapping:
457
+ 1: "other"
458
+ 6: "ethernet"
459
+ 24: "loopback"
460
+ 131: "tunnel"
461
+ 161: "lag"
462
+```
463
+
464
+#### Tag fallback (first non-empty wins)
465
+
466
+If you declare the **same tag name** multiple times, tags are evaluated **in order** and the **first non-empty** value is kept. This lets you fall back from a preferred column to an alternative. (Internally, the tag adder only sets a tag if it isn’t already set or is empty.)
467
+
468
+```yaml
469
+metrics:
470
+ - MIB: IF-MIB
471
+ table:
472
+ OID: 1.3.6.1.2.1.31.1.1
473
+ name: ifXTable
474
+ symbols:
475
+ - OID: 1.3.6.1.2.1.31.1.1.1.6
476
+ name: ifHCInOctets
477
+ chart_meta:
478
+ description: Traffic
479
+ family: 'Network/Interface/Traffic/In'
480
+ unit: "bit/s"
481
+ scale_factor: 8 # Octets → bits
482
+ metric_tags:
483
+ - tag: interface
484
+ symbol: { OID: 1.3.6.1.2.1.31.1.1.1.1, name: ifName } # preferred
485
+ - tag: interface
486
+ table: ifTable
487
+ symbol: { OID: 1.3.6.1.2.1.2.2.1.2, name: ifDescr } # fallback
488
+```
489
+
490
### 6. static_tags
491
492
The `static_tags` section defines **fixed key–value pairs** that are attached to every metric collected by the profile.
@@ -1414,15 +1523,17 @@ Common use cases:
1523
```yaml
1524
virtual_metrics:
1525
- name: <string>
1526
+
1527
+ # Option 1 — Direct sources (no fallback)
1528
sources:
1529
- { metric: <metricName>, table: <tableName>, as: <dimensionName> }
1419
- # Optional: direct primary source set
1530
1531
+ # Option 2 — Alternatives (with fallback sets)
1532
alternatives:
1422
- - sources:
1533
+ - sources: # Try this first (preferred)
1534
- { metric: <metricNameA>, table: <tableName>, as: <dimensionName> }
1535
- { metric: <metricNameB>, table: <tableName>, as: <dimensionName> }
1425
- - sources:
1536
+ - sources: # Fallback if the first set is missing
1537
- { metric: <fallbackMetricA>, table: <tableName>, as: <dimensionName> }
1538
- { metric: <fallbackMetricB>, table: <tableName>, as: <dimensionName> }
1539
@@ -1434,6 +1545,13 @@ virtual_metrics:
1545
unit: ...
1546
```
1547
1548
+**Sources vs. Alternatives**:
1549
+
1550
+- `sources:` defines the **primary or default** input set — used when there is only one way to compute the metric.
1551
+- `alternatives:` defines **ordered fallback sets**, each containing its own `sources:` block.
1552
+
1553
+The collector evaluates alternatives **in order** and uses the **first** set that successfully produces data.
1554
+
1555
### Config reference
1556
1557
| Item | Field | Type | Required | Default | Applies to | Description |
@@ -1555,7 +1673,7 @@ virtual_metrics:
1673
**What this does**:
1674
1675
- Defines two **alternatives**, each as a list of sources.
1558
-- At runtime, the collector **picks the first alternative whose sources produce data** (HC first).
1676
+- At runtime, the collector **evaluates alternatives in order and uses the first one where all source metrics exist and contain data** (HC first).
1677
- Once a winner is found, **later alternatives are ignored**.
1678
- The parent emits metrics using **its own** `name` and `chart_meta`, sourcing values from the selected child.
1679
- If both `sources` and `alternatives` are present, `alternatives` take precedence.