perception_system —— 跨平台系统感知框架
Windows 64 模块 / Linux 43 模块,统一异步事件总线发布。只报变化 · 事件驱动 · 异常隔离 · 无需管理员。
传感器(钩子/WMI/COM//proc//sys/inotify)──▶ 有界队列 ──▶ 异步排水 ──▶ EventBus ──▶ 订阅回调
Windows 64 / Linux 43 微秒级入队 事件循环上 通配/白名单 并发隔离派发
平台支持
| 平台 |
模块 |
说明 |
| Windows 8.1 |
61–64 |
GPU/虚拟桌面语义缺席处诚实降级 |
| Windows 10 / 11 |
64 |
全集 |
| Linux(物理机/WSL2/容器) |
43 |
各模块独立降级(无 X/NM/pcscd/设备 → E_UNAVAILABLE INFO 自停) |
| macOS 等 |
0 |
核心总线可用,传感器空集 |
安装
需要 Python ≥ 3.12。
pip install perception-system # pip
uv add perception-system # uv:加入当前项目依赖
uv tool install perception-system # uv:全局安装命令行工具
可选依赖(按需,缺失时对应传感器诚实降级,其余模块不受影响):
pip install "perception-system[audio,winrt]" # Windows:音量 / 环境光传感器
pip install "perception-system[smartcard]" # Linux:智能卡读卡器传感器
安装后即可运行演示(perception-demo 与 python -m perception 等价):
perception-demo --quick # 5 秒冒烟
perception-demo --list # 列出当前平台可用传感器
perception-demo # 安静传感器全家桶(15 秒)
perception-demo --all # 全部传感器(含输入钩子 / 屏幕 / 隐私域)
快速开始
import asyncio
from perception import PerceptionApp
import perception.win # Windows:64 模块(Linux 上无害空注册)
# import perception.linux # Linux:43 模块
app = PerceptionApp() # 全局单例
app.add_all_source() # 一键装配当前平台全部模块
app.all_subscribe(lambda e: print(e.topic, e.kind))
app.run_sync(30)
按需装配 + 白名单订阅:
app = PerceptionApp()
app.add_source("windowstate", settle_s=0.5)
app.add_source("windowhealth", hang_interval=3)
app.add_all_source(exclude=["clip*"], params={"idle": {"interval": 5}})
app.subscribe(my_handler, modules=["window*", "process"], min_severity="warning")
异步环境:
async def main():
app = PerceptionApp()
app.add_source("windowstate", settle_s=0.5)
app.add_source("process")
async def on_event(e): # 异步 handler:独立 Task 并发派发
print(e.topic, e.payload.get("event"))
app.subscribe(on_event, modules=["window*"])
await app.start()
try:
await asyncio.sleep(30) # 并发跑任意业务协程
finally:
await app.stop() # 幂等 + 冲刷在途事件
asyncio.run(main())
安静运行推荐配置:
app.add_all_source(exclude=["input", "mousetrace", "clipcontent", "eventlog"])
for m in ("process", "netquality", "diskspace", "mempressure"):
app.add_source(m, interval=10) # 服务器典型:只装关心的域 + 拉长轮询
API
全局单例(PerceptionApp 构造参数)
| 用法 / 参数 |
语义 |
PerceptionApp() |
进程内全局单例(重复调用幂等返回) |
unique=True |
独立实例(测试/嵌入/多应用并行) |
bus=EventBus() / registry=Registry |
自定义总线/注册表(仅首次创建生效) |
process_lock= |
"warn"(默认,检测他进程持守卫→WARNING)/ "strict"(RuntimeError)/ "off" |
PerceptionApp.reset_singleton() |
丢弃单例并释放守卫(重建前先 await stop()) |
装配
| 方法 |
参数 |
语义 |
add(module) |
Source/Pipeline/Subscriber 实例 |
按类型自动归置 |
add_source(name, **kw) |
注册名 + 构造参数 |
如 add_source("idle", interval=5);非法参数构造期抛错;按名幂等 |
add_all_source(exclude=, params=) |
exclude=["clip*"](fnmatch 通配)/ params={"idle": {"interval": 3}} |
装配当前平台全部模块(Win64/Linux43);幂等;未知名字 KeyError |
add_pipeline / add_subscriber |
同 add_source |
|
from_spec(dict) |
{"sources": [...], "pipelines": [...], "subscribers": [...]} |
声明式规格;条目 "名字" / ["名字", {参数}];独立实例 |
get_source(name) |
|
取已装配源(未装配 KeyError) |
list_modules() |
|
返回 {模块名: 发布主题}(不实例化) |
模块名与 perception.<模块名> 主题对应;例外:system→perception.sysres、fontchange→perception.font。废弃名 network(→netproc)、fullscreen(→busy)add_source 给出迁移指引。
订阅
| 方法 / 参数 |
语义 |
subscribe(handler, modules=, exclude=, min_severity=, snapshot=) |
modules=None 订阅全部;条目支持 fnmatch 通配;modules=[]=显式空集;白名单命中优先于 exclude |
all_subscribe(handler, exclude=, min_severity=, snapshot=) |
全域订阅(全部模块 + app 生命周期事件) |
handler |
同步/异步皆可;单 Event 参数;回调异常被隔离(E_SUBSCRIBER) |
min_severity |
debug / info / warning / error / critical |
snapshot=True(默认) |
订阅首轮每模块送一条 {"event": "snapshot", "state": …}(状态机模块=当前状态;流式模块= None);min_severity 高于 info 会滤掉快照 |
返回 Subscription |
.unsubscribe() 退订,或 with 上下文 |
for m in ("idle", "busy", "netquality"):
app.add_source(m)
app.subscribe(on_event, modules=["idle", "busy", "netquality"])
# → 立即收到 3 条 snapshot(idle=当前闲置秒数),此后只在变化时收到事件
生命周期
| 方法 |
语义 |
await start() / await stop() |
订阅者→管道→源按序启停;stop 幂等 + 冲刷在途事件 |
await run(duration) / run_sync(duration) |
启动并运行 duration 秒后优雅停止(None=永久) |
publish / publish_sync |
便捷发布一条事件 |
传感器公共参数(全部模块继承)
| 参数 |
默认 |
说明 |
name |
注册名 |
事件 source 字段 |
enabled |
True |
装配后是否启用 |
queue_size |
10000 |
队列容量;溢出丢弃+计数+E_BACKPRESSURE;0/负值构造期 ValueError |
max_restarts |
5 |
看门狗崩溃重启上限(超出熔断 E_STOPPED) |
restart_backoff |
1.0 |
重启退避基数秒(指数翻倍封顶 30) |
interval(轮询类) |
各模块各异 |
轮询周期秒;0=普查一次后静默;负值或 <0.05s → E_CONFIG 退出 |
常用模块参数速查
| 模块 |
常用参数 |
idle |
idle_after=300、interval=5 |
windowstate |
settle_s=0.35(几何防抖)、geometry=True |
windowtree |
z_top=10 |
windowhealth |
hang_interval=2、flash_seconds(闪退寿命阈) |
hardware / mempressure |
cpu_threshold=90;commit_threshold=90、swap_threshold=100 |
diskspace |
threshold_pct=10、threshold_gb、drives(None=全部盘) |
netquality |
probe_host=1.1.1.1 |
netproc |
established_only=True |
filesystem |
paths(缺省=当前目录)、recursive=True |
eventlog |
logs、event_ids 过滤 |
input |
capture_keys=False(隐私)、rate_limit_hz=200、mouse_move=False |
clipcontent |
默认禁用;启用后 capture_text=False |
wmievt |
query(自定义 WQL) |
timeaware |
interval=1(tick 秒)、ntp_interval=1(小时)、servers、drift_ms=1000 |
格式规范
事件信封(frozen dataclass)
| 字段 |
说明 |
|
字段 |
说明 |
topic |
路由主题 |
|
event_id |
uuid4 唯一 |
payload |
负载(必含 event 键) |
|
ts |
Unix 秒 |
severity |
debug..critical |
|
source |
模块名 |
meta |
元数据(derived_from 等) |
|
|
|
统一输出格式:所有事件负载必有 event 键——数据事件为事件名(snake_case);perception.system 主题的系统/错误事件 event 与 kind 同值(kind 为兼容别名)。错误信封:event/kind/module/code/message/time/epoch_ms/location/detail/hint。
统一回调参数:所有事件回调(app.subscribe / bus.subscribe / Subscriber.handle / Stage.process)参数有且只有一个 Event;同步/异步皆可;回调异常被隔离(bus_error 信封)。例外:EventBus(error_cb=...) 为 (event, exc) 双参。
快照事件:{"event": "snapshot", "state": <dict|None>}。
| code |
场景 |
E_CONFIG |
配置非法(早失败/非法 WQL) |
E_INIT |
句柄初始化失败 → 看门狗重启 |
E_CRASH |
sense() 崩溃 → 指数退避自愈重启 |
E_STOPPED |
重启超限熔断停转 |
E_SOFT_EXIT |
sense() 自然结束(不重启) |
E_UNAVAILABLE |
依赖/硬件不可用 → 诚实降级退出 |
E_BACKPRESSURE |
队列溢出丢弃计数 |
E_SUBSCRIBER |
订阅回调异常(被隔离) |
E_TIMEOUT |
感知源采集超时 |
完整模块列表(Windows 64)
Linux 列:✓ 同码=中立 14(同码同事件)· ✓ 原生=/proc /sys /发行版设施 15 · ✓ X11=ctypes Xlib 9 · ✓ 近似=Windows 概念的 Linux 对应物 5 · —=无对应。合计 Linux 43。
| 模块 |
主题 |
Linux |
|
模块 |
主题 |
Linux |
adapter |
perception.adapter |
✓ 同码 |
|
output |
perception.output |
— |
appusage |
perception.appusage |
— |
|
perf |
perception.perf |
✓ 同码 |
audio |
perception.audio |
✓ X11 |
|
power |
perception.power |
✓ 原生 |
audioroute |
perception.audioroute |
— |
|
print |
perception.print |
— |
autolaunch |
perception.autolaunch |
✓ 原生 |
|
printers |
perception.printers |
— |
bluetooth |
perception.bluetooth |
✓ 原生 |
|
process |
perception.process |
✓ 同码 |
busy |
perception.busy |
✓ X11 |
|
procres |
perception.procres |
✓ 同码 |
cammic |
perception.cammic |
✓ 原生 |
|
procrich |
perception.procrich |
✓ 同码 |
clipboard |
perception.clipboard |
— |
|
proxy |
perception.proxy |
✓ 原生 |
clipcontent |
perception.clipcontent |
— |
|
registry |
perception.registry |
— |
defender |
perception.defender |
— |
|
route |
perception.route |
✓ 原生 |
desktop |
perception.desktop |
✓ X11 |
|
screen |
perception.screen |
✓ X11 |
device |
perception.device |
✓ 原生 |
|
screensaver |
perception.screensaver |
✓ X11 |
diskspace |
perception.diskspace |
✓ 同码 |
|
seccorr |
perception.seccorr |
— |
drivers |
perception.drivers |
✓ 原生 |
|
security |
perception.security |
✓ 近似 |
elevated |
perception.elevated |
— |
|
service |
perception.service |
✓ 近似 |
eventlog |
perception.eventlog |
✓ 近似 |
|
session |
perception.session |
— |
filesystem |
perception.filesystem |
✓ 同码 |
|
smartcard |
perception.smartcard |
✓ 原生 |
fontchange |
perception.font |
✓ 原生 |
|
sysinfo |
perception.sysinfo |
✓ 原生 |
gpu |
perception.gpu |
— |
|
sysparam |
perception.sysparam |
✓ 近似 |
hardware |
perception.hardware |
✓ 同码 |
|
system |
perception.sysres |
✓ 同码 |
hwinfo |
perception.hwinfo |
✓ 原生 |
|
thermal |
perception.thermal |
✓ 原生 |
idle |
perception.idle |
✓ X11 |
|
timechange |
perception.timechange |
— |
input |
perception.input |
✓ X11 |
|
uac |
perception.uac |
— |
inputstats |
perception.inputstats |
— |
|
vpn |
perception.vpn |
✓ 原生 |
ipaddr |
perception.ipaddr |
✓ 同码 |
|
wifi |
perception.wifi |
✓ 原生 |
mempressure |
perception.mempressure |
✓ 同码 |
|
window |
perception.window |
✓ X11 |
mousetrace |
perception.mousetrace |
✓ X11 |
|
windowhealth |
perception.windowhealth |
— |
netproc |
perception.netproc |
✓ 同码 |
|
windowstate |
perception.windowstate |
— |
netquality |
perception.netquality |
✓ 同码 |
|
windowtree |
perception.windowtree |
— |
timeaware |
perception.timeaware |
✓ 同码 |
|
winsensors |
perception.winsensors |
— |
|
|
|
|
wmievt |
perception.wmievt |
— |
|
|
|
|
wupdate |
perception.wupdate |
✓ 近似 |
Windows 64 模块目录
主题 = perception.<注册名>(例外见上)。机制:推送=系统钩子零轮询 · 轮询=低频差分 · 采样=周期抓帧 · 普查=一次后静默 · †=派生消费上游流。
输入与人机交互(6)
| 模块 |
机制 |
事件 |
备注 |
input |
低级钩子推送 |
key/sys_key_down·up;left/right/middle/x_down·up;wheel;move |
capture_keys 附键名;rate_limit_hz=200;mouse_move 默认过滤 |
idle |
GetLastInputInfo 轮询 |
idle / active |
idle_after=300,滞回防抖 |
inputstats† |
消费 input 流 |
input_stats |
去标识化;flush=60s |
mousetrace |
独占钩子+50ms 结算 |
move(轨迹);_click;_double_click;scroll_up/down |
事件带 source(mouse/touch/pen) |
session |
WTS 通知推送 |
lock/unlock/logon/logoff/console_/remote_ |
|
desktop |
DESKTOPSWITCH 钩子 |
desktop_switch |
|
窗口与应用程序(7)
| 模块 |
机制 |
事件 |
备注 |
window |
SetWinEventHook |
foreground/create/destroy/rename/show/hide |
title_cache 附标题 |
windowstate |
WinEvent+防抖 |
geometry;minimized/unminimized;maximized/unmaximized;shown/hidden;left/entered_desktop |
settle_s=0.35;vdesktop 由 IVirtualDesktopManager 裁决 |
windowtree |
REORDER 节流扫描 |
z_changed;topmost_on/off;dialog_opened/closed;reparented |
z_top=10 |
windowhealth |
CREATE/DESTROY 追踪+卡死轮询 |
window_hung/recovered;flash_exit;window_crashed |
每进程收敛一报;崩溃带 log_confirmed(WER 日志佐证) |
appusage† |
消费 window 流 |
usage_report(exe→秒) |
flush=60s |
busy |
SHQueryUserNotificationState 轮询 |
busy/not_busy/qbusy/presentation_mode… |
系统权威全屏判定 |
screensaver |
SPI 轮询 |
screensaver_on/off |
|
进程与服务(9)
| 模块 |
机制 |
事件 |
备注 |
process |
PID 差分 1s |
start / exit |
短命 <1s 漏检 → 用 wmievt |
wmievt |
WMI watcher 阻塞拉取 |
process_start(默认,可配 WQL) |
进程创建零漏检 |
procrich† |
process+psutil 补查 |
process_rich |
富化失败属常态(短命进程) |
procres |
psutil 穿越去抖 |
hot / cooled |
targets/pids;cpu/mem 阈值 |
service |
EnumServicesStatus 差分 |
state/removed/census/poll_error |
names 过滤 |
drivers |
SERVICE_DRIVER 掩码 |
driver_appeared/disappeared |
与 service 正交 |
elevated |
TokenElevation 差分 |
elevated_process |
默认排除 consent/svchost/dwm |
uac† |
consent.exe 特征 |
uac_prompt / uac_closed |
|
seccorr† |
多信号共现窗 |
correlation |
window=120s、min_signals=2 |
系统资源与硬件(11)
| 模块 |
机制 |
事件 |
备注 |
hardware |
psutil CPU 穿越 |
threshold / sample |
cpu_threshold=90;per_cpu |
perf |
psutil 计数器差分 |
threshold / sample |
磁盘/网络速率 |
system |
pids 差分 |
process_count / sample / threshold |
主题 perception.sysres |
mempressure |
提交率+换页去抖 |
pressure / relieved |
commit_threshold=90、swap_threshold=100 |
diskspace |
每盘独立阈值 |
low / recovered |
threshold_pct 或 threshold_gb(同给取更严) |
gpu |
PDH GPU Engine 汇总 |
high / normal |
无 GPU/远程会话/Win8.1 → E_UNAVAILABLE |
thermal |
MSAcpi 热区 |
hot / cooled |
无 ACPI 热区 → E_UNAVAILABLE |
winsensors |
winsdk 光感(可选依赖) |
dark / bright |
缺 winsdk/无硬件 → E_UNAVAILABLE |
power |
WM_POWERBROADCAST+轮询 |
suspend/resume/battery…;ac_status |
|
sysinfo |
WMI/注册表普查 |
census / changed |
interval=0 一次后静默 |
hwinfo |
WMI 7 类普查 |
census / changed |
无序列号无 MAC;单类失败记 missing |
屏幕/显示/剪贴板(4)
| 模块 |
机制 |
事件 |
备注 |
screen |
mss 抓帧采样 |
change |
threshold=0.01+节流 |
output |
WM_DISPLAYCHANGE |
display_change |
分辨率/色深 |
clipboard |
WM_CLIPBOARDUPDATE |
update(seq) |
不含内容 |
clipcontent |
同上+二次授权 |
content_change |
默认禁用·隐私;capture_text=False |
网络与连接(8)
| 模块 |
机制 |
事件 |
备注 |
wifi |
wlanapi 原生通知 |
connected/disconnected/associating… |
零轮询;include_ssid |
ipaddr |
net_if_addrs 差分 |
iface_up/down/gone;addr_added/removed |
|
route |
路由表差分 |
default_gateway_changed |
Linux 版读 /proc/net/route |
adapter |
net_if_stats 差分 |
adapter_new/up/down;speed_changed |
|
vpn |
适配器特征+路由归属 |
vpn_up/down;route_takeover/released |
|
netproc |
单快照三路语义 |
connections/threshold;conn_open/close |
established_only;含 pid |
netquality |
TCP 探测状态机 |
offline/online;slow/speed_recovered;fluctuation |
probe_host=1.1.1.1 |
proxy |
注册表通知 |
proxy_enabled/disabled/change |
|
安全与设备(9)
| 模块 |
机制 |
事件 |
备注 |
eventlog |
NotifyChangeEventLog 增量 |
record / read_error |
logs/event_ids 过滤 |
security |
Application 1116/1117 |
record |
eventlog 预设别名 |
registry |
RegNotifyChangeKeyValue |
change |
hive/path/subtree |
defender |
SecurityCenter2 位解码 |
av_present;realtime_*;signatures_outdated |
多杀软全报 |
smartcard |
SCardGetStatusChange 阻塞 |
card_inserted/removed;reader_removed |
0 CPU 等待 |
cammic |
ConsentStore 反窃听 |
cam/mic_active;cam/mic_inactive |
占用即 WARNING,含 app/since |
device |
WM_DEVICECHANGE+接口通知 |
arrival/removal/query_remove…(卷/接口/端口 3 层) |
Linux 版读 /sys/bus/usb |
bluetooth |
BTHENUM 配对集差分 |
bt_device_paired/removed |
只报配对集 |
autolaunch |
Run 键通知+目录 |
autolaunch_added/changed/removed |
|
文件/打印/音频/系统设置(10)
| 模块 |
机制 |
事件 |
备注 |
filesystem |
watchdog→ReadDirectoryChangesW |
created/modified/deleted/moved |
paths 缺省=当前目录 |
print |
EnumJobs 差分 |
job_new/job_status/job_done/poll_error |
无默认打印机 → E_UNAVAILABLE |
printers |
EnumPrinters 差分 |
printer_added/removed;default_printer_changed |
|
audio |
pycaw 轮询(可选依赖) |
volume(1% 台阶);active/silent |
缺 pycaw → E_UNAVAILABLE |
audioroute |
IMMDevice 差分 |
default_changed |
render/capture 角色 |
fontchange |
WM_FONTCHANGE |
fonts_changed |
主题 perception.font |
timechange |
WM_TIMECHANGE |
system_time_changed |
|
timeaware |
秒级 tick + SNTP |
tick;ntp_sync;clock_drift;ntp_unreachable |
首 tick 即校时→每小时;服务器国内优先探测链;离线 tick 照常 |
sysparam |
WM_SETTINGCHANGE |
setting_change;dark_mode |
track_dark_mode |
wupdate |
WUApi COM |
reboot_required/not_required |
wuauserv 停用 → E_UNAVAILABLE |
Linux 43 模块
| 模块 |
机制 |
事件/备注 |
| 中立 14(与 Windows 同码同事件) |
|
|
| process/hardware/perf/system/mempressure/diskspace/procres |
psutil 轮询差分 |
同 Windows |
timeaware |
秒级 tick + 小时级 NTP 校时 |
同 Windows |
| netproc/netquality/ipaddr/adapter |
psutil/socket |
同 Windows |
| filesystem |
watchdog→inotify |
同 Windows |
| procrich† |
消费 process 流 |
同 Windows |
| /proc /sys 原生 7 |
|
|
sysinfo |
/etc/os-release+uname+/proc/uptime |
census/changed |
hwinfo |
/proc/cpuinfo+meminfo+/sys/class/dmi//sys/block |
无序列号;DMI 缺失记 missing |
thermal |
/sys/class/thermal_zone*/temp |
无热区(VM)→ E_UNAVAILABLE |
power |
/sys/class/power_supply |
事件名与 Windows 对齐 |
route |
/proc/net/route 差分 |
小端十六进制网关解码;零子进程 |
device |
/sys/bus/usb/devices 差分 |
arrival/removal 对齐 Windows DBT;无 serial |
bluetooth |
/sys/class/bluetooth + /var/lib/bluetooth |
配对集 root 700 → 非特权空集等待 |
| X11 GUI 会话域 9(ctypes libX11/Xss/Xrandr 零新依赖;纯 Wayland → 自停) |
|
|
idle |
XScreenSaver idle 毫秒 |
idle/active;快照实时值 |
screensaver |
XScreenSaver state 差分 |
screensaver_on/off |
window |
root 子结构通知+焦点轮询 |
create/destroy/show/hide/foreground/rename(xid+title) |
mousetrace |
XQueryPointer 50Hz 差分 |
move 段+按钮翻转;滚轮无轮询途径不发 |
input |
XQueryKeymap 位图差分 |
key_down/up(keycode+keysym 名) |
busy |
前台 _NET_WM_STATE_FULLSCREEN |
busy/not_busy |
desktop |
_NET_CURRENT_DESKTOP 属性通知 |
desktop_switch(old/new) |
screen |
Xrandr 当前配置差分 |
display_change(width/height) |
audio |
pactl→amixer 双后端 |
volume/mute;active/silent 仅 pactl(approx) |
| 发行版兼容域 5(多后端探测链,全缺才降级) |
|
|
wifi |
nmcli 差分 |
connected/disconnected+ssid |
vpn |
psutil 接口差分+/proc/net/route |
vpn_up/down;route_takeover/released |
smartcard |
pyscard(可选 extra [smartcard]) |
card_inserted/removed |
autolaunch |
XDG autostart+systemd user |
autolaunch_added/changed/removed |
proxy |
gsettings→kreadconfig→env 三后端 |
proxy_enabled/disabled/change |
| Windows 近似物 8 |
|
|
eventlog |
journalctl→syslog/messages 流式 |
log(限流 50/s) |
security |
auth 设施过滤 |
auth_failure(WARNING)/auth_success |
service |
systemctl list-units 差分 |
service_up/down/failed |
drivers |
/proc/modules 差分 |
driver_appeared/disappeared |
wupdate |
dpkg/rpm/pacman/apk 数据库 mtime |
pkgdb_changed |
sysparam |
/proc/sys 键值差分 |
param_changed;keys 可配 |
fontchange |
字体目录 watchdog |
font_added/removed |
cammic |
psutil fd 扫 /dev/video*//dev/snd |
cam/mic_active;mic 仅 ALSA 直连可见 |