feat: expose true sampling timestamps and cache read cadence
This commit is contained in:
@@ -59,3 +59,7 @@ This project targets Raspberry Pi. Other Linux platforms are not covered by its
|
|||||||
## v3.8.0 网络流量
|
## v3.8.0 网络流量
|
||||||
|
|
||||||
主接口每个网络采集周期读取 sysfs 的 rx_bytes/tx_bytes,以单调时间差计算字节/秒,API 新增 rx_bytes_per_second 和 tx_bytes_per_second。首次采样、接口切换、计数器重置或读取失败返回空值;不修改监控告警、硬件插件控制或 API 可选安装行为。2026-10-14 已在 Gateway 部署,实机上下行速率与 Console 标准历史指标验证通过。
|
主接口每个网络采集周期读取 sysfs 的 rx_bytes/tx_bytes,以单调时间差计算字节/秒,API 新增 rx_bytes_per_second 和 tx_bytes_per_second。首次采样、接口切换、计数器重置或读取失败返回空值;不修改监控告警、硬件插件控制或 API 可选安装行为。2026-10-14 已在 Gateway 部署,实机上下行速率与 Console 标准历史指标验证通过。
|
||||||
|
|
||||||
|
## v3.9.0 采样时间
|
||||||
|
|
||||||
|
API 状态新增 system.observed_at、network.observed_at 和 collection.interval_seconds。Console 可每秒读取缓存,网络等低频指标保留实际采样时间,供历史去重。数据来源与原网络采样周期保持。
|
||||||
|
|||||||
+2
-2
@@ -1,8 +1,8 @@
|
|||||||
ecf1884bb89b86ed4573d4d922a971abde43772bf7b2ffa6a999a12fbfb72caf .gitignore
|
ecf1884bb89b86ed4573d4d922a971abde43772bf7b2ffa6a999a12fbfb72caf .gitignore
|
||||||
56b7a3ed6a6a8dbbcf02a80b6219a5e6aab0df2ef04cdff90895784c311e5cfa README.md
|
ba2329dc02e9e09f5989c0dc6f174e0ce36b126b94249092a7ec97eb0e2a1d9d README.md
|
||||||
64a9708701f8c8d872a587e8a2845afff463797b06a2791319daadd705933d31 README.zh-CN.md
|
64a9708701f8c8d872a587e8a2845afff463797b06a2791319daadd705933d31 README.zh-CN.md
|
||||||
c5853f283c0951b43f2bacbc49e66c26d3a605a184d427828e042eb9236d2740 app/network_rates.py
|
c5853f283c0951b43f2bacbc49e66c26d3a605a184d427828e042eb9236d2740 app/network_rates.py
|
||||||
003e6766552823e8cd8ec56888c385d0607df0c14ab7dff166472fcf6914ff9c app/pigway_pi_control.py
|
439602f2f6188558f1f16b6630a65438806d98dabd4c6f7fa5270e9f3845bf54 app/pigway_pi_control.py
|
||||||
757eb6a83ca07740a2389af9b51c6fd5d940b4eb86abbc603f231409416d45db app/pigway_pi_control_api.py
|
757eb6a83ca07740a2389af9b51c6fd5d940b4eb86abbc603f231409416d45db app/pigway_pi_control_api.py
|
||||||
3a8a368bbf299eb2d6cccc968a4aacf070058bddebdc5176083a97ac579d720d app/plugin_api.py
|
3a8a368bbf299eb2d6cccc968a4aacf070058bddebdc5176083a97ac579d720d app/plugin_api.py
|
||||||
d5a783b64a10fa43191a813ef73ef8f762e359b0bd42ec155724fa46216298b0 config/pigway-pi-control.conf
|
d5a783b64a10fa43191a813ef73ef8f762e359b0bd42ec155724fa46216298b0 config/pigway-pi-control.conf
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
import time,socket,subprocess,configparser,signal,re,argparse,json,os,platform
|
import time,socket,subprocess,configparser,signal,re,argparse,json,os,platform
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
APP_VERSION="3.8.0"
|
APP_VERSION="3.9.0"
|
||||||
import sys
|
import sys
|
||||||
sys.path.append("/usr/local/share/pigway-pi-control")
|
sys.path.append("/usr/local/share/pigway-pi-control")
|
||||||
from shutil import disk_usage
|
from shutil import disk_usage
|
||||||
@@ -105,6 +105,8 @@ prev_cpu=None
|
|||||||
page=0; page_since=time.monotonic()
|
page=0; page_since=time.monotonic()
|
||||||
cpu_hi=mem_hi=0
|
cpu_hi=mem_hi=0
|
||||||
net_ok=link_ok=True
|
net_ok=link_ok=True
|
||||||
|
sensor_observed_at=None
|
||||||
|
network_observed_at=None
|
||||||
network_rates=NetworkRates()
|
network_rates=NetworkRates()
|
||||||
net_rx_bytes_per_second=None; net_tx_bytes_per_second=None
|
net_rx_bytes_per_second=None; net_tx_bytes_per_second=None
|
||||||
net_iface=""; net_kind="NET"; net_metric="DOWN"; net_speed_mbps=None; ip_label="IP4"; ip="NO IP"
|
net_iface=""; net_kind="NET"; net_metric="DOWN"; net_speed_mbps=None; ip_label="IP4"; ip="NO IP"
|
||||||
@@ -424,10 +426,11 @@ def write_status(cpu,temp,mem,disk):
|
|||||||
disk_total,disk_used,disk_free=disk_usage("/")
|
disk_total,disk_used,disk_free=disk_usage("/")
|
||||||
signal=wifi_percent(net_metric) if net_kind=="WIF" else None
|
signal=wifi_percent(net_metric) if net_kind=="WIF" else None
|
||||||
state={
|
state={
|
||||||
"version":APP_VERSION,"timestamp":int(time.time()),"uptime_seconds":uptime_seconds(),
|
"version":APP_VERSION,"timestamp":int(time.time()),
|
||||||
|
"collection":{"interval_seconds":min(1.0,SENSOR_INTERVAL,NETWORK_INTERVAL,SERVICE_INTERVAL,HEALTH_INTERVAL)},"uptime_seconds":uptime_seconds(),
|
||||||
"machine":{"id":DEVICE_ID,"name":DEVICE_NAME,"hostname":socket.gethostname()},
|
"machine":{"id":DEVICE_ID,"name":DEVICE_NAME,"hostname":socket.gethostname()},
|
||||||
"device":DEVICE_INFO,
|
"device":DEVICE_INFO,
|
||||||
"system":{"load_average":load_average(),"cpu_percent":round(cpu,1),
|
"system":{"observed_at":sensor_observed_at,"load_average":load_average(),"cpu_percent":round(cpu,1),
|
||||||
"cpu_freq_mhz":round(cpu_freq_mhz()),"temperature_c":round(temp,1),
|
"cpu_freq_mhz":round(cpu_freq_mhz()),"temperature_c":round(temp,1),
|
||||||
"memory_percent":round(memory_calculated if memory_total else mem,1),
|
"memory_percent":round(memory_calculated if memory_total else mem,1),
|
||||||
"memory_total_bytes":memory_total,"memory_used_bytes":memory_used,
|
"memory_total_bytes":memory_total,"memory_used_bytes":memory_used,
|
||||||
@@ -436,7 +439,7 @@ def write_status(cpu,temp,mem,disk):
|
|||||||
"disk_used_bytes":disk_used,"disk_free_bytes":disk_free,
|
"disk_used_bytes":disk_used,"disk_free_bytes":disk_free,
|
||||||
"root_readonly":bool(fs_readonly)},
|
"root_readonly":bool(fs_readonly)},
|
||||||
"power":health,
|
"power":health,
|
||||||
"network":{"interface":net_iface,"kind":net_kind,"metric":net_metric,
|
"network":{"observed_at":network_observed_at,"interface":net_iface,"kind":net_kind,"metric":net_metric,
|
||||||
"link_speed_mbps":net_speed_mbps,
|
"link_speed_mbps":net_speed_mbps,
|
||||||
"rx_bytes_per_second":net_rx_bytes_per_second,
|
"rx_bytes_per_second":net_rx_bytes_per_second,
|
||||||
"tx_bytes_per_second":net_tx_bytes_per_second,
|
"tx_bytes_per_second":net_tx_bytes_per_second,
|
||||||
@@ -484,12 +487,13 @@ try:
|
|||||||
if now-last_sensor >= SENSOR_INTERVAL:
|
if now-last_sensor >= SENSOR_INTERVAL:
|
||||||
sample_elapsed=now-last_sensor if last_sensor else 0.0
|
sample_elapsed=now-last_sensor if last_sensor else 0.0
|
||||||
c=cpu_pct(); t=temp_c(); m=mem_pct(); d=disk_pct()
|
c=cpu_pct(); t=temp_c(); m=mem_pct(); d=disk_pct()
|
||||||
latest=(c,t,m,d); last_sensor=now; agent["last_sensor_ok"]=now
|
latest=(c,t,m,d); sensor_observed_at=int(time.time()); last_sensor=now; agent["last_sensor_ok"]=now
|
||||||
|
|
||||||
if now>=monitor_ready_at and now-last_net >= NETWORK_INTERVAL:
|
if now>=monitor_ready_at and now-last_net >= NETWORK_INTERVAL:
|
||||||
old_id=(net_iface,ip)
|
old_id=(net_iface,ip)
|
||||||
net_iface,net_kind,net_metric,net_speed_mbps,ip_label,ip=primary_network()
|
net_iface,net_kind,net_metric,net_speed_mbps,ip_label,ip=primary_network()
|
||||||
net_rx_bytes_per_second,net_tx_bytes_per_second=network_rates.sample(net_iface,now)
|
net_rx_bytes_per_second,net_tx_bytes_per_second=network_rates.sample(net_iface,now)
|
||||||
|
network_observed_at=int(time.time())
|
||||||
raw_link_ok=ip!="NO IP"; raw_net_ok=internet() if raw_link_ok else False
|
raw_link_ok=ip!="NO IP"; raw_net_ok=internet() if raw_link_ok else False
|
||||||
if raw_link_ok:
|
if raw_link_ok:
|
||||||
link_failure_since=None;link_ok=True
|
link_failure_since=None;link_ok=True
|
||||||
|
|||||||
Reference in New Issue
Block a user