@cryptotaxi247 / netdata-1 / commits / fa8aae90e

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.