跳转到内容
Argus
开发版
下载GitHub
文档/架构/采集层 argus-core

采集层 argus-core

crates/argus-core 封装 Windows 系统查询与进程操作。采样结果以可序列化的快照提供给应用服务、界面和诊断示例。

模块

模块职责
diagnostics.rs记录原始错误码、固定错误类别及直接参与失败的路径。路径限长并转义,重复失败按原因限频。服务和提权助手通过有界缓冲区向宿主传递诊断
collector.rs把系统与进程采样合成一份快照,并给每个进程附上 GPU 占用和是否拥有任务栏窗口
app_windows.rs用 EnumWindows 找出拥有任务栏窗口的进程(可见、无所有者,排除工具窗口、桌面与任务栏),界面据此判断是否归入“应用”。打包应用的外框窗口归到其中核心窗口所属的进程;排除被 DWM 隐藏的窗口,计入其他虚拟桌面上的窗口。每次约 0.3–0.7 ms
process.rs一次 NtQuerySystemInformation(SystemProcessInformation) 拿到全部进程与线程,按周期计数差量计算 CPU、按字节差量计算 I/O 速率;复用进程表,每个实例缓存一个查询句柄,用于效率模式与退出后的最终周期读数,并校验创建时间防止 PID 复用;新进程出现时用该句柄读取应用包标识(每个约 5 µs)
paths.rs优先用 SystemProcessIdInformation 取得标准权限可查询的映像路径,再映射为 DOS 路径;设备映射缺失时用有限查询权限取得 Win32 路径,并缓存经路径后缀核验的盘符映射。进程拒绝打开时使用 GLOBALROOT 扩展路径供文件接口读取,设备映射查询失败记录原始错误码
meta.rs在后台线程解析文件描述、公司名和图标(PNG),按路径缓存;普通路径使用外壳图标,GLOBALROOT 等扩展路径通过 SHDefExtractIconW 读取可执行文件资源。结合系统组件目录与版本资源识别 Windows 组件,不在采样线程重复读取文件。应用包的名称由另一后台线程解析(外壳每个应用约 10–50 ms,不拖慢图标),按包版本与应用缓存
package.rs读取 MSIX 包的 AUMID、包全名和本地化显示名。用清单的 Executable 识别应用主进程,其他进程保留各自的文件描述。名称解析最多等待 3 秒
webview.rs识别其他应用启动的 WebView2 进程。按父进程、创建时间、会话和运行时路径归组,按实例缓存解析结果。启动参数读取失败最多尝试三次,快照仅包含宿主名称、图标和进程角色
system.rs总 CPU(含内核时间)、每个逻辑处理器的 CPU、内存、提交、缓存。以标准权限查询 SystemMemoryListInformation,取得已修改页、各优先级的备用页、空闲与已清零页;内存组成按互不重叠的页列表显示,已缓存为备用与已修改之和。查询不可用时显示总量,组成明细留空
cpu.rs按处理器组读取独立空闲计数与周期计数,校验处理器时钟与原生计数的单位、连续性和分母;异常时重新建立基线或回退时间计数
details.rs按需查询单个进程:命令行、用户、完整性级别、架构、优先级、版本
services.rs通过服务控制管理器(SCM):一次 EnumServicesStatusExW 取得全部服务状态;启动类型、路径、描述每个服务要三次 RPC,所以缓存起来偶尔刷新;名称与描述按界面语言从 MUI 读取;启停服务、修改启动类型
startup.rs、startup/packaged.rs注册表 Run 键、启动文件夹(解析 .lnk)与当前账户的应用包启动任务;传统项目使用 StartupApproved,应用包结合 AppModel 注册状态、首次激活与用户授权标记判断是否启用,并记录禁用时间。显示程序名称和应用包本地化名称,保留原始项目标识;包清单与名称按包版本、位置和清单修改时间缓存,状态每次重新读取
connections.rsTCP / UDP(IPv4 / IPv6)端点与所属进程(netstat -ano 显示的内容);断开 IPv4 TCP 连接
filelock.rs以当前账户权限通过 Restart Manager 查找打开文件或加载 DLL 的进程。整批查询被拒时二分重试,隔离无法检查的文件
handles.rs按需枚举系统 File 句柄,复制后用 NtQueryObject 查询类型与名称,以文件 ID 匹配文件(含硬链接)、以路径边界匹配目录及其后代。只在辅助进程运行,流式报告进度与匹配项
actions.rs结束进程 / 进程树、设置优先级、开关效率模式(EcoQoS 加低优先级,与系统任务管理器相同):都先校验 PID 与启动时间,防止 PID 被复用;结束时拦截关键系统进程
gpu_process.rs每进程 GPU:每次采样一个 PDH 查询,读出各引擎占用;显存使用 GPU Process Memory 的 Local Usage / Non Local Usage 驻留计数,按 PID、完整 LUID 与物理适配器去重,区分缺失和零值;除最忙引擎外保留非零节点贡献及完整身份,供应用与分类汇总使用
disk_process.rs优先复用普通进程信息中的磁盘计数尾部,旧系统回退完整进程信息的扩展记录,按 PID、创建时间和来源采样时间换算速率;逐条检查扩展线程数组与磁盘记录边界,不读取字符串及账户数据。Windows 10 的完整记录尾部按 UTF-16 对齐,数值按字节解码,以兼容未按 8 字节对齐的后续记录。普通尾部需同时通过系统版本、返回长度及图像名称边界校验;完整信息查询由管理员宿主的后台读取器或特权服务执行
net_process.rs每进程网络:优先使用独立 GUID 的私有系统 ETW 会话,仅启用 NETWORK_TCPIP;系统会话不可用时回退到 Microsoft-Windows-Kernel-Network。按提供者区分事件 ID 与操作码,解析 TCP / UDP、IPv4 / IPv6 收发字节,排除重传和复制事件。本地与服务客户端随采样周期换算速率,最短统计窗口为 0.5 秒,容许 50 ms 的调度与 IPC 抖动,并校验进程实例。快速采样时,独立线程每 250 ms 将事件送入实时消费者;最近 1.5 秒没有快速读取时停止额外刷新,采用 ETW 自身的一秒刷新定时器。关闭会话前先停止刷新线程。服务通过 take_bytes 维护多读者的累计计数。启动会话需要相应权限;GUI 与服务保留独立会话名,清理各自残留会话。日志记录选用的来源,并在启动后 5 秒及后续每 30 秒检查 ETW 丢失计数
rules.rs规则引擎:按程序名匹配,新进程出现时套用一次;apply_with 允许宿主后台线程选择本地或服务执行器,规则或权限来源改变时重新检查。分别统计已应用、权限不足和其他执行失败的次数
history.rs历史记录:把采样按 5 秒一帧汇总(CPU 平均值与最高值、内存、磁盘与网络吞吐量、最忙的 GPU、电池电量与充放电功率,以及 CPU、内存、I/O、GPU、网络各自最高的几个进程),没有采样的 5 秒不写帧(后台刷新间隔长于 5 秒时帧随之变稀),追加写入每天(UTC)一个的二进制文件,保留 7 天。每帧整块写入并刷新,重新打开时截掉崩溃留下的半帧;进程名在文件内只写一次。读取侧按时间范围分桶汇总(空桶不输出,曲线上留出断档),或取离某一时刻最近的一帧;另有占用统计、清除和过期清理。每次采样约 30 µs,每帧约 460 字节
pdh.rsPDH 查询的薄封装,sensors.rs 与 gpu_process.rs 共用
privilege.rsArgus 自身的提权状态、启用 SeDebugPrivilege、提高自身优先级
theme.rs系统个性化颜色(强调色)
i18n.rs原生层的文案:编译时嵌入 locales/*/native.json,tr! 按当前语言查找;进程级语言默认取父进程通过 ARGUS_LOCALE 传入的值,否则为 Windows 显示语言,宿主再按设置覆盖
nt.rswindows crate 没有(完整)提供的原生结构,布局按 phnt 头文件的 x64 版本

进程附加计数

进程列的附加计数来自同一次 SystemProcessInformation:用户态/内核态 CPU 时间按 100 ns 转为毫秒,工作集峰值、虚拟地址空间与累计 I/O 保持字节,缺页保留次数。虚拟地址空间包含预留与已提交范围;它和工作集峰值均按单进程展示。ProcessCounters 展平到进程 JSON 中,采样不增加逐进程系统调用。界面仍以 PID 与创建时间关联进程实例。结构字段与单位可参考 Windows 进程快照及内存计数。

进程显存使用驻留计数,与 DXGI 的预算用量口径对应。Dedicated Usage / Shared Usage 属于另一组提交计数,部分 Windows/驱动组合下会累积异常,因此不作为驻留计数的回退来源。来源关系可参照 System Informer 的 GPU 计数实现与 Microsoft 的计数异常说明。应用分组累加成员的有效读数,任一成员缺失时保留未知;整机显存继续取适配器统计,避免重复归属的共享资源进入物理总量。

CPU 占用

整体与各逻辑处理器的占用使用 SystemProcessorIdleInformation 的独立空闲时间,以及 SystemProcessorPerformanceInformation 的总时间差量。独立空闲时间可避开部分系统旧 IdleTime 将短时运行计入空闲的问题。处理器按 (group, processor) 配对;整体占用先合计原始时间再换算,避免将各核量化误差截断后累加。来源缺失时只使用同一来源的成对读数,计数重置或分组变化时重新建立基线。内核占用保留 Windows 时间计数器实际报告的内核运行量,不把新旧空闲时间的差额归为内核工作。

独立空闲查询成功但计数不变、旧空闲计数仍增长时,该处理器在当前区间回退到旧空闲差量;两者均不增长时仍按满载计算。独立计数恢复增长后自动恢复使用,回退区间不参与进程 CPU 的精确空闲比例校验。

进程占用使用 SystemProcessInformation.CycleTime 差量,分母为经过校验的处理器时钟增量乘以全机逻辑处理器数。仅在 Windows 选择无内核切换的 QPC 时基、周期单位与独立空闲计数或完整原生周期总量相符时使用;同时检查时钟速率、计数单调性、采样间隔和处理器数量。该分母覆盖整个采样间隔,包括期间创建并退出的进程。无法确认时基或某条进程计数失效时改用 CPU 时间差。累计 CPU 时间直接取 Windows 用户态与内核态时间。上述查询使用标准权限。

hardware/

性能页的设备数据。数据来源与限制的用户向说明见硬件数据的来源与限制。

模块职责
cpu.rs型号、拓扑(每个逻辑处理器属于哪个核心、是性能核还是能效核)、缓存、虚拟化
sensors.rs在标准权限下通过 PDH 批量读取 CPU 频率、ACPI 温度和可用功耗计数。功耗按域合计多个封装的有效读数,保留有效零值,过滤缺失、负数和非有限值
battery.rs电池类驱动 IOCTL:电量、充放电功率、电压、设计 / 完全充电容量、循环次数。标准用户可以只读打开电池设备
memory.rs解析 SMBIOS(类型 17)中的内存条:速度、插槽、外形规格、DDR 代数
disk.rs以 FILE_ANY_ACCESS 存储 IOCTL 查询型号、容量、介质、卷及温度,通过 IOCTL_DISK_PERFORMANCE 计算活动时间、传输速率和响应时间
disk_details.rs、disk_details/磁盘详情的单次只读查询:基本身份、扇区、TRIM、NVMe 控制器身份与 SMART 健康日志、PCIe 链路。只由前端明确请求触发,在命令工作线程执行,结果与周期采样分离
net.rs网络适配器:接口表(GetIfTable2)取吞吐量,GetAdaptersAddresses 取地址
gpu.rs通过 D3DKMT 查询节点计时、显存和性能数据。逐节点维护计时基线,查询失败或计数重置后重建,可选的性能查询间隔 5 秒重试。占用率结合有效的进程引擎读数与 NVIDIA 核心利用率,并注明来源。PCI 地址用于匹配厂商设备
vendor_gpu/AMD ADL2 PMLog / Overdrive 与 Intel IGCL 电源域及设备遥测,独立线程加载 System32 库、读取数据;容量为 1 的请求队列,最短 500 ms 采集间隔,过期缓存不进入快照。IGCL 温度、频率、电压及芯片能量不依赖电源域枚举;逐项校验支持标记、单位、类型与范围,有效零值保留,失败后间隔 5 秒重试。ControlLib.dll 加载后固定在进程中直至退出:它注册的 ETW 提供程序不随 ctlClose 和卸载注销,卸载后一旦有跟踪会话启用该提供程序,系统就会调用已卸载的回调,进程崩溃
kernel_sensors.rs与特权服务共享的固定 CPU 传感器快照;枚举定义的功耗、电压、电流、时钟和限制,每个物理核心的读数、SMU 状态及主板风扇、电源轨和温度,另有可选的核显温度、频率与 VID。宿主按开关异步补充;核显字段与 PP1 功耗仅映射到单插槽 Intel 系统中 PCI 0:2:0 上唯一的 Intel 适配器,与显卡驱动提供的读数按来源合并
nvml.rsNVIDIA 板卡功耗、功耗上限及可选的 GPU 核心利用率:只从 System32 加载驱动附带的 nvml.dll,按 PCI 位置匹配,不支持或无效的读数不参与补充。核心利用率用于覆盖部分驱动原生节点计时遗漏的 CUDA 等负载,不替代单独的 Windows 引擎曲线

CPU 虚拟化状态优先使用 Windows 的可用标志;Hyper-V 或 VBS 占用虚拟化扩展时,结合 Hv#1 接口的 CreatePartitions 权限识别宿主。普通虚拟机客体继续按其可用的虚拟化扩展判断。权限位定义见 Hyper-V 分区权限。

磁盘详情接口

宿主命令 disk_details 接受 { "index": 0 },调用 hardware::disk_details::query(index),按 PhysicalDrive 编号返回 DiskDetails。每次请求读取一份新的 SMART 数据,完成后关闭句柄。磁盘温度和活动率另由周期采样维护。

设备以零访问权限打开,通过 Windows 存储属性查询读取;PCIe 参数通过匹配物理磁盘编号的 PnP 设备树取得,只采用最近 PCI 控制器节点的属性。使用系统现有权限,设备或驱动拒绝时返回对应状态。

返回项内容与单位
identity、capacityBytes、volumes型号、固件、序列号、总线与原始总线编号、可移动标记、字节容量和盘符
solidState、logicalSectorBytes、physicalSectorBytes、trimEnabled介质类型、逻辑/物理扇区字节数、Windows 存储栈的 TRIM 支持
pcieLink当前与控制器最大链路的 PCIe 代数、通道数;缺失的部分为 null,最大值取控制器端点能力
nvmeIdentityNVMe 版本、固件与身份、易失性写入缓存能力、Dataset Management 能力、告警/严重温度阈值
nvmeHealth严重警告原始位、可用备用空间及阈值、已用寿命百分比、剩余寿命估计、累计读写量与命令数、忙碌分钟、通电次数与小时、不安全关机、介质错误、错误日志条数、超温分钟、八个温度传感器,以及 NVMe 1.3 及以上的热管理转换次数和持续秒数
queriedAt、queries请求开始时的 Unix 毫秒时间戳;各查询的 ready、unsupported、accessDenied、unavailable、invalidData 状态及原始 Win32 错误码

NVMe 健康日志按控制器读取;同一控制器的多个命名空间可能共享计数。128 位累计计数序列化为十进制字符串,保留全部精度。读写数据单位按每单位 512,000 字节换算,原始计数同时返回;乘法溢出时换算值为 null。温度保留开尔文原值并提供摄氏度值,未报告的传感器保留槽位。寿命估计取 max(0, 100 - percentageUsed),严重警告位独立返回,前端应分别展示。序列号只进入显式请求的详情结果,不写入诊断日志或周期快照。

SATA、USB、RAID 等设备提供可读取的通用身份及存储属性;NVMe 专属字段保持 null。ATA 厂商 SMART 解释与 USB/RAID 透传覆盖见路线图。设备响应先校验实际返回字节数、结构版本、偏移和长度,再解析字段;缺失字段保持 null。

接口依据:Windows NVMe 查询、NVMe 健康日志字段、NVMe 控制器身份。

示例

examples/ 下的示例直接打印采集结果(dump、hardware、disk_details、m3、lockers、gpu_processes、gpu_diagnostics、history);gpu_compute 提供有界的 CUDA 测试负载。用法见环境与命令。