Skip to content

系统健康监控 ​

本文于2026-10-04按开发候选源码核对。现场行为以已部署固件为准;新增分池接口、TLS保护和资源观察尚须集中验证及部署,不能据本文认定设备已经更新。当前候选状态见验收状态。

坏配置、启动失败或维护前的身份/配置核对见故障恢复与配置保全;配置迁移、网络回退与OTA回滚分别适用,不能相互替代。

监控范围与频率 ​

启用的HealthMonitor在主循环推进时,每5秒检查内部DRAM、最大连续块、低水位、文件系统挂载和Wi-Fi状态,并推进内存保护与恢复。该周期不是独立实时任务的截止时间保证。

数据真实范围注意事项
DRAM空闲/最大块/最低水位内部8-bit堆,不包括PSRAM保护网络等关键分配;不能用PSRAM空闲量抵消内部压力
任务栈水位日志新候选每60秒只查询调用者自身,范围标为current-taskESP-IDF水位单位为字节;不假定调用者名称,不再查询可能已销毁的短寿命任务句柄
运行指标摘要每60秒输出[METRICS],包括heap/min/dram8/blk8/frag/mqtt_q/sse/poll/up队列、连接和轮询值由对应业务路径更新;不证明物理链路正常
DRAM趋势每小时保存该小时最低水位,至少6个样本才判断趋势后半段平均水位比前半段低超过8192字节时标记疑似泄漏,不是泄漏定位或长稳通过
CPU占用当前健康结构中的cpuUsage为占位0不能解释为实测CPU空闲

内存口径统一 ​

开发候选在完整GET /api/system/info?full=1与GET /api/system/diag-bundle的data.memory.capabilityPools中提供三类分配器统计。裸/api/system/info默认精简;显式full仍可能因内存保护降级,缺失该块时保留未知:

对象分配能力字段
internal8内部、可按字节访问observed/free/minFree/largestBlock
internalDma内部、DMA、可按字节访问同上
psram8PSRAM、可按字节访问同上

数值单位为字节,未观察的数值为null。内部DMA与内部8-bit池有重叠,不能相加。atomicSnapshot=false说明三次读取不是同一原子时刻;minimumScope=sum_of_heap_low_watermarks表示各内存区域低水位之和,这些低点不一定同时发生,也不是某个功能的独占峰值。sampledAtUptimeMs是设备运行计时,不是UTC。

接口不重置水位、不创建采样任务、不触发资源恢复。精简、probe、health响应不增加该采样,旧固件也可能缺字段。缺字段与实测0必须区分。

原有data.memory.heapTotal/heapFree/heapUsed/heapMinFree/heapMaxAlloc来自ESP堆接口;total/free/used/usagePercent是页面汇总,可能包含PSRAM。比较页面与API时使用同一响应口径,不能把不同请求或不同堆范围的值直接相减。

开发者单次任务栈快照 ​

2026-10-04后继候选新增POST /api/system/task-stack-snapshot,需要登录和开发者模式;r20集中诊断r2已通过26项Host回归,完整固件候选与实机尚未验收,也未部署。页面和健康检查不会自动调用。该调试操作可能暂时挂起调度,不能作为常规探活或轮询接口。

请求须通过健康监控、内部8-bit空闲至少32768字节、最大连续块至少8192字节的检查;SEVERE及以上、采集忙、30秒冷却或任务超过48均不启动扫描。PSRAM不能替代内部预算。未知结果不返回旧列表,也不把SDK返回0或超容量解释为没有任务。

每个条目只包含SDK已复制的任务编号、优先级、状态和highWaterBytes;任务名为null,不再访问可能销毁的任务或名字指针。编号不是跨重启身份,0字节是有效的低水位。completeAtCapture=true只说明本次SDK列表完整,不说明任务在响应时仍存在,也不证明最差业务路径已覆盖。

响应保留前后任务数和captureDurationUs。后者是SDK调用的实测耗时,不能限制或中断该调用;hardDeadlineEnforced=false、atomicSnapshot=false。开发者仍须在具体板型、稳定候选和受控负载下验证扫描开销、内部堆、HTTP延迟及WDT。一次快照不等于所有功能内存收益、全场景任务峰值或长稳验收。

内存保护与恢复 ​

NORMAL/WARN/SEVERE/CRITICAL综合内部DRAM空闲量、连续块、碎片情况和芯片档位决定,并带有启动宽限与恢复迟滞。不能仅凭一个空闲值推断完整等级。绝对DRAM危急不会被启动宽限屏蔽。

压力升高时,系统可暂停日志、Modbus、规则执行及可选外设,保留管理入口并尝试恢复。资源释放忙或失败时,暂停请求不等于释放完成,应同时查看实例/退役和Worker状态。当前开发批次将MQTTS保护改为保留scheme/port/enabled的运行期暂停,禁止自动切换明文,仍待统一验证。memoryDegradation.mqttsPaused表示暂停,mqttsProtection=pause_without_plaintext_fallback说明策略;旧兼容字段mqttsDowngraded固定为false。metrics对应memguard.mqtts_paused/mqtts_protection,其旧mqtts_downgraded也固定为false。

