Skip to content

Metrics Reference

All metric names and attributes follow the OpenTelemetry semantic conventions for hardware and system metrics. See the semconv registry for the full instrument list.

Collected for each detected GPU on Linux and Windows. Availability depends on vendor, OS, and GPU model.

MetricTypeUnitDescriptionNVIDIAAMDIntel
hw.gpu.utilizationGauge1GPU compute/encoder/decoder utilization (0.0–1.0)YesYesYes*
hw.gpu.memory.utilizationGauge1Fraction of GPU memory used (usage / limit)YesYesYes*
hw.gpu.memory.controller.utilizationGauge1Memory controller busy fraction (extension; NVML/AMD)YesYes-
hw.gpu.memory.limitUpDownCounterByTotal GPU memoryYesYesYes*
hw.gpu.memory.usageUpDownCounterByUsed GPU memoryYesYesYes*
hw.gpu.memory.freeUpDownCounterByFree GPU memoryYesYesYes*
hw.temperatureGaugeCelDie or memory temperatureYesYesYes
hw.fan.speedGaugerpmFan speed-†YesYes*
hw.fan.speed_ratioGauge1Fan speed as fraction of maxYes--
hw.powerGaugeWCurrent power drawYesYesYes
hw.power.limitGaugeWPower limit/capYesYesYes
hw.energyCounterJCumulative energy consumedYesYesYes
hw.gpu.speedGaugeHzClock frequency (hw.gpu.clock_domain)YesYesYes*
hw.gpu.ioCounterByCumulative PCIe I/O bytesYesYes¶Soft‡
hw.gpu.interconnect.ioCounterByCumulative NVLink / XGMI bytesYes§Yes¶-
hw.statusUpDownCounter1Hardware status (up / throttled states)YesYesYes
hw.gpu.allocatedGauge11 when process memory or util ≥ thresholdYesYesYes
hw.gpu.idleGauge1Idle ratio (1 - utilization) when util knownYesYesYes*
hw.errorsCounter{error}ECC, PCIe, XID, and RAS error countsYesYes (RAS + PCIe replay¶)-

* Intel support depends on driver (i915/Xe) and kernel version.

† NVIDIA NVML reports fan speed as a percentage — use hw.fan.speed_ratio; hw.fan.speed (rpm) is omitted for NVIDIA.

§ Requires OTEL_GPU_INTERCONNECT_ENABLED (default true).

¶ AMD XGMI / PCIe when the driver exposes counters.

‡ Soft / best-effort when the kernel exposes the counters.

* Intel device util/VRAM/power/throttle/media use Level Zero Sysman when available (Linux/Windows); otherwise DRM/hwmon/PDH subset. Encoder/decoder util comes from media engine groups or Windows PDH VideoEncode/VideoDecode.

† NVIDIA NVML exposes fan speed as a percentage, not RPM, so hw.fan.speed is not emitted for NVIDIA — use hw.fan.speed_ratio instead.

‡ Soft-omitted when the vendor library/driver path does not expose the counter. Core util/memory/power still collect without those libraries. Windows AMD has no PCIe/XGMI throughput API (ADL).

§ NVLink on Linux and Windows NVIDIA when the GPU exposes enabled NVLink links (rates after the second sample).

¶ AMD Linux via libamd_smi (amdsmi_get_gpu_pci_throughput, amdsmi_get_link_metrics, amdsmi_get_violation_status) when present; soft-omitted on VMs/consumer cards without those counters. AMD media util (MmActivity) is exported as hw.gpu.task=encoder when the driver only exposes a combined VCN counter (decoder stays unset).

All GPU metrics carry these base attributes:

AttributeDescriptionExample
hw.idUnique device identifier (required by spec)GPU-a1b2c3d4-5678-...
hw.nameProduct nameNVIDIA A100-SXM4-80GB
hw.vendorVendor namenvidia, amd, intel
gpu.indexZero-based device index0, 1
gpu.pci_addressPCI bus address0000:01:00.0

Additional per-metric attributes:

