Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 14 additions & 12 deletions docs/PLUGIN_DOC.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
| OsPlugin | sh -c '( lsb_release -ds &#124;&#124; (cat /etc/\*release &#124; grep PRETTY_NAME) &#124;&#124; uname -om ) 2>/dev/null &#124; head -n1'<br>cat /etc/\*release &#124; grep VERSION_ID<br>wmic os get Version /value<br>wmic os get Caption /Value | **Analyzer Args:**<br>- `exp_os`: Union[str, list] — Expected OS name/version string(s) to match (e.g. from lsb_release or /etc/os-release).<br>- `exact_match`: bool — If True, require exact match for exp_os; otherwise substring match. | - | [OsDataModel](#OsDataModel-Model) | [OsCollector](#Collector-Class-OsCollector) | [OsAnalyzer](#Data-Analyzer-Class-OsAnalyzer) |
| PackagePlugin | dnf list --installed<br>dpkg-query -W<br>pacman -Q<br>cat /etc/\*release<br>wmic product get name,version | **Analyzer Args:**<br>- `exp_package_ver`: Dict[str, Optional[str]] — Map package name -> expected version (None = any version). Checked against installed packages.<br>- `regex_match`: bool — If True, match package versions with regex; otherwise exact or prefix match.<br>- `rocm_regex`: Optional[str] — Optional regex to identify ROCm package version (used when enable_rocm_regex is True).<br>- `enable_rocm_regex`: bool — If True, use rocm_regex (or default pattern) to extract ROCm version for checks. | - | [PackageDataModel](#PackageDataModel-Model) | [PackageCollector](#Collector-Class-PackageCollector) | [PackageAnalyzer](#Data-Analyzer-Class-PackageAnalyzer) |
| PciePlugin | lspci -d {vendor_id}: -nn<br>lspci -x<br>lspci -xxxx<br>lspci -PP<br>lspci -PP -d {vendor_id}:{dev_id}<br>lspci -PP -D -d {vendor_id}:{dev_id}<br>lspci -PP -D<br>lspci -vvv<br>lspci -vvvt | **Analyzer Args:**<br>- `exp_speed`: int — Expected PCIe link speed (generation 1–5).<br>- `exp_width`: int — Expected PCIe link width in lanes (1–16).<br>- `exp_sriov_count`: int — Expected SR-IOV virtual function count.<br>- `exp_gpu_count_override`: Optional[int] — Override expected GPU count for validation.<br>- `exp_max_payload_size`: Union[Dict[int, int], int, NoneType] — Expected max payload size: int for all devices, or dict keyed by device ID.<br>- `exp_max_rd_req_size`: Union[Dict[int, int], int, NoneType] — Expected max read request size: int for all devices, or dict keyed by device ID.<br>- `exp_ten_bit_tag_req_en`: Union[Dict[int, int], int, NoneType] — Expected 10-bit tag request enable: int for all devices, or dict keyed by device ID. | - | [PcieDataModel](#PcieDataModel-Model) | [PcieCollector](#Collector-Class-PcieCollector) | [PcieAnalyzer](#Data-Analyzer-Class-PcieAnalyzer) |
| ProcessPlugin | top -b -n 1<br>rocm-smi --showpids<br>top -b -n 1 -o %CPU | **Analyzer Args:**<br>- `max_kfd_processes`: int — Maximum allowed number of KFD (Kernel Fusion Driver) processes; 0 disables the check.<br>- `max_cpu_usage`: float — Maximum allowed CPU usage (percent) for process checks. | **Collection Args:**<br>- `html_view`: bool — When true, include logged command artifacts in command_artifacts.html using human-readable output.<br>- `top_n_process`: int — Number of top processes by CPU usage to collect (e.g. for top -b -n 1 -o %%CPU). | [ProcessDataModel](#ProcessDataModel-Model) | [ProcessCollector](#Collector-Class-ProcessCollector) | [ProcessAnalyzer](#Data-Analyzer-Class-ProcessAnalyzer) |
| ProcessPlugin | for p in {pids}; do printf "%s:" "$p"; cat /proc/$p/comm 2>/dev/null &#124;&#124; true; printf "\n"; done<br>printf "__SAMPLER__:%s\n" "$$"; for f in /proc/[0-9]\*/stat; do [ -r "$f" ] &#124;&#124; continue; pid="${f#/proc/}"; pid="${pid%/stat}"; [ "$pid" = "$$" ] && continue; printf "%s&#124;" "$pid"; cat "$f" 2>/dev/null &#124;&#124; true; printf "\n"; done<br>cat /proc/stat | **Analyzer Args:**<br>- `max_cpu_usage`: float — Maximum allowed aggregate CPU execution percentage; idle and I/O-wait time are excluded. | **Collection Args:**<br>- `html_view`: bool — When true, include logged command artifacts in command_artifacts.html using human-readable output.<br>- `top_n_process`: int — Number of top processes by CPU usage to collect.<br>- `sample_interval_seconds`: float — Wall-clock interval between procfs CPU samples. | [ProcessDataModel](#ProcessDataModel-Model) | [ProcessCollector](#Collector-Class-ProcessCollector) | [ProcessAnalyzer](#Data-Analyzer-Class-ProcessAnalyzer) |
| RdmaPlugin | rdma link -j<br>rdma dev<br>rdma link<br>rdma statistic -j | **Analyzer Args:**<br>- `exclusion_regex`: Optional[list[str]] — Regex patterns matched against an interface netdev; matching interfaces are skipped. | **Collection Args:**<br>- `html_view`: bool — When true, include logged command artifacts in command_artifacts.html using human-readable output. | [RdmaDataModel](#RdmaDataModel-Model) | [RdmaCollector](#Collector-Class-RdmaCollector) | [RdmaAnalyzer](#Data-Analyzer-Class-RdmaAnalyzer) |
| RegexSearchPlugin | No collector step: reads local text from the CLI --data path (file or directory).<br>Directory scans load each file's contents into RegexSearchData for analysis. | Runs RegexSearchAnalyzer: user-defined patterns via analysis_args.error_regex (same shape as Dmesg).<br>Emits regex match events with optional per-file source in the description when scanning directories.<br>**Analyzer Args:**<br>- `error_regex`: Optional[list[dict[str, Any]]] — Regex patterns to search for; each dict may include regex (str), message, event_category, event_priority (same as Dme...<br>- `interval_to_collapse_event`: int — Seconds within which repeated events are collapsed into one.<br>- `num_timestamps`: int — Number of timestamps to include per event in output. | - | [RegexSearchData](#RegexSearchData-Model) | - | [RegexSearchAnalyzer](#Data-Analyzer-Class-RegexSearchAnalyzer) |
| RocmPlugin | {rocm_path}/opencl/bin/\*/clinfo<br>env &#124; grep -Ei 'rocm&#124;hsa&#124;hip&#124;mpi&#124;openmp&#124;ucx&#124;miopen'<br>ls /sys/class/kfd/kfd/proc/<br>grep -i -E 'rocm' /etc/ld.so.conf.d/\*<br>{rocm_path}/bin/rocminfo<br>ls -v -d {rocm_path}\*<br>ls -v -d {rocm_path}-[3-7]\* &#124; tail -1<br>ldconfig -p &#124; grep -i -E 'rocm'<br>grep . -H -r -i {rocm_path}/.info/\* | **Analyzer Args:**<br>- `exp_rocm`: Union[str, list] — Expected ROCm version string(s) to match (e.g. from rocminfo).<br>- `exp_rocm_latest`: str — Expected 'latest' ROCm path or version string for versioned installs.<br>- `exp_rocm_sub_versions`: dict[str, Union[str, list]] — Map sub-version name (e.g. version_rocm) to expected string or list of allowed strings. | **Collection Args:**<br>- `html_view`: bool — When true, include logged command artifacts in command_artifacts.html using human-readable output.<br>- `rocm_path`: str — Base path to ROCm installation (e.g. /opt/rocm). Used for rocminfo, clinfo, and version discovery. | [RocmDataModel](#RocmDataModel-Model) | [RocmCollector](#Collector-Class-RocmCollector) | [RocmAnalyzer](#Data-Analyzer-Class-RocmAnalyzer) |
Expand Down Expand Up @@ -982,7 +982,7 @@ PcieDataModel

### Description

Collect Process details
Collect aggregate CPU usage and top processes from Linux procfs.

**Bases**: ['InBandDataCollector']

Expand All @@ -991,19 +991,19 @@ Collect Process details
### Class Variables

- **SUPPORTED_OS_FAMILY**: `{<OSFamily.LINUX: 3>}`
- **CMD_KFD**: `rocm-smi --showpids`
- **CMD_CPU_USAGE**: `top -b -n 1`
- **CMD_PROCESS**: `top -b -n 1 -o %CPU `
- **CMD_PROC_STAT**: `cat /proc/stat`
- **CMD_PROCESS_STAT**: `printf "__SAMPLER__:%s\n" "$$"; for f in /proc/[0-9]*/stat; do [ -r "$f" ] || continue; pid="${f#/proc/}"; pid="${pid%/stat}"; [ "$pid" = "$$" ] && continue; printf "%s|" "$pid"; cat "$f" 2>/dev/null || true; printf "\n"; done`
- **CMD_PROCESS_NAMES**: `for p in {pids}; do printf "%s:" "$p"; cat /proc/$p/comm 2>/dev/null || true; printf "\n"; done`

### Provides Data

ProcessDataModel

### Commands

- top -b -n 1
- rocm-smi --showpids
- top -b -n 1 -o %CPU
- for p in {pids}; do printf "%s:" "$p"; cat /proc/$p/comm 2>/dev/null || true; printf "\n"; done
- printf "__SAMPLER__:%s\n" "$$"; for f in /proc/[0-9]\*/stat; do [ -r "$f" ] || continue; pid="${f#/proc/}"; pid="${pid%/stat}"; [ "$pid" = "$$" ] && continue; printf "%s|" "$pid"; cat "$f" 2>/dev/null || true; printf "\n"; done
- cat /proc/stat

## Collector Class RdmaCollector

Expand Down Expand Up @@ -1882,13 +1882,16 @@ class for collection of PCIe data.

## ProcessDataModel Model

### Description

CPU execution usage (excluding idle and I/O-wait) and top processes from procfs.

**Link to code**: [processdata.py](https://github.com/amd/node-scraper/blob/HEAD/nodescraper/plugins/inband/process/processdata.py)

**Bases**: ['DataModel']

### Model annotations and fields

- **kfd_process**: `Optional[int]`
- **cpu_usage**: `Optional[float]`
- **processes**: `Optional[list[tuple[str, str]]]`

Expand Down Expand Up @@ -2430,7 +2433,7 @@ Check PCIe Data for errors

### Description

Check cpu and kfd processes are within allowed maximum cpu and gpu usage
Check aggregate CPU usage against the configured maximum.

**Bases**: ['DataAnalyzer']

Expand Down Expand Up @@ -2840,8 +2843,7 @@ Arguments for PCIe analyzer

### Annotations / fields

- **max_kfd_processes**: `int` — Maximum allowed number of KFD (Kernel Fusion Driver) processes; 0 disables the check.
- **max_cpu_usage**: `float` — Maximum allowed CPU usage (percent) for process checks.
- **max_cpu_usage**: `float` — Maximum allowed aggregate CPU execution percentage; idle and I/O-wait time are excluded.

## Analyzer Args Class RdmaAnalyzerArgs

Expand Down
3 changes: 3 additions & 0 deletions nodescraper/enums/eventcategory.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ class EventCategory(AutoNameStrEnum):
- OS
Generic Operating System events.
Does not include specific events from OS which point to another category
- PROCESS_READ
Successful CPU process collection events.
- PLATFORM
Generic Platform Errors e.g. topo enumeration
Platform-specific errors which do not fall under other categories (e.g. BMC, SMC, UBB)
Expand Down Expand Up @@ -79,6 +81,7 @@ class EventCategory(AutoNameStrEnum):
RAS = auto()
IO = auto()
OS = auto()
PROCESS_READ = auto()
PLATFORM = auto()
APPLICATION = auto()
MEMORY = auto()
Expand Down
11 changes: 5 additions & 6 deletions nodescraper/plugins/inband/process/analyzer_args.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,12 @@


class ProcessAnalyzerArgs(AnalyzerArgs):
max_kfd_processes: int = Field(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why are we removing this information?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was intentionally removed to match the upstream change. AMD SMI now owns that functionality, so ProcessPlugin is limited to CPU process collection

default=0,
description="Maximum allowed number of KFD (Kernel Fusion Driver) processes; 0 disables the check.",
)
max_cpu_usage: float = Field(
default=20.0,
description="Maximum allowed CPU usage (percent) for process checks.",
description=(
"Maximum allowed aggregate CPU execution percentage; idle and I/O-wait time "
"are excluded."
),
)

@classmethod
Expand All @@ -50,4 +49,4 @@ def build_from_model(cls, datamodel: ProcessDataModel) -> "ProcessAnalyzerArgs":
Returns:
ProcessAnalyzerArgs: instance of analyzer args class
"""
return cls(max_kfd_processes=datamodel.kfd_process, max_cpu_usage=datamodel.cpu_usage)
return cls(max_cpu_usage=datamodel.cpu_usage)
9 changes: 6 additions & 3 deletions nodescraper/plugins/inband/process/collector_args.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,10 @@
class ProcessCollectorArgs(CollectorArgs):
top_n_process: int = Field(
default=10,
description=(
"Number of top processes by CPU usage to collect " "(e.g. for top -b -n 1 -o %%CPU)."
),
description="Number of top processes by CPU usage to collect.",
)
sample_interval_seconds: float = Field(
default=1.0,
gt=0,
description="Wall-clock interval between procfs CPU samples.",
)
18 changes: 2 additions & 16 deletions nodescraper/plugins/inband/process/process_analyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,15 @@


class ProcessAnalyzer(DataAnalyzer[ProcessDataModel, ProcessAnalyzerArgs]):
"""Check cpu and kfd processes are within allowed maximum cpu and gpu usage"""
"""Check aggregate CPU usage against the configured maximum."""

DATA_MODEL = ProcessDataModel

def analyze_data(
self, data: ProcessDataModel, args: Optional[ProcessAnalyzerArgs] = None
) -> TaskResult:
"""
Analyze the process data to check if the number of KFD processes and CPU usage
are within the allowed limits.
Analyze whether aggregate CPU usage is within the allowed limit.

Args:
data (ProcessDataModel): The process data to analyze.
Expand All @@ -56,19 +55,6 @@ def analyze_data(
args = ProcessAnalyzerArgs()

has_errors = False
if data.kfd_process is not None and data.kfd_process > args.max_kfd_processes:
has_errors = True
self._log_event(
category=EventCategory.OS,
description=f"Kfd processes {data.kfd_process} exeed max limit {args.max_kfd_processes}",
data={
"kfd_process": data.kfd_process,
"kfd_process_limit": args.max_kfd_processes,
},
priority=EventPriority.CRITICAL,
console_log=True,
)

if data.cpu_usage is not None and data.cpu_usage > args.max_cpu_usage:
has_errors = True
self._log_event(
Expand Down
Loading
Loading