旧固件已经写盘的降级记录不会被抹掉。有完整有效的原TLS协议/端口证据时,新候选才按该安全配置加载;元数据缺失时拒绝启动,不能猜测端口或继续明文。旧版持久禁用且enabled=false的配置仍保持禁用,须用户明确选择保存。运行期暂停、历史禁用和恢复排队是不同状态;重建已排队不代表已连接。

GET /api/health和GET /api/system/status可返回data.memoryDegradation。其中level、active、modbusStopped、periphExecPaused、optionalPeripheralsSuspended和actions说明降级状态;这些字段不是功能独占内存测量。临时降级、用户保存的开关和实际对象是否保留,应分别核对功能配置。

极低内存或长期无法恢复时,代码可能安排重启,并具有启动循环保护。不同路径的计时条件不同,不能概括为“一次低水位就重启”或“统一90秒重启”。管理页面、恢复和重启仍可能受OOM或底层故障影响,不保证任何故障下均可访问。

接口拒绝与退避 ​

重型接口可因保护等级或内存不足返回503。响应带有Retry-After时按其退避;没有该头时也应有限退避,避免并发重试。认证错误401/403须先处理登录/权限,不能当作内存不足。

OTA还检查可用升级分区和至少20KiB内部DRAM;本批修复将PSRAM从该准入统计排除。SSE新连接和广播的连续块门槛为8192字节,本批同样统一为内部8-bit口径;保持原阈值和认证/容量保护,待集中回归。SSE槽位满时通常拒绝新连接;连接登记还保留按连接时间选择最老槽位的兜底逻辑,不是按最近活动排序的LRU服务保证。

诊断接口 ​

接口返回范围包装与限制
GET /api/health、GET /api/system/healthstatus/timestamp/freeHeap/memory及可用的降级状态相同轻量处理器,标准success/data包装;status=healthy本身不证明未降级
GET /api/system/info?full=1完整系统信息、页面内存与可用的分池快照需登录;裸URL默认精简,显式full仍可能因内存保护降级,精简/probe路径字段较少
GET /api/system/metricsheap/mqtt/sse/poll/memguard/stability等运行指标需登录;直接返回指标JSON,没有success/data包装;HealthMonitor不可用时返回503
GET /api/system/diag-bundledata.device/restart/memory/filesystem/network/runtime/logs需登录,受重型请求和低内存保护;网络及部分内容按实际对象可用性返回

metrics字段与单位 ​

heap.free/min/largest_block/dram_free/dram_largest使用字节;历史兼容字段heap.psram_total/psram_free使用KiB。uptime使用秒,boot_time_ms与poll.duration_ms使用毫秒。读取时不要把这些单位混合。

memguard.level_name给出等级,stability.dram_history_count/leak_suspect/uptime_hours给出趋势观察状态。heap.tls_supported只是旧PSRAM条件标记,不证明TLS握手、证书或平台认证通过。当前接口不提供taskStackWatermarks全任务数组,也不提供所谓每小时自动定位泄漏对象的报告。

重启与运行快照 ​

诊断包的restart.resetReason/resetReasonCode/abnormalRestart描述本次启动。只有snapshotValid=true时才有可用的lastRestartReason/lastRestartContext/lastUptimeMs/preRestart。lastUptimeMs是上次快照的运行时标,不是UTC时间。

preRestart可包含重启前heap、连续块、碎片、guard、Wi-Fi与队列等值;它是一次保留快照,不是restartHistory列表或完整掉电记录。新候选保留旧命名任务栈字段为null,并给出taskWatermarkStatus=unknown,因为原名字查询不能保证任务在后续读取时仍存活;不会以未知0字节推断栈溢出。RTC旧结构与证据保留,没有在重启流程增加全任务扫描。没有有效快照时不能补造原因、计数或时间。

runtime.taskCount是任务数,sseClients/sseMaxClients在对应Web对象存在时提供;不表示逐任务栈、实际吞吐或物理连接质量。filesystem描述LittleFS统计,SD卡使用自身诊断,不混为同一个文件系统。

采集与验收 ​

碎片百分比按同一内部DRAM范围计算100 × (1 − largest/free)并做边界保护。低空闲或小连续块可能来自负载峰值、长期碎片或泄漏,单个样本无法区分;保存采样时刻、固件、板型、配置、业务负载和原始失败记录。

实际功能收益须比较关闭、启用无实例、单实例、多实例、停用生效和再启用六组状态,记录内部DRAM、连续块、DMA、PSRAM、任务栈及峰值。估算预算、对象存在、主机测试和编译结果不能代替这些实测。

24小时/7天验收以同一稳定候选的真实有效样本跨度和连续业务覆盖为准。设备uptime、脚本进程存在、登录等待、截图或导出时间均不能补足测量期;恢复后不得抹去先前断连、坏响应或重启。当前这些现场项目仍待授权和执行,见发布检查清单。

排障时先减少重复打开的页面,保存轻量状态和已有日志,再在内存允许时导出一次诊断包。修改功能或迁移配置须保留用户意图和备份,不能以“自动裁剪大配置”作为默认部署行为。涉及输出、RTC、接线及刷写须按具体设备流程确认。

相关文档 ​

蜂信物联 | fastbee.cn