MetricAttributeValues
hw.gpu.utilizationhw.gpu.taskgeneral, encoder, decoder
hw.temperaturehw.sensor_locationdie, memory
hw.gpu.speedhw.gpu.clock_domaingraphics, memory, sm
hw.gpu.ionetwork.io.directionreceive, transmit
hw.gpu.interconnect.ionetwork.io.directionreceive, transmit
hw.gpu.interconnect.iohw.gpu.interconnect.typenvlink, xgmi, other
hw.statusstatus / throttle attrsup / throttled + reason labels
hw.errorserror.typecorrected, uncorrected, pcie_replay, xid, ras_corrected, ras_uncorrected
hw.errorshw.typegpu
MIG devicesgpu.mig.enabled, gpu.mig.device_id, gpu.parent.uuid, gpu.mig.instance_id, gpu.mig.profileLinux NVIDIA only (MIG is not available on Windows)
Partitions (RDC)hw.parent, hw.gpu.partitionAMD compute partitions when available

Collected on all platforms (Linux, macOS, Windows) via gopsutil. Follows the OTel semantic conventions for system metrics.

MetricTypeUnitDescriptionAttributes
system.cpu.utilizationGauge1CPU utilization per logical core (0.0–1.0)cpu.logical_number
system.cpu.logical.countUpDownCounter{cpu}Number of logical CPU cores
system.memory.usageUpDownCounterByMemory bytes by statesystem.memory.state={used,free,cached,buffers}
system.memory.utilizationGauge1Memory utilization (0.0–1.0)
system.disk.ioCounterByDisk I/O bytessystem.device, disk.io.direction={read,write}
system.disk.operationsCounter{operation}Disk I/O operationssystem.device, disk.io.direction={read,write}
system.filesystem.usageUpDownCounterByFilesystem space by statesystem.device, system.filesystem.mountpoint, system.filesystem.type, system.filesystem.state={used,free}
system.filesystem.utilizationGauge1Filesystem utilization (0.0–1.0)system.device, system.filesystem.mountpoint, system.filesystem.type
system.network.ioCounterByNetwork I/O bytesnetwork.interface.name, network.io.direction={receive,transmit}
system.network.errorsCounter{error}Network errorsnetwork.interface.name, network.io.direction={receive,transmit}

Self-monitoring of the collector process. Follows the OTel semantic conventions for process metrics.

MetricTypeUnitDescriptionAttributes
process.cpu.timeCountersCumulative CPU timecpu.mode={user,system}
process.cpu.utilizationGauge1CPU utilization (0.0–1.0)
process.memory.usageUpDownCounterByResident memory (RSS)
process.memory.virtualUpDownCounterByVirtual memory size
process.thread.countUpDownCounter{thread}OS thread count
process.unix.file_descriptor.countUpDownCounter{file_descriptor}Open file descriptors (Linux/macOS)
process.runtime.go.goroutinesGauge{goroutine}Go goroutine count
process.runtime.go.mem.heap_allocGaugeByGo heap memory allocated

Collected on each scrape from NVML (NVIDIA) or DRM fdinfo (AMD/Intel). Requires host PID visibility — Docker --pid=host / Compose pid: host, or Kubernetes hostPID: true — so /proc shows workload PIDs. Without it, device-level hw.gpu.* metrics still work, but per-process cmdline, state (including zombies), and GPU process metrics will be missing or incomplete.

These attributes support views like zombie-process triage: filter process.state == "zombie" and show process.command_line, process.pid, process.owner, and process.uptime (age).

MetricTypeUnitDescriptionNVIDIAAMDIntel
process.gpu.memory.usageUpDownCounterByGPU memory used by a process on a deviceYesYesYes
process.gpu.memory.utilizationGauge1Process memory / device memory limit (0–1); omitted when limit unknownYesYesYes
process.gpu.utilizationGauge1Per-process GPU utilization (0.0–1.0)YesYesYes
process.uptimeGaugesProcess uptime for GPU-attributed PIDsYesYesYes
AttributeDescription
process.pidHost process ID
process.executable.nameShort name from /proc/<pid>/comm (or Windows image basename)
process.command_lineTruncated command line (see OTEL_GPU_PROCESS_CMDLINE)
process.staterunning, sleeping, zombie, stopped, dead, unknown
process.owner / process.owner.useridUsername and UID/SID
process.workload.kindllm_inference, llm_training, or other
process.workload.frameworkvllm, ollama, llama.cpp, sglang, tgi, triton, ray, pytorch, unknown
hw.id, hw.name, hw.vendor, gpu.index, gpu.pci_addressSame device attrs as hw.gpu.*
hw.gpu.taskOn utilization only: general, encoder, decoder
k8s.pod.uidFrom cgroup path when present
k8s.pod.name, k8s.namespace.name, k8s.container.nameVia kubelet PodResources (GPU device join) and/or pod API lookup
container.idRuntime container ID when resolvable

Enable with OTEL_GPU_EBPF_ENABLED (on by default on Linux for serving+ / all modes; off in light). Soft-fails without caps. Discovers libcudart.so* (CUDA runtime API) and libcuda.so* (CUDA driver API) from common install paths and from /proc/*/maps (with Docker --pid=host / Kubernetes hostPID: true), so fleet DaemonSets do not need a CUDA toolkit mount. Driver-API probes extend coverage to frameworks that never load libcudart (llama.cpp, Ollama). Attaches uprobes/uretprobes for launches (cudaLaunchKernel, cudaLaunchKernelExC, cooperative, cuLaunchKernel, cuLaunchKernelEx), graph replays (cudaGraphLaunch, cuGraphLaunch), alloc/free, memcpy, stream/device/event sync, and cudaSetDevice. PIDs that map libcudart skip driver launch/graph events so runtime wrappers are not double-counted. AMD/Intel do not use this path — their per-process metrics come from DRM fdinfo.

MetricTypeUnitDescriptionAttributes
gpu.kernel.launch.callsCounter{call}CUDA kernel launch count (runtime and driver APIs)process.pid, process.executable.name, cuda.kernel.name, hw.id / gpu.index when known
gpu.kernel.grid.sizeHistogram{thread}Total threads in grid per launchsame
gpu.kernel.block.sizeHistogram{thread}Threads per block per launchsame
gpu.kernel.shared_memoryHistogramByDynamic shared memory per launch (cudaLaunchKernel sharedMem)same
gpu.kernel.durationHistogramsModel estimate of launch→sync duration (shared store with occupancy; cardinality-capped names)same + optional cuda.launch.kind=graph
gpu.graph.launch.callsCounter{call}CUDA graph replay invocations (cudaGraphLaunch / cuGraphLaunch). Counts replays, not the kernels executed inside each replay — that number is not observable at this API-tracing layerprocess.pid, process.executable.name, hw.id / gpu.index when known
gpu.memory.allocationsCounterByBytes allocated via cudaMallocprocess.pid, process.executable.name, hw.id / gpu.index when known
gpu.memory.copiesHistogramByBytes per cudaMemcpyAsyncprocess.pid, cuda.memcpy.kind, hw.id / gpu.index when known

hw.id is set after cudaSetDevice for that thread, or immediately on single-GPU hosts. On multi-GPU hosts before cudaSetDevice, join via process.pid as before. Linux/NVIDIA (CUDA) only — same eBPF path for Kubernetes and non-Kubernetes when host PID is visible. AMD/Intel use device/process metrics via DRM fdinfo, not these kernel series.

These are CPU-side model estimates, not hardware SM occupancy (warps resident / max warps). Spans run from kernel launch to sync API return; thread-seconds are clamped to NVML CUDA core count and normalized so multi-process totals do not exceed device capacity.

MetricTypeUnitDescription
process.gpu.core.usageGauge{cores}Normalized avg CUDA cores from launch→sync thread-seconds
process.gpu.estimated.sm_activeGauge1Fraction of interval with any launch→sync span (gpu.measurement.source=ebpf_model)
hw.gpu.core.limitGauge{cores}NVML CUDA core count
hw.gpu.estimated.sm_activeGauge1Device-wide union of launch→sync spans

Prefer NVML process.gpu.utilization for sampled SM%. These estimates are not DCGM hw.gpu.sm.utilization / hw.gpu.sm.occupancy. Use them when NVML process util is unavailable or when correlating launch→sync activity with device util.

Known limits: no GPU completion signal (late sync inflates usage); cudaGraphLaunch / cuGraphLaunch is one composite span and gpu.graph.launch.calls counts replays, not kernels (no per-node kernels inside a graph); cudaStreamWaitEvent wait edges are not modeled; sync cudaMemcpy and default-stream sync are treated as device-wide (legacy default-stream semantics).


Enable with OTEL_GPU_DCGM_ENABLED=true. Soft-fails when libdcgm is missing. DCGM is optional — continuous clocks (graphics / sm / memory), util, and power work from NVML alone. Metrics carry gpu.measurement.source=dcgm. Set OTEL_GPU_DCGM_PREFER=true so DCGM owns overlapping IO / power / util / graphics clock / idle (NVML suppresses those series — single producer). Memory clock stays on NVML.

MetricTypeUnitAttributes
hw.gpu.engine.utilizationGauge1hw.gpu.engine
hw.gpu.sm.utilizationGauge1DCP SM active
hw.gpu.sm.occupancyGauge1DCP SM occupancy
hw.gpu.pipe.utilizationGauge1hw.gpu.pipe=tensor|fp16|fp32|fp64
hw.gpu.memory.bandwidth.utilizationGauge1
hw.gpu.io / hw.gpu.interconnect.ioCounterByPrefer only; rate-integrated PCIe / NVLink
hw.gpu.speedGaugeHzPrefer only; hw.gpu.clock_domain=graphics (field 100)
hw.gpu.idleGauge1Prefer only; derived from Prefer util
hw.power / hw.gpu.utilization / hw.gpu.memory.controller.utilizationGaugePrefer onlyFields 155 / 203 / 204 (204 → controller util)
shield360.collector.gpu.dcgm.sample_validUpDownCounter10 on blank sample

Control plane: POST /v1/dcgm/pause and POST /v1/dcgm/resume (loopback OTEL_GPU_CONTROL_ADDR).


Enable with OTEL_GPU_RDC_ENABLED=true. Soft-fails when librdc is missing. Metrics carry gpu.measurement.source=rdc. Partition samples may set hw.parent.

MetricTypeUnitNotes
hw.gpu.sm.utilizationGauge1SM/CU active
hw.gpu.sm.occupancyGauge1CU / SM occupancy
hw.gpu.pipe.utilizationGauge1fp16 / fp32 / fp64 from EVAL_FLOPS percent
hw.gpu.simd.utilizationGauge1SIMD utilization

Enable with OTEL_GPU_KINETO_ENABLED=true. Does not emit continuous metrics. Use the control API:

  • POST /v1/profile/gpu — match GPU PIDs and write on-demand libkineto config
  • Requires OTEL_GPU_CONTROL_ADDR (loopback by default; set OTEL_GPU_CONTROL_ALLOW_REMOTE=true + token for multi-node)

Self-metric: shield360.collector.profile.requests.

Multi-node fan-out (no always-on collector cost):

Terminal window
go run ./cmd/profile-fanout --hosts node1,node2 --port 1919 --token "$TOKEN" --duration-ms 500
# or SLURM:
go run ./cmd/profile-fanout --job-id 12345 --port 1919 --token "$TOKEN"

Enable with OTEL_HOST_INTEL_PT_ENABLED=true and a control address. Does not run continuously.

  • POST /v1/profile/cpu/pt with {"duration_ms":500}
  • Requires Linux intel_pt PMU and perf in PATH
  • Caps: duration, CPU count, AUX buffer pages (see configuration)

Fan-out: profile-fanout --profile cpu-pt ...


Enable with OTEL_HOST_PMU_ENABLED=true.

MetricNotes
hw.cpu.instructions / hw.cpu.cycles / cache / branch / TLBCore PMU
hw.cpu.memory.ioWhen memory_bandwidth or uncore is in OTEL_HOST_PMU_EVENTS; IMC CAS×64 bytes

Enable with OTEL_TPU_ENABLED=true. Scrapes a Prometheus-format TPU endpoint (OTEL_TPU_ENDPOINT, default http://127.0.0.1:2112/metrics) and re-exports allowlisted series. Soft-fails when the endpoint is unreachable.


FlagDefaultMetrics surface
OTEL_HOST_NIC_ENABLEDfalsePer-NIC hardware counters beyond basic system.network.*
OTEL_HOST_RDMA_ENABLEDfalseRDMA device counters (OTEL_HOST_RDMA_COUNTERS allowlist)

Soft-omitted when sysfs/counters are unavailable.


FeatureNVIDIAAMDIntel
Device hw.gpu.* / spec hw.*YesYesPartial
process.gpu.memory.usage / memory.utilization / utilizationNVMLDRM fdinfoDRM fdinfo
Pod UID on process metricscgroupcgroupcgroup
eBPF activity + occupancyYes (default on Linux)
DCGM profilingOptional
RDC profilingOptional (soft-skip without librdc)