diff --git a/.gitignore b/.gitignore index e3f3dfe..3373075 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ __pycache__/ *.pyc dist/ .DS_Store +.data/ diff --git a/README.md b/README.md index 67e9907..36efd71 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ ```sh mkdir -p dist -python3 package.py plugin dist/pigway-agent-1.0.0.zip +python3 package.py plugin dist/pigway-agent-1.1.0.zip ``` 在控制中心的机器管理页面安装 ZIP,再启用。开发时可用 `PIGWAY_ADAPTER_PATH=/absolute/path/pigway-console-adapter-raspberry-pi/plugin` 加载源码;Docker 推荐使用持久化数据卷中的安装包。 @@ -20,3 +20,7 @@ python3 package.py plugin dist/pigway-agent-1.0.0.zip ## Naming and compatibility This project targets Raspberry Pi. Other Linux platforms are not covered by its support claim and may have separately maintained adapters. Repository naming does not change the existing `pigway-agent` adapter ID or `pigway-pi-control` service, configuration and API identifiers. + +## v1.1.0 历史指标 + +将现有 Agent API 的内存/磁盘字节数、开机时长与链路速度补充到标准 metrics,Console v2.1.0 可直接统一记录历史。不需要更新或新增树莓派进程。现有设备端没有上传下载流量计数,因此本版没有实际流量曲线;链路速度仅代表协商速率。 diff --git a/SHA256SUMS b/SHA256SUMS index 1debb20..6a55e34 100644 --- a/SHA256SUMS +++ b/SHA256SUMS @@ -1,7 +1,7 @@ -7d856a7ec552a841097cd14f2f3e357efcd05c13f70eb98a415789e615f6fbf2 .gitignore -c68eb6c829b19905e0dcea372514e8538ce01e13c40dd437d23cf122ad71511f README.md +3cfd361f7663a9a9c93b507d17bb1c7e98003d61316826f0a4ba4a93594f72d4 .gitignore +2a476aea1b4fcaf43ace0a7f297e4f5c3cd5014b79992bb5bedf84faa194071f README.md d081c599d821149853368b1a8637c57a16995344406ff5ec9d7619b66e0479b3 package.py -d75aeb77a9dd8b74d3d6a0d3811a40d5578dd634a6d35ee5d3352163a7bcb039 plugin/manifest.json +cf40d1302a8398497e4d6724ec0a22b24420e32ed2697ba3f4d039d193cf38ea plugin/manifest.json e5c04001dbd8ed8bba614f7b341237fc6487a9a8fe2f28ccb6f59278725b0a69 plugin/ui/config.js c98f34119436e3020ef20b325f91617943aefe662119cf76738e0226c2e91cbb plugin/ui/device.js 89b9d7994e7477e18c3f43e6f0975e04d5106056ba581b2964db0f39183d6f8a plugin/ui/hardware.js @@ -11,4 +11,5 @@ fadb6bf24d6fcf569fc4157847a3585a1008aad99ce5a0e2b87c9c0658f6d225 plugin/ui/over 5d967b5d4e62eed7022bc04fe29e4ed670f2e288cf20adae0c25233f94a29079 plugin/ui/services.js 56e67d2839cbb865133e3b5f796a07f36595c0f6c30480f8e2fac79e7d51e03f plugin/ui/styles.css 0b79b9c5b5f23727164e05b127caca72255416309166ba200ccbd15a9667473c plugin/ui/translations.js -7a9212e2f0c30ce2158d9d0e7f2af29171ffeb6c707cbd8c9b677ef893a573d4 plugin/worker.py +0c37e4604a30c13923b45316d21c841164c48e8b632c3a3f8febd778b434c2f8 plugin/worker.py +9ffd557bb01ccda24970af1cfc5ec395721d5b1e613bfc013feb27d074582b7e tests/test_metrics.py diff --git a/plugin/manifest.json b/plugin/manifest.json index db525d4..3cb84f3 100644 --- a/plugin/manifest.json +++ b/plugin/manifest.json @@ -1,7 +1,7 @@ { "id": "pigway-agent", "name": "PIGWay Raspberry Pi Agent", - "version": "1.0.0", + "version": "1.1.0", "protocol_version": 1, "entrypoint": "worker.py", "runtime": "python3", diff --git a/plugin/worker.py b/plugin/worker.py index 52c3a40..2f1d195 100644 --- a/plugin/worker.py +++ b/plugin/worker.py @@ -61,11 +61,19 @@ def collect(device): raise AdapterError('INVALID_RESPONSE') metrics = [] units = {'cpu_percent': 'percent', 'memory_percent': 'percent', 'disk_percent': 'percent', - 'temperature_c': 'celsius', 'cpu_freq_mhz': 'megahertz'} + 'temperature_c': 'celsius', 'cpu_freq_mhz': 'megahertz', + 'memory_total_bytes': 'bytes', 'memory_used_bytes': 'bytes', + 'disk_total_bytes': 'bytes', 'disk_used_bytes': 'bytes'} for key, unit in units.items(): number = value['system'].get(key) if isinstance(number, (int, float)) and not isinstance(number, bool): metrics.append({'resource_id': 'host', 'key': key, 'value': number, 'unit': unit}) + uptime = value.get('uptime_seconds') + if isinstance(uptime, (int, float)) and not isinstance(uptime, bool): + metrics.append({'resource_id': 'host', 'key': 'uptime_seconds', 'value': uptime, 'unit': 'seconds'}) + speed = value.get('network', {}).get('link_speed_mbps') + if isinstance(speed, (int, float)) and not isinstance(speed, bool): + metrics.append({'resource_id': 'host', 'key': 'network_link_speed_mbps', 'value': speed, 'unit': 'megabits_per_second'}) return {'schema_version': 1, 'observed_at': value.get('timestamp'), 'identity': {'reported_name': value['machine'].get('name'), 'category': 'host', 'details': value.get('device', {})}, diff --git a/tests/test_metrics.py b/tests/test_metrics.py new file mode 100644 index 0000000..6f756a0 --- /dev/null +++ b/tests/test_metrics.py @@ -0,0 +1,29 @@ +import sys +import unittest +from pathlib import Path +from unittest.mock import patch +sys.path.insert(0,str(Path(__file__).resolve().parents[1]/'plugin')) +import worker + + +class MetricsTests(unittest.TestCase): + def test_existing_agent_fields_become_standard_history_metrics(self): + value = {'timestamp': 123, 'machine': {'name':'Pi'}, 'system': { + 'cpu_percent': 10, 'memory_total_bytes': 8000, 'memory_used_bytes': 4000, + 'disk_total_bytes': 16000, 'disk_used_bytes': 5000}, + 'uptime_seconds': 1000, 'network': {'link_speed_mbps':1000}, + 'display': {'alerts': []}} + with patch.object(worker,'request',return_value=value): result=worker.collect({}) + values = {m['key']:m['value'] for m in result['metrics']} + self.assertEqual(values['memory_used_bytes'],4000) + self.assertEqual(values['uptime_seconds'],1000) + self.assertEqual(values['network_link_speed_mbps'],1000) + self.assertNotIn('network_rx_bytes_per_second',values) + self.assertTrue(result['alerts_complete']) + + def test_absent_or_boolean_fields_not_invented(self): + value={'system': {'cpu_percent': True}, 'machine':{}, 'network': {'link_speed_mbps': None}} + with patch.object(worker,'request',return_value=value): result=worker.collect({}) + self.assertEqual(result['metrics'],[]) + +if __name__=='__main__': unittest.main()