Skip to content

inputs.nvidia_smi: many fields are parsed into the schema structs but never emitted #19404

Description

@81reap

Use Case

I want to cutover my custom python exporter with Telegraf. I primarily use it to export host level metrics for my ML server. I like Telegraf as an option but there are a few limitations for Nvidia GPU monitoring.

  1. Why did the GPU slow down, and for how long?

nvidia-smi reports <clocks_event_reasons_counters> and is the only way to attribute a throttle without catching it in the act. Reporting this helps catch issues that may happen between two log scrapes.

  1. How close is the GPU to throttling?

On Ada and later, gpu_temp_tlimit reports the card's thermal margin in degrees. This changes based on the card and cooling policy and is more actionable than absolute temperature.

  1. Is the bottleneck the bus?

rx_util / tx_util report host to device transfer saturation. This helps identify issues with a GPU sitting at low utilisation under an heavy load.

  1. Misc metrics.
  • average_power_draw -> instantaneous power_draw is noisy
  • min / max / default / requested power limits -> detect a GPU running under a non-stock cap

Expected behavior

Fields that nvidia-smi reports and the plugin already parses are emitted on the
nvidia_smi measurement.

Actual behavior

1. Schema v13 parses ~25 fields it never emits

schema_v13/types.go fully defines <clocks_event_reasons_counters>, <temperature>, <gpu_power_readings> and the PCIe utilisation tags. schema_v13/parser.go writes only temperature_gpu and power_limit and nothing at all from the counters:

$ grep -c SetIfUsed plugins/inputs/nvidia_smi/schema_v13/parser.go
79
$ grep -c ClocksEvent plugins/inputs/nvidia_smi/schema_v13/parser.go
0

A fully populated block from nvidia-smi -q -x on this host:

<temperature>
    <gpu_temp>38 C</gpu_temp>
    <gpu_temp_tlimit>49 C</gpu_temp_tlimit>
    <gpu_temp_max_tlimit_threshold>-7 C</gpu_temp_max_tlimit_threshold>
    <gpu_temp_slow_tlimit_threshold>-2 C</gpu_temp_slow_tlimit_threshold>
    <gpu_temp_max_gpu_tlimit_threshold>0 C</gpu_temp_max_gpu_tlimit_threshold>
    <gpu_target_temperature>88 C</gpu_target_temperature>
    <memory_temp>N/A</memory_temp>
    <gpu_temp_max_mem_tlimit_threshold>N/A</gpu_temp_max_mem_tlimit_threshold>
</temperature>

Of which Telegraf emits exactly one field:

$ telegraf --test --config repro.conf | grep -o 'temperature[^,]*'
temperature_gpu=38i

2. Schema v12 has the same gap, for ~17 fields

schema_v12/types.go already declares GpuTempTlimit, SupportedGpuTargetTemp, RxUtil / TxUtil and the full GpuPowerReadings block, and schema_v12/parser.go writes none of them.

3. power_limit is missing entirely on some v12 cards

The v12 parser reads only GpuPowerReadings.PowerLimit, but many cards report <current_power_limit> inside <gpu_power_readings> and no <power_limit> tag. The v13 parser already handles both. These testdata are missing power_limit expectation in the test suite:

Fixture power_limit
testdata/a100-sxm4-v12.xml absent (card reports 500.00 W)
testdata/rtx-3060-v12.xml absent (card reports 170.00 W)
testdata/rtx-3080-v12.xml absent (card reports 336.00 W)

This is adjacent to #15279 but not the same case. That issue covered the RTX 3090, which uses the legacy <power_readings> block with a power_limit tag. Cards using <gpu_power_readings> with only current_power_limit were never wired up.

4. Absolute temperature thresholds are dropped at unmarshal on v13

The v13 Temperature struct declares only the *_tlimit_threshold tag. Cards reporting absolute thresholds use different tag names (gpu_temp_max_threshold, gpu_temp_slow_threshold, gpu_temp_max_gpu_threshold, gpu_temp_max_mem_threshold), which are discarded by the XML unmarshaler before any parser code runs.

The existing testdata/rtx-3080-v13.xml reports 98 C / 95 C / 93 C for those tags but none are collected.

5. Values above 2^31 are silently dropped on 32-bit builds

common.SetIfUsed parses integers with strconv.Atoi, which is documented as equivalent to ParseInt(s, 10, 0)int-sized, so 32 bits on the 32-bit targets Telegraf ships (linux_i386, linux_armhf, freebsd_i386, windows_i386, per the Makefile). SetIfUsed assigns only when err == nil, so an out-of-range value produces no log line, no error, and no field:

$ GOARCH=386 GOOS=linux go run atoi.go   # strconv.Atoi("4251825415")
2147483647 strconv.Atoi: parsing "4251825415": value out of range

The throttle counters are microsecond accumulators, so they cross 2^31 after roughly 36 minutes of throttling. My current machine is already past it:

$ nvidia-smi -q -x | grep sw_power_cap
    <clocks_event_reasons_counters_sw_power_cap>4251825415 us</clocks_event_reasons_counters_sw_power_cap>

6. The README is outdated

Additional info

System: Telegraf 1.39.2, NVIDIA driver 595.84 (nvsmi_device_v13.dtd),
NVIDIA RTX 4000 SFF Ada Generation, Linux 6.18.40.

Config:

[[inputs.nvidia_smi]]

Metadata

Metadata

Assignees

No one assigned

    Labels

    feature requestRequests for new plugin and for new features to existing plugins

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions