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.
- 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.
- 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.
- 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.
- 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:
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.
nvidia-smireports<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.On Ada and later,
gpu_temp_tlimitreports the card's thermal margin in degrees. This changes based on the card and cooling policy and is more actionable than absolute temperature.rx_util/tx_utilreport host to device transfer saturation. This helps identify issues with a GPU sitting at low utilisation under an heavy load.average_power_draw-> instantaneouspower_drawis noisymin/max/default/requestedpower limits -> detect a GPU running under a non-stock capExpected behavior
Fields that
nvidia-smireports and the plugin already parses are emitted on thenvidia_smimeasurement.Actual behavior
1. Schema v13 parses ~25 fields it never emits
schema_v13/types.gofully defines<clocks_event_reasons_counters>,<temperature>,<gpu_power_readings>and the PCIe utilisation tags.schema_v13/parser.gowrites onlytemperature_gpuandpower_limitand nothing at all from the counters:A fully populated block from
nvidia-smi -q -xon this host:Of which Telegraf emits exactly one field:
2. Schema v12 has the same gap, for ~17 fields
schema_v12/types.goalready declaresGpuTempTlimit,SupportedGpuTargetTemp,RxUtil/TxUtiland the fullGpuPowerReadingsblock, andschema_v12/parser.gowrites none of them.3.
power_limitis missing entirely on some v12 cardsThe 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 missingpower_limitexpectation in the test suite:power_limittestdata/a100-sxm4-v12.xml500.00 W)testdata/rtx-3060-v12.xml170.00 W)testdata/rtx-3080-v12.xml336.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 apower_limittag. Cards using<gpu_power_readings>with onlycurrent_power_limitwere never wired up.4. Absolute temperature thresholds are dropped at unmarshal on v13
The v13
Temperaturestruct declares only the*_tlimit_thresholdtag. 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.xmlreports98 C/95 C/93 Cfor those tags but none are collected.5. Values above 2^31 are silently dropped on 32-bit builds
common.SetIfUsedparses integers withstrconv.Atoi, which is documented as equivalent toParseInt(s, 10, 0)—int-sized, so 32 bits on the 32-bit targets Telegraf ships (linux_i386,linux_armhf,freebsd_i386,windows_i386, per theMakefile).SetIfUsedassigns only whenerr == nil, so an out-of-range value produces no log line, no error, and no field:The throttle counters are microsecond accumulators, so they cross 2^31 after roughly 36 minutes of throttling. My current machine is already past it:
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: