Remove Node.js cache files containing npm vulnerability data for vitest and vite packages
Some checks failed
Tests / Backend Tests (Python) (3.10) (push) Has been cancelled
Tests / Backend Tests (Python) (3.11) (push) Has been cancelled
Tests / Backend Tests (Python) (3.12) (push) Has been cancelled
Tests / Frontend Tests (JS) (push) Has been cancelled
Tests / Integration Tests (push) Has been cancelled
Tests / All Tests Passed (push) Has been cancelled

This commit is contained in:
Bruno Charest 2025-12-15 20:36:06 -05:00
parent 27eed55c9b
commit 68a9b0f390
123 changed files with 13216 additions and 157 deletions

BIN
.coverage Normal file

Binary file not shown.

View File

@ -1 +0,0 @@
{"source":"tMBsdAS7JBTyRORp0YaJR984WAAsOxgmReSLBN0Nd41GhzEakjROICqAJ31iOdYG5Ijo/MlJ01p3ig1iN88+Tw==","name":"@vitest/mocker","dependency":"vite","title":"Depends on vulnerable versions of vite","url":null,"severity":"moderate","versions":["2.1.0-beta.7","2.1.0","2.1.1","2.1.2","2.1.3","2.1.4","2.1.5","2.1.6","2.1.7","2.1.8","2.1.9","2.2.0-beta.1","2.2.0-beta.2","3.0.0-beta.1","3.0.0-beta.2","3.0.0-beta.3","3.0.0-beta.4","3.0.0","3.0.1","3.0.2","3.0.3","3.0.4","3.0.5","3.0.6","3.0.7","3.0.8","3.0.9","3.1.0-beta.1","3.1.0-beta.2","3.1.0","3.1.1","3.1.2","3.1.3","3.1.4","3.2.0-beta.1","3.2.0-beta.2","3.2.0-beta.3","3.2.0","3.2.1","3.2.2","3.2.3","3.2.4","4.0.0-beta.1","4.0.0-beta.2","4.0.0-beta.3","4.0.0-beta.4","4.0.0-beta.5","4.0.0-beta.6","4.0.0-beta.7","4.0.0-beta.8","4.0.0-beta.9","4.0.0-beta.10","4.0.0-beta.11","4.0.0-beta.12","4.0.0-beta.13","4.0.0-beta.14","4.0.0-beta.15","4.0.0-beta.16","4.0.0-beta.17","4.0.0-beta.18","4.0.0-beta.19","4.0.0","4.0.1","4.0.2","4.0.3","4.0.4","4.0.5","4.0.6","4.0.7","4.0.8","4.0.9","4.0.10","4.0.11","4.0.12","4.0.13","4.0.14","4.0.15"],"vulnerableVersions":["2.1.0-beta.7","2.1.0","2.1.1","2.1.2","2.1.3","2.1.4","2.1.5","2.1.6","2.1.7","2.1.8","2.1.9","2.2.0-beta.1","2.2.0-beta.2","3.0.0-beta.1","3.0.0-beta.2","3.0.0-beta.3","3.0.0-beta.4"],"cwe":["CWE-346"],"cvss":{"score":5.3,"vectorString":"CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:N/A:N"},"range":"<=3.0.0-beta.4","id":"SJ6ALG5CByItLFxBhtpyrxAdDoKdsJCSnzbVFPNK6WdVHJq3/BQr5X33nTvglq430Jo7eFZBpLt727pFLHxHzA=="}

View File

@ -1 +0,0 @@
{"source":"SJ6ALG5CByItLFxBhtpyrxAdDoKdsJCSnzbVFPNK6WdVHJq3/BQr5X33nTvglq430Jo7eFZBpLt727pFLHxHzA==","name":"vitest","dependency":"@vitest/mocker","title":"Depends on vulnerable versions of @vitest/mocker","url":null,"severity":"moderate","versions":["0.0.0","0.0.1","0.0.2","0.0.3","0.0.4","0.0.6","0.0.7","0.0.8","0.0.9","0.0.10","0.0.11","0.0.12","0.0.13","0.0.14","0.0.15","0.0.16","0.0.17","0.0.18","0.0.19","0.0.20","0.0.21","0.0.22","0.0.23","0.0.24","0.0.25","0.0.26","0.0.27","0.0.28","0.0.29","0.0.30","0.0.31","0.0.32","0.0.33","0.0.34","0.0.35","0.0.36","0.0.37","0.0.38","0.0.39","0.0.40","0.0.41","0.0.42","0.0.43","0.0.44","0.0.45","0.0.46","0.0.47","0.0.48","0.0.49","0.0.50","0.0.51","0.0.52","0.0.53","0.0.54","0.0.55","0.0.56","0.0.57","0.0.58","0.0.59","0.0.60","0.0.61","0.0.62","0.0.63","0.0.64","0.0.65","0.0.66","0.0.67","0.0.68","0.0.69","0.0.70","0.0.71","0.0.72","0.0.73","0.0.74","0.0.75","0.0.76","0.0.77","0.0.78","0.0.79","0.0.80","0.0.81","0.0.82","0.0.83","0.0.84","0.0.85","0.0.87","0.0.88","0.0.89","0.0.90","0.0.91","0.0.92","0.0.93","0.0.94","0.0.95","0.0.96","0.0.97","0.0.98","0.0.99","0.0.100","0.0.101","0.0.102","0.0.103","0.0.104","0.0.105","0.0.106","0.0.107","0.0.108","0.0.109","0.0.110","0.0.111","0.0.112","0.0.113","0.0.114","0.0.115","0.0.116","0.0.117","0.0.118","0.0.119","0.0.120","0.0.121","0.0.122","0.0.123","0.0.124","0.0.125","0.0.126","0.0.127","0.0.128","0.0.129","0.0.130","0.0.131","0.0.132","0.0.133","0.0.134","0.0.135","0.0.136","0.0.137","0.0.138","0.0.139","0.0.140","0.0.141","0.0.142","0.1.0","0.1.12","0.1.13","0.1.14","0.1.15","0.1.16","0.1.17","0.1.18","0.1.19","0.1.20","0.1.21","0.1.23","0.1.24","0.1.25","0.1.26","0.1.27","0.2.0","0.2.1","0.2.2","0.2.3","0.2.4","0.2.5","0.2.6","0.2.7","0.2.8","0.3.0","0.3.1","0.3.2","0.3.3","0.3.4","0.3.5","0.3.6","0.4.0","0.4.1","0.4.2","0.4.3","0.5.0","0.5.1","0.5.2","0.5.3","0.5.4","0.5.5","0.5.6","0.5.7","0.5.8","0.5.9","0.6.0","0.6.1","0.6.3","0.7.0","0.7.1","0.7.2","0.7.3","0.7.4","0.7.5","0.7.6","0.7.7","0.7.8","0.7.9","0.7.10","0.7.11","0.7.12","0.7.13","0.8.0","0.8.1","0.8.2","0.8.3","0.8.4","0.8.5","0.9.0","0.9.1","0.9.2","0.9.3","0.9.4","0.10.0","0.10.1","0.10.2","0.10.3","0.10.4","0.10.5","0.11.0","0.12.0","0.12.1","0.12.2","0.12.3","0.12.4","0.12.5","0.12.6","0.12.7","0.12.8","0.12.9","0.12.10","0.13.0","0.13.1","0.14.0","0.14.1","0.14.2","0.15.0","0.15.1","0.15.2","0.16.0","0.17.0","0.17.1","0.18.0","0.18.1","0.19.0","0.19.1","0.20.0","0.20.1","0.20.2","0.20.3","0.21.0","0.21.1","0.22.0","0.22.1","0.23.0","0.23.1","0.23.2","0.23.4","0.24.0","0.24.1","0.24.2","0.24.3","0.24.4","0.24.5","0.25.0","0.25.1","0.25.2","0.25.3","0.25.4","0.25.5","0.25.6","0.25.7","0.25.8","0.26.0","0.26.1","0.26.2","0.26.3","0.27.0","0.27.1","0.27.2","0.27.3","0.28.0","0.28.1","0.28.2","0.28.3","0.28.4","0.28.5","0.29.0","0.29.1","0.29.2","0.29.3","0.29.4","0.29.5","0.29.6","0.29.7","0.29.8","0.30.0","0.30.1","0.31.0","0.31.1","0.31.2","0.31.3","0.31.4","0.32.0","0.32.1","0.32.2","0.32.3","0.32.4","0.33.0","0.34.0","0.34.1","0.34.2","0.34.3","0.34.4","0.34.5","0.34.6","1.0.0-beta.0","1.0.0-beta.1","1.0.0-beta.2","1.0.0-beta.3","1.0.0-beta.4","1.0.0-beta.5","1.0.0-beta.6","1.0.0","1.0.1","1.0.2","1.0.3","1.0.4","1.1.0","1.1.1","1.1.2","1.1.3","1.2.0","1.2.1","1.2.2","1.3.0","1.3.1","1.4.0","1.5.0","1.5.1","1.5.2","1.5.3","1.6.0","1.6.1","2.0.0-beta.1","2.0.0-beta.2","2.0.0-beta.3","2.0.0-beta.5","2.0.0-beta.6","2.0.0-beta.7","2.0.0-beta.8","2.0.0-beta.9","2.0.0-beta.10","2.0.0-beta.11","2.0.0-beta.12","2.0.0-beta.13","2.0.0","2.0.1","2.0.2","2.0.3","2.0.4","2.0.5","2.1.0-beta.1","2.1.0-beta.2","2.1.0-beta.3","2.1.0-beta.4","2.1.0-beta.5","2.1.0-beta.6","2.1.0-beta.7","2.1.0","2.1.1","2.1.2","2.1.3","2.1.4","2.1.5","2.1.6","2.1.7","2.1.8","2.1.9","2.2.0-beta.1","2.2.0-beta.2","3.0.0-beta.1","3.0.0-beta.2","3.0.0-beta.3","3.0.0-beta.4","3.0.0","3.0.1","3.0.2","3.0.3","3.0.4","3.0.5","3.0.6","3.0.7","3.0.8","3.0.9","3.1.0-beta.1","3.1.0-beta.2","3.1.0","3.1.1","3.1.2","3.1.3","3.1.4","3.2.0-beta.1","3.2.0-beta.2","3.2.0-beta.3","3.2.0","3.2.1","3.2.2","3.2.3","3.2.4","4.0.0-beta.1","4.0.0-beta.2","4.0.0-beta.3","4.0.0-beta.4","4.0.0-beta.5","4.0.0-beta.6","4.0.0-beta.7","4.0.0-beta.8","4.0.0-beta.9","4.0.0-beta.10","4.0.0-beta.11","4.0.0-beta.12","4.0.0-beta.13","4.0.0-beta.14","4.0.0-beta.15","4.0.0-beta.16","4.0.0-beta.17","4.0.0-beta.18","4.0.0-beta.19","4.0.0","4.0.1","4.0.2","4.0.3","4.0.4","4.0.5","4.0.6","4.0.7","4.0.8","4.0.9","4.0.10","4.0.11","4.0.12","4.0.13","4.0.14","4.0.15"],"vulnerableVersions":["2.1.0","2.1.1","2.1.2","2.1.3","2.1.4","2.1.5","2.1.6","2.1.7","2.1.8","2.1.9","2.2.0-beta.1","2.2.0-beta.2","3.0.0-beta.1","3.0.0-beta.2","3.0.0-beta.3","3.0.0-beta.4"],"cwe":["CWE-346"],"cvss":{"score":5.3,"vectorString":"CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:N/A:N"},"range":"2.1.0-beta.1 - 3.0.0-beta.4","id":"BSMf7BHi5iZnvIquFfRkjWP6a8w6U34XKSRTgPQahAegm6GPZJH2KxXV9Lykl5yaU1n6yOYaeIOzMIn67rnZBA=="}

View File

@ -1 +0,0 @@
{"source":"XRC5FYn4BgxTqFRmBvXrbhEb/XwDQF7aS38Di6r7Pv9zY1oGG9mQ2VYohi/Jc8TchbgRdRy0c0xiUZ9w83+tUA==","name":"@vitest/ui","dependency":"vitest","title":"Depends on vulnerable versions of vitest","url":null,"severity":"moderate","versions":["0.0.119","0.0.120","0.0.121","0.0.122","0.0.123","0.0.124","0.0.125","0.0.126","0.0.127","0.0.128","0.0.129","0.0.130","0.0.131","0.0.132","0.0.133","0.0.134","0.0.135","0.0.136","0.0.137","0.0.138","0.0.139","0.0.140","0.0.141","0.0.142","0.1.0","0.1.12","0.1.13","0.1.14","0.1.15","0.1.16","0.1.17","0.1.18","0.1.19","0.1.20","0.1.21","0.1.22","0.1.23","0.1.24","0.1.25","0.1.26","0.1.27","0.2.0","0.2.1","0.2.2","0.2.3","0.2.4","0.2.5","0.2.6","0.2.7","0.2.8","0.3.0","0.3.1","0.3.2","0.3.3","0.3.4","0.3.5","0.3.6","0.4.0","0.4.1","0.4.2","0.4.3","0.5.0","0.5.1","0.5.2","0.5.3","0.5.4","0.5.5","0.5.6","0.5.7","0.5.8","0.5.9","0.6.0","0.6.1","0.6.3","0.7.0","0.7.1","0.7.2","0.7.3","0.7.4","0.7.5","0.7.6","0.7.7","0.7.8","0.7.9","0.7.10","0.7.11","0.7.12","0.7.13","0.8.0","0.8.1","0.8.2","0.8.3","0.8.4","0.8.5","0.9.0","0.9.1","0.9.2","0.9.3","0.9.4","0.10.0","0.10.1","0.10.2","0.10.3","0.10.4","0.10.5","0.11.0","0.12.0","0.12.1","0.12.2","0.12.3","0.12.4","0.12.5","0.12.6","0.12.7","0.12.8","0.12.9","0.12.10","0.13.0","0.13.1","0.14.0","0.14.1","0.14.2","0.15.0","0.15.1","0.15.2","0.16.0","0.17.0","0.17.1","0.18.0","0.18.1","0.19.0","0.19.1","0.20.0","0.20.1","0.20.2","0.20.3","0.21.0","0.21.1","0.22.0","0.22.1","0.23.0","0.23.1","0.23.2","0.23.4","0.24.0","0.24.1","0.24.2","0.24.3","0.24.4","0.24.5","0.25.0","0.25.1","0.25.2","0.25.3","0.25.4","0.25.5","0.25.6","0.25.7","0.25.8","0.26.0","0.26.1","0.26.2","0.26.3","0.27.0","0.27.1","0.27.2","0.27.3","0.28.0","0.28.1","0.28.2","0.28.3","0.28.4","0.28.5","0.29.0","0.29.1","0.29.2","0.29.3","0.29.4","0.29.5","0.29.6","0.29.7","0.29.8","0.30.0","0.30.1","0.31.0","0.31.1","0.31.2","0.31.3","0.31.4","0.32.0","0.32.1","0.32.2","0.32.3","0.32.4","0.33.0","0.34.0","0.34.1","0.34.2","0.34.3","0.34.4","0.34.5","0.34.6","0.34.7","1.0.0-beta.0","1.0.0-beta.1","1.0.0-beta.2","1.0.0-beta.3","1.0.0-beta.4","1.0.0-beta.5","1.0.0-beta.6","1.0.0","1.0.1","1.0.2","1.0.3","1.0.4","1.1.0","1.1.1","1.1.2","1.1.3","1.2.0","1.2.1","1.2.2","1.3.0","1.3.1","1.4.0","1.5.0","1.5.1","1.5.2","1.5.3","1.6.0","1.6.1","2.0.0-beta.1","2.0.0-beta.2","2.0.0-beta.3","2.0.0-beta.5","2.0.0-beta.6","2.0.0-beta.7","2.0.0-beta.8","2.0.0-beta.9","2.0.0-beta.10","2.0.0-beta.11","2.0.0-beta.12","2.0.0-beta.13","2.0.0","2.0.1","2.0.2","2.0.3","2.0.4","2.0.5","2.1.0-beta.1","2.1.0-beta.2","2.1.0-beta.3","2.1.0-beta.4","2.1.0-beta.5","2.1.0-beta.6","2.1.0-beta.7","2.1.0","2.1.1","2.1.2","2.1.3","2.1.4","2.1.5","2.1.6","2.1.7","2.1.8","2.1.9","2.2.0-beta.1","2.2.0-beta.2","3.0.0-beta.1","3.0.0-beta.2","3.0.0-beta.3","3.0.0-beta.4","3.0.0","3.0.1","3.0.2","3.0.3","3.0.4","3.0.5","3.0.6","3.0.7","3.0.8","3.0.9","3.1.0-beta.1","3.1.0-beta.2","3.1.0","3.1.1","3.1.2","3.1.3","3.1.4","3.2.0-beta.1","3.2.0-beta.2","3.2.0-beta.3","3.2.0","3.2.1","3.2.2","3.2.3","3.2.4","4.0.0-beta.1","4.0.0-beta.2","4.0.0-beta.3","4.0.0-beta.4","4.0.0-beta.5","4.0.0-beta.6","4.0.0-beta.7","4.0.0-beta.8","4.0.0-beta.9","4.0.0-beta.10","4.0.0-beta.11","4.0.0-beta.12","4.0.0-beta.13","4.0.0-beta.15","4.0.0-beta.16","4.0.0-beta.17","4.0.0-beta.18","4.0.0-beta.19","4.0.0","4.0.1","4.0.2","4.0.3","4.0.4","4.0.5","4.0.6","4.0.7","4.0.8","4.0.9","4.0.10","4.0.11","4.0.12","4.0.13","4.0.14","4.0.15"],"vulnerableVersions":["0.0.119","0.0.120","0.0.121","0.0.122","0.31.0","0.31.1","0.31.2","0.31.3","0.31.4","0.32.0","0.32.1","0.32.2","0.32.3","0.32.4","0.33.0","0.34.0","0.34.1","0.34.2","0.34.3","0.34.4","0.34.5","0.34.6","0.34.7","1.0.0-beta.0","1.0.0-beta.1","1.0.0-beta.2","1.0.0-beta.3","1.0.0-beta.4","1.0.0-beta.5","1.0.0-beta.6","1.0.0","1.0.1","1.0.2","1.0.3","1.0.4","1.1.0","1.1.1","1.1.2","1.1.3","1.2.0","1.2.1","1.2.2","1.3.0","1.3.1","1.4.0","1.5.0","1.5.1","1.5.2","1.5.3","1.6.0","1.6.1","2.0.0-beta.1","2.0.0-beta.2","2.0.0-beta.3","2.0.0-beta.5","2.0.0-beta.6","2.0.0-beta.7","2.0.0-beta.8","2.0.0-beta.9","2.0.0-beta.10","2.0.0-beta.11","2.0.0-beta.12","2.0.0-beta.13","2.0.0","2.0.1","2.0.2","2.0.3","2.0.4","2.0.5","2.1.0-beta.1","2.1.0-beta.2","2.1.0-beta.3","2.1.0-beta.4","2.1.0-beta.5","2.1.0-beta.6","2.1.0-beta.7","2.1.0","2.1.1","2.1.2","2.1.3","2.1.4","2.1.5","2.1.6","2.1.7","2.1.8","2.1.9","2.2.0-beta.1","2.2.0-beta.2"],"cwe":["CWE-346"],"cvss":{"score":5.3,"vectorString":"CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:N/A:N"},"range":"<=0.0.122 || 0.31.0 - 2.2.0-beta.2","id":"Jf346EgaLUMIfps0Iiyt01/MkMDYEflXXoeXUYIe8k0MNuye+LW8u7aFPu9FPsI7LxiqUGdiHEW8m5Owev1tvg=="}

View File

@ -1 +0,0 @@
{"source":"XRC5FYn4BgxTqFRmBvXrbhEb/XwDQF7aS38Di6r7Pv9zY1oGG9mQ2VYohi/Jc8TchbgRdRy0c0xiUZ9w83+tUA==","name":"@vitest/coverage-v8","dependency":"vitest","title":"Depends on vulnerable versions of vitest","url":null,"severity":"moderate","versions":["0.32.0","0.32.1","0.32.2","0.32.3","0.32.4","0.33.0","0.34.0","0.34.1","0.34.2","0.34.3","0.34.4","0.34.5","0.34.6","1.0.0-beta.0","1.0.0-beta.1","1.0.0-beta.2","1.0.0-beta.3","1.0.0-beta.4","1.0.0-beta.5","1.0.0-beta.6","1.0.0","1.0.1","1.0.2","1.0.3","1.0.4","1.1.0","1.1.1","1.1.2","1.1.3","1.2.0","1.2.1","1.2.2","1.3.0","1.3.1","1.4.0","1.5.0","1.5.1","1.5.2","1.5.3","1.6.0","1.6.1","2.0.0-beta.1","2.0.0-beta.2","2.0.0-beta.3","2.0.0-beta.5","2.0.0-beta.6","2.0.0-beta.7","2.0.0-beta.8","2.0.0-beta.9","2.0.0-beta.10","2.0.0-beta.11","2.0.0-beta.12","2.0.0-beta.13","2.0.0","2.0.1","2.0.2","2.0.3","2.0.4","2.0.5","2.1.0-beta.1","2.1.0-beta.2","2.1.0-beta.3","2.1.0-beta.4","2.1.0-beta.5","2.1.0-beta.6","2.1.0-beta.7","2.1.0","2.1.1","2.1.2","2.1.3","2.1.4","2.1.5","2.1.6","2.1.7","2.1.8","2.1.9","2.2.0-beta.1","2.2.0-beta.2","3.0.0-beta.1","3.0.0-beta.2","3.0.0-beta.3","3.0.0-beta.4","3.0.0","3.0.1","3.0.2","3.0.3","3.0.4","3.0.5","3.0.6","3.0.7","3.0.8","3.0.9","3.1.0-beta.1","3.1.0-beta.2","3.1.0","3.1.1","3.1.2","3.1.3","3.1.4","3.2.0-beta.1","3.2.0-beta.2","3.2.0-beta.3","3.2.0","3.2.1","3.2.2","3.2.3","3.2.4","4.0.0-beta.1","4.0.0-beta.2","4.0.0-beta.3","4.0.0-beta.4","4.0.0-beta.5","4.0.0-beta.6","4.0.0-beta.7","4.0.0-beta.8","4.0.0-beta.9","4.0.0-beta.10","4.0.0-beta.11","4.0.0-beta.12","4.0.0-beta.13","4.0.0-beta.15","4.0.0-beta.16","4.0.0-beta.17","4.0.0-beta.18","4.0.0-beta.19","4.0.0","4.0.1","4.0.2","4.0.3","4.0.4","4.0.5","4.0.6","4.0.7","4.0.8","4.0.9","4.0.10","4.0.11","4.0.12","4.0.13","4.0.14","4.0.15"],"vulnerableVersions":["0.32.0","0.32.1","0.32.2","0.32.3","0.32.4","0.33.0","0.34.0","0.34.1","0.34.2","0.34.3","0.34.4","0.34.5","0.34.6","1.0.0-beta.0","1.0.0-beta.1","1.0.0-beta.2","1.0.0-beta.3","1.0.0-beta.4","1.0.0-beta.5","1.0.0-beta.6","1.0.0","1.0.1","1.0.2","1.0.3","1.0.4","1.1.0","1.1.1","1.1.2","1.1.3","1.2.0","1.2.1","1.2.2","1.3.0","1.3.1","1.4.0","1.5.0","1.5.1","1.5.2","1.5.3","1.6.0","1.6.1","2.0.0-beta.1","2.0.0-beta.2","2.0.0-beta.3","2.0.0-beta.5","2.0.0-beta.6","2.0.0-beta.7","2.0.0-beta.8","2.0.0-beta.9","2.0.0-beta.10","2.0.0-beta.11","2.0.0-beta.12","2.0.0-beta.13","2.0.0","2.0.1","2.0.2","2.0.3","2.0.4","2.0.5","2.1.0-beta.1","2.1.0-beta.2","2.1.0-beta.3","2.1.0-beta.4","2.1.0-beta.5","2.1.0-beta.6","2.1.0-beta.7","2.1.0","2.1.1","2.1.2","2.1.3","2.1.4","2.1.5","2.1.6","2.1.7","2.1.8","2.1.9","2.2.0-beta.1","2.2.0-beta.2"],"cwe":["CWE-346"],"cvss":{"score":5.3,"vectorString":"CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:N/A:N"},"range":"<=2.2.0-beta.2","id":"8w+D6EgR9fC9fwYIQ5/ztU9fStSsiqzhMfsCGt9lhWi+PYQh74d1bO5hc5jsgsMwHJULRmw+J1H+qZOG8c5J0Q=="}

View File

@ -1,2 +0,0 @@
2e12a9b844aef75f193f3ea8822eee13774ea567 {"key":"security-advisory:vite-node:qYQfE1mMxIUuwRggKZ3LbYT3bx3mXjMCa+BErBSpF5ui1NkOZf8s+ygWxS4DHMFgC2TLwtHm6g4avxKZe91a0g==","integrity":"sha512-nxdT8QydAqgMng/xbZpOTCRysrlmcx+v96My/WW4ahEYsoeB3FvZ7jdxeXRAnwUH/M8foahgJqmtb19znCjcDg==","time":1765766031210,"size":6009}

View File

@ -1,2 +0,0 @@
1a72432cee955b10236d41af5ab95e104045b7fa {"key":"make-fetch-happen:request-cache:https://registry.npmjs.org/@vitest%2fmocker","integrity":"sha512-a5S7B//4P1CHJIxlBcby50eqmu9TpRI5wjBeFEeZDDvCGJjOLSiVjD/oMA3hal7XLRqTla5XBI6dXCouFNFwZg==","time":1765766030950,"size":87422,"metadata":{"time":1765766030905,"url":"https://registry.npmjs.org/@vitest%2fmocker","reqHeaders":{"accept":"application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*"},"resHeaders":{"cache-control":"public, max-age=300","content-encoding":"gzip","content-type":"application/vnd.npm.install-v1+json","date":"Mon, 15 Dec 2025 02:33:51 GMT","etag":"W/\"7df105404e25b46a75ea949538d59f9a\"","last-modified":"Tue, 02 Dec 2025 15:52:20 GMT","vary":"accept-encoding, accept"},"options":{"compress":true}}}

View File

@ -1,2 +0,0 @@
3672bc1447385ab62995f47b4a0badb49679ccf6 {"key":"make-fetch-happen:request-cache:https://registry.npmjs.org/vitest","integrity":"sha512-f5YcdsQviENFPRNlF8LkdnO7ACI+Oq3eXwwQAb6v2OSNjCT+S6p0FhGAI7q3hZGrj49GJlRy33A+Jk01k2cjSw==","time":1765766031086,"size":1180529,"metadata":{"time":1765766030861,"url":"https://registry.npmjs.org/vitest","reqHeaders":{"accept":"application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*"},"resHeaders":{"cache-control":"public, max-age=300","content-encoding":"gzip","content-type":"application/vnd.npm.install-v1+json","date":"Mon, 15 Dec 2025 02:33:51 GMT","etag":"W/\"4dc2e5ea516804f198067da951ab43d8\"","last-modified":"Tue, 02 Dec 2025 15:52:43 GMT","vary":"accept-encoding, accept"},"options":{"compress":true}}}

View File

@ -1,2 +0,0 @@
47f70fd675b2f69c0d6a85eb9369c7da878afd9b {"key":"security-advisory:esbuild:jKdCIzePj7J1488qgRXvF8Srh9wutSuR1exB8YooNX62hT+qhtrUXYbArLNoIhgwbaCqKpmduh18syZU7BR9SA==","integrity":"sha512-zdpBkCaGUhdHZVdnjMCKbBbbjWTLNzlSIEnXVtd0ELv9GCWQX5tkGUiZmAS/jF/JKKlamLpTxwDaQ3oOCj5ysw==","time":1765766030357,"size":8960}

View File

@ -1,2 +0,0 @@
2332762012e041091533c9aed83b4f2d787a3215 {"key":"security-advisory:@vitest/ui:Jf346EgaLUMIfps0Iiyt01/MkMDYEflXXoeXUYIe8k0MNuye+LW8u7aFPu9FPsI7LxiqUGdiHEW8m5Owev1tvg==","integrity":"sha512-u6J/+HU60BfxuF/HlokFtjMjmSfbE83BEh+/a6xcrfgMokM/wNSMc7NLWdZQ+pdbVAjSsub1mSwq6QP72c4ohQ==","time":1765766032096,"size":4661}

View File

@ -1,2 +0,0 @@
626281a27b99bfcdad4afc2c96b3f9248417eb55 {"key":"make-fetch-happen:request-cache:https://registry.npmjs.org/vite-node","integrity":"sha512-iZAhK2AcQq6fr04N+T66mYmujvab61DUgYu/85GG/CE2IkydDLkpndn23fHqGwb00AlB3z22D4GlyRbvAh4lcA==","time":1765766030946,"size":451021,"metadata":{"time":1765766030859,"url":"https://registry.npmjs.org/vite-node","reqHeaders":{"accept":"application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*"},"resHeaders":{"cache-control":"public, max-age=300","content-encoding":"gzip","content-type":"application/vnd.npm.install-v1+json","date":"Mon, 15 Dec 2025 02:33:51 GMT","etag":"W/\"d350de18ef91ca8751e353690ea27a62\"","last-modified":"Tue, 18 Nov 2025 04:12:58 GMT","vary":"accept-encoding, accept"},"options":{"compress":true}}}

View File

@ -1,2 +0,0 @@
f35dbeb40f044e172b1ca4d897d2e500dcbd0432 {"key":"make-fetch-happen:request-cache:https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.53.3.tgz","integrity":"sha512-3EhFi1FU6YL8HTUJZ51imGJWEX//ajQPfqWLI3BQq4TlvHy4X0MOr5q3D2Zof/ka0d5FNdPwZXm3Yyib/UEd+w==","time":1765766030434,"size":948163,"metadata":{"time":1765766029992,"url":"https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.53.3.tgz","reqHeaders":{},"resHeaders":{"cache-control":"public, must-revalidate, max-age=31557600","content-type":"application/octet-stream","date":"Mon, 15 Dec 2025 02:33:50 GMT","etag":"\"c66ffcc20a57dbe1a43de0a27ac067f2\"","last-modified":"Wed, 19 Nov 2025 06:33:17 GMT","vary":"Accept-Encoding"},"options":{"compress":true}}}

View File

@ -1,2 +0,0 @@
432aec095fe104de014305fb7a5d87bf0917deed {"key":"make-fetch-happen:request-cache:https://registry.npmjs.org/@vitest%2fui","integrity":"sha512-zNKW5+TGaQxQ4Qm2G0FtndnJYVzke9uChFG6kqJxO2NCU63z5tD5Pi9Zfi2W6Dt6IHmbEsAugrYdFzWm+dte1A==","time":1765766032014,"size":652263,"metadata":{"time":1765766031824,"url":"https://registry.npmjs.org/@vitest%2fui","reqHeaders":{"accept":"application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*"},"resHeaders":{"cache-control":"public, max-age=300","content-encoding":"gzip","content-type":"application/vnd.npm.install-v1+json","date":"Mon, 15 Dec 2025 02:33:52 GMT","etag":"W/\"9a5d3c02c0b4b761bc124bb69eaacb12\"","last-modified":"Tue, 02 Dec 2025 15:53:02 GMT","vary":"accept-encoding, accept"},"options":{"compress":true}}}

View File

@ -1,2 +0,0 @@
ede0d0eeb8dd9c78464015afe9acdfd52f031cab {"key":"make-fetch-happen:request-cache:https://registry.npmjs.org/esbuild","integrity":"sha512-zk9502gz9ZrR1BFDoLm0FyP7QNGYC/7VAGZEEjxPNbC1hVy2MhqCBFn/pkgBzWqOZKLcvZVRQ7aigxDiun0Z3w==","time":1765766030220,"size":876133,"metadata":{"time":1765766030005,"url":"https://registry.npmjs.org/esbuild","reqHeaders":{"accept":"application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*"},"resHeaders":{"cache-control":"public, max-age=300","content-encoding":"gzip","content-type":"application/vnd.npm.install-v1+json","date":"Mon, 15 Dec 2025 02:33:50 GMT","etag":"W/\"bf0daeeda89637bf815b29850db7c1fe\"","last-modified":"Wed, 03 Dec 2025 20:25:14 GMT","vary":"accept-encoding, accept"},"options":{"compress":true}}}

View File

@ -1,2 +0,0 @@
5d3b61a36ec4e845838e09602bf39d1ee38fbe3c {"key":"security-advisory:vitest:XRC5FYn4BgxTqFRmBvXrbhEb/XwDQF7aS38Di6r7Pv9zY1oGG9mQ2VYohi/Jc8TchbgRdRy0c0xiUZ9w83+tUA==","integrity":"sha512-ld+a/MCAvt1L06nn35BcemBZyQE7JstqQ8uTYe4ITA4mv5vrV+L3SmPEfIGrB0AwQgKA33s2Fm9jgLY02cAlNA==","time":1765766031428,"size":7669}

View File

@ -1,2 +0,0 @@
d189339d6a231a8b5234ac4089080d7dc7c21519 {"key":"security-advisory:vitest:BSMf7BHi5iZnvIquFfRkjWP6a8w6U34XKSRTgPQahAegm6GPZJH2KxXV9Lykl5yaU1n6yOYaeIOzMIn67rnZBA==","integrity":"sha512-ucm3IO1FNmtJ/kyjkwNIbelDZs+ReTPlKrAuXmB1f4CNxhLEGaJ5sT9Lbhj/5WZNAyQTV1AoqIcvozuN6FF/uQ==","time":1765766031642,"size":4966}

View File

@ -1,2 +0,0 @@
d4301f14b31721928ac72fb22e62413069c937f3 {"key":"make-fetch-happen:request-cache:https://registry.npmjs.org/@vitest%2fcoverage-v8","integrity":"sha512-kU7xr5YxXmaA8+h6LFoIWXwh9SbSluL+3GecXjmh13xZ9B6g1oNiQ6STDyWwvRDf4FpOEKeGLnSyOiCo082VOA==","time":1765766031857,"size":201709,"metadata":{"time":1765766031802,"url":"https://registry.npmjs.org/@vitest%2fcoverage-v8","reqHeaders":{"accept":"application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*"},"resHeaders":{"cache-control":"public, max-age=300","content-encoding":"gzip","content-type":"application/vnd.npm.install-v1+json","date":"Mon, 15 Dec 2025 02:33:52 GMT","etag":"W/\"6793f4301477626363f1ef2bc31276ad\"","last-modified":"Tue, 02 Dec 2025 15:52:58 GMT","vary":"accept-encoding, accept"},"options":{"compress":true}}}

View File

@ -1,2 +0,0 @@
427bbadc8c936fd9fbe914939e2513ef725ccfa3 {"key":"security-advisory:vitest:/pX+ULPoj9dEnRcNW69EXnv2mQCWcvTXV+PKVdUpqTO30rpIrWPLiQ08km9aOcIK0/KGaALKzFSV/S2lNDmaxg==","integrity":"sha512-Kh8fcVKrEx054bW7rniMm32181EtKAzAlj/2FWXCm4JmuUSDkozzLrtfxrZImXWPg4ITm87Kr1UMzRrB3/DE6w==","time":1765766031561,"size":5996}

View File

@ -1,2 +0,0 @@
98b2d5afec7abf1a83609237552cd95cfeace6af {"key":"make-fetch-happen:request-cache:https://registry.npmjs.org/vite","integrity":"sha512-RlrpATiAfKMJTK7Geu4iv6GjqsgcfXiaO9jPkpYhjiIVenFSTmRW6shMb79KPJpuxJZ7uT6q5/MX9e3IgUJSpQ==","time":1765766030573,"size":2142322,"metadata":{"time":1765766030429,"url":"https://registry.npmjs.org/vite","reqHeaders":{"accept":"application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*"},"resHeaders":{"cache-control":"public, max-age=300","content-encoding":"gzip","content-type":"application/vnd.npm.install-v1+json","date":"Mon, 15 Dec 2025 02:33:50 GMT","etag":"W/\"69222b9fe8dd5a978b903508b4c87155\"","last-modified":"Fri, 12 Dec 2025 02:39:05 GMT","vary":"accept-encoding, accept"},"options":{"compress":true}}}

View File

@ -1,2 +0,0 @@
93632c14fa7edbc4f90d697b47caed2669e4f415 {"key":"make-fetch-happen:request-cache:https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz","integrity":"sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==","time":1765766031087,"size":4129742,"metadata":{"time":1765766029973,"url":"https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz","reqHeaders":{},"resHeaders":{"cache-control":"public, must-revalidate, max-age=31557600","content-type":"application/octet-stream","date":"Mon, 15 Dec 2025 02:33:50 GMT","etag":"\"a81560e260b8093916a4e5f0e719af65\"","last-modified":"Sun, 09 Jun 2024 21:17:16 GMT","vary":"Accept-Encoding"},"options":{"compress":true}}}

View File

@ -1,2 +0,0 @@
4c93dcd01c1f55edf353b5a8c283f2fccd18d4d9 {"key":"security-advisory:@vitest/coverage-v8:8w+D6EgR9fC9fwYIQ5/ztU9fStSsiqzhMfsCGt9lhWi+PYQh74d1bO5hc5jsgsMwHJULRmw+J1H+qZOG8c5J0Q==","integrity":"sha512-00fh/GKzTm96OjkSfWpwyLY6TJBjqgzvPI3NSJdxCiAR+yNXx+rMR6zgy/kNe9FGdFi1hho30D2BN/zWPIWp6g==","time":1765766032024,"size":2876}

View File

@ -1,2 +0,0 @@
42180b6796906671888f2daf75d6715255cbfcc0 {"key":"make-fetch-happen:request-cache:https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.53.3.tgz","integrity":"sha512-eoROhjcc6HbZCJr+tvVT8X4fW3/5g/WkGvvmwz/88sDtSJzO7r/blvoBDgISDiCjDRZmHpwud7h+6Q9JxFwq1Q==","time":1765766030436,"size":954224,"metadata":{"time":1765766030024,"url":"https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.53.3.tgz","reqHeaders":{},"resHeaders":{"cache-control":"public, must-revalidate, max-age=31557600","content-type":"application/octet-stream","date":"Mon, 15 Dec 2025 02:33:50 GMT","etag":"\"a2011fdf9e385023746daa23f40153a7\"","last-modified":"Wed, 19 Nov 2025 06:33:21 GMT","vary":"Accept-Encoding"},"options":{"compress":true}}}

View File

@ -1,2 +0,0 @@
5841bbbc4112e649bb0be28e17edb937d9050434 {"key":"security-advisory:vite:tMBsdAS7JBTyRORp0YaJR984WAAsOxgmReSLBN0Nd41GhzEakjROICqAJ31iOdYG5Ijo/MlJ01p3ig1iN88+Tw==","integrity":"sha512-jFpi79Tu3C3tuIzBbesR1hKq25UaEE33lOPKarwVD/uynMIgovv2y2ku3lQzj4tWJRCqlMIthX/3uZA7imtN8A==","time":1765766030791,"size":15571}

View File

@ -1,2 +0,0 @@
53fa5ae0a6ee63e208e75352f54bcea6b342d96a {"key":"security-advisory:@vitest/mocker:SJ6ALG5CByItLFxBhtpyrxAdDoKdsJCSnzbVFPNK6WdVHJq3/BQr5X33nTvglq430Jo7eFZBpLt727pFLHxHzA==","integrity":"sha512-qzxZ1rQ1tV5WsIR+MdhY/4Mgw4T8YEECHwEAXk4WVTOQsKt6Py+JJoQzRfoEyWvZZ2jkIGjl3CsJ0Wi4I9VSWg==","time":1765766031212,"size":1519}

View File

@ -1,2 +0,0 @@
1d7006c87afb3418178d1e1eb7163a58fbc5e7c8 {"key":"security-advisory:vitest:B2iyJpQbKqq262urQixaYzRevOIazSKgo7gmc56QnnJ5+jtweKinFTx59GfPkNHv+WUcYBtgMVPbBDE5hghSXA==","integrity":"sha512-LH8mubJiYTVx3aZSuBf+3jNtZpQ2bsbKkbZgJn1diR4BbvIy2/vTrC3njCqJbbv5BkeqdTNhhVNuXNxRAqfN7g==","time":1765766032263,"size":5436}

View File

@ -0,0 +1,119 @@
"""Add Docker management tables
Revision ID: 0011
Revises: 0010
Create Date: 2025-01-15
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision: str = '0011_add_docker_management_tables'
down_revision: Union[str, None] = '0010_remove_logs_foreign_keys'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
# Add Docker-related columns to hosts table
op.add_column('hosts', sa.Column('docker_enabled', sa.Boolean(), nullable=False, server_default=sa.text('0')))
op.add_column('hosts', sa.Column('docker_version', sa.String(50), nullable=True))
op.add_column('hosts', sa.Column('docker_status', sa.String(20), nullable=True))
op.add_column('hosts', sa.Column('docker_last_collect_at', sa.DateTime(timezone=True), nullable=True))
# Create docker_containers table
op.create_table(
'docker_containers',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('host_id', sa.String(), nullable=False),
sa.Column('container_id', sa.String(64), nullable=False),
sa.Column('name', sa.String(255), nullable=False),
sa.Column('image', sa.String(255), nullable=True),
sa.Column('state', sa.String(20), nullable=False, server_default='unknown'),
sa.Column('status', sa.String(255), nullable=True),
sa.Column('health', sa.String(20), nullable=True),
sa.Column('created_at', sa.DateTime(timezone=True), nullable=True),
sa.Column('ports', sa.JSON(), nullable=True),
sa.Column('labels', sa.JSON(), nullable=True),
sa.Column('compose_project', sa.String(255), nullable=True),
sa.Column('last_update_at', sa.DateTime(timezone=True), nullable=False, server_default=sa.func.now()),
sa.ForeignKeyConstraint(['host_id'], ['hosts.id'], ondelete='CASCADE'),
sa.PrimaryKeyConstraint('id')
)
op.create_index('ix_docker_containers_host_id', 'docker_containers', ['host_id'])
op.create_index('ix_docker_containers_container_id', 'docker_containers', ['container_id'])
# Create docker_images table
op.create_table(
'docker_images',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('host_id', sa.String(), nullable=False),
sa.Column('image_id', sa.String(64), nullable=False),
sa.Column('repo_tags', sa.JSON(), nullable=True),
sa.Column('size', sa.BigInteger(), nullable=True),
sa.Column('created', sa.DateTime(timezone=True), nullable=True),
sa.Column('last_update_at', sa.DateTime(timezone=True), nullable=False, server_default=sa.func.now()),
sa.ForeignKeyConstraint(['host_id'], ['hosts.id'], ondelete='CASCADE'),
sa.PrimaryKeyConstraint('id')
)
op.create_index('ix_docker_images_host_id', 'docker_images', ['host_id'])
# Create docker_volumes table
op.create_table(
'docker_volumes',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('host_id', sa.String(), nullable=False),
sa.Column('name', sa.String(255), nullable=False),
sa.Column('driver', sa.String(50), nullable=True),
sa.Column('mountpoint', sa.Text(), nullable=True),
sa.Column('scope', sa.String(20), nullable=True),
sa.Column('last_update_at', sa.DateTime(timezone=True), nullable=False, server_default=sa.func.now()),
sa.ForeignKeyConstraint(['host_id'], ['hosts.id'], ondelete='CASCADE'),
sa.PrimaryKeyConstraint('id')
)
op.create_index('ix_docker_volumes_host_id', 'docker_volumes', ['host_id'])
# Create docker_alerts table
op.create_table(
'docker_alerts',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('host_id', sa.String(), nullable=False),
sa.Column('container_name', sa.String(255), nullable=False),
sa.Column('severity', sa.String(20), nullable=False, server_default='warning'),
sa.Column('state', sa.String(20), nullable=False, server_default='open'),
sa.Column('message', sa.Text(), nullable=True),
sa.Column('opened_at', sa.DateTime(timezone=True), nullable=False, server_default=sa.func.now()),
sa.Column('closed_at', sa.DateTime(timezone=True), nullable=True),
sa.Column('acknowledged_at', sa.DateTime(timezone=True), nullable=True),
sa.Column('acknowledged_by', sa.String(100), nullable=True),
sa.Column('last_notified_at', sa.DateTime(timezone=True), nullable=True),
sa.ForeignKeyConstraint(['host_id'], ['hosts.id'], ondelete='CASCADE'),
sa.PrimaryKeyConstraint('id')
)
op.create_index('idx_docker_alerts_state_host', 'docker_alerts', ['state', 'host_id'])
def downgrade() -> None:
# Drop Docker tables
op.drop_index('idx_docker_alerts_state_host', 'docker_alerts')
op.drop_table('docker_alerts')
op.drop_index('ix_docker_volumes_host_id', 'docker_volumes')
op.drop_table('docker_volumes')
op.drop_index('ix_docker_images_host_id', 'docker_images')
op.drop_table('docker_images')
op.drop_index('ix_docker_containers_container_id', 'docker_containers')
op.drop_index('ix_docker_containers_host_id', 'docker_containers')
op.drop_table('docker_containers')
# Remove Docker columns from hosts
op.drop_column('hosts', 'docker_last_collect_at')
op.drop_column('hosts', 'docker_status')
op.drop_column('hosts', 'docker_version')
op.drop_column('hosts', 'docker_enabled')

View File

@ -0,0 +1,80 @@
"""Add unique constraints to Docker tables.
Revision ID: 0012
Revises: 0011
Create Date: 2025-12-15
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision: str = '0012'
down_revision: Union[str, None] = '0011_add_docker_management_tables'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
"""Add unique constraints to Docker tables to prevent duplicates."""
# First, clean up any existing duplicates before adding constraints
# For docker_containers: keep only the most recent entry per (host_id, container_id)
op.execute("""
DELETE FROM docker_containers
WHERE id NOT IN (
SELECT MAX(id) FROM docker_containers
GROUP BY host_id, container_id
)
""")
# For docker_images: keep only the most recent entry per (host_id, image_id)
op.execute("""
DELETE FROM docker_images
WHERE id NOT IN (
SELECT MAX(id) FROM docker_images
GROUP BY host_id, image_id
)
""")
# For docker_volumes: keep only the most recent entry per (host_id, name)
op.execute("""
DELETE FROM docker_volumes
WHERE id NOT IN (
SELECT MAX(id) FROM docker_volumes
GROUP BY host_id, name
)
""")
# Now add unique constraints
# Note: SQLite doesn't support adding constraints directly, so we use CREATE UNIQUE INDEX
op.create_index(
'uq_docker_containers_host_container',
'docker_containers',
['host_id', 'container_id'],
unique=True
)
op.create_index(
'uq_docker_images_host_image',
'docker_images',
['host_id', 'image_id'],
unique=True
)
op.create_index(
'uq_docker_volumes_host_name',
'docker_volumes',
['host_id', 'name'],
unique=True
)
def downgrade() -> None:
"""Remove unique constraints from Docker tables."""
op.drop_index('uq_docker_containers_host_container', table_name='docker_containers')
op.drop_index('uq_docker_images_host_image', table_name='docker_images')
op.drop_index('uq_docker_volumes_host_name', table_name='docker_volumes')

View File

@ -25,9 +25,21 @@ all:
hosts: {} hosts: {}
env_test2: env_test2:
hosts: {} hosts: {}
local_test:
hosts:
localhost:
ansible_connection: local
ansible_python_interpreter: '{{ ansible_playbook_python }}'
role_docker: role_docker:
hosts: hosts:
automate.prod.home: null
dev.lab.home: null dev.lab.home: null
dev.prod.home: null
jump.point.home: null
media.labb.home: null
orangepi.pc.home: null
raspi.4gb.home: null
raspi.8gb.home: null
role_lab_servers: role_lab_servers:
hosts: hosts:
dev.lab.home: null dev.lab.home: null
@ -58,8 +70,3 @@ all:
ali2v.truenas.home: ali2v.truenas.home:
ansible_python_interpreter: /usr/bin/python3 ansible_python_interpreter: /usr/bin/python3
hp.truenas.home: null hp.truenas.home: null
local_test:
hosts:
localhost:
ansible_connection: local
ansible_python_interpreter: '{{ ansible_playbook_python }}'

165
app/crud/docker_alert.py Normal file
View File

@ -0,0 +1,165 @@
"""CRUD operations for Docker alerts."""
from datetime import datetime
from typing import List, Optional
from sqlalchemy import select, func
from sqlalchemy.ext.asyncio import AsyncSession
from app.models.docker_alert import DockerAlert
class DockerAlertRepository:
"""Repository for Docker alert CRUD operations."""
def __init__(self, session: AsyncSession):
self.session = session
async def get(self, alert_id: int) -> Optional[DockerAlert]:
"""Get an alert by its ID."""
result = await self.session.execute(
select(DockerAlert).where(DockerAlert.id == alert_id)
)
return result.scalar_one_or_none()
async def get_open_alert(self, host_id: str, container_name: str) -> Optional[DockerAlert]:
"""Get an open alert for a specific container."""
result = await self.session.execute(
select(DockerAlert).where(
DockerAlert.host_id == host_id,
DockerAlert.container_name == container_name,
DockerAlert.state == "open"
)
)
return result.scalar_one_or_none()
async def list_alerts(
self,
host_id: Optional[str] = None,
state: Optional[str] = None,
severity: Optional[str] = None,
limit: int = 100,
offset: int = 0
) -> List[DockerAlert]:
"""List alerts with optional filters."""
query = select(DockerAlert)
if host_id:
query = query.where(DockerAlert.host_id == host_id)
if state:
query = query.where(DockerAlert.state == state)
if severity:
query = query.where(DockerAlert.severity == severity)
query = query.order_by(DockerAlert.opened_at.desc()).limit(limit).offset(offset)
result = await self.session.execute(query)
return list(result.scalars().all())
async def count_alerts(
self,
host_id: Optional[str] = None,
state: Optional[str] = None
) -> dict:
"""Count alerts by state."""
base_query = select(DockerAlert)
if host_id:
base_query = base_query.where(DockerAlert.host_id == host_id)
# Count open
open_query = select(func.count(DockerAlert.id)).where(DockerAlert.state == "open")
if host_id:
open_query = open_query.where(DockerAlert.host_id == host_id)
# Count acknowledged
ack_query = select(func.count(DockerAlert.id)).where(DockerAlert.state == "acknowledged")
if host_id:
ack_query = ack_query.where(DockerAlert.host_id == host_id)
# Count total
total_query = select(func.count(DockerAlert.id))
if host_id:
total_query = total_query.where(DockerAlert.host_id == host_id)
open_result = await self.session.execute(open_query)
ack_result = await self.session.execute(ack_query)
total_result = await self.session.execute(total_query)
return {
"total": total_result.scalar() or 0,
"open": open_result.scalar() or 0,
"acknowledged": ack_result.scalar() or 0
}
async def count_open_by_host(self, host_id: str) -> int:
"""Count open alerts for a host."""
result = await self.session.execute(
select(func.count(DockerAlert.id)).where(
DockerAlert.host_id == host_id,
DockerAlert.state == "open"
)
)
return result.scalar() or 0
async def create(
self,
host_id: str,
container_name: str,
severity: str = "warning",
message: Optional[str] = None
) -> DockerAlert:
"""Create a new alert."""
alert = DockerAlert(
host_id=host_id,
container_name=container_name,
severity=severity,
state="open",
message=message,
opened_at=datetime.utcnow()
)
self.session.add(alert)
return alert
async def acknowledge(
self,
alert_id: int,
acknowledged_by: str
) -> Optional[DockerAlert]:
"""Acknowledge an alert."""
alert = await self.get(alert_id)
if alert and alert.state == "open":
alert.state = "acknowledged"
alert.acknowledged_at = datetime.utcnow()
alert.acknowledged_by = acknowledged_by
return alert
return None
async def close(self, alert_id: int) -> Optional[DockerAlert]:
"""Close an alert."""
alert = await self.get(alert_id)
if alert and alert.state in ("open", "acknowledged"):
alert.state = "closed"
alert.closed_at = datetime.utcnow()
return alert
return None
async def close_for_container(self, host_id: str, container_name: str) -> int:
"""Close all open alerts for a container."""
result = await self.session.execute(
select(DockerAlert).where(
DockerAlert.host_id == host_id,
DockerAlert.container_name == container_name,
DockerAlert.state.in_(["open", "acknowledged"])
)
)
alerts = result.scalars().all()
count = 0
for alert in alerts:
alert.state = "closed"
alert.closed_at = datetime.utcnow()
count += 1
return count
async def update_last_notified(self, alert_id: int) -> None:
"""Update the last notified timestamp."""
alert = await self.get(alert_id)
if alert:
alert.last_notified_at = datetime.utcnow()

View File

@ -0,0 +1,140 @@
"""CRUD operations for Docker containers."""
from datetime import datetime
from typing import List, Optional
from sqlalchemy import case, delete, func, select
from sqlalchemy.ext.asyncio import AsyncSession
from app.models.docker_container import DockerContainer
class DockerContainerRepository:
"""Repository for Docker container CRUD operations."""
def __init__(self, session: AsyncSession):
self.session = session
async def get(self, container_db_id: int) -> Optional[DockerContainer]:
"""Get a container by its database ID."""
result = await self.session.execute(
select(DockerContainer).where(DockerContainer.id == container_db_id)
)
return result.scalar_one_or_none()
async def get_by_container_id(self, host_id: str, container_id: str) -> Optional[DockerContainer]:
"""Get a container by host ID and Docker container ID."""
result = await self.session.execute(
select(DockerContainer).where(
DockerContainer.host_id == host_id,
DockerContainer.container_id == container_id
).limit(1)
)
return result.scalars().first()
async def get_by_name(self, host_id: str, name: str) -> Optional[DockerContainer]:
"""Get a container by host ID and container name."""
result = await self.session.execute(
select(DockerContainer).where(
DockerContainer.host_id == host_id,
DockerContainer.name == name
).limit(1)
)
return result.scalars().first()
async def list_by_host(
self,
host_id: str,
state: Optional[str] = None,
compose_project: Optional[str] = None
) -> List[DockerContainer]:
"""List all containers for a host with optional filters."""
query = select(DockerContainer).where(DockerContainer.host_id == host_id)
if state:
query = query.where(DockerContainer.state == state)
if compose_project:
query = query.where(DockerContainer.compose_project == compose_project)
query = query.order_by(DockerContainer.name)
result = await self.session.execute(query)
return list(result.scalars().all())
async def count_by_host(self, host_id: str) -> dict:
"""Count containers by state for a host."""
result = await self.session.execute(
select(
func.count(DockerContainer.id).label('total'),
func.sum(case((DockerContainer.state == 'running', 1), else_=0)).label('running')
).where(DockerContainer.host_id == host_id)
)
row = result.one()
return {
"total": row.total or 0,
"running": row.running or 0
}
async def upsert(
self,
host_id: str,
container_id: str,
name: str,
image: Optional[str] = None,
state: str = "unknown",
status: Optional[str] = None,
health: Optional[str] = None,
created_at: Optional[datetime] = None,
ports: Optional[dict] = None,
labels: Optional[dict] = None,
compose_project: Optional[str] = None
) -> DockerContainer:
"""Create or update a container."""
existing = await self.get_by_container_id(host_id, container_id)
if existing:
existing.name = name
existing.image = image
existing.state = state
existing.status = status
existing.health = health
existing.created_at = created_at
existing.ports = ports
existing.labels = labels
existing.compose_project = compose_project
existing.last_update_at = datetime.utcnow()
return existing
container = DockerContainer(
host_id=host_id,
container_id=container_id,
name=name,
image=image,
state=state,
status=status,
health=health,
created_at=created_at,
ports=ports,
labels=labels,
compose_project=compose_project
)
self.session.add(container)
return container
async def delete_by_host(self, host_id: str) -> int:
"""Delete all containers for a host."""
result = await self.session.execute(
delete(DockerContainer).where(DockerContainer.host_id == host_id)
)
return result.rowcount
async def delete_stale(self, host_id: str, current_container_ids: List[str]) -> int:
"""Delete containers that no longer exist on the host."""
if not current_container_ids:
return await self.delete_by_host(host_id)
result = await self.session.execute(
delete(DockerContainer).where(
DockerContainer.host_id == host_id,
DockerContainer.container_id.notin_(current_container_ids)
)
)
return result.rowcount

103
app/crud/docker_image.py Normal file
View File

@ -0,0 +1,103 @@
"""CRUD operations for Docker images."""
from datetime import datetime
from typing import List, Optional
from sqlalchemy import select, delete, func
from sqlalchemy.ext.asyncio import AsyncSession
from app.models.docker_image import DockerImage
class DockerImageRepository:
"""Repository for Docker image CRUD operations."""
def __init__(self, session: AsyncSession):
self.session = session
async def get(self, image_db_id: int) -> Optional[DockerImage]:
"""Get an image by its database ID."""
result = await self.session.execute(
select(DockerImage).where(DockerImage.id == image_db_id)
)
return result.scalar_one_or_none()
async def get_by_image_id(self, host_id: str, image_id: str) -> Optional[DockerImage]:
"""Get an image by host ID and Docker image ID."""
result = await self.session.execute(
select(DockerImage).where(
DockerImage.host_id == host_id,
DockerImage.image_id == image_id
).limit(1)
)
return result.scalars().first()
async def list_by_host(self, host_id: str) -> List[DockerImage]:
"""List all images for a host."""
result = await self.session.execute(
select(DockerImage)
.where(DockerImage.host_id == host_id)
.order_by(DockerImage.last_update_at.desc())
)
return list(result.scalars().all())
async def count_by_host(self, host_id: str) -> dict:
"""Count images and total size for a host."""
result = await self.session.execute(
select(
func.count(DockerImage.id).label('total'),
func.coalesce(func.sum(DockerImage.size), 0).label('total_size')
).where(DockerImage.host_id == host_id)
)
row = result.one()
return {
"total": row.total or 0,
"total_size": row.total_size or 0
}
async def upsert(
self,
host_id: str,
image_id: str,
repo_tags: Optional[List[str]] = None,
size: Optional[int] = None,
created: Optional[datetime] = None
) -> DockerImage:
"""Create or update an image."""
existing = await self.get_by_image_id(host_id, image_id)
if existing:
existing.repo_tags = repo_tags
existing.size = size
existing.created = created
existing.last_update_at = datetime.utcnow()
return existing
image = DockerImage(
host_id=host_id,
image_id=image_id,
repo_tags=repo_tags,
size=size,
created=created
)
self.session.add(image)
return image
async def delete_by_host(self, host_id: str) -> int:
"""Delete all images for a host."""
result = await self.session.execute(
delete(DockerImage).where(DockerImage.host_id == host_id)
)
return result.rowcount
async def delete_stale(self, host_id: str, current_image_ids: List[str]) -> int:
"""Delete images that no longer exist on the host."""
if not current_image_ids:
return await self.delete_by_host(host_id)
result = await self.session.execute(
delete(DockerImage).where(
DockerImage.host_id == host_id,
DockerImage.image_id.notin_(current_image_ids)
)
)
return result.rowcount

96
app/crud/docker_volume.py Normal file
View File

@ -0,0 +1,96 @@
"""CRUD operations for Docker volumes."""
from datetime import datetime
from typing import List, Optional
from sqlalchemy import select, delete, func
from sqlalchemy.ext.asyncio import AsyncSession
from app.models.docker_volume import DockerVolume
class DockerVolumeRepository:
"""Repository for Docker volume CRUD operations."""
def __init__(self, session: AsyncSession):
self.session = session
async def get(self, volume_db_id: int) -> Optional[DockerVolume]:
"""Get a volume by its database ID."""
result = await self.session.execute(
select(DockerVolume).where(DockerVolume.id == volume_db_id)
)
return result.scalar_one_or_none()
async def get_by_name(self, host_id: str, name: str) -> Optional[DockerVolume]:
"""Get a volume by host ID and volume name."""
result = await self.session.execute(
select(DockerVolume).where(
DockerVolume.host_id == host_id,
DockerVolume.name == name
).limit(1)
)
return result.scalars().first()
async def list_by_host(self, host_id: str) -> List[DockerVolume]:
"""List all volumes for a host."""
result = await self.session.execute(
select(DockerVolume)
.where(DockerVolume.host_id == host_id)
.order_by(DockerVolume.name)
)
return list(result.scalars().all())
async def count_by_host(self, host_id: str) -> int:
"""Count volumes for a host."""
result = await self.session.execute(
select(func.count(DockerVolume.id)).where(DockerVolume.host_id == host_id)
)
return result.scalar() or 0
async def upsert(
self,
host_id: str,
name: str,
driver: Optional[str] = None,
mountpoint: Optional[str] = None,
scope: Optional[str] = None
) -> DockerVolume:
"""Create or update a volume."""
existing = await self.get_by_name(host_id, name)
if existing:
existing.driver = driver
existing.mountpoint = mountpoint
existing.scope = scope
existing.last_update_at = datetime.utcnow()
return existing
volume = DockerVolume(
host_id=host_id,
name=name,
driver=driver,
mountpoint=mountpoint,
scope=scope
)
self.session.add(volume)
return volume
async def delete_by_host(self, host_id: str) -> int:
"""Delete all volumes for a host."""
result = await self.session.execute(
delete(DockerVolume).where(DockerVolume.host_id == host_id)
)
return result.rowcount
async def delete_stale(self, host_id: str, current_volume_names: List[str]) -> int:
"""Delete volumes that no longer exist on the host."""
if not current_volume_names:
return await self.delete_by_host(host_id)
result = await self.session.execute(
delete(DockerVolume).where(
DockerVolume.host_id == host_id,
DockerVolume.name.notin_(current_volume_names)
)
)
return result.rowcount

View File

@ -72,3 +72,13 @@ class HostRepository:
) )
result = await self.session.execute(stmt) result = await self.session.execute(stmt)
return result.rowcount > 0 return result.rowcount > 0
async def list_docker_enabled(self) -> list[Host]:
"""List all hosts with Docker monitoring enabled."""
stmt = (
select(Host)
.where(Host.deleted_at.is_(None), Host.docker_enabled == True)
.order_by(Host.name)
)
result = await self.session.execute(stmt)
return result.scalars().all()

814
app/docker_section.js Normal file
View File

@ -0,0 +1,814 @@
/**
* Docker Section Management
* Handles Docker hosts, containers, images, volumes, and alerts
*/
const dockerSection = {
hosts: [],
currentHostId: null,
_initialized: false,
stats: {
total_hosts: 0,
enabled_hosts: 0,
total_containers: 0,
running_containers: 0,
total_images: 0,
open_alerts: 0
},
async init() {
await this.loadDockerHosts();
await this.loadStats();
this.setupEventListeners();
this.setupWebSocket();
},
async ensureInit() {
if (this._initialized) return;
this._initialized = true;
await this.init();
},
setupEventListeners() {
// Search filter
const searchInput = document.getElementById('docker-search');
if (searchInput) {
searchInput.addEventListener('input', (e) => {
this.filterHosts(e.target.value);
});
}
// Tab switching
document.querySelectorAll('.docker-tab').forEach(tab => {
tab.addEventListener('click', (e) => {
const tabName = e.currentTarget.dataset.tab;
this.switchTab(tabName);
});
});
},
setupWebSocket() {
if (window.dashboard && window.dashboard.ws) {
const originalOnMessage = window.dashboard.ws.onmessage;
window.dashboard.ws.onmessage = (event) => {
if (originalOnMessage) originalOnMessage(event);
try {
const data = JSON.parse(event.data);
this.handleWebSocketMessage(data);
} catch (e) {
console.error('Docker WS parse error:', e);
}
};
}
},
handleWebSocketMessage(data) {
switch (data.type) {
case 'docker_host_updated':
this.updateHostCard(data.host || data.data);
break;
case 'docker_alert_opened':
this.showAlertNotification(data.data);
this.updateAlertsBadge();
break;
case 'docker_alert_closed':
case 'docker_alert_acknowledged':
this.updateAlertsBadge();
break;
}
},
async fetchAPI(endpoint, options = {}) {
const token = localStorage.getItem('accessToken');
const apiKey = localStorage.getItem('apiKey');
const headers = {
'Content-Type': 'application/json',
...options.headers
};
if (token) {
headers['Authorization'] = `Bearer ${token}`;
} else if (apiKey) {
headers['X-API-Key'] = apiKey;
}
const response = await fetch(`${window.location.origin}${endpoint}`, {
...options,
headers
});
if (!response.ok) {
// Handle 401 Unauthorized - redirect to login
if (response.status === 401) {
this.showToast('Session expirée, reconnexion requise', 'error');
if (window.dashboard && typeof window.dashboard.logout === 'function') {
window.dashboard.logout();
}
return null;
}
throw new Error(`API Error: ${response.status}`);
}
return response.json();
},
async loadDockerHosts() {
try {
const response = await this.fetchAPI('/api/docker/hosts');
this.hosts = response.hosts || [];
this.renderHostsGrid();
} catch (error) {
console.error('Error loading Docker hosts:', error);
this.renderError('Erreur lors du chargement des hosts Docker');
}
},
async loadStats() {
try {
const stats = await this.fetchAPI('/api/docker/stats');
this.stats = stats;
this.updateStatsDisplay();
} catch (error) {
console.error('Error loading Docker stats:', error);
}
},
updateStatsDisplay() {
const el = (id, value) => {
const elem = document.getElementById(id);
if (elem) elem.textContent = value;
};
el('docker-stat-hosts', this.stats.enabled_hosts || 0);
el('docker-stat-containers', this.stats.running_containers || 0);
el('docker-stat-images', this.stats.total_images || 0);
el('docker-stat-alerts', this.stats.open_alerts || 0);
// Update alerts badge
const badge = document.getElementById('docker-alerts-badge');
if (badge) {
if (this.stats.open_alerts > 0) {
badge.textContent = this.stats.open_alerts;
badge.classList.remove('hidden');
} else {
badge.classList.add('hidden');
}
}
},
renderHostsGrid() {
const grid = document.getElementById('docker-hosts-grid');
if (!grid) return;
if (this.hosts.length === 0) {
grid.innerHTML = `
<div class="glass-card p-6 text-center col-span-full">
<i class="fab fa-docker text-4xl text-gray-600 mb-4"></i>
<p class="text-gray-400">Aucun host Docker configuré</p>
<p class="text-gray-500 text-sm mt-2">Activez Docker sur un host dans la section Hosts</p>
</div>
`;
return;
}
grid.innerHTML = this.hosts.map(host => this.renderHostCard(host)).join('');
},
renderHostCard(host) {
const statusColor = host.docker_status === 'online' ? 'green' :
host.docker_status === 'offline' ? 'red' : 'yellow';
const statusText = host.docker_status || 'unknown';
const lastCollect = host.docker_last_collect_at
? this.formatRelativeTime(host.docker_last_collect_at)
: 'Jamais';
return `
<div class="glass-card p-4 cursor-pointer hover:border-purple-500/50 transition-all"
data-host-id="${host.host_id}" onclick="dockerSection.viewDetails('${host.host_id}')">
<div class="flex items-center justify-between mb-3">
<h3 class="font-semibold text-lg truncate">${host.host_name}</h3>
<span class="px-2 py-1 rounded-full text-xs font-medium bg-${statusColor}-500/20 text-${statusColor}-400">
${statusText}
</span>
</div>
<div class="text-sm text-gray-400 mb-3">${host.host_ip}</div>
<div class="grid grid-cols-2 gap-2 mb-3 text-sm">
<div class="flex items-center gap-2">
<i class="fas fa-box text-blue-400"></i>
<span>${host.containers_running}/${host.containers_total} containers</span>
</div>
<div class="flex items-center gap-2">
<i class="fas fa-layer-group text-purple-400"></i>
<span>${host.images_total} images</span>
</div>
</div>
${host.open_alerts > 0 ? `
<div class="flex items-center gap-2 text-sm text-red-400 mb-3">
<i class="fas fa-exclamation-triangle"></i>
<span>${host.open_alerts} alerte(s)</span>
</div>
` : ''}
<div class="flex items-center justify-between text-xs text-gray-500">
<span><i class="fas fa-clock mr-1"></i>${lastCollect}</span>
${host.docker_version ? `<span>v${host.docker_version}</span>` : ''}
</div>
<div class="flex gap-2 mt-3 pt-3 border-t border-gray-700">
<button onclick="event.stopPropagation(); dockerSection.collectNow('${host.host_id}')"
class="flex-1 px-3 py-1.5 bg-gray-700 hover:bg-gray-600 rounded text-sm transition-colors">
<i class="fas fa-sync mr-1"></i>Collecter
</button>
<button onclick="event.stopPropagation(); dockerSection.toggleDockerEnabled('${host.host_id}', ${!host.docker_enabled})"
class="px-3 py-1.5 ${host.docker_enabled ? 'bg-red-600/20 text-red-400 hover:bg-red-600/30' : 'bg-green-600/20 text-green-400 hover:bg-green-600/30'} rounded text-sm transition-colors">
<i class="fas fa-${host.docker_enabled ? 'pause' : 'play'}"></i>
</button>
</div>
</div>
`;
},
filterHosts(query) {
const cards = document.querySelectorAll('#docker-hosts-grid > div[data-host-id]');
const lowerQuery = query.toLowerCase();
cards.forEach(card => {
const hostId = card.dataset.hostId;
const host = this.hosts.find(h => h.host_id === hostId);
if (host) {
const matches = host.host_name.toLowerCase().includes(lowerQuery) ||
host.host_ip.toLowerCase().includes(lowerQuery);
card.style.display = matches ? '' : 'none';
}
});
},
async viewDetails(hostId) {
this.currentHostId = hostId;
const host = this.hosts.find(h => h.host_id === hostId);
if (!host) return;
document.getElementById('docker-host-name').innerHTML =
`<i class="fab fa-docker mr-2 text-blue-400"></i>${host.host_name}`;
// Show modal
document.getElementById('docker-detail-modal').classList.remove('hidden');
// Load containers by default
this.switchTab('containers');
await this.loadContainers(hostId);
},
closeModal() {
document.getElementById('docker-detail-modal').classList.add('hidden');
this.currentHostId = null;
},
switchTab(tabName) {
// Update tab buttons
document.querySelectorAll('.docker-tab').forEach(tab => {
tab.classList.toggle('active', tab.dataset.tab === tabName);
tab.classList.toggle('text-gray-400', tab.dataset.tab !== tabName);
});
// Update tab content
document.querySelectorAll('.docker-tab-content').forEach(content => {
content.classList.toggle('hidden', !content.id.endsWith(tabName));
});
// Load content for the tab
if (this.currentHostId) {
switch (tabName) {
case 'containers':
this.loadContainers(this.currentHostId);
break;
case 'images':
this.loadImages(this.currentHostId);
break;
case 'volumes':
this.loadVolumes(this.currentHostId);
break;
case 'host-alerts':
this.loadHostAlerts(this.currentHostId);
break;
}
}
},
async loadContainers(hostId) {
const container = document.getElementById('docker-containers-list');
container.innerHTML = '<div class="loading-spinner mx-auto"></div>';
try {
const response = await this.fetchAPI(`/api/docker/hosts/${hostId}/containers`);
const containers = response.containers || [];
if (containers.length === 0) {
container.innerHTML = '<p class="text-gray-400 text-center py-4">Aucun container</p>';
return;
}
container.innerHTML = containers.map(c => this.renderContainerRow(c, hostId)).join('');
} catch (error) {
container.innerHTML = `<p class="text-red-400 text-center py-4">Erreur: ${error.message}</p>`;
}
},
renderContainerRow(c, hostId) {
const stateColors = {
running: 'green',
exited: 'red',
paused: 'yellow',
created: 'blue',
dead: 'red'
};
const stateColor = stateColors[c.state] || 'gray';
const healthBadge = c.health ? `
<span class="px-2 py-0.5 rounded text-xs bg-${c.health === 'healthy' ? 'green' : 'red'}-500/20 text-${c.health === 'healthy' ? 'green' : 'red'}-400">
${c.health}
</span>
` : '';
// Parse ports and create clickable links
const portLinks = this.parsePortLinks(c.ports, hostId);
return `
<div class="bg-gray-800/50 rounded-lg p-3 flex items-center justify-between gap-4">
<div class="flex-1 min-w-0">
<div class="flex items-center gap-2 flex-wrap">
<span class="w-2 h-2 rounded-full bg-${stateColor}-500"></span>
<span class="font-medium truncate">${c.name}</span>
${c.compose_project ? `<span class="px-2 py-0.5 rounded text-xs bg-purple-500/20 text-purple-400">${c.compose_project}</span>` : ''}
${healthBadge}
${portLinks}
</div>
<div class="text-sm text-gray-400 truncate mt-1">${c.image}</div>
<div class="text-xs text-gray-500 mt-1">${c.status || c.state}</div>
</div>
<div class="flex items-center gap-1">
${c.state !== 'running' ? `
<button onclick="dockerSection.startContainer('${hostId}', '${c.container_id}')"
class="p-2 hover:bg-gray-700 rounded transition-colors text-green-400" title="Démarrer">
<i class="fas fa-play"></i>
</button>
` : `
<button onclick="dockerSection.stopContainer('${hostId}', '${c.container_id}')"
class="p-2 hover:bg-gray-700 rounded transition-colors text-red-400" title="Arrêter">
<i class="fas fa-stop"></i>
</button>
`}
<button onclick="dockerSection.restartContainer('${hostId}', '${c.container_id}')"
class="p-2 hover:bg-gray-700 rounded transition-colors text-yellow-400" title="Redémarrer">
<i class="fas fa-redo"></i>
</button>
<button onclick="dockerSection.showLogs('${hostId}', '${c.container_id}', '${c.name}')"
class="p-2 hover:bg-gray-700 rounded transition-colors text-blue-400" title="Logs">
<i class="fas fa-file-alt"></i>
</button>
<button onclick="dockerSection.showInspect('${hostId}', '${c.container_id}', '${c.name}')"
class="p-2 hover:bg-gray-700 rounded transition-colors text-cyan-400" title="Inspect">
<i class="fas fa-search"></i>
</button>
</div>
</div>
`;
},
parsePortLinks(ports, hostId) {
if (!ports) return '';
// Get host IP for building URLs
const host = this.hosts.find(h => h.host_id === hostId);
const hostIp = host ? host.host_ip : 'localhost';
// Parse ports from the raw string or object
const portStr = ports.raw || (typeof ports === 'string' ? ports : '');
if (!portStr) return '';
// Extract port mappings like "0.0.0.0:8080->80/tcp" or "8080/tcp"
const portRegex = /(?:([\d.]+):)?(\d+)->\d+\/tcp/g;
const links = [];
let match;
while ((match = portRegex.exec(portStr)) !== null) {
const bindIp = match[1] || '0.0.0.0';
const hostPort = match[2];
// Skip if bound to 127.0.0.1 only (not accessible externally)
if (bindIp === '127.0.0.1') continue;
// Determine protocol (https for common secure ports)
const protocol = ['443', '8443', '9443'].includes(hostPort) ? 'https' : 'http';
const url = `${protocol}://${hostIp}:${hostPort}`;
links.push(`
<a href="${url}" target="_blank" rel="noopener noreferrer"
onclick="event.stopPropagation()"
class="px-2 py-0.5 rounded text-xs bg-blue-500/20 text-blue-400 hover:bg-blue-500/30 transition-colors"
title="Ouvrir ${url}">
<i class="fas fa-external-link-alt mr-1"></i>${hostPort}
</a>
`);
}
return links.join('');
},
async loadImages(hostId) {
const container = document.getElementById('docker-images-list');
container.innerHTML = '<div class="loading-spinner mx-auto"></div>';
try {
const response = await this.fetchAPI(`/api/docker/hosts/${hostId}/images`);
if (!response) return; // 401 handled
const images = response.images || [];
if (images.length === 0) {
container.innerHTML = '<p class="text-gray-400 text-center py-4">Aucune image</p>';
return;
}
// Show unused count if any
const unusedInfo = response.unused_count > 0
? `<div class="text-sm text-yellow-400 mb-3"><i class="fas fa-info-circle mr-1"></i>${response.unused_count} image(s) non utilisée(s)</div>`
: '';
container.innerHTML = unusedInfo + images.map(img => {
const unusedBadge = !img.in_use
? `<span class="px-2 py-0.5 rounded text-xs bg-yellow-500/20 text-yellow-400 cursor-help" title="Cette image n'est utilisée par aucun container">Unused</span>`
: '';
return `
<div class="bg-gray-800/50 rounded-lg p-3 flex items-center justify-between gap-4">
<div class="flex-1 min-w-0">
<div class="flex items-center gap-2 flex-wrap">
<span class="font-medium">${img.repo_tags?.[0] || img.image_id.substring(0, 12)}</span>
${unusedBadge}
</div>
<div class="text-sm text-gray-400 mt-1">
<span class="mr-4"><i class="fas fa-hdd mr-1"></i>${this.formatBytes(img.size)}</span>
<span><i class="fas fa-clock mr-1"></i>${this.formatRelativeTime(img.created)}</span>
</div>
</div>
<div class="flex items-center gap-1">
<button onclick="dockerSection.removeImage('${hostId}', '${img.image_id}', ${!img.in_use})"
class="p-2 hover:bg-gray-700 rounded transition-colors ${img.in_use ? 'text-gray-500' : 'text-red-400'}"
title="${img.in_use ? 'Supprimer (forcé car en cours d\'utilisation)' : 'Supprimer l\'image'}">
<i class="fas fa-trash"></i>
</button>
</div>
</div>
`;
}).join('');
} catch (error) {
container.innerHTML = `<p class="text-red-400 text-center py-4">Erreur: ${error.message}</p>`;
}
},
async loadVolumes(hostId) {
const container = document.getElementById('docker-volumes-list');
container.innerHTML = '<div class="loading-spinner mx-auto"></div>';
try {
const response = await this.fetchAPI(`/api/docker/hosts/${hostId}/volumes`);
const volumes = response.volumes || [];
if (volumes.length === 0) {
container.innerHTML = '<p class="text-gray-400 text-center py-4">Aucun volume</p>';
return;
}
container.innerHTML = volumes.map(vol => `
<div class="bg-gray-800/50 rounded-lg p-3">
<div class="font-medium">${vol.name}</div>
<div class="text-sm text-gray-400 mt-1">
<span class="mr-4"><i class="fas fa-cog mr-1"></i>${vol.driver}</span>
<span class="truncate"><i class="fas fa-folder mr-1"></i>${vol.mountpoint}</span>
</div>
</div>
`).join('');
} catch (error) {
container.innerHTML = `<p class="text-red-400 text-center py-4">Erreur: ${error.message}</p>`;
}
},
async loadHostAlerts(hostId) {
const container = document.getElementById('docker-host-alerts-list');
container.innerHTML = '<div class="loading-spinner mx-auto"></div>';
try {
const response = await this.fetchAPI(`/api/docker/alerts?host_id=${hostId}`);
const alerts = response.alerts || [];
if (alerts.length === 0) {
container.innerHTML = '<p class="text-gray-400 text-center py-4">Aucune alerte</p>';
return;
}
container.innerHTML = alerts.map(alert => this.renderAlertRow(alert)).join('');
} catch (error) {
container.innerHTML = `<p class="text-red-400 text-center py-4">Erreur: ${error.message}</p>`;
}
},
renderAlertRow(alert) {
const severityColors = {
warning: 'yellow',
error: 'red',
critical: 'red'
};
const color = severityColors[alert.severity] || 'gray';
return `
<div class="bg-gray-800/50 rounded-lg p-3 border-l-4 border-${color}-500">
<div class="flex items-center justify-between">
<div class="flex items-center gap-2">
<i class="fas fa-exclamation-triangle text-${color}-400"></i>
<span class="font-medium">${alert.container_name}</span>
<span class="px-2 py-0.5 rounded text-xs bg-${color}-500/20 text-${color}-400">${alert.severity}</span>
</div>
${alert.state === 'open' ? `
<button onclick="dockerSection.acknowledgeAlert(${alert.id})"
class="px-2 py-1 text-xs bg-gray-700 hover:bg-gray-600 rounded transition-colors">
Acquitter
</button>
` : `
<span class="text-xs text-gray-500">${alert.state}</span>
`}
</div>
<div class="text-sm text-gray-400 mt-2">${alert.message}</div>
<div class="text-xs text-gray-500 mt-1">${this.formatRelativeTime(alert.opened_at)}</div>
</div>
`;
},
// Container Actions
async startContainer(hostId, containerId) {
await this.executeAction(hostId, containerId, 'start');
},
async stopContainer(hostId, containerId) {
await this.executeAction(hostId, containerId, 'stop');
},
async restartContainer(hostId, containerId) {
await this.executeAction(hostId, containerId, 'restart');
},
async executeAction(hostId, containerId, action) {
try {
const response = await this.fetchAPI(`/api/docker/containers/${hostId}/${containerId}/${action}`, {
method: 'POST'
});
if (response.success) {
this.showToast(`Container ${action} successful`, 'success');
// Refresh containers list
setTimeout(() => this.loadContainers(hostId), 1000);
} else {
this.showToast(`Failed: ${response.error || response.message}`, 'error');
}
} catch (error) {
this.showToast(`Error: ${error.message}`, 'error');
}
},
async showLogs(hostId, containerId, containerName) {
document.getElementById('docker-logs-title').innerHTML =
`<i class="fas fa-file-alt mr-2 text-green-400"></i>${containerName} - Logs`;
document.getElementById('docker-logs-content').textContent = 'Chargement des logs...';
document.getElementById('docker-logs-modal').classList.remove('hidden');
try {
const response = await this.fetchAPI(`/api/docker/containers/${hostId}/${containerId}/logs?tail=500`);
document.getElementById('docker-logs-content').textContent = response.logs || 'Aucun log disponible';
} catch (error) {
document.getElementById('docker-logs-content').textContent = `Erreur: ${error.message}`;
}
},
closeLogsModal() {
document.getElementById('docker-logs-modal').classList.add('hidden');
},
async showInspect(hostId, containerId, containerName) {
document.getElementById('docker-logs-title').innerHTML =
`<i class="fas fa-search mr-2 text-cyan-400"></i>${containerName} - Inspect`;
document.getElementById('docker-logs-content').textContent = 'Chargement des informations...';
document.getElementById('docker-logs-modal').classList.remove('hidden');
try {
const response = await this.fetchAPI(`/api/docker/containers/${hostId}/${containerId}/inspect`);
if (!response) return; // 401 handled
// Format JSON nicely
const inspectData = response.inspect_data || {};
document.getElementById('docker-logs-content').textContent =
JSON.stringify(inspectData, null, 2);
} catch (error) {
document.getElementById('docker-logs-content').textContent = `Erreur: ${error.message}`;
}
},
async removeImage(hostId, imageId, canDeleteDirectly = false) {
const force = !canDeleteDirectly;
const confirmMsg = force
? 'Cette image est utilisée par un ou plusieurs containers. Voulez-vous forcer la suppression ?'
: 'Voulez-vous supprimer cette image ?';
if (!confirm(confirmMsg)) return;
try {
const response = await this.fetchAPI(`/api/docker/images/${hostId}/${imageId}?force=${force}`, {
method: 'DELETE'
});
if (!response) return; // 401 handled
if (response.success) {
this.showToast('Image supprimée avec succès', 'success');
// Refresh images list
await this.loadImages(hostId);
} else {
this.showToast(`Erreur: ${response.error || response.message}`, 'error');
}
} catch (error) {
this.showToast(`Erreur: ${error.message}`, 'error');
}
},
async collectNow(hostId) {
try {
this.showToast('Collection en cours...', 'info');
const response = await this.fetchAPI(`/api/docker/hosts/${hostId}/collect`, {
method: 'POST'
});
if (response.success) {
this.showToast(`Collection terminée: ${response.containers_count} containers`, 'success');
await this.loadDockerHosts();
await this.loadStats();
} else {
this.showToast(`Erreur: ${response.error}`, 'error');
}
} catch (error) {
this.showToast(`Erreur: ${error.message}`, 'error');
}
},
async collectAll() {
try {
this.showToast('Collection de tous les hosts...', 'info');
const response = await this.fetchAPI('/api/docker/collect-all', {
method: 'POST'
});
this.showToast(`Collecte terminée: ${response.successful}/${response.total_hosts} hosts`,
response.failed > 0 ? 'warning' : 'success');
await this.loadDockerHosts();
await this.loadStats();
} catch (error) {
this.showToast(`Erreur: ${error.message}`, 'error');
}
},
async toggleDockerEnabled(hostId, enabled) {
try {
await this.fetchAPI(`/api/docker/hosts/${hostId}/enable`, {
method: 'POST',
body: JSON.stringify({ enabled })
});
this.showToast(`Docker monitoring ${enabled ? 'activé' : 'désactivé'}`, 'success');
await this.loadDockerHosts();
await this.loadStats();
} catch (error) {
this.showToast(`Erreur: ${error.message}`, 'error');
}
},
async acknowledgeAlert(alertId) {
try {
await this.fetchAPI(`/api/docker/alerts/${alertId}/acknowledge`, {
method: 'POST'
});
this.showToast('Alerte acquittée', 'success');
if (this.currentHostId) {
await this.loadHostAlerts(this.currentHostId);
}
await this.loadStats();
} catch (error) {
this.showToast(`Erreur: ${error.message}`, 'error');
}
},
showAlerts() {
// Navigate to alerts tab in modal or show alerts modal
if (this.currentHostId) {
this.switchTab('host-alerts');
}
},
updateHostCard(hostData) {
const card = document.querySelector(`[data-host-id="${hostData.host_id}"]`);
if (card) {
card.outerHTML = this.renderHostCard(hostData);
}
},
async updateAlertsBadge() {
await this.loadStats();
},
showAlertNotification(alert) {
this.showToast(`Alerte Docker: ${alert.container_name} - ${alert.message}`, 'warning');
},
renderError(message) {
const grid = document.getElementById('docker-hosts-grid');
if (grid) {
grid.innerHTML = `
<div class="glass-card p-6 text-center col-span-full">
<i class="fas fa-exclamation-circle text-4xl text-red-500 mb-4"></i>
<p class="text-red-400">${message}</p>
</div>
`;
}
},
showToast(message, type = 'info') {
// Use existing toast system or create simple one
if (window.dashboard && window.dashboard.showToast) {
window.dashboard.showToast(message, type);
} else {
console.log(`[${type.toUpperCase()}] ${message}`);
}
},
formatRelativeTime(dateStr) {
if (!dateStr) return 'N/A';
const date = new Date(dateStr);
const now = new Date();
const diffMs = now - date;
const diffMins = Math.floor(diffMs / 60000);
const diffHours = Math.floor(diffMins / 60);
const diffDays = Math.floor(diffHours / 24);
if (diffMins < 1) return 'À l\'instant';
if (diffMins < 60) return `Il y a ${diffMins}min`;
if (diffHours < 24) return `Il y a ${diffHours}h`;
return `Il y a ${diffDays}j`;
},
formatBytes(bytes) {
if (!bytes) return '0 B';
const k = 1024;
const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i];
}
};
function setupDockerAutoInit() {
// Initialize when Docker page is shown
const dockerPage = document.getElementById('page-docker');
if (!dockerPage) return;
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (
mutation.target.id === 'page-docker' &&
mutation.target.classList.contains('active')
) {
dockerSection.ensureInit();
}
});
});
observer.observe(dockerPage, { attributes: true, attributeFilter: ['class'] });
// Also initialize if already on Docker page
if (dockerPage.classList.contains('active')) {
dockerSection.ensureInit();
}
}
// If this script is loaded after DOMContentLoaded (common when injected late),
// a DOMContentLoaded listener would never fire. Handle both cases.
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', setupDockerAutoInit);
} else {
setupDockerAutoInit();
}

View File

@ -163,6 +163,29 @@ def create_app() -> FastAPI:
# Démarrer le scheduler # Démarrer le scheduler
await scheduler_service.start_async() await scheduler_service.start_async()
# Ajouter les jobs Docker au scheduler
from app.services.docker_service import docker_service
from app.services.docker_alerts import docker_alerts_service
scheduler_service.scheduler.add_job(
docker_service.collect_all_hosts,
trigger="interval",
seconds=60, # Toutes les minutes
id="docker_collect",
name="Docker Metrics Collection",
replace_existing=True
)
scheduler_service.scheduler.add_job(
docker_alerts_service.check_all_alerts,
trigger="interval",
seconds=30, # Toutes les 30 secondes
id="docker_alerts",
name="Docker Alerts Check",
replace_existing=True
)
print("🐳 Docker monitoring jobs scheduled")
# Afficher l'état du service de notification # Afficher l'état du service de notification
ntfy_status = "activé" if notification_service.enabled else "désactivé" ntfy_status = "activé" if notification_service.enabled else "désactivé"
print(f"🔔 Service de notification ntfy: {ntfy_status} ({notification_service.config.base_url})") print(f"🔔 Service de notification ntfy: {ntfy_status} ({notification_service.config.base_url})")

View File

@ -676,6 +676,14 @@
body.light-theme .text-gray-300, body.light-theme .text-gray-300,
body.light-theme .text-gray-400, body.light-theme .text-gray-400,
body.light-theme .text-gray-500 {
color: #4b5563 !important;
}
body.light-theme .text-gray-400 {
color: #374151 !important;
}
body.light-theme .text-gray-500 { body.light-theme .text-gray-500 {
color: #6b7280 !important; color: #6b7280 !important;
} }
@ -685,6 +693,22 @@
background-color: #e5e5e5 !important; background-color: #e5e5e5 !important;
} }
body.light-theme .bg-gray-800\/40 {
background-color: rgba(229, 231, 235, 0.75) !important;
}
body.light-theme .bg-gray-800\/60 {
background-color: rgba(229, 231, 235, 0.9) !important;
}
body.light-theme .border-gray-700\/60 {
border-color: #d1d5db !important;
}
body.light-theme .border-red-700\/60 {
border-color: #fca5a5 !important;
}
body.light-theme .bg-black { body.light-theme .bg-black {
background-color: #f5f5f5 !important; background-color: #f5f5f5 !important;
} }
@ -762,12 +786,47 @@
color: #f9fafb !important; color: #f9fafb !important;
} }
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
/* Navigation active state */ /* Navigation active state */
.nav-link.active { .desktop-nav-links .nav-link {
color: #7c3aed !important; display: inline-flex;
font-weight: 600; align-items: center;
border-bottom: 2px solid #7c3aed; justify-content: center;
padding-bottom: 2px; width: 40px;
height: 40px;
border-radius: 10px;
transition: background-color 0.2s ease, color 0.2s ease, transform 0.2s ease;
}
.desktop-nav-links .nav-link:hover {
background: rgba(255, 255, 255, 0.06);
}
.desktop-nav-links .nav-link.active {
color: #c4b5fd !important;
background: rgba(124, 58, 237, 0.18);
box-shadow: 0 0 0 1px rgba(124, 58, 237, 0.25) inset;
}
body.light-theme .desktop-nav-links .nav-link:hover {
background: rgba(0, 0, 0, 0.06);
}
body.light-theme .desktop-nav-links .nav-link.active {
color: #6d28d9 !important;
background: rgba(124, 58, 237, 0.14);
box-shadow: 0 0 0 1px rgba(124, 58, 237, 0.22) inset;
} }
/* Page transitions */ /* Page transitions */
@ -974,6 +1033,15 @@
background: linear-gradient(180deg, #f9fafb 0%, #e5e7eb 100%); background: linear-gradient(180deg, #f9fafb 0%, #e5e7eb 100%);
} }
body.light-theme #page-hosts > div,
body.light-theme #page-playbooks > div,
body.light-theme #page-schedules > div,
body.light-theme #page-alerts > div,
body.light-theme #page-docker > div,
body.light-theme #page-configuration > div {
background: linear-gradient(180deg, #f9fafb 0%, #e5e7eb 100%) !important;
}
/* Badges "Ready" / "Non configuré" en haut du bloc Hosts */ /* Badges "Ready" / "Non configuré" en haut du bloc Hosts */
body.light-theme .bg-green-600\/20 { body.light-theme .bg-green-600\/20 {
background-color: #bbf7d0 !important; /* vert clair plein */ background-color: #bbf7d0 !important; /* vert clair plein */
@ -2801,6 +2869,10 @@
<i class="fas fa-file-alt"></i> <i class="fas fa-file-alt"></i>
<span>Logs</span> <span>Logs</span>
</button> </button>
<button type="button" data-page="docker" class="mobile-nav-link" onclick="mobileNavigateTo('docker'); return false;">
<i class="fab fa-docker"></i>
<span>Docker</span>
</button>
<button type="button" data-page="alerts" class="mobile-nav-link" onclick="mobileNavigateTo('alerts'); return false;"> <button type="button" data-page="alerts" class="mobile-nav-link" onclick="mobileNavigateTo('alerts'); return false;">
<i class="fas fa-bell"></i> <i class="fas fa-bell"></i>
<span>Alertes</span> <span>Alertes</span>
@ -2841,15 +2913,46 @@
<!-- Desktop Navigation --> <!-- Desktop Navigation -->
<div class="desktop-nav-links"> <div class="desktop-nav-links">
<a href="#" data-page="dashboard" class="nav-link text-gray-300 hover:text-white transition-colors">Dashboard</a> <a href="#" data-page="dashboard" class="nav-link text-gray-300 hover:text-white transition-colors" title="Dashboard" aria-label="Dashboard">
<a href="#" data-page="hosts" class="nav-link text-gray-300 hover:text-white transition-colors">Hosts</a> <i class="fas fa-gauge-high"></i>
<a href="#" data-page="playbooks" class="nav-link text-gray-300 hover:text-white transition-colors">Playbooks</a> <span class="sr-only">Dashboard</span>
<a href="#" data-page="tasks" class="nav-link text-gray-300 hover:text-white transition-colors">Tasks</a> </a>
<a href="#" data-page="schedules" class="nav-link text-gray-300 hover:text-white transition-colors">Schedules</a> <a href="#" data-page="hosts" class="nav-link text-gray-300 hover:text-white transition-colors" title="Hosts" aria-label="Hosts">
<a href="#" data-page="logs" class="nav-link text-gray-300 hover:text-white transition-colors">Logs</a> <i class="fas fa-server"></i>
<a href="#" data-page="alerts" class="nav-link text-gray-300 hover:text-white transition-colors">Alertes</a> <span class="sr-only">Hosts</span>
<a href="#" data-page="configuration" class="nav-link text-gray-300 hover:text-white transition-colors">Configuration</a> </a>
<a href="#" data-page="help" class="nav-link text-gray-300 hover:text-white transition-colors">Aide</a> <a href="#" data-page="playbooks" class="nav-link text-gray-300 hover:text-white transition-colors" title="Playbooks" aria-label="Playbooks">
<i class="fas fa-book"></i>
<span class="sr-only">Playbooks</span>
</a>
<a href="#" data-page="tasks" class="nav-link text-gray-300 hover:text-white transition-colors" title="Tasks" aria-label="Tasks">
<i class="fas fa-list-check"></i>
<span class="sr-only">Tasks</span>
</a>
<a href="#" data-page="schedules" class="nav-link text-gray-300 hover:text-white transition-colors" title="Schedules" aria-label="Schedules">
<i class="fas fa-calendar-alt"></i>
<span class="sr-only">Schedules</span>
</a>
<a href="#" data-page="logs" class="nav-link text-gray-300 hover:text-white transition-colors" title="Logs" aria-label="Logs">
<i class="fas fa-file-alt"></i>
<span class="sr-only">Logs</span>
</a>
<a href="#" data-page="docker" class="nav-link text-gray-300 hover:text-white transition-colors" title="Docker" aria-label="Docker">
<i class="fab fa-docker"></i>
<span class="sr-only">Docker</span>
</a>
<a href="#" data-page="alerts" class="nav-link text-gray-300 hover:text-white transition-colors" title="Alertes" aria-label="Alertes">
<i class="fas fa-bell"></i>
<span class="sr-only">Alertes</span>
</a>
<a href="#" data-page="configuration" class="nav-link text-gray-300 hover:text-white transition-colors" title="Configuration" aria-label="Configuration">
<i class="fas fa-sliders-h"></i>
<span class="sr-only">Configuration</span>
</a>
<a href="#" data-page="help" class="nav-link text-gray-300 hover:text-white transition-colors" title="Aide" aria-label="Aide">
<i class="fas fa-question-circle"></i>
<span class="sr-only">Aide</span>
</a>
<button id="theme-toggle" class="p-2 rounded-lg bg-gray-800 hover:bg-gray-700 transition-colors touch-target"> <button id="theme-toggle" class="p-2 rounded-lg bg-gray-800 hover:bg-gray-700 transition-colors touch-target">
<i class="fas fa-moon text-gray-300"></i> <i class="fas fa-moon text-gray-300"></i>
</button> </button>
@ -3589,6 +3692,135 @@
</div> </div>
</section> </section>
<!-- ==================== PAGE: DOCKER ==================== -->
<section id="page-docker" class="page-section">
<div class="pt-20 sm:pt-24 pb-8 sm:pb-16 min-h-screen bg-gradient-to-b from-gray-900 to-black">
<div class="max-w-7xl mx-auto px-4 sm:px-6">
<!-- Header -->
<div class="text-center mb-6 sm:mb-12">
<h2 class="text-2xl sm:text-3xl font-bold gradient-text fade-in">
<i class="fab fa-docker mr-2"></i>Docker Hosts
</h2>
<p class="text-gray-400 mt-2">Surveillance et gestion des containers Docker</p>
</div>
<!-- Stats Cards -->
<div class="grid grid-cols-2 sm:grid-cols-4 gap-4 mb-8">
<div class="metric-card">
<div class="text-2xl font-bold text-purple-400" id="docker-stat-hosts">0</div>
<div class="text-gray-400 text-sm">Hosts Docker</div>
</div>
<div class="metric-card">
<div class="text-2xl font-bold text-green-400" id="docker-stat-containers">0</div>
<div class="text-gray-400 text-sm">Containers</div>
</div>
<div class="metric-card">
<div class="text-2xl font-bold text-blue-400" id="docker-stat-images">0</div>
<div class="text-gray-400 text-sm">Images</div>
</div>
<div class="metric-card">
<div class="text-2xl font-bold text-red-400" id="docker-stat-alerts">0</div>
<div class="text-gray-400 text-sm">Alertes</div>
</div>
</div>
<!-- Actions Bar -->
<div class="flex flex-wrap gap-4 mb-6 items-center justify-between">
<div class="flex gap-2">
<button onclick="dockerSection.collectAll()" class="btn-primary flex items-center gap-2">
<i class="fas fa-sync"></i>
<span class="hidden sm:inline">Collecter Tout</span>
</button>
<button onclick="dockerSection.showAlerts()" class="px-4 py-2 bg-gray-700 hover:bg-gray-600 rounded-lg transition-colors flex items-center gap-2">
<i class="fas fa-bell"></i>
<span class="hidden sm:inline">Alertes Docker</span>
<span id="docker-alerts-badge" class="hidden px-2 py-0.5 bg-red-600 text-white text-xs rounded-full">0</span>
</button>
</div>
<input type="text" id="docker-search" placeholder="Rechercher un host..."
class="px-4 py-2 bg-gray-800 border border-gray-700 rounded-lg text-white placeholder-gray-500 focus:outline-none focus:border-purple-500 w-full sm:w-64">
</div>
<!-- Docker Hosts Grid -->
<div id="docker-hosts-grid" class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
<!-- Docker host cards will be rendered here by JS -->
<div class="glass-card p-6 text-center col-span-full">
<div class="loading-spinner mx-auto mb-4"></div>
<p class="text-gray-400">Chargement des hosts Docker...</p>
</div>
</div>
</div>
</div>
</section>
<!-- END PAGE: DOCKER -->
<!-- Docker Host Detail Modal -->
<div id="docker-detail-modal" class="fixed inset-0 bg-black/80 backdrop-blur-sm z-50 hidden flex items-center justify-center p-4">
<div class="glass-card w-full max-w-4xl max-h-[90vh] overflow-hidden flex flex-col">
<div class="flex justify-between items-center p-4 border-b border-gray-700">
<h3 id="docker-host-name" class="text-xl font-bold"><i class="fab fa-docker mr-2 text-blue-400"></i>Host Docker</h3>
<button onclick="dockerSection.closeModal()" class="p-2 hover:bg-gray-700 rounded-lg transition-colors">
<i class="fas fa-times"></i>
</button>
</div>
<!-- Tabs -->
<div class="flex border-b border-gray-700">
<button class="docker-tab active px-4 py-3 text-sm font-medium" data-tab="containers">
<i class="fas fa-box mr-2"></i>Containers
</button>
<button class="docker-tab px-4 py-3 text-sm font-medium text-gray-400" data-tab="images">
<i class="fas fa-layer-group mr-2"></i>Images
</button>
<button class="docker-tab px-4 py-3 text-sm font-medium text-gray-400" data-tab="volumes">
<i class="fas fa-database mr-2"></i>Volumes
</button>
<button class="docker-tab px-4 py-3 text-sm font-medium text-gray-400" data-tab="host-alerts">
<i class="fas fa-exclamation-triangle mr-2"></i>Alertes
</button>
</div>
<!-- Tab Content -->
<div class="flex-1 overflow-auto p-4">
<div id="docker-tab-containers" class="docker-tab-content">
<div id="docker-containers-list" class="space-y-2">
<!-- Containers will be rendered here -->
</div>
</div>
<div id="docker-tab-images" class="docker-tab-content hidden">
<div id="docker-images-list" class="space-y-2">
<!-- Images will be rendered here -->
</div>
</div>
<div id="docker-tab-volumes" class="docker-tab-content hidden">
<div id="docker-volumes-list" class="space-y-2">
<!-- Volumes will be rendered here -->
</div>
</div>
<div id="docker-tab-host-alerts" class="docker-tab-content hidden">
<div id="docker-host-alerts-list" class="space-y-2">
<!-- Host alerts will be rendered here -->
</div>
</div>
</div>
</div>
</div>
<!-- Container Logs Modal -->
<div id="docker-logs-modal" class="fixed inset-0 bg-black/80 backdrop-blur-sm z-50 hidden flex items-center justify-center p-4">
<div class="glass-card w-full max-w-4xl max-h-[90vh] overflow-hidden flex flex-col">
<div class="flex justify-between items-center p-4 border-b border-gray-700">
<h3 id="docker-logs-title" class="text-xl font-bold"><i class="fas fa-file-alt mr-2 text-green-400"></i>Container Logs</h3>
<button onclick="dockerSection.closeLogsModal()" class="p-2 hover:bg-gray-700 rounded-lg transition-colors">
<i class="fas fa-times"></i>
</button>
</div>
<div class="flex-1 overflow-auto p-4">
<pre id="docker-logs-content" class="bg-black/50 p-4 rounded-lg text-sm font-mono text-gray-300 whitespace-pre-wrap overflow-x-auto"></pre>
</div>
</div>
</div>
<section id="page-configuration" class="page-section"> <section id="page-configuration" class="page-section">
<div class="pt-20 sm:pt-24 pb-8 sm:pb-16 min-h-screen bg-gradient-to-b from-gray-900 to-black"> <div class="pt-20 sm:pt-24 pb-8 sm:pb-16 min-h-screen bg-gradient-to-b from-gray-900 to-black">
<div class="max-w-7xl mx-auto px-4 sm:px-6"> <div class="max-w-7xl mx-auto px-4 sm:px-6">
@ -4109,10 +4341,6 @@
} }
} }
// Setup desktop theme toggles
document.getElementById('theme-toggle')?.addEventListener('click', toggleTheme);
document.getElementById('theme-toggle-mobile')?.addEventListener('click', toggleTheme);
// Initialize mobile nav links state // Initialize mobile nav links state
updateMobileNavLinks(currentPage); updateMobileNavLinks(currentPage);
}); });
@ -4459,5 +4687,8 @@
} }
} }
</script> </script>
<!-- Docker Section JavaScript -->
<script src="/static/docker_section.js"></script>
</body> </body>
</html> </html>

View File

@ -364,7 +364,37 @@ class DashboardManager {
try { try {
const response = await fetch(url, { ...defaultOptions, ...options }); const response = await fetch(url, { ...defaultOptions, ...options });
if (!response.ok) { if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`); // Handle 401 Unauthorized - redirect to login
if (response.status === 401) {
this.showNotification('Session expirée, reconnexion requise', 'error');
this.logout();
const err = new Error('Session expirée');
err.status = 401;
throw err;
}
let errorDetail = null;
try {
const contentType = response.headers.get('content-type') || '';
if (contentType.includes('application/json')) {
errorDetail = await response.json();
} else {
const text = await response.text();
errorDetail = text ? { detail: text } : null;
}
} catch (_) {
errorDetail = null;
}
const serverMessage =
(errorDetail && (errorDetail.detail || errorDetail.message || errorDetail.error))
? (errorDetail.detail || errorDetail.message || errorDetail.error)
: response.statusText;
const err = new Error(`HTTP ${response.status}: ${serverMessage || 'Erreur inconnue'}`);
err.status = response.status;
err.detail = errorDetail;
throw err;
} }
return await response.json(); return await response.json();
} catch (error) { } catch (error) {
@ -583,6 +613,18 @@ class DashboardManager {
case 'schedule_run_finished': case 'schedule_run_finished':
this.handleScheduleRunFinished(data.data); this.handleScheduleRunFinished(data.data);
break; break;
case 'metrics_collection_complete':
this.showNotification(
`Collecte des métriques terminée: ${data.data?.success || 0}/${data.data?.total || 0} réussi(es)`,
(data.data && data.data.failed && data.data.failed > 0) ? 'warning' : 'success'
);
this.loadHostMetrics().then(() => {
this.renderHosts();
});
this.loadLogs().then(() => {
this.renderLogs();
});
break;
} }
} }
@ -917,13 +959,17 @@ class DashboardManager {
} }
setupEventListeners() { setupEventListeners() {
// Theme toggle // Theme toggle (desktop + mobile)
const themeToggle = document.getElementById('theme-toggle'); const onToggleTheme = () => {
if (themeToggle) {
themeToggle.addEventListener('click', () => {
this.toggleTheme(); this.toggleTheme();
}); };
}
document.getElementById('theme-toggle')?.addEventListener('click', onToggleTheme);
document.getElementById('theme-toggle-mobile')?.addEventListener('click', onToggleTheme);
document.getElementById('mobile-theme-toggle')?.addEventListener('click', onToggleTheme);
// Expose for inline handlers (e.g. mobile nav button)
window.toggleTheme = onToggleTheme;
// Metrics collection configuration (Configuration page) // Metrics collection configuration (Configuration page)
const configPage = document.getElementById('page-configuration'); const configPage = document.getElementById('page-configuration');
@ -1179,26 +1225,35 @@ class DashboardManager {
toggleTheme() { toggleTheme() {
const body = document.body; const body = document.body;
const currentTheme = body.classList.contains('light-theme') ? 'light' : 'dark'; const isLight = body.classList.toggle('light-theme');
const newTheme = currentTheme === 'dark' ? 'light' : 'dark';
if (newTheme === 'light') { const themeIcons = document.querySelectorAll('#theme-toggle i, #theme-toggle-mobile i, #mobile-theme-icon');
body.classList.add('light-theme'); themeIcons.forEach(icon => {
document.getElementById('theme-toggle').innerHTML = '<i class="fas fa-sun text-yellow-400"></i>'; icon.className = isLight ? 'fas fa-sun text-yellow-400' : 'fas fa-moon text-gray-300';
} else { });
body.classList.remove('light-theme');
document.getElementById('theme-toggle').innerHTML = '<i class="fas fa-moon text-gray-300"></i>'; const mobileLabel = document.getElementById('mobile-theme-label');
if (mobileLabel) {
mobileLabel.textContent = isLight ? 'Thème clair' : 'Thème sombre';
} }
// Persist theme preference localStorage.setItem('theme', isLight ? 'light' : 'dark');
localStorage.setItem('theme', newTheme);
} }
loadThemePreference() { loadThemePreference() {
const savedTheme = localStorage.getItem('theme'); const savedTheme = localStorage.getItem('theme');
if (savedTheme === 'light') { if (savedTheme === 'light') {
document.body.classList.add('light-theme'); document.body.classList.add('light-theme');
document.getElementById('theme-toggle').innerHTML = '<i class="fas fa-sun text-yellow-400"></i>';
const themeIcons = document.querySelectorAll('#theme-toggle i, #theme-toggle-mobile i, #mobile-theme-icon');
themeIcons.forEach(icon => {
icon.className = 'fas fa-sun text-yellow-400';
});
const mobileLabel = document.getElementById('mobile-theme-label');
if (mobileLabel) {
mobileLabel.textContent = 'Thème clair';
}
} }
} }
@ -2083,20 +2138,8 @@ class DashboardManager {
}); });
if (result.success) { if (result.success) {
let message = `Métriques collectées pour ${result.hosts_collected} hôte(s) en ${result.execution_time?.toFixed(1) || 0}s`; const message = result.message || `Collecte des métriques lancée pour ${result.hosts_count || 0} hôte(s)`;
this.showNotification(message, 'success');
if (result.errors && result.errors.length > 0) {
message += ` (${result.errors.length} erreur(s))`;
console.warn('Erreurs de collecte:', result.errors);
}
this.showNotification(message, result.errors && result.errors.length > 0 ? 'warning' : 'success');
// Reload host metrics and logs
await this.loadHostMetrics();
await this.loadLogs();
this.renderHosts();
this.renderLogs();
} else { } else {
const errorMsg = result.error_detail || result.errors?.[0] || 'Erreur inconnue'; const errorMsg = result.error_detail || result.errors?.[0] || 'Erreur inconnue';
console.error('Échec de la collecte:', errorMsg); console.error('Échec de la collecte:', errorMsg);
@ -2104,7 +2147,9 @@ class DashboardManager {
} }
} catch (error) { } catch (error) {
console.error('Error collecting metrics:', error); console.error('Error collecting metrics:', error);
const errorMsg = error.detail || error.message || 'Erreur inconnue'; const errorMsg = (error.detail && (error.detail.detail || error.detail.message || error.detail.error))
? (error.detail.detail || error.detail.message || error.detail.error)
: (error.message || 'Erreur inconnue');
this.showNotification(`Erreur lors de la collecte des métriques: ${errorMsg}`, 'error'); this.showNotification(`Erreur lors de la collecte des métriques: ${errorMsg}`, 'error');
} finally { } finally {
this.metricsLoading = false; this.metricsLoading = false;

View File

@ -9,6 +9,10 @@ from .user import User, UserRole
from .host_metrics import HostMetrics from .host_metrics import HostMetrics
from .alert import Alert from .alert import Alert
from .app_setting import AppSetting from .app_setting import AppSetting
from .docker_container import DockerContainer
from .docker_image import DockerImage
from .docker_volume import DockerVolume
from .docker_alert import DockerAlert
__all__ = [ __all__ = [
"Base", "Base",
@ -23,4 +27,8 @@ __all__ = [
"UserRole", "UserRole",
"HostMetrics", "HostMetrics",
"AppSetting", "AppSetting",
"DockerContainer",
"DockerImage",
"DockerVolume",
"DockerAlert",
] ]

View File

@ -112,7 +112,19 @@ async def get_db() -> AsyncGenerator[AsyncSession, None]:
async def init_db() -> None: async def init_db() -> None:
"""Create all tables (mostly for dev/tests; migrations should be handled by Alembic).""" """Create all tables (mostly for dev/tests; migrations should be handled by Alembic)."""
from . import host, task, schedule, schedule_run, log, alert, app_setting # noqa: F401 from . import (
host,
task,
schedule,
schedule_run,
log,
alert,
app_setting,
docker_container,
docker_image,
docker_volume,
docker_alert,
) # noqa: F401
async with engine.begin() as conn: async with engine.begin() as conn:
await conn.run_sync(Base.metadata.create_all) await conn.run_sync(Base.metadata.create_all)

View File

@ -0,0 +1,55 @@
"""Docker Alert model for Homelab Automation."""
from __future__ import annotations
from datetime import datetime
from typing import Optional
from sqlalchemy import DateTime, ForeignKey, Integer, String, Text, Index
from sqlalchemy.orm import Mapped, mapped_column, relationship
from sqlalchemy.sql import func
from .database import Base
class DockerAlert(Base):
"""Model representing a Docker alert for container issues."""
__tablename__ = "docker_alerts"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
host_id: Mapped[str] = mapped_column(String, ForeignKey("hosts.id", ondelete="CASCADE"), nullable=False)
container_name: Mapped[str] = mapped_column(String(255), nullable=False)
severity: Mapped[str] = mapped_column(String(20), nullable=False, default="warning") # warning/error/critical
state: Mapped[str] = mapped_column(String(20), nullable=False, default="open") # open/closed/acknowledged
message: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
opened_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False, server_default=func.now())
closed_at: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True), nullable=True)
acknowledged_at: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True), nullable=True)
acknowledged_by: Mapped[Optional[str]] = mapped_column(String(100), nullable=True)
last_notified_at: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True), nullable=True)
# Relationship to host
host: Mapped["Host"] = relationship("Host", back_populates="docker_alerts")
__table_args__ = (
Index("idx_docker_alerts_state_host", "state", "host_id"),
{"sqlite_autoincrement": True},
)
def __repr__(self) -> str: # pragma: no cover
return f"<DockerAlert id={self.id} container={self.container_name} severity={self.severity}>"
def to_dict(self) -> dict:
"""Convert to dictionary for API responses."""
return {
"id": self.id,
"host_id": self.host_id,
"container_name": self.container_name,
"severity": self.severity,
"state": self.state,
"message": self.message,
"opened_at": self.opened_at.isoformat() if self.opened_at else None,
"closed_at": self.closed_at.isoformat() if self.closed_at else None,
"acknowledged_at": self.acknowledged_at.isoformat() if self.acknowledged_at else None,
"acknowledged_by": self.acknowledged_by,
"last_notified_at": self.last_notified_at.isoformat() if self.last_notified_at else None,
}

View File

@ -0,0 +1,61 @@
"""Docker Container model for Homelab Automation."""
from __future__ import annotations
from datetime import datetime
from typing import Optional
from sqlalchemy import DateTime, ForeignKey, Integer, String, Text, JSON, UniqueConstraint
from sqlalchemy.orm import Mapped, mapped_column, relationship
from sqlalchemy.sql import func
from .database import Base
class DockerContainer(Base):
"""Model representing a Docker container on a host."""
__tablename__ = "docker_containers"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
host_id: Mapped[str] = mapped_column(String, ForeignKey("hosts.id", ondelete="CASCADE"), nullable=False)
container_id: Mapped[str] = mapped_column(String(64), nullable=False)
name: Mapped[str] = mapped_column(String(255), nullable=False)
image: Mapped[Optional[str]] = mapped_column(String(255), nullable=True)
state: Mapped[str] = mapped_column(String(20), nullable=False, default="unknown") # running/exited/paused/created/dead
status: Mapped[Optional[str]] = mapped_column(String(255), nullable=True) # Up 2 hours, Exited (0) 5 minutes ago
health: Mapped[Optional[str]] = mapped_column(String(20), nullable=True) # healthy/unhealthy/starting/none
created_at: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True), nullable=True)
ports: Mapped[Optional[dict]] = mapped_column(JSON, nullable=True)
labels: Mapped[Optional[dict]] = mapped_column(JSON, nullable=True)
compose_project: Mapped[Optional[str]] = mapped_column(String(255), nullable=True) # com.docker.compose.project
last_update_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True), nullable=False, server_default=func.now(), onupdate=func.now()
)
# Relationship to host
host: Mapped["Host"] = relationship("Host", back_populates="docker_containers")
__table_args__ = (
UniqueConstraint('host_id', 'container_id', name='uq_docker_containers_host_container'),
{"sqlite_autoincrement": True},
)
def __repr__(self) -> str: # pragma: no cover
return f"<DockerContainer id={self.id} name={self.name} state={self.state}>"
def to_dict(self) -> dict:
"""Convert to dictionary for API responses."""
return {
"id": self.id,
"host_id": self.host_id,
"container_id": self.container_id,
"name": self.name,
"image": self.image,
"state": self.state,
"status": self.status,
"health": self.health,
"created_at": self.created_at.isoformat() if self.created_at else None,
"ports": self.ports,
"labels": self.labels,
"compose_project": self.compose_project,
"last_update_at": self.last_update_at.isoformat() if self.last_update_at else None,
}

View File

@ -0,0 +1,50 @@
"""Docker Image model for Homelab Automation."""
from __future__ import annotations
from datetime import datetime
from typing import Optional
from sqlalchemy import BigInteger, DateTime, ForeignKey, Integer, String, JSON, UniqueConstraint
from sqlalchemy.orm import Mapped, mapped_column, relationship
from sqlalchemy.sql import func
from .database import Base
class DockerImage(Base):
"""Model representing a Docker image on a host."""
__tablename__ = "docker_images"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
host_id: Mapped[str] = mapped_column(String, ForeignKey("hosts.id", ondelete="CASCADE"), nullable=False)
image_id: Mapped[str] = mapped_column(String(64), nullable=False)
repo_tags: Mapped[Optional[list]] = mapped_column(JSON, nullable=True) # ["nginx:latest", "nginx:1.25"]
size: Mapped[Optional[int]] = mapped_column(BigInteger, nullable=True)
created: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True), nullable=True)
last_update_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True), nullable=False, server_default=func.now(), onupdate=func.now()
)
# Relationship to host
host: Mapped["Host"] = relationship("Host", back_populates="docker_images")
__table_args__ = (
UniqueConstraint('host_id', 'image_id', name='uq_docker_images_host_image'),
{"sqlite_autoincrement": True},
)
def __repr__(self) -> str: # pragma: no cover
tags = self.repo_tags[0] if self.repo_tags else self.image_id[:12]
return f"<DockerImage id={self.id} tags={tags}>"
def to_dict(self) -> dict:
"""Convert to dictionary for API responses."""
return {
"id": self.id,
"host_id": self.host_id,
"image_id": self.image_id,
"repo_tags": self.repo_tags,
"size": self.size,
"created": self.created.isoformat() if self.created else None,
"last_update_at": self.last_update_at.isoformat() if self.last_update_at else None,
}

View File

@ -0,0 +1,49 @@
"""Docker Volume model for Homelab Automation."""
from __future__ import annotations
from datetime import datetime
from typing import Optional
from sqlalchemy import DateTime, ForeignKey, Integer, String, Text, UniqueConstraint
from sqlalchemy.orm import Mapped, mapped_column, relationship
from sqlalchemy.sql import func
from .database import Base
class DockerVolume(Base):
"""Model representing a Docker volume on a host."""
__tablename__ = "docker_volumes"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
host_id: Mapped[str] = mapped_column(String, ForeignKey("hosts.id", ondelete="CASCADE"), nullable=False)
name: Mapped[str] = mapped_column(String(255), nullable=False)
driver: Mapped[Optional[str]] = mapped_column(String(50), nullable=True)
mountpoint: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
scope: Mapped[Optional[str]] = mapped_column(String(20), nullable=True) # local/global
last_update_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True), nullable=False, server_default=func.now(), onupdate=func.now()
)
# Relationship to host
host: Mapped["Host"] = relationship("Host", back_populates="docker_volumes")
__table_args__ = (
UniqueConstraint('host_id', 'name', name='uq_docker_volumes_host_name'),
{"sqlite_autoincrement": True},
)
def __repr__(self) -> str: # pragma: no cover
return f"<DockerVolume id={self.id} name={self.name}>"
def to_dict(self) -> dict:
"""Convert to dictionary for API responses."""
return {
"id": self.id,
"host_id": self.host_id,
"name": self.name,
"driver": self.driver,
"mountpoint": self.mountpoint,
"scope": self.scope,
"last_update_at": self.last_update_at.isoformat() if self.last_update_at else None,
}

View File

@ -24,12 +24,30 @@ class Host(Base):
updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False, server_default=func.now(), onupdate=func.now()) updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False, server_default=func.now(), onupdate=func.now())
deleted_at: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True)) deleted_at: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True))
# Docker-related fields
docker_enabled: Mapped[bool] = mapped_column(Boolean, nullable=False, server_default=text("0"))
docker_version: Mapped[Optional[str]] = mapped_column(String(50), nullable=True)
docker_status: Mapped[Optional[str]] = mapped_column(String(20), nullable=True) # online/offline/error
docker_last_collect_at: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True), nullable=True)
bootstrap_statuses: Mapped[List["BootstrapStatus"]] = relationship( bootstrap_statuses: Mapped[List["BootstrapStatus"]] = relationship(
"BootstrapStatus", back_populates="host", cascade="all, delete-orphan" "BootstrapStatus", back_populates="host", cascade="all, delete-orphan"
) )
metrics: Mapped[List["HostMetrics"]] = relationship( metrics: Mapped[List["HostMetrics"]] = relationship(
"HostMetrics", back_populates="host", cascade="all, delete-orphan" "HostMetrics", back_populates="host", cascade="all, delete-orphan"
) )
docker_containers: Mapped[List["DockerContainer"]] = relationship(
"DockerContainer", back_populates="host", cascade="all, delete-orphan"
)
docker_images: Mapped[List["DockerImage"]] = relationship(
"DockerImage", back_populates="host", cascade="all, delete-orphan"
)
docker_volumes: Mapped[List["DockerVolume"]] = relationship(
"DockerVolume", back_populates="host", cascade="all, delete-orphan"
)
docker_alerts: Mapped[List["DockerAlert"]] = relationship(
"DockerAlert", back_populates="host", cascade="all, delete-orphan"
)
def __repr__(self) -> str: # pragma: no cover - debug helper def __repr__(self) -> str: # pragma: no cover - debug helper
return f"<Host id={self.id} name={self.name} ip={self.ip_address}>" return f"<Host id={self.id} name={self.name} ip={self.ip_address}>"

View File

@ -24,6 +24,7 @@ from app.routes.metrics import router as metrics_router
from app.routes.builtin_playbooks import router as builtin_playbooks_router from app.routes.builtin_playbooks import router as builtin_playbooks_router
from app.routes.server import router as server_router from app.routes.server import router as server_router
from app.routes.alerts import router as alerts_router from app.routes.alerts import router as alerts_router
from app.routes.docker import router as docker_router
# Router principal qui agrège tous les sous-routers # Router principal qui agrège tous les sous-routers
api_router = APIRouter() api_router = APIRouter()
@ -46,6 +47,7 @@ api_router.include_router(metrics_router, prefix="/metrics", tags=["Metrics"])
api_router.include_router(builtin_playbooks_router, prefix="/builtin-playbooks", tags=["Builtin Playbooks"]) api_router.include_router(builtin_playbooks_router, prefix="/builtin-playbooks", tags=["Builtin Playbooks"])
api_router.include_router(server_router, prefix="/server", tags=["Server"]) api_router.include_router(server_router, prefix="/server", tags=["Server"])
api_router.include_router(alerts_router, prefix="/alerts", tags=["Alerts"]) api_router.include_router(alerts_router, prefix="/alerts", tags=["Alerts"])
api_router.include_router(docker_router, prefix="/docker", tags=["Docker"])
__all__ = [ __all__ = [
"api_router", "api_router",

View File

@ -14,8 +14,9 @@ from sqlalchemy.ext.asyncio import AsyncSession
from app.core.config import settings from app.core.config import settings
from app.core.dependencies import get_db, verify_api_key from app.core.dependencies import get_db, verify_api_key
from app.crud.task import TaskRepository from app.crud.task import TaskRepository
from app.schemas.ansible import AnsibleExecutionRequest, AdHocCommandRequest, AdHocCommandResult from app.schemas.ansible import AnsibleExecutionRequest, AdHocCommandRequest, AdHocCommandResult, BootstrapRequest
from app.schemas.task_api import Task from app.schemas.task_api import Task
from app.schemas.common import CommandResult
from app.schemas.common import LogEntry from app.schemas.common import LogEntry
from app.services import ( from app.services import (
ansible_service, ansible_service,
@ -23,9 +24,10 @@ from app.services import (
notification_service, notification_service,
adhoc_history_service, adhoc_history_service,
db, db,
bootstrap_status_service,
) )
from app.services.task_log_service import TaskLogService from app.services.task_log_service import TaskLogService
from app.utils.ssh_utils import find_ssh_private_key from app.utils.ssh_utils import find_ssh_private_key, bootstrap_host
router = APIRouter() router = APIRouter()
@ -110,6 +112,113 @@ async def get_ssh_config(api_key_valid: bool = Depends(verify_api_key)):
} }
@router.post("/bootstrap", response_model=CommandResult)
async def bootstrap_ansible_host_compat(
request: BootstrapRequest,
api_key_valid: bool = Depends(verify_api_key),
):
"""Compat: Bootstrap un hôte via /api/ansible/bootstrap (historique UI).
La route canonical est /api/bootstrap, mais l'UI historique appelle /api/ansible/bootstrap.
"""
import asyncio
import logging
import traceback
logger = logging.getLogger("bootstrap_endpoint")
try:
logger.info(f"[BOOTSTRAP] Bootstrap request for host={request.host}, user={request.automation_user}")
result = bootstrap_host(
host=request.host,
root_password=request.root_password,
automation_user=request.automation_user,
)
logger.info(f"[BOOTSTRAP] Bootstrap result: status={result.status}, return_code={result.return_code}")
if result.return_code != 0:
raise HTTPException(
status_code=500,
detail={
"status": result.status,
"return_code": result.return_code,
"stdout": result.stdout,
"stderr": result.stderr,
},
)
host_name = request.host
for h in db.hosts:
if h.ip == request.host or h.name == request.host:
host_name = h.name
break
bootstrap_status_service.set_bootstrap_status(
host_name=host_name,
success=True,
details=f"Bootstrap réussi via API (user: {request.automation_user})",
)
db.invalidate_hosts_cache()
log_entry = LogEntry(
id=db.get_next_id("logs"),
timestamp=datetime.now(timezone.utc),
level="INFO",
message=f"Bootstrap réussi pour {host_name} (user: {request.automation_user})",
source="bootstrap",
host=host_name,
)
db.logs.insert(0, log_entry)
await ws_manager.broadcast(
{
"type": "bootstrap_success",
"data": {
"host": host_name,
"user": request.automation_user,
"status": "ok",
"bootstrap_ok": True,
},
}
)
asyncio.create_task(notification_service.notify_bootstrap_success(host_name))
return result
except HTTPException as http_exc:
error_detail = str(http_exc.detail) if http_exc.detail else "Erreur inconnue"
asyncio.create_task(
notification_service.notify_bootstrap_failed(
hostname=request.host,
error=error_detail[:200],
)
)
raise
except Exception as e:
logger.error(f"[BOOTSTRAP] Bootstrap exception: {e}")
logger.error(traceback.format_exc())
log_entry = LogEntry(
id=db.get_next_id("logs"),
timestamp=datetime.now(timezone.utc),
level="ERROR",
message=f"Échec bootstrap pour {request.host}: {str(e)}",
source="bootstrap",
host=request.host,
)
db.logs.insert(0, log_entry)
asyncio.create_task(
notification_service.notify_bootstrap_failed(
hostname=request.host,
error=str(e)[:200],
)
)
raise HTTPException(status_code=500, detail=str(e))
@router.post("/execute") @router.post("/execute")
async def execute_ansible_playbook( async def execute_ansible_playbook(
request: AnsibleExecutionRequest, request: AnsibleExecutionRequest,

View File

@ -3,15 +3,18 @@ Routes API pour les builtin playbooks (collecte métriques).
""" """
import asyncio import asyncio
import uuid
from typing import Optional from typing import Optional
from fastapi import APIRouter, Depends, HTTPException, BackgroundTasks from fastapi import APIRouter, Depends, HTTPException, BackgroundTasks
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.exc import OperationalError
from app.core.config import settings from app.core.config import settings
from app.core.dependencies import get_db, verify_api_key from app.core.dependencies import get_db, verify_api_key
from app.crud.host import HostRepository from app.crud.host import HostRepository
from app.crud.host_metrics import HostMetricsRepository from app.crud.host_metrics import HostMetricsRepository
from app.models.database import async_session_maker
from app.services import ansible_service, ws_manager from app.services import ansible_service, ws_manager
from app.services.builtin_playbooks import ( from app.services.builtin_playbooks import (
BuiltinPlaybookService, BuiltinPlaybookService,
@ -23,6 +26,46 @@ from app.services.builtin_playbooks import (
router = APIRouter() router = APIRouter()
async def _sync_hosts_from_inventory(db_session: AsyncSession) -> int:
repo = HostRepository(db_session)
inventory_hosts = ansible_service.get_hosts_from_inventory()
created_or_updated = 0
for inv_host in inventory_hosts:
existing = await repo.get_by_name(inv_host.name)
ip_address = inv_host.ansible_host or inv_host.name
ansible_group = getattr(inv_host, "group", None)
inv_groups = getattr(inv_host, "groups", None) or []
docker_enabled = "role_docker" in inv_groups
if existing:
await repo.update(
existing,
ip_address=ip_address,
ansible_group=ansible_group,
docker_enabled=docker_enabled or existing.docker_enabled,
)
created_or_updated += 1
else:
created = await repo.create(
id=uuid.uuid4().hex,
name=inv_host.name,
ip_address=ip_address,
ansible_group=ansible_group,
status="unknown",
reachable=False,
last_seen=None,
)
if docker_enabled:
await repo.update(created, docker_enabled=True)
created_or_updated += 1
if created_or_updated:
await db_session.commit()
return created_or_updated
def _get_service() -> BuiltinPlaybookService: def _get_service() -> BuiltinPlaybookService:
"""Récupère ou initialise le service builtin playbooks.""" """Récupère ou initialise le service builtin playbooks."""
try: try:
@ -116,8 +159,8 @@ async def execute_builtin_playbook_background(
} }
}) })
# Planifier l'exécution en arrière-plan # Lancer en arrière-plan via la boucle asyncio active (retour immédiat)
background_tasks.add_task(asyncio.create_task, run_in_background()) asyncio.create_task(run_in_background())
return { return {
"message": f"Builtin playbook '{builtin_id}' planifié pour exécution sur {target}", "message": f"Builtin playbook '{builtin_id}' planifié pour exécution sur {target}",
@ -134,23 +177,58 @@ async def collect_all_metrics(
): ):
"""Collecte les métriques de tous les hôtes.""" """Collecte les métriques de tous les hôtes."""
host_repo = HostRepository(db_session) host_repo = HostRepository(db_session)
try:
hosts = await host_repo.list(limit=1000)
except OperationalError as e:
raise HTTPException(
status_code=500,
detail=f"Base de données non initialisée/migrations manquantes (hosts): {str(e)}",
)
if not hosts:
await _sync_hosts_from_inventory(db_session)
hosts = await host_repo.list(limit=1000) hosts = await host_repo.list(limit=1000)
if not hosts: if not hosts:
return {"message": "Aucun hôte trouvé", "hosts_count": 0} return {"success": True, "message": "Aucun hôte trouvé", "hosts_count": 0}
async def collect_for_all(): async def collect_for_all():
service = _get_service() service = _get_service()
results = [] results = []
for host in hosts: async with async_session_maker() as session:
host_repo_bg = HostRepository(session)
metrics_repo = HostMetricsRepository(session)
hosts_bg = await host_repo_bg.list(limit=1000)
for host in hosts_bg:
try: try:
result = await service.execute_builtin("collect_system_info", host.name) result = await service.execute_builtin("collect_system_info", host.name)
ok = bool(result.get("success", False))
if ok:
for hostname, metrics_data in result.get("parsed_metrics", {}).items():
target_host = await host_repo_bg.get_by_name(hostname)
if not target_host:
continue
metrics_create = service.create_metrics_from_parsed(
host_id=target_host.id,
parsed_data=metrics_data,
builtin_id="collect_system_info",
execution_time_ms=result.get("execution_time_ms", 0),
)
await metrics_repo.create(**metrics_create.model_dump())
await session.commit()
results.append({ results.append({
"host": host.name, "host": host.name,
"success": result.get("success", False) "success": ok,
}) })
except Exception as e: except Exception as e:
await session.rollback()
results.append({ results.append({
"host": host.name, "host": host.name,
"success": False, "success": False,
@ -160,15 +238,17 @@ async def collect_all_metrics(
await ws_manager.broadcast({ await ws_manager.broadcast({
"type": "metrics_collection_complete", "type": "metrics_collection_complete",
"data": { "data": {
"total": len(hosts), "total": len(results),
"success": sum(1 for r in results if r.get("success")), "success": sum(1 for r in results if r.get("success")),
"failed": sum(1 for r in results if not r.get("success")) "failed": sum(1 for r in results if not r.get("success"))
} }
}) })
background_tasks.add_task(asyncio.create_task, collect_for_all()) # Lancer en arrière-plan via la boucle asyncio active (retour immédiat)
asyncio.create_task(collect_for_all())
return { return {
"success": True,
"message": f"Collecte des métriques lancée pour {len(hosts)} hôte(s)", "message": f"Collecte des métriques lancée pour {len(hosts)} hôte(s)",
"hosts_count": len(hosts) "hosts_count": len(hosts)
} }

425
app/routes/docker.py Normal file
View File

@ -0,0 +1,425 @@
"""Docker management API routes."""
from typing import Optional
from fastapi import APIRouter, Depends, HTTPException, status, Query
from sqlalchemy.ext.asyncio import AsyncSession
from app.core.dependencies import get_db, verify_api_key, get_current_user, require_admin
from app.crud.docker_container import DockerContainerRepository
from app.crud.docker_image import DockerImageRepository
from app.crud.docker_volume import DockerVolumeRepository
from app.crud.docker_alert import DockerAlertRepository
from app.crud.host import HostRepository
from app.schemas.docker import (
DockerHostListResponse,
DockerHostInfo,
EnableDockerRequest,
DockerContainerListResponse,
DockerContainerResponse,
DockerImageListResponse,
DockerImageExtendedListResponse,
DockerImageExtendedResponse,
DockerVolumeListResponse,
DockerAlertListResponse,
DockerAlertAcknowledgeRequest,
ContainerActionResponse,
ContainerLogsRequest,
ContainerLogsResponse,
ContainerInspectResponse,
DockerCollectResponse,
DockerCollectAllResponse,
DockerStatsResponse,
ImageActionResponse,
)
from app.services.docker_service import docker_service
from app.services.docker_actions import docker_actions
from app.services.docker_alerts import docker_alerts_service
router = APIRouter()
# === Docker Hosts ===
@router.get("/hosts", response_model=DockerHostListResponse)
async def list_docker_hosts(
api_key_valid: bool = Depends(verify_api_key),
):
"""List all hosts with Docker information."""
hosts = await docker_service.get_docker_hosts()
enabled = sum(1 for h in hosts if h.get("docker_enabled"))
return DockerHostListResponse(
hosts=[DockerHostInfo(**h) for h in hosts],
total=len(hosts),
enabled=enabled
)
@router.post("/hosts/{host_id}/enable")
async def enable_docker_monitoring(
host_id: str,
request: EnableDockerRequest = None,
api_key_valid: bool = Depends(verify_api_key),
):
"""Enable or disable Docker monitoring on a host."""
enabled = request.enabled if request else True
success = await docker_service.enable_docker_monitoring(host_id, enabled)
if not success:
raise HTTPException(status_code=404, detail="Host not found")
action = "enabled" if enabled else "disabled"
return {"message": f"Docker monitoring {action} for host", "host_id": host_id}
@router.post("/hosts/{host_id}/collect", response_model=DockerCollectResponse)
async def collect_docker_now(
host_id: str,
api_key_valid: bool = Depends(verify_api_key),
):
"""Force an immediate Docker collection on a host."""
result = await docker_service.collect_docker_host(host_id)
return DockerCollectResponse(
success=result.get("success", False),
host_id=host_id,
host_name=result.get("host_name", ""),
message="Collection completed" if result.get("success") else "Collection failed",
docker_version=result.get("docker_version"),
containers_count=result.get("containers_count", 0),
images_count=result.get("images_count", 0),
volumes_count=result.get("volumes_count", 0),
duration_ms=result.get("duration_ms", 0),
error=result.get("error")
)
@router.post("/collect-all", response_model=DockerCollectAllResponse)
async def collect_all_docker_hosts(
api_key_valid: bool = Depends(verify_api_key),
):
"""Collect Docker info from all enabled hosts."""
result = await docker_service.collect_all_hosts()
normalized_results = []
for r in result.get("results", []):
if not isinstance(r, dict):
continue
normalized_results.append({
"success": bool(r.get("success", False)),
"host_id": r.get("host_id", ""),
"host_name": r.get("host_name", ""),
"message": r.get("message") or ("Collection completed" if r.get("success") else "Collection failed"),
"docker_version": r.get("docker_version"),
"containers_count": r.get("containers_count", 0),
"images_count": r.get("images_count", 0),
"volumes_count": r.get("volumes_count", 0),
"duration_ms": r.get("duration_ms", 0),
"error": r.get("error"),
})
return DockerCollectAllResponse(
success=result.get("success", False),
message=f"Collected from {result.get('successful', 0)}/{result.get('total_hosts', 0)} hosts",
total_hosts=result.get("total_hosts", 0),
successful=result.get("successful", 0),
failed=result.get("failed", 0),
results=[DockerCollectResponse(**r) for r in normalized_results]
)
# === Containers ===
@router.get("/hosts/{host_id}/containers", response_model=DockerContainerListResponse)
async def get_containers(
host_id: str,
state: Optional[str] = Query(None, description="Filter by state"),
compose_project: Optional[str] = Query(None, description="Filter by compose project"),
api_key_valid: bool = Depends(verify_api_key),
db_session: AsyncSession = Depends(get_db),
):
"""List containers for a host."""
container_repo = DockerContainerRepository(db_session)
containers = await container_repo.list_by_host(host_id, state=state, compose_project=compose_project)
counts = await container_repo.count_by_host(host_id)
return DockerContainerListResponse(
containers=[DockerContainerResponse(
id=c.id,
host_id=c.host_id,
container_id=c.container_id,
name=c.name,
image=c.image,
state=c.state,
status=c.status,
health=c.health,
ports=c.ports,
labels=c.labels,
compose_project=c.compose_project,
created_at=c.created_at,
last_update_at=c.last_update_at
) for c in containers],
total=counts.get("total", 0),
running=counts.get("running", 0),
stopped=counts.get("total", 0) - counts.get("running", 0)
)
@router.post("/containers/{host_id}/{container_id}/start", response_model=ContainerActionResponse)
async def start_container(
host_id: str,
container_id: str,
user: dict = Depends(get_current_user),
):
"""Start a stopped container."""
result = await docker_actions.start_container(host_id, container_id)
return ContainerActionResponse(**result)
@router.post("/containers/{host_id}/{container_id}/stop", response_model=ContainerActionResponse)
async def stop_container(
host_id: str,
container_id: str,
timeout: int = Query(10, ge=1, le=300),
user: dict = Depends(get_current_user),
):
"""Stop a running container."""
result = await docker_actions.stop_container(host_id, container_id, timeout=timeout)
return ContainerActionResponse(**result)
@router.post("/containers/{host_id}/{container_id}/restart", response_model=ContainerActionResponse)
async def restart_container(
host_id: str,
container_id: str,
timeout: int = Query(10, ge=1, le=300),
user: dict = Depends(get_current_user),
):
"""Restart a container."""
result = await docker_actions.restart_container(host_id, container_id, timeout=timeout)
return ContainerActionResponse(**result)
@router.post("/containers/{host_id}/{container_id}/remove", response_model=ContainerActionResponse)
async def remove_container(
host_id: str,
container_id: str,
force: bool = Query(False, description="Force remove running container"),
remove_volumes: bool = Query(False, description="Remove associated volumes"),
user: dict = Depends(require_admin),
):
"""Remove a container (admin only)."""
result = await docker_actions.remove_container(
host_id, container_id, force=force, remove_volumes=remove_volumes
)
return ContainerActionResponse(**result)
@router.post("/containers/{host_id}/{container_id}/redeploy", response_model=ContainerActionResponse)
async def redeploy_container(
host_id: str,
container_id: str,
user: dict = Depends(get_current_user),
):
"""Redeploy a container by pulling latest image."""
result = await docker_actions.redeploy_container(host_id, container_id)
return ContainerActionResponse(**result)
@router.get("/containers/{host_id}/{container_id}/logs", response_model=ContainerLogsResponse)
async def get_container_logs(
host_id: str,
container_id: str,
tail: int = Query(200, ge=1, le=5000),
timestamps: bool = Query(False),
since: Optional[str] = Query(None),
api_key_valid: bool = Depends(verify_api_key),
):
"""Get container logs."""
result = await docker_actions.get_container_logs(
host_id, container_id, tail=tail, timestamps=timestamps, since=since
)
return ContainerLogsResponse(**result)
@router.get("/containers/{host_id}/{container_id}/inspect", response_model=ContainerInspectResponse)
async def inspect_container(
host_id: str,
container_id: str,
api_key_valid: bool = Depends(verify_api_key),
):
"""Get detailed container information."""
result = await docker_actions.inspect_container(host_id, container_id)
return ContainerInspectResponse(**result)
# === Images ===
@router.get("/hosts/{host_id}/images", response_model=DockerImageExtendedListResponse)
async def get_images(
host_id: str,
api_key_valid: bool = Depends(verify_api_key),
db_session: AsyncSession = Depends(get_db),
):
"""List images for a host with usage information."""
image_repo = DockerImageRepository(db_session)
container_repo = DockerContainerRepository(db_session)
images = await image_repo.list_by_host(host_id)
counts = await image_repo.count_by_host(host_id)
# Get all container images to determine which images are in use
containers = await container_repo.list_by_host(host_id)
used_images = set()
for c in containers:
if c.image:
used_images.add(c.image)
# Also add the image without tag for matching
if ':' in c.image:
used_images.add(c.image.split(':')[0])
unused_count = 0
images_with_usage = []
for img in images:
# Check if image is in use by comparing repo_tags
in_use = False
if img.repo_tags:
for tag in img.repo_tags:
if tag in used_images:
in_use = True
break
# Check without tag
if ':' in tag and tag.split(':')[0] in used_images:
in_use = True
break
if not in_use:
unused_count += 1
images_with_usage.append({
"id": img.id,
"host_id": img.host_id,
"image_id": img.image_id,
"repo_tags": img.repo_tags,
"size": img.size,
"created": img.created,
"last_update_at": img.last_update_at,
"in_use": in_use
})
return DockerImageExtendedListResponse(
images=[DockerImageExtendedResponse(**img) for img in images_with_usage],
total=counts.get("total", 0),
total_size=counts.get("total_size", 0),
unused_count=unused_count
)
@router.delete("/images/{host_id}/{image_id}", response_model=ImageActionResponse)
async def remove_image(
host_id: str,
image_id: str,
force: bool = Query(False, description="Force remove even if image is in use"),
user: dict = Depends(require_admin),
):
"""Remove a Docker image (admin only)."""
result = await docker_actions.remove_image(host_id, image_id, force=force)
return ImageActionResponse(**result)
# === Volumes ===
@router.get("/hosts/{host_id}/volumes", response_model=DockerVolumeListResponse)
async def get_volumes(
host_id: str,
api_key_valid: bool = Depends(verify_api_key),
db_session: AsyncSession = Depends(get_db),
):
"""List volumes for a host."""
volume_repo = DockerVolumeRepository(db_session)
volumes = await volume_repo.list_by_host(host_id)
total = await volume_repo.count_by_host(host_id)
return DockerVolumeListResponse(
volumes=[{
"id": vol.id,
"host_id": vol.host_id,
"name": vol.name,
"driver": vol.driver,
"mountpoint": vol.mountpoint,
"scope": vol.scope,
"last_update_at": vol.last_update_at
} for vol in volumes],
total=total
)
# === Alerts ===
@router.get("/alerts", response_model=DockerAlertListResponse)
async def list_alerts(
host_id: Optional[str] = Query(None),
state: Optional[str] = Query("open", description="Filter by state: open, closed, acknowledged"),
severity: Optional[str] = Query(None, description="Filter by severity"),
limit: int = Query(100, ge=1, le=500),
offset: int = Query(0, ge=0),
api_key_valid: bool = Depends(verify_api_key),
):
"""List Docker alerts."""
result = await docker_alerts_service.get_alerts(
host_id=host_id,
state=state,
severity=severity,
limit=limit,
offset=offset
)
return DockerAlertListResponse(
alerts=result.get("alerts", []),
total=result.get("total", 0),
open_count=result.get("open_count", 0),
acknowledged_count=result.get("acknowledged_count", 0)
)
@router.post("/alerts/{alert_id}/acknowledge")
async def acknowledge_alert(
alert_id: int,
request: DockerAlertAcknowledgeRequest = None,
user: dict = Depends(get_current_user),
):
"""Acknowledge an alert."""
username = user.get("username", "unknown")
note = request.note if request else None
result = await docker_alerts_service.acknowledge_alert(alert_id, username, note)
if not result:
raise HTTPException(status_code=404, detail="Alert not found or already acknowledged")
return {"message": "Alert acknowledged", "alert": result}
@router.post("/alerts/{alert_id}/close")
async def close_alert(
alert_id: int,
user: dict = Depends(get_current_user),
):
"""Close an alert manually."""
result = await docker_alerts_service.close_alert(alert_id)
if not result:
raise HTTPException(status_code=404, detail="Alert not found or already closed")
return {"message": "Alert closed", "alert": result}
# === Stats ===
@router.get("/stats", response_model=DockerStatsResponse)
async def get_docker_stats(
api_key_valid: bool = Depends(verify_api_key),
):
"""Get global Docker statistics."""
stats = await docker_alerts_service.get_stats()
return DockerStatsResponse(**stats)

View File

@ -3,6 +3,7 @@ Routes API pour les health checks.
""" """
from datetime import datetime, timezone from datetime import datetime, timezone
import sys
from fastapi import APIRouter, Depends, HTTPException from fastapi import APIRouter, Depends, HTTPException
@ -34,6 +35,29 @@ async def global_health_check():
} }
@router.get("/runtime")
async def runtime_info(api_key_valid: bool = Depends(verify_api_key)):
"""Runtime diagnostics (python executable, asyncssh availability)."""
try:
import asyncssh # type: ignore
asyncssh_ok = True
asyncssh_version = getattr(asyncssh, "__version__", None)
except Exception as e:
asyncssh_ok = False
asyncssh_version = None
asyncssh_error = str(e)
else:
asyncssh_error = None
return {
"python_executable": sys.executable,
"python_version": sys.version,
"asyncssh_available": asyncssh_ok,
"asyncssh_version": asyncssh_version,
"asyncssh_error": asyncssh_error,
}
@router.get("/{host_name}", response_model=HealthCheck) @router.get("/{host_name}", response_model=HealthCheck)
async def check_host_health(host_name: str, api_key_valid: bool = Depends(verify_api_key)): async def check_host_health(host_name: str, api_key_valid: bool = Depends(verify_api_key)):
"""Effectue un health check sur un hôte spécifique.""" """Effectue un health check sur un hôte spécifique."""

View File

@ -2,13 +2,16 @@
Routes API pour les métriques système et des hôtes. Routes API pour les métriques système et des hôtes.
""" """
from datetime import timezone
from typing import Optional from typing import Optional
from fastapi import APIRouter, Depends, HTTPException from fastapi import APIRouter, Depends, HTTPException
from pydantic import BaseModel from pydantic import BaseModel
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
import pytz
from app.core.dependencies import get_db, verify_api_key from app.core.dependencies import get_db, verify_api_key
from app.core.config import settings
from app.crud.host_metrics import HostMetricsRepository from app.crud.host_metrics import HostMetricsRepository
@ -22,6 +25,15 @@ class CollectionScheduleRequest(BaseModel):
router = APIRouter() router = APIRouter()
def _to_app_timezone(dt):
if dt is None:
return None
if getattr(dt, "tzinfo", None) is None:
dt = dt.replace(tzinfo=timezone.utc)
tz = pytz.timezone(settings.scheduler_timezone)
return dt.astimezone(tz)
@router.get("") @router.get("")
async def get_metrics(api_key_valid: bool = Depends(verify_api_key)): async def get_metrics(api_key_valid: bool = Depends(verify_api_key)):
"""Récupère les métriques système globales.""" """Récupère les métriques système globales."""
@ -41,6 +53,7 @@ async def get_all_hosts_metrics(
# Convertir en dict host_id -> metrics # Convertir en dict host_id -> metrics
result = {} result = {}
for host_id, m in metrics_dict.items(): for host_id, m in metrics_dict.items():
collected_at = _to_app_timezone(m.collected_at)
result[m.host_id] = { result[m.host_id] = {
"host_id": m.host_id, "host_id": m.host_id,
"metric_type": m.metric_type, "metric_type": m.metric_type,
@ -56,7 +69,8 @@ async def get_all_hosts_metrics(
"disk_root_used_gb": m.disk_root_used_gb, "disk_root_used_gb": m.disk_root_used_gb,
"os_name": m.os_name, "os_name": m.os_name,
"uptime_human": m.uptime_human, "uptime_human": m.uptime_human,
"collected_at": m.collected_at, "last_collected": collected_at,
"collected_at": collected_at,
"collection_status": "success" if not m.error_message else "failed", "collection_status": "success" if not m.error_message else "failed",
"error_message": m.error_message, "error_message": m.error_message,
} }
@ -119,6 +133,8 @@ async def get_host_metrics(
if not metrics: if not metrics:
return {"host_id": host_id, "collection_status": "no_data"} return {"host_id": host_id, "collection_status": "no_data"}
collected_at = _to_app_timezone(metrics.collected_at)
return { return {
"host_id": metrics.host_id, "host_id": metrics.host_id,
"metric_type": metrics.metric_type, "metric_type": metrics.metric_type,
@ -135,7 +151,8 @@ async def get_host_metrics(
"disk_info": metrics.disk_info, "disk_info": metrics.disk_info,
"os_name": metrics.os_name, "os_name": metrics.os_name,
"uptime_human": metrics.uptime_human, "uptime_human": metrics.uptime_human,
"collected_at": metrics.collected_at, "last_collected": collected_at,
"collected_at": collected_at,
"collection_status": "success" if not metrics.error_message else "failed", "collection_status": "success" if not metrics.error_message else "failed",
"error_message": metrics.error_message, "error_message": metrics.error_message,
} }

275
app/schemas/docker.py Normal file
View File

@ -0,0 +1,275 @@
"""Pydantic schemas for Docker management."""
from datetime import datetime
from typing import Optional, List, Dict, Any, Literal
from pydantic import BaseModel, Field, ConfigDict
# === Container Schemas ===
class DockerContainerBase(BaseModel):
"""Base schema for Docker container."""
container_id: str = Field(..., description="Docker container ID")
name: str = Field(..., description="Container name")
image: Optional[str] = Field(None, description="Image name")
state: Literal["running", "exited", "paused", "created", "dead", "restarting", "removing", "unknown"] = Field(
"unknown", description="Container state"
)
status: Optional[str] = Field(None, description="Container status string")
health: Optional[Literal["healthy", "unhealthy", "starting", "none"]] = Field(
None, description="Health check status"
)
ports: Optional[Dict[str, Any]] = Field(None, description="Port mappings")
labels: Optional[Dict[str, str]] = Field(None, description="Container labels")
compose_project: Optional[str] = Field(None, description="Docker Compose project name")
class DockerContainerResponse(DockerContainerBase):
"""Response schema for Docker container."""
id: int
host_id: str
created_at: Optional[datetime] = None
last_update_at: Optional[datetime] = None
model_config = ConfigDict(from_attributes=True)
class DockerContainerListResponse(BaseModel):
"""Response for listing containers."""
containers: List[DockerContainerResponse]
total: int
running: int
stopped: int
# === Image Schemas ===
class DockerImageBase(BaseModel):
"""Base schema for Docker image."""
image_id: str = Field(..., description="Docker image ID")
repo_tags: Optional[List[str]] = Field(None, description="Repository tags")
size: Optional[int] = Field(None, description="Image size in bytes")
class DockerImageResponse(DockerImageBase):
"""Response schema for Docker image."""
id: int
host_id: str
created: Optional[datetime] = None
last_update_at: Optional[datetime] = None
model_config = ConfigDict(from_attributes=True)
class DockerImageListResponse(BaseModel):
"""Response for listing images."""
images: List[DockerImageResponse]
total: int
total_size: int
# === Volume Schemas ===
class DockerVolumeBase(BaseModel):
"""Base schema for Docker volume."""
name: str = Field(..., description="Volume name")
driver: Optional[str] = Field(None, description="Volume driver")
mountpoint: Optional[str] = Field(None, description="Mount point path")
scope: Optional[str] = Field(None, description="Volume scope")
class DockerVolumeResponse(DockerVolumeBase):
"""Response schema for Docker volume."""
id: int
host_id: str
last_update_at: Optional[datetime] = None
model_config = ConfigDict(from_attributes=True)
class DockerVolumeListResponse(BaseModel):
"""Response for listing volumes."""
volumes: List[DockerVolumeResponse]
total: int
# === Alert Schemas ===
class DockerAlertBase(BaseModel):
"""Base schema for Docker alert."""
container_name: str = Field(..., description="Container name")
severity: Literal["warning", "error", "critical"] = Field("warning", description="Alert severity")
message: Optional[str] = Field(None, description="Alert message")
class DockerAlertResponse(DockerAlertBase):
"""Response schema for Docker alert."""
id: int
host_id: str
state: Literal["open", "closed", "acknowledged"] = "open"
opened_at: datetime
closed_at: Optional[datetime] = None
acknowledged_at: Optional[datetime] = None
acknowledged_by: Optional[str] = None
last_notified_at: Optional[datetime] = None
host_name: Optional[str] = None
model_config = ConfigDict(from_attributes=True)
class DockerAlertListResponse(BaseModel):
"""Response for listing alerts."""
alerts: List[DockerAlertResponse]
total: int
open_count: int
acknowledged_count: int
class DockerAlertAcknowledgeRequest(BaseModel):
"""Request to acknowledge an alert."""
note: Optional[str] = Field(None, description="Optional note for acknowledgement")
# === Docker Host Schemas ===
class DockerHostInfo(BaseModel):
"""Docker information for a host."""
host_id: str
host_name: str
host_ip: str
docker_enabled: bool = False
docker_version: Optional[str] = None
docker_status: Optional[Literal["online", "offline", "error"]] = None
docker_last_collect_at: Optional[datetime] = None
containers_total: int = 0
containers_running: int = 0
images_total: int = 0
volumes_total: int = 0
open_alerts: int = 0
model_config = ConfigDict(from_attributes=True)
class DockerHostListResponse(BaseModel):
"""Response for listing Docker hosts."""
hosts: List[DockerHostInfo]
total: int
enabled: int
class EnableDockerRequest(BaseModel):
"""Request to enable Docker monitoring on a host."""
enabled: bool = Field(True, description="Enable or disable Docker monitoring")
# === Container Action Schemas ===
class ContainerActionResponse(BaseModel):
"""Response for container actions."""
success: bool
message: str
container_id: str
action: str
output: Optional[str] = None
error: Optional[str] = None
class ContainerLogsRequest(BaseModel):
"""Request for container logs."""
tail: int = Field(200, ge=1, le=5000, description="Number of lines to retrieve")
timestamps: bool = Field(False, description="Include timestamps")
since: Optional[str] = Field(None, description="Show logs since timestamp or relative time")
class ContainerLogsResponse(BaseModel):
"""Response for container logs."""
container_id: str
container_name: str
logs: str
lines: int
class ContainerInspectResponse(BaseModel):
"""Response for container inspect."""
container_id: str
container_name: str
inspect_data: Dict[str, Any]
# === Collection Schemas ===
class DockerCollectRequest(BaseModel):
"""Request to trigger Docker collection."""
force: bool = Field(False, description="Force collection even if recently collected")
class DockerCollectResponse(BaseModel):
"""Response for Docker collection."""
success: bool
host_id: str
host_name: str
message: str
docker_version: Optional[str] = None
containers_count: int = 0
images_count: int = 0
volumes_count: int = 0
duration_ms: int = 0
error: Optional[str] = None
class DockerCollectAllResponse(BaseModel):
"""Response for collecting all Docker hosts."""
success: bool
message: str
total_hosts: int
successful: int
failed: int
results: List[DockerCollectResponse]
# === Stats Schemas ===
class DockerStatsResponse(BaseModel):
"""Global Docker statistics."""
total_hosts: int
enabled_hosts: int
online_hosts: int
total_containers: int
running_containers: int
total_images: int
total_volumes: int
open_alerts: int
last_collection: Optional[datetime] = None
# === Image Action Schemas ===
class ImageActionResponse(BaseModel):
"""Response for image actions."""
success: bool
message: str
image_id: str
action: str
output: Optional[str] = None
error: Optional[str] = None
# === Extended Image Response with usage info ===
class DockerImageExtendedResponse(DockerImageBase):
"""Response schema for Docker image with usage info."""
id: int
host_id: str
created: Optional[datetime] = None
last_update_at: Optional[datetime] = None
in_use: bool = Field(True, description="Whether the image is used by at least one container")
model_config = ConfigDict(from_attributes=True)
class DockerImageExtendedListResponse(BaseModel):
"""Response for listing images with usage info."""
images: List[DockerImageExtendedResponse]
total: int
total_size: int
unused_count: int = 0

View File

@ -11,6 +11,7 @@ mais pas dans la section Tasks (pour éviter de polluer l'interface).
from __future__ import annotations from __future__ import annotations
import asyncio import asyncio
import ast
import json import json
import re import re
import time import time
@ -107,6 +108,16 @@ BUILTIN_PLAYBOOKS: Dict[str, BuiltinPlaybookDefinition] = {
class BuiltinPlaybookService: class BuiltinPlaybookService:
"""Service pour gérer et exécuter les builtin playbooks.""" """Service pour gérer et exécuter les builtin playbooks."""
def _loads_jsonish(self, payload: str) -> dict:
payload = payload.strip()
payload = payload.replace('\\"', '"').replace('\\n', '\n')
payload = re.sub(r"\\\s*\n", "", payload)
try:
return json.loads(payload)
except json.JSONDecodeError:
return ast.literal_eval(payload)
def __init__(self, ansible_dir: Path, ansible_service=None): def __init__(self, ansible_dir: Path, ansible_service=None):
""" """
Args: Args:
@ -267,15 +278,17 @@ class BuiltinPlaybookService:
print(f"[BUILTIN] Found {len(matches)} METRICS_JSON matches") print(f"[BUILTIN] Found {len(matches)} METRICS_JSON matches")
parse_errors: list[str] = []
for match in matches: for match in matches:
try: try:
data = json.loads(match.strip()) data = self._loads_jsonish(match)
host = data.get("host", "unknown") host = data.get("host", "unknown")
metrics = data.get("data", {}) metrics = data.get("data", {})
metrics_by_host[host] = metrics metrics_by_host[host] = metrics
print(f"[BUILTIN] Parsed metrics for host: {host}") print(f"[BUILTIN] Parsed metrics for host: {host}")
except json.JSONDecodeError as e: except (ValueError, SyntaxError) as e:
print(f"[BUILTIN] JSON decode error: {e}") parse_errors.append(str(e))
continue continue
# Fallback: essayer de parser les debug outputs Ansible standards # Fallback: essayer de parser les debug outputs Ansible standards
@ -295,18 +308,20 @@ class BuiltinPlaybookService:
try: try:
# Le JSON est échappé dans le msg, il faut le décoder # Le JSON est échappé dans le msg, il faut le décoder
unescaped = match.replace('\\"', '"').replace('\\n', '\n') unescaped = match.replace('\\"', '"').replace('\\n', '\n')
data = json.loads(unescaped.strip()) data = self._loads_jsonish(unescaped)
host = data.get("host", "unknown") host = data.get("host", "unknown")
metrics = data.get("data", {}) metrics = data.get("data", {})
metrics_by_host[host] = metrics metrics_by_host[host] = metrics
print(f"[BUILTIN] Parsed metrics from msg for host: {host}") print(f"[BUILTIN] Parsed metrics from msg for host: {host}")
except json.JSONDecodeError as e: except (ValueError, SyntaxError) as e:
print(f"[BUILTIN] JSON decode error in msg pattern: {e}") parse_errors.append(str(e))
continue continue
print(f"[BUILTIN] Total hosts with metrics: {len(metrics_by_host)}") print(f"[BUILTIN] Total hosts with metrics: {len(metrics_by_host)}")
if not metrics_by_host and stdout: if not metrics_by_host and stdout:
# Log un extrait du stdout pour debug # Log un extrait du stdout pour debug
if parse_errors:
print(f"[BUILTIN] JSON decode error: {parse_errors[-1]}")
print(f"[BUILTIN] Stdout sample (first 500 chars): {stdout[:500]}") print(f"[BUILTIN] Stdout sample (first 500 chars): {stdout[:500]}")
return metrics_by_host return metrics_by_host

View File

@ -0,0 +1,617 @@
"""Docker container actions service.
Provides methods to execute actions on Docker containers via SSH.
"""
from __future__ import annotations
import asyncio
import logging
from typing import Dict, Any, Optional
try:
import asyncssh
except ModuleNotFoundError: # pragma: no cover
asyncssh = None
from app.core.config import settings
from app.models.database import async_session_maker
from app.crud.host import HostRepository
from app.crud.docker_container import DockerContainerRepository
logger = logging.getLogger("homelab.docker.actions")
# Standard log prefix
LOG_PREFIX = "[DOCKER]"
class DockerActionError(Exception):
"""Error executing Docker action."""
pass
class DockerActionsService:
"""Service for executing Docker container actions via SSH."""
def __init__(self):
self.ssh_key_path = settings.ssh_key_path
self.ssh_user = settings.ssh_user
self.connect_timeout = 5
self.exec_timeout = 30 # Longer timeout for actions
self._locks: Dict[str, asyncio.Lock] = {}
def _get_lock(self, container_key: str) -> asyncio.Lock:
"""Get or create a lock for a container to prevent concurrent actions."""
if container_key not in self._locks:
self._locks[container_key] = asyncio.Lock()
return self._locks[container_key]
async def _ssh_connect(self, host_ip: str) -> asyncssh.SSHClientConnection:
"""Establish SSH connection to a host."""
if asyncssh is None:
raise DockerActionError(
"Missing dependency: asyncssh. Install it to enable Docker container actions over SSH."
)
try:
conn = await asyncio.wait_for(
asyncssh.connect(
host_ip,
username=self.ssh_user,
client_keys=[self.ssh_key_path],
known_hosts=None,
),
timeout=self.connect_timeout
)
return conn
except asyncio.TimeoutError:
raise DockerActionError(f"SSH connection timeout to {host_ip}")
except asyncssh.Error as e:
raise DockerActionError(f"SSH error: {e}")
except Exception as e:
raise DockerActionError(f"Connection failed: {e}")
async def _ssh_exec(
self,
conn: asyncssh.SSHClientConnection,
command: str,
timeout: Optional[int] = None
) -> Dict[str, Any]:
"""Execute a command and return result dict."""
timeout = timeout or self.exec_timeout
try:
result = await asyncio.wait_for(
conn.run(command, check=False),
timeout=timeout
)
return {
"stdout": result.stdout or "",
"stderr": result.stderr or "",
"exit_code": result.exit_status,
"success": result.exit_status == 0
}
except asyncio.TimeoutError:
raise DockerActionError(f"Command timeout")
except Exception as e:
raise DockerActionError(f"Execution error: {e}")
async def _run_docker(
self,
conn: asyncssh.SSHClientConnection,
cmd: str,
use_sudo_state: Dict[str, Optional[bool]],
timeout: Optional[int] = None,
) -> Dict[str, Any]:
"""Run a docker command, preferring sudo -n to avoid docker.sock permission issues.
use_sudo_state is a mutable dict holding a cached decision for the current connection.
"""
def _is_sudo_unavailable(stderr: str) -> bool:
s = (stderr or "").lower()
return any(
token in s
for token in (
"sudo: a password is required",
"sudo: no tty present",
"not in the sudoers",
"sudo: permission denied",
"sudo: command not found",
)
)
use_sudo = use_sudo_state.get("value")
if use_sudo is True:
return await self._ssh_exec(conn, f"sudo -n {cmd}", timeout=timeout)
if use_sudo is False:
return await self._ssh_exec(conn, cmd, timeout=timeout)
# First try with sudo -n
sudo_res = await self._ssh_exec(conn, f"sudo -n {cmd}", timeout=timeout)
if sudo_res["success"]:
use_sudo_state["value"] = True
return sudo_res
# If sudo is unavailable, fall back to plain docker
if _is_sudo_unavailable(sudo_res.get("stderr", "")):
use_sudo_state["value"] = False
return await self._ssh_exec(conn, cmd, timeout=timeout)
# Sudo ran but failed; try plain docker (rootless docker)
plain_res = await self._ssh_exec(conn, cmd, timeout=timeout)
if plain_res["success"]:
use_sudo_state["value"] = False
return plain_res
# Keep sudo as preferred (best chance for next commands)
use_sudo_state["value"] = True
merged = (plain_res.get("stderr") or "").strip()
sudo_err = (sudo_res.get("stderr") or "").strip()
if sudo_err:
merged = (merged + "\n" if merged else "") + f"sudo_err: {sudo_err}"
plain_res["stderr"] = merged
return plain_res
async def _get_host_info(self, host_id: str) -> Dict[str, Any]:
"""Get host information from database."""
async with async_session_maker() as session:
host_repo = HostRepository(session)
host = await host_repo.get(host_id)
if not host:
raise DockerActionError(f"Host not found: {host_id}")
return {
"id": host.id,
"name": host.name,
"ip": host.ip_address
}
async def start_container(
self,
host_id: str,
container_id: str
) -> Dict[str, Any]:
"""Start a stopped container."""
host = await self._get_host_info(host_id)
lock_key = f"{host_id}:{container_id}"
async with self._get_lock(lock_key):
try:
conn = await self._ssh_connect(host["ip"])
try:
use_sudo_state: Dict[str, Optional[bool]] = {"value": None}
result = await self._run_docker(conn, f"docker start {container_id}", use_sudo_state)
return {
"success": result["success"],
"message": "Container started successfully" if result["success"] else "Failed to start container",
"container_id": container_id,
"action": "start",
"output": result["stdout"].strip(),
"error": result["stderr"].strip() if not result["success"] else None
}
finally:
conn.close()
except DockerActionError as e:
return {
"success": False,
"message": str(e),
"container_id": container_id,
"action": "start",
"output": None,
"error": str(e)
}
async def stop_container(
self,
host_id: str,
container_id: str,
timeout: int = 10
) -> Dict[str, Any]:
"""Stop a running container."""
host = await self._get_host_info(host_id)
lock_key = f"{host_id}:{container_id}"
async with self._get_lock(lock_key):
try:
conn = await self._ssh_connect(host["ip"])
try:
use_sudo_state: Dict[str, Optional[bool]] = {"value": None}
result = await self._ssh_exec(
conn,
f"sudo -n docker stop -t {timeout} {container_id}",
timeout=timeout + 10
)
if not result["success"]:
# Use the common docker runner to handle sudo fallback and rootless docker
result = await self._run_docker(
conn,
f"docker stop -t {timeout} {container_id}",
use_sudo_state,
timeout=timeout + 10,
)
return {
"success": result["success"],
"message": "Container stopped successfully" if result["success"] else "Failed to stop container",
"container_id": container_id,
"action": "stop",
"output": result["stdout"].strip(),
"error": result["stderr"].strip() if not result["success"] else None
}
finally:
conn.close()
except DockerActionError as e:
return {
"success": False,
"message": str(e),
"container_id": container_id,
"action": "stop",
"output": None,
"error": str(e)
}
async def restart_container(
self,
host_id: str,
container_id: str,
timeout: int = 10
) -> Dict[str, Any]:
"""Restart a container."""
host = await self._get_host_info(host_id)
lock_key = f"{host_id}:{container_id}"
async with self._get_lock(lock_key):
try:
conn = await self._ssh_connect(host["ip"])
try:
use_sudo_state: Dict[str, Optional[bool]] = {"value": None}
result = await self._ssh_exec(
conn,
f"sudo -n docker restart -t {timeout} {container_id}",
timeout=timeout + 15
)
if not result["success"]:
result = await self._run_docker(
conn,
f"docker restart -t {timeout} {container_id}",
use_sudo_state,
timeout=timeout + 15,
)
return {
"success": result["success"],
"message": "Container restarted successfully" if result["success"] else "Failed to restart container",
"container_id": container_id,
"action": "restart",
"output": result["stdout"].strip(),
"error": result["stderr"].strip() if not result["success"] else None
}
finally:
conn.close()
except DockerActionError as e:
return {
"success": False,
"message": str(e),
"container_id": container_id,
"action": "restart",
"output": None,
"error": str(e)
}
async def remove_container(
self,
host_id: str,
container_id: str,
force: bool = False,
remove_volumes: bool = False
) -> Dict[str, Any]:
"""Remove a container."""
host = await self._get_host_info(host_id)
lock_key = f"{host_id}:{container_id}"
async with self._get_lock(lock_key):
try:
conn = await self._ssh_connect(host["ip"])
try:
use_sudo_state: Dict[str, Optional[bool]] = {"value": None}
flags = []
if force:
flags.append("-f")
if remove_volumes:
flags.append("-v")
flags_str = " ".join(flags)
result = await self._run_docker(
conn,
f"docker rm {flags_str} {container_id}",
use_sudo_state,
)
return {
"success": result["success"],
"message": "Container removed successfully" if result["success"] else "Failed to remove container",
"container_id": container_id,
"action": "remove",
"output": result["stdout"].strip(),
"error": result["stderr"].strip() if not result["success"] else None
}
finally:
conn.close()
except DockerActionError as e:
return {
"success": False,
"message": str(e),
"container_id": container_id,
"action": "remove",
"output": None,
"error": str(e)
}
async def get_container_logs(
self,
host_id: str,
container_id: str,
tail: int = 200,
timestamps: bool = False,
since: Optional[str] = None
) -> Dict[str, Any]:
"""Get container logs."""
host = await self._get_host_info(host_id)
try:
conn = await self._ssh_connect(host["ip"])
try:
use_sudo_state: Dict[str, Optional[bool]] = {"value": None}
flags = [f"--tail {tail}"]
if timestamps:
flags.append("--timestamps")
if since:
flags.append(f"--since {since}")
flags_str = " ".join(flags)
result = await self._run_docker(
conn,
f"docker logs {flags_str} {container_id} 2>&1",
use_sudo_state,
timeout=30,
)
# Get container name
name_result = await self._run_docker(
conn,
f"docker inspect --format '{{{{.Name}}}}' {container_id}",
use_sudo_state,
)
container_name = name_result["stdout"].strip().lstrip("/")
logs = result["stdout"]
lines = len(logs.split('\n')) if logs else 0
return {
"container_id": container_id,
"container_name": container_name,
"logs": logs,
"lines": lines
}
finally:
conn.close()
except DockerActionError as e:
return {
"container_id": container_id,
"container_name": "",
"logs": f"Error retrieving logs: {e}",
"lines": 0
}
async def inspect_container(
self,
host_id: str,
container_id: str
) -> Dict[str, Any]:
"""Get detailed container information."""
host = await self._get_host_info(host_id)
try:
conn = await self._ssh_connect(host["ip"])
try:
use_sudo_state: Dict[str, Optional[bool]] = {"value": None}
result = await self._run_docker(
conn,
f"docker inspect {container_id}",
use_sudo_state,
)
if result["success"]:
import json
try:
inspect_data = json.loads(result["stdout"])
if isinstance(inspect_data, list) and len(inspect_data) > 0:
inspect_data = inspect_data[0]
container_name = inspect_data.get("Name", "").lstrip("/")
return {
"container_id": container_id,
"container_name": container_name,
"inspect_data": inspect_data
}
except json.JSONDecodeError:
pass
return {
"container_id": container_id,
"container_name": "",
"inspect_data": {"error": result["stderr"] or "Failed to parse inspect data"}
}
finally:
conn.close()
except DockerActionError as e:
return {
"container_id": container_id,
"container_name": "",
"inspect_data": {"error": str(e)}
}
async def redeploy_container(
self,
host_id: str,
container_id: str
) -> Dict[str, Any]:
"""Redeploy a container by pulling latest image and recreating.
This only works for containers started with docker-compose or with
enough metadata to recreate them.
"""
host = await self._get_host_info(host_id)
lock_key = f"{host_id}:{container_id}"
async with self._get_lock(lock_key):
try:
conn = await self._ssh_connect(host["ip"])
try:
use_sudo_state: Dict[str, Optional[bool]] = {"value": None}
# Get container info first
inspect_result = await self._run_docker(
conn,
f"docker inspect --format '{{{{.Config.Image}}}}' {container_id}",
use_sudo_state,
)
if not inspect_result["success"]:
return {
"success": False,
"message": "Failed to get container image",
"container_id": container_id,
"action": "redeploy",
"output": None,
"error": inspect_result["stderr"]
}
image = inspect_result["stdout"].strip()
# Check if it's a compose container
labels_result = await self._run_docker(
conn,
f"docker inspect --format '{{{{index .Config.Labels \"com.docker.compose.project.working_dir\"}}}}' {container_id}",
use_sudo_state,
)
compose_dir = labels_result["stdout"].strip()
if compose_dir:
# Use docker-compose to redeploy
service_result = await self._run_docker(
conn,
f"docker inspect --format '{{{{index .Config.Labels \"com.docker.compose.service\"}}}}' {container_id}",
use_sudo_state,
)
service_name = service_result["stdout"].strip()
# Pull and recreate with docker-compose
# Keep working directory change in shell, run docker via sudo -n
result = await self._ssh_exec(
conn,
f"cd {compose_dir} && sudo -n docker compose pull {service_name} && sudo -n docker compose up -d {service_name}",
timeout=120,
)
if not result["success"]:
# Fallback: try without sudo (rootless docker / sudo unavailable)
result = await self._ssh_exec(
conn,
f"cd {compose_dir} && docker compose pull {service_name} && docker compose up -d {service_name}",
timeout=120,
)
else:
# Simple pull and restart
pull_result = await self._run_docker(
conn,
f"docker pull {image}",
use_sudo_state,
timeout=120,
)
if not pull_result["success"]:
return {
"success": False,
"message": "Failed to pull image",
"container_id": container_id,
"action": "redeploy",
"output": pull_result["stdout"],
"error": pull_result["stderr"]
}
# Restart container with new image
result = await self._run_docker(
conn,
f"docker restart {container_id}",
use_sudo_state,
)
return {
"success": result["success"],
"message": "Container redeployed successfully" if result["success"] else "Failed to redeploy container",
"container_id": container_id,
"action": "redeploy",
"output": result["stdout"].strip(),
"error": result["stderr"].strip() if not result["success"] else None
}
finally:
conn.close()
except DockerActionError as e:
return {
"success": False,
"message": str(e),
"container_id": container_id,
"action": "redeploy",
"output": None,
"error": str(e)
}
async def remove_image(
self,
host_id: str,
image_id: str,
force: bool = False
) -> Dict[str, Any]:
"""Remove a Docker image."""
host = await self._get_host_info(host_id)
try:
conn = await self._ssh_connect(host["ip"])
try:
use_sudo_state: Dict[str, Optional[bool]] = {"value": None}
flags = "-f" if force else ""
result = await self._run_docker(
conn,
f"docker rmi {flags} {image_id}".strip(),
use_sudo_state,
)
return {
"success": result["success"],
"message": "Image removed successfully" if result["success"] else "Failed to remove image",
"image_id": image_id,
"action": "remove",
"output": result["stdout"].strip(),
"error": result["stderr"].strip() if not result["success"] else None
}
finally:
conn.close()
except DockerActionError as e:
return {
"success": False,
"message": str(e),
"image_id": image_id,
"action": "remove",
"output": None,
"error": str(e)
}
# Singleton instance
docker_actions = DockerActionsService()

View File

@ -0,0 +1,385 @@
"""Docker alerts service.
Handles detection of container issues and alert notifications.
"""
import asyncio
import logging
from datetime import datetime, timezone, timedelta
from typing import Dict, Any, List, Optional
from app.models.database import async_session_maker
from app.crud.host import HostRepository
from app.crud.docker_container import DockerContainerRepository
from app.crud.docker_alert import DockerAlertRepository
from app.services.notification_service import notification_service
from app.services.websocket_service import ws_manager
logger = logging.getLogger("homelab.docker.alerts")
# Cooldown period between notifications for the same alert (5 minutes)
NOTIFICATION_COOLDOWN_SECONDS = 300
class DockerAlertsService:
"""Service for detecting Docker container issues and managing alerts."""
def __init__(self):
self._last_check: Optional[datetime] = None
async def check_all_alerts(self) -> Dict[str, Any]:
"""Check all Docker-enabled hosts for container issues.
Returns:
Summary of alerts opened/closed
"""
result = {
"hosts_checked": 0,
"alerts_opened": 0,
"alerts_closed": 0,
"notifications_sent": 0
}
async with async_session_maker() as session:
host_repo = HostRepository(session)
container_repo = DockerContainerRepository(session)
alert_repo = DockerAlertRepository(session)
# Get all Docker-enabled hosts
hosts = await host_repo.list_docker_enabled()
result["hosts_checked"] = len(hosts)
for host in hosts:
try:
# Get all containers for this host
containers = await container_repo.list_by_host(host.id)
for container in containers:
await self._check_container(
session, host, container, alert_repo, result
)
except Exception as e:
logger.error(f"Error checking alerts for host {host.id}: {e}")
await session.commit()
self._last_check = datetime.now(timezone.utc)
return result
async def _check_container(
self,
session,
host,
container,
alert_repo: DockerAlertRepository,
result: Dict[str, Any]
) -> None:
"""Check a single container for issues."""
labels = container.labels or {}
# Only monitor containers with homelab.monitor=true label
should_monitor = labels.get("homelab.monitor", "").lower() == "true"
if not should_monitor:
return
expected_state = labels.get("homelab.desired", "running")
current_state = container.state
health = container.health
alert_needed = False
severity = "warning"
message = None
# Case 1: Container should be running but isn't
if expected_state == "running" and current_state != "running":
alert_needed = True
severity = "error"
message = f"Container {container.name} is {current_state}, expected running"
# Case 2: Container is unhealthy
elif health == "unhealthy":
alert_needed = True
severity = "warning"
message = f"Container {container.name} health check failing"
# Case 3: Container is healthy and running - close any open alerts
elif current_state == "running" and health in ("healthy", None, "none"):
closed = await alert_repo.close_for_container(host.id, container.name)
if closed > 0:
result["alerts_closed"] += closed
logger.info(f"Closed {closed} alert(s) for {container.name} on {host.name}")
# Broadcast alert closure
await ws_manager.broadcast({
"type": "docker_alert_closed",
"data": {
"host_id": host.id,
"host_name": host.name,
"container_name": container.name
}
})
return
if alert_needed:
await self._open_or_update_alert(
session, host, container.name, severity, message, alert_repo, result
)
async def _open_or_update_alert(
self,
session,
host,
container_name: str,
severity: str,
message: str,
alert_repo: DockerAlertRepository,
result: Dict[str, Any]
) -> None:
"""Open a new alert or update existing one."""
# Check for existing open alert
existing = await alert_repo.get_open_alert(host.id, container_name)
if existing:
# Check if we should send another notification
should_notify = False
if existing.last_notified_at:
cooldown_elapsed = (
datetime.now(timezone.utc) - existing.last_notified_at.replace(tzinfo=timezone.utc)
).total_seconds() > NOTIFICATION_COOLDOWN_SECONDS
should_notify = cooldown_elapsed
else:
should_notify = True
if should_notify:
await self._send_notification(host, container_name, severity, message)
await alert_repo.update_last_notified(existing.id)
result["notifications_sent"] += 1
else:
# Create new alert
alert = await alert_repo.create(
host_id=host.id,
container_name=container_name,
severity=severity,
message=message
)
result["alerts_opened"] += 1
logger.info(f"Opened alert for {container_name} on {host.name}: {message}")
# Send notification
await self._send_notification(host, container_name, severity, message)
await alert_repo.update_last_notified(alert.id)
result["notifications_sent"] += 1
# Broadcast new alert via WebSocket
await ws_manager.broadcast({
"type": "docker_alert_opened",
"data": {
"id": alert.id,
"host_id": host.id,
"host_name": host.name,
"container_name": container_name,
"severity": severity,
"message": message,
"opened_at": datetime.now(timezone.utc).isoformat()
}
})
async def _send_notification(
self,
host,
container_name: str,
severity: str,
message: str
) -> None:
"""Send ntfy notification for an alert."""
try:
priority_map = {
"warning": 3,
"error": 4,
"critical": 5
}
priority = priority_map.get(severity, 3)
emoji = "🚨" if severity == "critical" else "⚠️" if severity == "error" else "🔔"
await notification_service.send(
topic="homelab-docker",
title=f"{emoji} Docker Alert - {host.name}",
message=f"{container_name}: {message}",
priority=priority,
tags=["docker", severity]
)
logger.info(f"Sent notification for {container_name} on {host.name}")
except Exception as e:
logger.error(f"Failed to send notification: {e}")
async def acknowledge_alert(
self,
alert_id: int,
acknowledged_by: str,
note: Optional[str] = None
) -> Optional[Dict[str, Any]]:
"""Acknowledge an alert."""
async with async_session_maker() as session:
alert_repo = DockerAlertRepository(session)
host_repo = HostRepository(session)
alert = await alert_repo.acknowledge(alert_id, acknowledged_by)
if alert:
host = await host_repo.get(alert.host_id)
await session.commit()
# Broadcast acknowledgement
await ws_manager.broadcast({
"type": "docker_alert_acknowledged",
"data": {
"id": alert.id,
"host_id": alert.host_id,
"host_name": host.name if host else "",
"container_name": alert.container_name,
"acknowledged_by": acknowledged_by,
"acknowledged_at": alert.acknowledged_at.isoformat() if alert.acknowledged_at else None
}
})
return alert.to_dict()
return None
async def close_alert(self, alert_id: int) -> Optional[Dict[str, Any]]:
"""Manually close an alert."""
async with async_session_maker() as session:
alert_repo = DockerAlertRepository(session)
host_repo = HostRepository(session)
alert = await alert_repo.close(alert_id)
if alert:
host = await host_repo.get(alert.host_id)
await session.commit()
# Broadcast closure
await ws_manager.broadcast({
"type": "docker_alert_closed",
"data": {
"id": alert.id,
"host_id": alert.host_id,
"host_name": host.name if host else "",
"container_name": alert.container_name
}
})
return alert.to_dict()
return None
async def get_alerts(
self,
host_id: Optional[str] = None,
state: Optional[str] = None,
severity: Optional[str] = None,
limit: int = 100,
offset: int = 0
) -> Dict[str, Any]:
"""Get alerts with optional filters."""
async with async_session_maker() as session:
alert_repo = DockerAlertRepository(session)
host_repo = HostRepository(session)
alerts = await alert_repo.list_alerts(
host_id=host_id,
state=state,
severity=severity,
limit=limit,
offset=offset
)
counts = await alert_repo.count_alerts(host_id=host_id)
# Enrich with host names
result = []
for alert in alerts:
alert_dict = alert.to_dict()
host = await host_repo.get(alert.host_id)
alert_dict["host_name"] = host.name if host else ""
result.append(alert_dict)
return {
"alerts": result,
"total": counts["total"],
"open_count": counts["open"],
"acknowledged_count": counts["acknowledged"]
}
async def get_stats(self) -> Dict[str, Any]:
"""Get global Docker statistics."""
async with async_session_maker() as session:
from sqlalchemy import select, func
from app.models import Host, DockerContainer, DockerImage, DockerVolume, DockerAlert
# Count hosts
total_hosts = await session.execute(
select(func.count(Host.id)).where(Host.deleted_at.is_(None))
)
enabled_hosts = await session.execute(
select(func.count(Host.id)).where(
Host.deleted_at.is_(None),
Host.docker_enabled == True
)
)
online_hosts = await session.execute(
select(func.count(Host.id)).where(
Host.deleted_at.is_(None),
Host.docker_enabled == True,
Host.docker_status == "online"
)
)
# Count containers
total_containers = await session.execute(
select(func.count(DockerContainer.id))
)
running_containers = await session.execute(
select(func.count(DockerContainer.id)).where(
DockerContainer.state == "running"
)
)
# Count images and volumes
total_images = await session.execute(
select(func.count(DockerImage.id))
)
total_volumes = await session.execute(
select(func.count(DockerVolume.id))
)
# Count open alerts
open_alerts = await session.execute(
select(func.count(DockerAlert.id)).where(
DockerAlert.state == "open"
)
)
# Last collection time
last_collect = await session.execute(
select(func.max(Host.docker_last_collect_at)).where(
Host.docker_enabled == True
)
)
return {
"total_hosts": total_hosts.scalar() or 0,
"enabled_hosts": enabled_hosts.scalar() or 0,
"online_hosts": online_hosts.scalar() or 0,
"total_containers": total_containers.scalar() or 0,
"running_containers": running_containers.scalar() or 0,
"total_images": total_images.scalar() or 0,
"total_volumes": total_volumes.scalar() or 0,
"open_alerts": open_alerts.scalar() or 0,
"last_collection": last_collect.scalar()
}
# Singleton instance
docker_alerts_service = DockerAlertsService()

View File

@ -0,0 +1,610 @@
"""Docker collection service using SSH.
Collects Docker information from hosts via SSH commands.
"""
from __future__ import annotations
import asyncio
import json
import logging
import sys
import time
from datetime import datetime, timezone
from typing import Dict, List, Optional, Any, Tuple
try:
import asyncssh
_asyncssh_import_error: Optional[BaseException] = None
except ModuleNotFoundError as e: # pragma: no cover
asyncssh = None
_asyncssh_import_error = e
from app.core.config import settings
from app.models.database import async_session_maker
from app.crud.host import HostRepository
from app.crud.docker_container import DockerContainerRepository
from app.crud.docker_image import DockerImageRepository
from app.crud.docker_volume import DockerVolumeRepository
from app.crud.docker_alert import DockerAlertRepository
from app.services.ansible_service import ansible_service
logger = logging.getLogger("homelab.docker")
# Log prefix for standardized output
LOG_PREFIX = "[DOCKER]"
class SSHConnectionError(Exception):
"""Error connecting to host via SSH."""
pass
class DockerNotAvailableError(Exception):
"""Docker is not available on the host."""
pass
class DockerService:
"""Service for collecting Docker information via SSH."""
def __init__(self):
self.ssh_key_path = settings.ssh_key_path
self.ssh_user = settings.ssh_user
self.ssh_remote_user = settings.ssh_remote_user
self.connect_timeout = 5
self.exec_timeout = 15
self._locks: Dict[str, asyncio.Lock] = {}
def _get_lock(self, host_id: str) -> asyncio.Lock:
"""Get or create a lock for a host to prevent concurrent operations."""
if host_id not in self._locks:
self._locks[host_id] = asyncio.Lock()
return self._locks[host_id]
async def _ssh_connect(self, host_ip: str) -> asyncssh.SSHClientConnection:
"""Establish SSH connection to a host."""
if asyncssh is None:
err = None
try:
err = str(_asyncssh_import_error) if _asyncssh_import_error else None
except Exception:
err = None
raise SSHConnectionError(
"Missing dependency: asyncssh. Install it to enable Docker SSH collection. "
f"(python={sys.executable}, import_error={err})"
)
last_err: Optional[BaseException] = None
tried_users: List[str] = []
for username in [self.ssh_remote_user, self.ssh_user]:
if not username or username in tried_users:
continue
tried_users.append(username)
try:
conn = await asyncio.wait_for(
asyncssh.connect(
host_ip,
username=username,
client_keys=[self.ssh_key_path],
known_hosts=None, # Accept any host key (homelab environment)
),
timeout=self.connect_timeout
)
return conn
except asyncio.TimeoutError as e:
last_err = e
continue
except asyncssh.Error as e:
last_err = e
continue
except Exception as e:
last_err = e
continue
if isinstance(last_err, asyncio.TimeoutError):
raise SSHConnectionError(f"SSH connection timeout to {host_ip} (users tried: {', '.join(tried_users)})")
raise SSHConnectionError(
f"SSH error connecting to {host_ip} (users tried: {', '.join(tried_users)}): {last_err}"
)
async def _ssh_exec(
self,
conn: asyncssh.SSHClientConnection,
command: str,
timeout: Optional[int] = None
) -> Tuple[str, str, int]:
"""Execute a command via SSH and return stdout, stderr, exit_code."""
timeout = timeout or self.exec_timeout
try:
result = await asyncio.wait_for(
conn.run(command, check=False),
timeout=timeout
)
return result.stdout or "", result.stderr or "", result.exit_status
except asyncio.TimeoutError:
raise SSHConnectionError(f"Command timeout: {command[:50]}...")
except Exception as e:
raise SSHConnectionError(f"Command execution error: {e}")
async def _parse_docker_json_lines(self, output: str) -> List[Dict[str, Any]]:
"""Parse Docker JSON output (one JSON object per line)."""
results = []
for line in output.strip().split('\n'):
line = line.strip()
if line:
try:
results.append(json.loads(line))
except json.JSONDecodeError:
continue
return results
async def collect_docker_host(self, host_id: str) -> Dict[str, Any]:
"""Collect Docker information from a single host.
Returns:
Dict with collection results including success status, counts, etc.
"""
start_time = time.time()
result = {
"success": False,
"host_id": host_id,
"host_name": "",
"message": "",
"docker_version": None,
"containers_count": 0,
"images_count": 0,
"volumes_count": 0,
"error": None,
"duration_ms": 0
}
async with self._get_lock(host_id):
async with async_session_maker() as session:
try:
# Get host info
host_repo = HostRepository(session)
host = await host_repo.get(host_id)
if not host:
result["error"] = "Host not found"
result["message"] = "Host not found"
return result
result["host_name"] = host.name
host_ip = host.ip_address
print(f"{LOG_PREFIX} Starting collection for host {host.name} ({host_id[:8]}...) at {host_ip}")
# Connect via SSH
conn = await self._ssh_connect(host_ip)
try:
use_sudo: Optional[bool] = None
async def run_docker(cmd: str) -> Tuple[str, str, int]:
nonlocal use_sudo
def _is_sudo_unavailable(stderr: str) -> bool:
s = (stderr or "").lower()
return any(
token in s
for token in (
"sudo: a password is required",
"sudo: no tty present",
"not in the sudoers",
"sudo: permission denied",
"sudo: command not found",
)
)
# If we've already determined sudo behavior, reuse it.
if use_sudo is True:
return await self._ssh_exec(conn, f"sudo -n {cmd}")
if use_sudo is False:
return await self._ssh_exec(conn, cmd)
# First call: prefer sudo -n (passwordless sudo) to avoid docker.sock permission issues.
sudo_out, sudo_err, sudo_code = await self._ssh_exec(conn, f"sudo -n {cmd}")
if sudo_code == 0:
use_sudo = True
return sudo_out, sudo_err, sudo_code
# If sudo is not available, fall back to non-sudo.
if _is_sudo_unavailable(sudo_err):
use_sudo = False
return await self._ssh_exec(conn, cmd)
# Sudo ran but command failed; try non-sudo as a fallback (e.g., rootless docker).
plain_out, plain_err, plain_code = await self._ssh_exec(conn, cmd)
if plain_code == 0:
use_sudo = False
return plain_out, plain_err, plain_code
# Keep sudo as preferred for subsequent commands (best chance to avoid docker.sock issues)
use_sudo = True
merged_err = (plain_err or "").strip()
if sudo_err:
merged_err = (merged_err + "\n" if merged_err else "") + f"sudo_err: {(sudo_err or '').strip()}"
return plain_out, merged_err, plain_code
# Get Docker version
base_version_cmd = "docker version --format '{{.Server.Version}}'"
version_out, version_err, version_code = await run_docker(base_version_cmd)
if version_code != 0:
err = (version_err or "").strip()
if "permission denied" in err.lower() and "docker.sock" in err.lower():
raise DockerNotAvailableError(
"Docker not available: permission denied while trying to connect to the Docker daemon socket. "
"Fix one of: set SSH_REMOTE_USER=root, add the SSH user to the 'docker' group, "
"or allow passwordless sudo for docker (sudo -n). "
f"Raw error: {err}"
)
raise DockerNotAvailableError(f"Docker not available: {err}")
docker_version = version_out.strip()
result["docker_version"] = docker_version
print(f"{LOG_PREFIX} {host.name}: Docker version {docker_version}, using sudo={use_sudo}")
# Collect containers
containers_out, _, _ = await run_docker(
"docker ps -a --format '{{json .}}' --no-trunc"
)
containers_data = await self._parse_docker_json_lines(containers_out)
print(f"{LOG_PREFIX} {host.name}: Found {len(containers_data)} container(s)")
# Collect images
images_out, _, _ = await run_docker(
"docker images --format '{{json .}}'"
)
images_data = await self._parse_docker_json_lines(images_out)
print(f"{LOG_PREFIX} {host.name}: Found {len(images_data)} image(s)")
# Collect volumes
volumes_out, _, _ = await run_docker(
"docker volume ls --format '{{json .}}'"
)
volumes_data = await self._parse_docker_json_lines(volumes_out)
print(f"{LOG_PREFIX} {host.name}: Found {len(volumes_data)} volume(s)")
finally:
conn.close()
# Store in database
container_repo = DockerContainerRepository(session)
image_repo = DockerImageRepository(session)
volume_repo = DockerVolumeRepository(session)
# Process containers
container_ids = []
for c in containers_data:
container_id = c.get("ID", "")
container_ids.append(container_id)
# Parse created time
created_at = None
created_str = c.get("CreatedAt", "")
if created_str:
try:
# Docker format: "2024-01-15 10:30:00 -0500 EST"
created_at = datetime.fromisoformat(
created_str.split(" ")[0] + "T" + created_str.split(" ")[1]
)
except (ValueError, IndexError):
pass
# Extract compose project from labels
compose_project = None
labels = c.get("Labels", "")
if labels:
for label in labels.split(","):
if "com.docker.compose.project=" in label:
compose_project = label.split("=", 1)[1]
break
# Parse labels into dict
labels_dict = {}
if labels:
for label in labels.split(","):
if "=" in label:
k, v = label.split("=", 1)
labels_dict[k] = v
# Parse ports
ports_str = c.get("Ports", "")
ports = {"raw": ports_str} if ports_str else None
# Determine health from status
status = c.get("Status", "")
health = None
if "(healthy)" in status.lower():
health = "healthy"
elif "(unhealthy)" in status.lower():
health = "unhealthy"
elif "(health: starting)" in status.lower():
health = "starting"
await container_repo.upsert(
host_id=host_id,
container_id=container_id,
name=c.get("Names", "").lstrip("/"),
image=c.get("Image", ""),
state=c.get("State", "unknown").lower(),
status=status,
health=health,
created_at=created_at,
ports=ports,
labels=labels_dict if labels_dict else None,
compose_project=compose_project
)
# Remove stale containers
await container_repo.delete_stale(host_id, container_ids)
result["containers_count"] = len(containers_data)
# Process images
image_ids = []
for img in images_data:
image_id = img.get("ID", "")
image_ids.append(image_id)
# Parse size (e.g., "150MB" -> bytes)
size_str = img.get("Size", "0")
size = self._parse_size(size_str)
# Parse created time
created = None
created_str = img.get("CreatedAt", "")
if created_str:
try:
created = datetime.fromisoformat(
created_str.split(" ")[0] + "T" + created_str.split(" ")[1]
)
except (ValueError, IndexError):
pass
# Get repo tags
repo = img.get("Repository", "<none>")
tag = img.get("Tag", "<none>")
repo_tags = None
if repo != "<none>":
repo_tags = [f"{repo}:{tag}"]
await image_repo.upsert(
host_id=host_id,
image_id=image_id,
repo_tags=repo_tags,
size=size,
created=created
)
await image_repo.delete_stale(host_id, image_ids)
result["images_count"] = len(images_data)
# Process volumes
volume_names = []
for vol in volumes_data:
name = vol.get("Name", "")
volume_names.append(name)
await volume_repo.upsert(
host_id=host_id,
name=name,
driver=vol.get("Driver", "local"),
mountpoint=vol.get("Mountpoint", ""),
scope=vol.get("Scope", "local")
)
await volume_repo.delete_stale(host_id, volume_names)
result["volumes_count"] = len(volumes_data)
# Update host Docker status
await host_repo.update(
host,
docker_version=docker_version,
docker_status="online",
docker_last_collect_at=datetime.now(timezone.utc)
)
await session.commit()
result["success"] = True
result["message"] = "Collection completed"
duration_ms = int((time.time() - start_time) * 1000)
print(f"{LOG_PREFIX} {host.name}: Collection completed in {duration_ms}ms - {len(containers_data)} containers, {len(images_data)} images, {len(volumes_data)} volumes")
except SSHConnectionError as e:
result["error"] = str(e)
result["message"] = "Collection failed"
# Update host status to offline
await host_repo.update(host, docker_status="offline")
await session.commit()
print(f"{LOG_PREFIX} {result.get('host_name', host_id)}: SSH connection error - {e}")
logger.warning(f"{LOG_PREFIX} SSH error collecting Docker from {host_id}: {e}")
except DockerNotAvailableError as e:
result["error"] = str(e)
result["message"] = "Collection failed"
await host_repo.update(host, docker_status="error")
await session.commit()
print(f"{LOG_PREFIX} {result.get('host_name', host_id)}: Docker not available - {e}")
logger.warning(f"{LOG_PREFIX} Docker not available on {host_id}: {e}")
except Exception as e:
result["error"] = str(e)
result["message"] = "Collection failed"
import traceback
tb = traceback.format_exc()
print(f"{LOG_PREFIX} {result.get('host_name', host_id)}: Collection error - {e}")
logger.error(f"{LOG_PREFIX} Error collecting Docker from {host_id}: {e}\n{tb}")
await session.rollback()
result["duration_ms"] = int((time.time() - start_time) * 1000)
if not result.get("message"):
result["message"] = "Collection completed" if result.get("success") else "Collection failed"
return result
async def collect_all_hosts(self) -> Dict[str, Any]:
"""Collect Docker information from all enabled hosts.
Returns:
Summary of collection results
"""
results = {
"success": True,
"total_hosts": 0,
"successful": 0,
"failed": 0,
"results": []
}
async with async_session_maker() as session:
host_repo = HostRepository(session)
hosts = await host_repo.list_docker_enabled()
results["total_hosts"] = len(hosts)
# Collect from all hosts concurrently (with limit)
semaphore = asyncio.Semaphore(5) # Max 5 concurrent collections
async def collect_with_semaphore(host):
async with semaphore:
return await self.collect_docker_host(host.id)
if hosts:
host_results = await asyncio.gather(
*[collect_with_semaphore(host) for host in hosts],
return_exceptions=True
)
for r in host_results:
if isinstance(r, Exception):
results["failed"] += 1
results["results"].append({
"success": False,
"host_id": "",
"host_name": "",
"message": "Collection failed",
"docker_version": None,
"containers_count": 0,
"images_count": 0,
"volumes_count": 0,
"duration_ms": 0,
"error": str(r)
})
elif r.get("success"):
results["successful"] += 1
results["results"].append(r)
else:
results["failed"] += 1
results["results"].append(r)
results["success"] = results["failed"] == 0
return results
def _parse_size(self, size_str: str) -> int:
"""Parse Docker size string to bytes."""
if not size_str:
return 0
size_str = size_str.upper().strip()
multipliers = {
"TB": 1024 ** 4,
"GB": 1024 ** 3,
"MB": 1024 ** 2,
"KB": 1024,
"B": 1,
}
# Important: match longer suffixes first, otherwise 'B' would match 'MB'
for suffix in ("TB", "GB", "MB", "KB", "B"):
mult = multipliers[suffix]
if size_str.endswith(suffix):
try:
num = float(size_str[:-len(suffix)])
return int(num * mult)
except ValueError:
return 0
try:
return int(size_str)
except ValueError:
return 0
async def get_docker_hosts(self) -> List[Dict[str, Any]]:
"""Get all hosts with Docker info."""
async with async_session_maker() as session:
host_repo = HostRepository(session)
container_repo = DockerContainerRepository(session)
image_repo = DockerImageRepository(session)
volume_repo = DockerVolumeRepository(session)
alert_repo = DockerAlertRepository(session)
# Best-effort: read inventory and only show hosts in role_docker group.
# Visibility is controlled by inventory membership; docker_enabled remains a user toggle.
docker_host_names: Optional[set[str]] = None
try:
inv_hosts = ansible_service.get_hosts_from_inventory()
docker_host_names = {
h.name
for h in inv_hosts
if "role_docker" in (getattr(h, "groups", None) or [])
}
except Exception:
# Inventory read is best-effort; do not break Docker UI
docker_host_names = None
# Return all active hosts so the UI can show both enabled and disabled
# Docker monitoring states (pause/play).
hosts = await host_repo.list(limit=1000)
hosts = [h for h in hosts if not h.deleted_at]
if docker_host_names is not None:
hosts = [h for h in hosts if h.name in docker_host_names]
hosts = sorted(hosts, key=lambda h: (h.name or ""))
result = []
for host in hosts:
if host.deleted_at:
continue
containers = await container_repo.count_by_host(host.id)
images = await image_repo.count_by_host(host.id)
volumes = await volume_repo.count_by_host(host.id)
open_alerts = await alert_repo.count_open_by_host(host.id)
result.append({
"host_id": host.id,
"host_name": host.name,
"host_ip": host.ip_address,
"docker_enabled": host.docker_enabled,
"docker_version": host.docker_version,
"docker_status": host.docker_status,
"docker_last_collect_at": host.docker_last_collect_at,
"containers_total": containers.get("total", 0),
"containers_running": containers.get("running", 0),
"images_total": images.get("total", 0),
"volumes_total": volumes,
"open_alerts": open_alerts
})
return result
async def enable_docker_monitoring(self, host_id: str, enabled: bool = True) -> bool:
"""Enable or disable Docker monitoring on a host."""
async with async_session_maker() as session:
host_repo = HostRepository(session)
host = await host_repo.get(host_id)
if not host:
return False
await host_repo.update(host, docker_enabled=enabled)
await session.commit()
# If enabling, trigger an immediate collection
if enabled:
asyncio.create_task(self.collect_docker_host(host_id))
return True
# Singleton instance
docker_service = DockerService()

View File

@ -23,6 +23,9 @@ from app.schemas.schedule_api import (
ScheduleUpdateRequest, ScheduleUpdateRequest,
ScheduleStats, ScheduleStats,
) )
from app.schemas.task_api import Task
from app.services.task_log_service import TaskLogService
from app.services.websocket_service import ws_manager
class SchedulerService: class SchedulerService:
@ -33,6 +36,7 @@ class SchedulerService:
self._schedules_cache: Dict[str, Schedule] = {} self._schedules_cache: Dict[str, Schedule] = {}
self._timezone = pytz.timezone(settings.scheduler_timezone) self._timezone = pytz.timezone(settings.scheduler_timezone)
self._started = False self._started = False
self._task_log_service = TaskLogService(settings.tasks_logs_dir)
@property @property
def scheduler(self) -> AsyncIOScheduler: def scheduler(self) -> AsyncIOScheduler:
@ -56,14 +60,14 @@ class SchedulerService:
await self._load_active_schedules_from_db() await self._load_active_schedules_from_db()
self.scheduler.start() self.scheduler.start()
self._started = True self._started = True
print(f" Scheduler démarré avec {len(self._schedules_cache)} schedule(s)") print(f" Scheduler démarré avec {len(self._schedules_cache)} schedule(s)")
def shutdown(self): def shutdown(self):
"""Arrête le scheduler proprement.""" """Arrête le scheduler proprement."""
if self._scheduler and self._started: if self._scheduler and self._started:
self._scheduler.shutdown(wait=False) self._scheduler.shutdown(wait=False)
self._started = False self._started = False
print(" Scheduler arrêté") print(" Scheduler arrêté")
async def _load_active_schedules_from_db(self): async def _load_active_schedules_from_db(self):
"""Charge les schedules actifs depuis la base de données.""" """Charge les schedules actifs depuis la base de données."""
@ -201,10 +205,50 @@ class SchedulerService:
status="running" status="running"
) )
task_id: Optional[str] = None
task_name = f"[Planifié] {schedule.name}"
target = schedule.target
# Créer une Task (pour aligner l'affichage UI sur /api/tasks/logs)
try:
async with async_session_maker() as session:
from app.crud.task import TaskRepository
task_id = uuid.uuid4().hex
run.task_id = task_id
repo = TaskRepository(session)
await repo.create(
id=task_id,
action=task_name,
target=target,
playbook=schedule.playbook,
status="running",
)
await session.commit()
await ws_manager.broadcast({
"type": "task_created",
"data": {
"id": task_id,
"name": task_name,
"host": target,
"status": "running",
"progress": 0,
"start_time": start_time,
"end_time": None,
"duration": None,
"output": None,
"error": None,
}
})
except Exception as e:
print(f"Erreur création Task pour schedule {schedule_id}: {e}")
try: try:
# Importer les services nécessaires # Importer les services nécessaires
from app.services.ansible_service import ansible_service from app.services.ansible_service import ansible_service
from app.services.websocket_service import ws_manager
from app.services.notification_service import notification_service from app.services.notification_service import notification_service
# Mettre à jour le statut # Mettre à jour le statut
@ -254,6 +298,69 @@ class SchedulerService:
await self._persist_run(run) await self._persist_run(run)
await self._update_schedule_stats_in_db(schedule) await self._update_schedule_stats_in_db(schedule)
# Mettre à jour la Task + générer le log markdown
try:
if task_id:
status = "completed" if result.get("success") else "failed"
mem_task = Task(
id=task_id,
name=task_name,
host=target,
status=status,
progress=100,
start_time=start_time,
end_time=end_time,
duration=f"{duration:.1f}s",
output=result.get("stdout", ""),
error=result.get("stderr", "") if not result.get("success") else None,
)
async with async_session_maker() as session:
from app.crud.task import TaskRepository
repo = TaskRepository(session)
db_task = await repo.get(task_id)
if db_task:
await repo.update(
db_task,
status=status,
completed_at=end_time,
error_message=mem_task.error,
result_data={"output": (result.get("stdout", "") or "")[:5000]},
)
await session.commit()
try:
log_path = self._task_log_service.save_task_log(
task=mem_task,
output=result.get("stdout", ""),
error=result.get("stderr", ""),
source_type="scheduled",
)
created_log = self._task_log_service.index_log_file(log_path)
if created_log:
await ws_manager.broadcast({
"type": "task_log_created",
"data": created_log.dict()
})
except Exception as log_error:
print(f"Erreur sauvegarde log markdown (schedule): {log_error}")
await ws_manager.broadcast({
"type": "task_completed" if status == "completed" else "task_failed",
"data": {
"id": task_id,
"status": status,
"progress": 100,
"duration": f"{duration:.1f}s",
"success": result.get("success", False),
"error": mem_task.error,
}
})
except Exception as e:
print(f"Erreur finalisation Task pour schedule {schedule_id}: {e}")
# Mettre à jour next_run # Mettre à jour next_run
job = self.scheduler.get_job(f"schedule_{schedule_id}") job = self.scheduler.get_job(f"schedule_{schedule_id}")
if job and job.next_run_time: if job and job.next_run_time:
@ -304,6 +411,62 @@ class SchedulerService:
await self._persist_run(run) await self._persist_run(run)
await self._update_schedule_stats_in_db(schedule) await self._update_schedule_stats_in_db(schedule)
# Mettre à jour la Task + générer le log markdown (échec)
try:
if task_id:
mem_task = Task(
id=task_id,
name=task_name,
host=target,
status="failed",
progress=100,
start_time=start_time,
end_time=end_time,
duration=f"{duration:.1f}s",
output="",
error=str(e),
)
async with async_session_maker() as session:
from app.crud.task import TaskRepository
repo = TaskRepository(session)
db_task = await repo.get(task_id)
if db_task:
await repo.update(
db_task,
status="failed",
completed_at=end_time,
error_message=str(e),
)
await session.commit()
try:
log_path = self._task_log_service.save_task_log(
task=mem_task,
error=str(e),
source_type="scheduled",
)
created_log = self._task_log_service.index_log_file(log_path)
if created_log:
await ws_manager.broadcast({
"type": "task_log_created",
"data": created_log.dict()
})
except Exception as log_error:
print(f"Erreur sauvegarde log markdown (schedule fail): {log_error}")
await ws_manager.broadcast({
"type": "task_failed",
"data": {
"id": task_id,
"status": "failed",
"error": str(e),
}
})
except Exception as inner_e:
print(f"Erreur finalisation Task (exception) pour schedule {schedule_id}: {inner_e}")
print(f"Erreur exécution schedule {schedule_id}: {e}") print(f"Erreur exécution schedule {schedule_id}: {e}")
async def _persist_run(self, run: ScheduleRun): async def _persist_run(self, run: ScheduleRun):

View File

@ -931,7 +931,7 @@ export default DashboardCore;
<div class='footer quiet pad2 space-top1 center small'> <div class='footer quiet pad2 space-top1 center small'>
Code coverage generated by Code coverage generated by
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a> <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
at 2025-12-15T13:17:18.856Z at 2025-12-15T14:35:27.374Z
</div> </div>
<script src="prettify.js"></script> <script src="prettify.js"></script>
<script> <script>

View File

@ -101,7 +101,7 @@
<div class='footer quiet pad2 space-top1 center small'> <div class='footer quiet pad2 space-top1 center small'>
Code coverage generated by Code coverage generated by
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a> <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
at 2025-12-15T13:17:18.856Z at 2025-12-15T14:35:27.374Z
</div> </div>
<script src="prettify.js"></script> <script src="prettify.js"></script>
<script> <script>

View File

@ -931,7 +931,7 @@ export default DashboardCore;
<div class='footer quiet pad2 space-top1 center small'> <div class='footer quiet pad2 space-top1 center small'>
Code coverage generated by Code coverage generated by
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a> <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
at 2025-12-15T13:17:19.105Z at 2025-12-15T14:35:27.612Z
</div> </div>
<script src="prettify.js"></script> <script src="prettify.js"></script>
<script> <script>

View File

@ -101,7 +101,7 @@
<div class='footer quiet pad2 space-top1 center small'> <div class='footer quiet pad2 space-top1 center small'>
Code coverage generated by Code coverage generated by
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a> <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
at 2025-12-15T13:17:19.105Z at 2025-12-15T14:35:27.612Z
</div> </div>
<script src="prettify.js"></script> <script src="prettify.js"></script>
<script> <script>

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,336 @@
# Docker Management - Documentation
## Vue d'ensemble
La fonctionnalité de gestion Docker permet de surveiller et gérer les containers Docker sur plusieurs hosts de votre homelab. Elle s'intègre harmonieusement avec l'architecture existante du Homelab Dashboard.
## Fonctionnalités
### Surveillance multi-hosts
- Collecte automatique des informations Docker via SSH
- Vue d'ensemble de tous les hosts Docker-enabled
- Statistiques globales (containers, images, volumes, alertes)
### Gestion des containers
- **Start/Stop/Restart** : Actions de base sur les containers
- **Logs** : Visualisation des logs en temps réel
- **Inspect** : Informations détaillées JSON
- **Redeploy** : Pull de l'image et recréation (support docker-compose)
### Alerting proactif
- Détection automatique des containers down
- Notifications ntfy lors d'alertes
- Système d'acquittement des alertes
- Labels pour configurer la surveillance
## Architecture
### Backend
```
app/
├── models/
│ ├── docker_container.py # Modèle SQLAlchemy containers
│ ├── docker_image.py # Modèle SQLAlchemy images
│ ├── docker_volume.py # Modèle SQLAlchemy volumes
│ └── docker_alert.py # Modèle SQLAlchemy alertes
├── crud/
│ ├── docker_container.py # CRUD operations containers
│ ├── docker_image.py # CRUD operations images
│ ├── docker_volume.py # CRUD operations volumes
│ └── docker_alert.py # CRUD operations alertes
├── schemas/
│ └── docker.py # Schémas Pydantic
├── services/
│ ├── docker_service.py # Service de collecte SSH
│ ├── docker_actions.py # Actions sur containers
│ └── docker_alerts.py # Gestion des alertes
└── routes/
└── docker.py # API endpoints
```
### Frontend
```
app/
├── index.html # Section Docker (page-docker)
└── docker_section.js # Logique JavaScript
```
## API Endpoints
### Hosts Docker
| Endpoint | Méthode | Description |
|----------|---------|-------------|
| `/api/docker/hosts` | GET | Liste tous les hosts avec infos Docker |
| `/api/docker/hosts/{host_id}/enable` | POST | Active/désactive surveillance Docker |
| `/api/docker/hosts/{host_id}/collect` | POST | Force une collecte immédiate |
| `/api/docker/collect-all` | POST | Collecte sur tous les hosts enabled |
### Containers
| Endpoint | Méthode | Description |
|----------|---------|-------------|
| `/api/docker/hosts/{host_id}/containers` | GET | Liste containers d'un host |
| `/api/docker/containers/{host_id}/{container_id}/start` | POST | Démarre un container |
| `/api/docker/containers/{host_id}/{container_id}/stop` | POST | Arrête un container |
| `/api/docker/containers/{host_id}/{container_id}/restart` | POST | Redémarre un container |
| `/api/docker/containers/{host_id}/{container_id}/remove` | POST | Supprime un container (admin) |
| `/api/docker/containers/{host_id}/{container_id}/redeploy` | POST | Redéploie un container |
| `/api/docker/containers/{host_id}/{container_id}/logs` | GET | Récupère les logs |
| `/api/docker/containers/{host_id}/{container_id}/inspect` | GET | Informations détaillées |
### Images & Volumes
| Endpoint | Méthode | Description |
|----------|---------|-------------|
| `/api/docker/hosts/{host_id}/images` | GET | Liste images d'un host |
| `/api/docker/hosts/{host_id}/volumes` | GET | Liste volumes d'un host |
### Alertes
| Endpoint | Méthode | Description |
|----------|---------|-------------|
| `/api/docker/alerts` | GET | Liste les alertes Docker |
| `/api/docker/alerts/{alert_id}/acknowledge` | POST | Acquitte une alerte |
| `/api/docker/alerts/{alert_id}/close` | POST | Ferme une alerte |
### Statistiques
| Endpoint | Méthode | Description |
|----------|---------|-------------|
| `/api/docker/stats` | GET | Statistiques globales Docker |
## Configuration
### Activer Docker sur un host
1. **Via l'API** :
```bash
curl -X POST -H "Authorization: Bearer $TOKEN" \
http://localhost:8000/api/docker/hosts/{host_id}/enable \
-H "Content-Type: application/json" \
-d '{"enabled": true}'
```
2. **Via l'interface** : Section Docker > Cliquez sur le bouton play/pause sur un host
### Labelliser les containers pour l'alerting
Ajoutez ces labels à vos containers pour activer la surveillance :
```yaml
# docker-compose.yml
services:
nginx:
image: nginx:latest
labels:
homelab.monitor: "true" # Active la surveillance
homelab.desired: "running" # État attendu (running/stopped)
```
Les containers avec `homelab.monitor: "true"` seront surveillés. Si leur état ne correspond pas à `homelab.desired`, une alerte sera créée.
### Jobs planifiés
Deux jobs APScheduler sont configurés automatiquement au démarrage :
1. **docker_collect** (toutes les 60 secondes) : Collecte les infos Docker de tous les hosts enabled
2. **docker_alerts** (toutes les 30 secondes) : Vérifie l'état des containers et génère des alertes
## Collecte via SSH
La collecte Docker utilise SSH pour exécuter des commandes Docker sur les hosts distants. Le système réutilise la configuration SSH existante (user `automation`, clés SSH).
### Commandes exécutées
```bash
# Version Docker
docker version --format '{{.Server.Version}}'
# Containers
docker ps -a --format '{{json .}}' --no-trunc
# Images
docker images --format '{{json .}}'
# Volumes
docker volume ls --format '{{json .}}'
```
### Timeouts
- **Connect timeout** : 5 secondes
- **Exec timeout** : 15 secondes (30 secondes pour les actions)
## Base de données
### Migration Alembic
```bash
# Appliquer la migration
alembic upgrade head
```
La migration `0011_add_docker_management_tables.py` crée :
- Extension de la table `hosts` avec colonnes Docker
- Table `docker_containers`
- Table `docker_images`
- Table `docker_volumes`
- Table `docker_alerts`
### Schéma des tables
```sql
-- Extension hosts
ALTER TABLE hosts ADD COLUMN docker_enabled BOOLEAN DEFAULT FALSE;
ALTER TABLE hosts ADD COLUMN docker_version TEXT;
ALTER TABLE hosts ADD COLUMN docker_status TEXT; -- online/offline/error
ALTER TABLE hosts ADD COLUMN docker_last_collect_at TIMESTAMP;
-- Containers
CREATE TABLE docker_containers (
id INTEGER PRIMARY KEY,
host_id TEXT REFERENCES hosts(id) ON DELETE CASCADE,
container_id TEXT NOT NULL,
name TEXT NOT NULL,
image TEXT,
state TEXT, -- running/exited/paused/created/dead
status TEXT, -- "Up 2 hours", etc.
health TEXT, -- healthy/unhealthy/starting/none
created_at TIMESTAMP,
ports JSON,
labels JSON,
compose_project TEXT, -- com.docker.compose.project
last_update_at TIMESTAMP
);
-- Alertes
CREATE TABLE docker_alerts (
id INTEGER PRIMARY KEY,
host_id TEXT REFERENCES hosts(id) ON DELETE CASCADE,
container_name TEXT NOT NULL,
severity TEXT, -- warning/error/critical
state TEXT, -- open/closed/acknowledged
message TEXT,
opened_at TIMESTAMP,
closed_at TIMESTAMP,
acknowledged_at TIMESTAMP,
acknowledged_by TEXT,
last_notified_at TIMESTAMP
);
```
## Interface utilisateur
### Section Docker
- **Statistiques** : Cards avec nombre de hosts, containers, images, alertes
- **Actions** : Bouton "Collecter Tout", accès aux alertes Docker
- **Recherche** : Filtre les hosts par nom ou IP
- **Grille hosts** : Cards cliquables pour chaque host Docker
### Modal détails host
Onglets disponibles :
- **Containers** : Liste avec actions (start/stop/restart/logs)
- **Images** : Liste des images avec taille
- **Volumes** : Liste des volumes
- **Alertes** : Alertes spécifiques à ce host
### Notifications temps réel
Via WebSocket, le frontend reçoit :
- `docker_host_updated` : Mise à jour d'un host
- `docker_alert_opened` : Nouvelle alerte
- `docker_alert_closed` : Alerte fermée
- `docker_alert_acknowledged` : Alerte acquittée
## Sécurité
- Toutes les routes nécessitent une authentification (JWT ou API Key)
- L'action `remove` nécessite le rôle `admin`
- Timeouts stricts pour éviter les blocages SSH
- Pas d'exécution de commandes arbitraires
## Exemples curl
### Lister les hosts Docker
```bash
curl -H "Authorization: Bearer $TOKEN" \
http://localhost:8000/api/docker/hosts
```
### Activer Docker sur un host
```bash
curl -X POST -H "Authorization: Bearer $TOKEN" \
http://localhost:8000/api/docker/hosts/host-123/enable \
-H "Content-Type: application/json" \
-d '{"enabled": true}'
```
### Forcer une collecte
```bash
curl -X POST -H "Authorization: Bearer $TOKEN" \
http://localhost:8000/api/docker/hosts/host-123/collect
```
### Démarrer un container
```bash
curl -X POST -H "Authorization: Bearer $TOKEN" \
http://localhost:8000/api/docker/containers/host-123/abc456def/start
```
### Voir les logs d'un container
```bash
curl -H "Authorization: Bearer $TOKEN" \
"http://localhost:8000/api/docker/containers/host-123/abc456def/logs?tail=200"
```
### Lister les alertes ouvertes
```bash
curl -H "Authorization: Bearer $TOKEN" \
"http://localhost:8000/api/docker/alerts?state=open"
```
### Acquitter une alerte
```bash
curl -X POST -H "Authorization: Bearer $TOKEN" \
http://localhost:8000/api/docker/alerts/1/acknowledge \
-H "Content-Type: application/json" \
-d '{"note": "Investigating the issue"}'
```
## Dépendances
### Python
- `asyncssh` : Connexions SSH asynchrones
- Dépendances existantes (FastAPI, SQLAlchemy, APScheduler, etc.)
### Ajout de asyncssh
Si asyncssh n'est pas installé :
```bash
pip install asyncssh
```
## Dépannage
### Erreur "Docker not available"
- Vérifier que Docker est installé sur le host
- Vérifier que l'utilisateur `automation` a les droits Docker (`docker` group)
### Timeouts SSH
- Vérifier la connectivité réseau
- Vérifier les clés SSH
- Augmenter les timeouts si nécessaire dans `docker_service.py`
### Containers non détectés
- Vérifier que Docker monitoring est activé sur le host
- Forcer une collecte manuelle
- Vérifier les logs de l'application
### Alertes non envoyées
- Vérifier que ntfy est configuré et activé
- Vérifier les labels `homelab.monitor` sur les containers
- Vérifier les logs pour les erreurs de notification

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,224 @@
# ✅ [Planifié] Health-check-5min
## Informations
| Propriété | Valeur |
|-----------|--------|
| **ID** | `18b20e3f2b854ff09fcc0a12bcc2883a` |
| **Nom** | [Planifié] Health-check-5min |
| **Cible** | `all` |
| **Statut** | completed |
| **Type** | Planifié |
| **Progression** | 100% |
| **Début** | 2025-12-16T00:00:00.001546+00:00 |
| **Fin** | 2025-12-16T00:00:26.808331+00:00 |
| **Durée** | 26.8s |
## Sortie
```
Using /mnt/c/dev/git/python/homelab-automation-api-v2/ansible/ansible.cfg as config file
PLAY [Health check on target host] *********************************************
TASK [Check if host is reachable (ping)] ***************************************
ok: [hp.nas.home] => {"changed": false, "ping": "pong"}
ok: [mimi.pc.home] => {"changed": false, "ping": "pong"}
ok: [hp2.i7.home] => {"changed": false, "ping": "pong"}
ok: [hp3.i5.home] => {"changed": false, "ping": "pong"}
ok: [ali2v.xeon.home] => {"changed": false, "ping": "pong"}
ok: [dev.lab.home] => {"changed": false, "ping": "pong"}
ok: [media.labb.home] => {"changed": false, "ping": "pong"}
ok: [raspi.8gb.home] => {"changed": false, "ping": "pong"}
ok: [raspi.4gb.home] => {"changed": false, "ping": "pong"}
ok: [automate.prod.home] => {"changed": false, "ping": "pong"}
ok: [ali2v.truenas.home] => {"changed": false, "ping": "pong"}
ok: [hp.truenas.home] => {"changed": false, "ping": "pong"}
ok: [dev.prod.home] => {"changed": false, "ping": "pong"}
ok: [localhost] => {"changed": false, "ping": "pong"}
ok: [jump.point.home] => {"changed": false, "ping": "pong"}
ok: [orangepi.pc.home] => {"changed": false, "ping": "pong"}
TASK [Gather minimal facts] ****************************************************
ok: [hp.nas.home]
ok: [mimi.pc.home]
ok: [hp2.i7.home]
ok: [ali2v.xeon.home]
ok: [hp3.i5.home]
ok: [dev.lab.home]
ok: [media.labb.home]
ok: [raspi.8gb.home]
ok: [raspi.4gb.home]
ok: [ali2v.truenas.home]
ok: [automate.prod.home]
ok: [dev.prod.home]
ok: [hp.truenas.home]
ok: [jump.point.home]
ok: [localhost]
ok: [orangepi.pc.home]
TASK [Get system uptime] *******************************************************
ok: [mimi.pc.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003846", "end": "2025-12-15 19:00:14.927037", "msg": "", "rc": 0, "start": "2025-12-15 19:00:14.923191", "stderr": "", "stderr_lines": [], "stdout": " 19:00:14 up 20 days, 8:10, 1 user, load average: 0.12, 0.12, 0.09", "stdout_lines": [" 19:00:14 up 20 days, 8:10, 1 user, load average: 0.12, 0.12, 0.09"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.002787", "end": "2025-12-15 19:00:14.949549", "msg": "", "rc": 0, "start": "2025-12-15 19:00:14.946762", "stderr": "", "stderr_lines": [], "stdout": " 19:00:14 up 1 day, 8:32, 1 user, load average: 0.46, 0.48, 0.60", "stdout_lines": [" 19:00:14 up 1 day, 8:32, 1 user, load average: 0.46, 0.48, 0.60"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.004200", "end": "2025-12-15 19:00:14.958825", "msg": "", "rc": 0, "start": "2025-12-15 19:00:14.954625", "stderr": "", "stderr_lines": [], "stdout": " 19:00:14 up 20 days, 7:24, 1 user, load average: 0.81, 0.86, 0.80", "stdout_lines": [" 19:00:14 up 20 days, 7:24, 1 user, load average: 0.81, 0.86, 0.80"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.008631", "end": "2025-12-15 19:00:15.670899", "msg": "", "rc": 0, "start": "2025-12-15 19:00:15.662268", "stderr": "", "stderr_lines": [], "stdout": " 19:00:15 up 192 days, 10:33, 1 user, load average: 0.16, 0.13, 0.13", "stdout_lines": [" 19:00:15 up 192 days, 10:33, 1 user, load average: 0.16, 0.13, 0.13"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.009372", "end": "2025-12-15 19:00:15.711691", "msg": "", "rc": 0, "start": "2025-12-15 19:00:15.702319", "stderr": "", "stderr_lines": [], "stdout": " 19:00:15 up 192 days, 10:33, 1 user, load average: 0.31, 0.26, 0.27", "stdout_lines": [" 19:00:15 up 192 days, 10:33, 1 user, load average: 0.31, 0.26, 0.27"]}
ok: [hp.nas.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:01.004206", "end": "2025-12-15 19:00:15.915096", "msg": "", "rc": 0, "start": "2025-12-15 19:00:14.910890", "stderr": "", "stderr_lines": [], "stdout": " 19:00:14 up 20 days, 5:51, 1 user, load average: 0.13, 0.11, 0.12", "stdout_lines": [" 19:00:14 up 20 days, 5:51, 1 user, load average: 0.13, 0.11, 0.12"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:01.004005", "end": "2025-12-15 19:00:15.925632", "msg": "", "rc": 0, "start": "2025-12-15 19:00:14.921627", "stderr": "", "stderr_lines": [], "stdout": " 19:00:14 up 20 days, 6:11, 1 user, load average: 0.81, 0.77, 0.70", "stdout_lines": [" 19:00:14 up 20 days, 6:11, 1 user, load average: 0.81, 0.77, 0.70"]}
ok: [dev.lab.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003027", "end": "2025-12-15 18:59:51.589223", "msg": "", "rc": 0, "start": "2025-12-15 18:59:51.586196", "stderr": "", "stderr_lines": [], "stdout": " 18:59:51 up 9 days, 6:49, 0 user, load average: 0.04, 0.09, 0.12", "stdout_lines": [" 18:59:51 up 9 days, 6:49, 0 user, load average: 0.04, 0.09, 0.12"]}
ok: [media.labb.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003548", "end": "2025-12-15 18:59:45.820393", "msg": "", "rc": 0, "start": "2025-12-15 18:59:45.816845", "stderr": "", "stderr_lines": [], "stdout": " 18:59:45 up 16 days, 3:01, 0 user, load average: 0.00, 0.01, 0.00", "stdout_lines": [" 18:59:45 up 16 days, 3:01, 0 user, load average: 0.00, 0.01, 0.00"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.004536", "end": "2025-12-15 19:00:16.480501", "msg": "", "rc": 0, "start": "2025-12-15 19:00:16.475965", "stderr": "", "stderr_lines": [], "stdout": " 19:00:16 up 1 day, 8:31, 1 user, load average: 0.11, 0.11, 0.04", "stdout_lines": [" 19:00:16 up 1 day, 8:31, 1 user, load average: 0.11, 0.11, 0.04"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.019459", "end": "2025-12-15 19:00:16.369456", "msg": "", "rc": 0, "start": "2025-12-15 19:00:16.349997", "stderr": "", "stderr_lines": [], "stdout": " 19:00:16 up 13 days, 8:26, 1 user, load average: 0.34, 0.17, 0.13", "stdout_lines": [" 19:00:16 up 13 days, 8:26, 1 user, load average: 0.34, 0.17, 0.13"]}
ok: [automate.prod.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003777", "end": "2025-12-15 18:59:48.650310", "msg": "", "rc": 0, "start": "2025-12-15 18:59:48.646533", "stderr": "", "stderr_lines": [], "stdout": " 18:59:48 up 18 days, 21:54, 0 user, load average: 0.41, 0.38, 0.40", "stdout_lines": [" 18:59:48 up 18 days, 21:54, 0 user, load average: 0.41, 0.38, 0.40"]}
ok: [dev.prod.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.002744", "end": "2025-12-15 18:59:54.717225", "msg": "", "rc": 0, "start": "2025-12-15 18:59:54.714481", "stderr": "", "stderr_lines": [], "stdout": " 18:59:54 up 15 days, 8:15, 0 user, load average: 0.07, 0.15, 0.13", "stdout_lines": [" 18:59:54 up 15 days, 8:15, 0 user, load average: 0.07, 0.15, 0.13"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.004535", "end": "2025-12-15 16:00:16.804789", "msg": "", "rc": 0, "start": "2025-12-15 16:00:16.800254", "stderr": "", "stderr_lines": [], "stdout": " 4:00PM up 20 days, 5:50, 1 user, load averages: 0.38, 0.26, 0.24", "stdout_lines": [" 4:00PM up 20 days, 5:50, 1 user, load averages: 0.38, 0.26, 0.24"]}
ok: [jump.point.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003708", "end": "2025-12-15 19:00:16.957215", "msg": "", "rc": 0, "start": "2025-12-15 19:00:16.953507", "stderr": "", "stderr_lines": [], "stdout": " 19:00:16 up 1 day, 8:31, 1 user, load average: 0.00, 0.01, 0.04", "stdout_lines": [" 19:00:16 up 1 day, 8:31, 1 user, load average: 0.00, 0.01, 0.04"]}
ok: [localhost] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.017263", "end": "2025-12-15 19:00:17.151340", "msg": "", "rc": 0, "start": "2025-12-15 19:00:17.134077", "stderr": "", "stderr_lines": [], "stdout": " 19:00:17 up 5:35, 1 user, load average: 1.45, 1.26, 1.20", "stdout_lines": [" 19:00:17 up 5:35, 1 user, load average: 1.45, 1.26, 1.20"]}
TASK [Get disk usage] **********************************************************
ok: [hp.nas.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004282", "end": "2025-12-15 19:00:17.433650", "msg": "", "rc": 0, "start": "2025-12-15 19:00:17.429368", "stderr": "", "stderr_lines": [], "stdout": "23%", "stdout_lines": ["23%"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004121", "end": "2025-12-15 19:00:17.445214", "msg": "", "rc": 0, "start": "2025-12-15 19:00:17.441093", "stderr": "", "stderr_lines": [], "stdout": "22%", "stdout_lines": ["22%"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004757", "end": "2025-12-15 19:00:17.477825", "msg": "", "rc": 0, "start": "2025-12-15 19:00:17.473068", "stderr": "", "stderr_lines": [], "stdout": "14%", "stdout_lines": ["14%"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005109", "end": "2025-12-15 19:00:17.506427", "msg": "", "rc": 0, "start": "2025-12-15 19:00:17.501318", "stderr": "", "stderr_lines": [], "stdout": "9%", "stdout_lines": ["9%"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005820", "end": "2025-12-15 19:00:17.501727", "msg": "", "rc": 0, "start": "2025-12-15 19:00:17.495907", "stderr": "", "stderr_lines": [], "stdout": "14%", "stdout_lines": ["14%"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004790", "end": "2025-12-15 18:59:53.434634", "msg": "", "rc": 0, "start": "2025-12-15 18:59:53.429844", "stderr": "", "stderr_lines": [], "stdout": "48%", "stdout_lines": ["48%"]}
ok: [media.labb.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.006566", "end": "2025-12-15 18:59:47.572244", "msg": "", "rc": 0, "start": "2025-12-15 18:59:47.565678", "stderr": "", "stderr_lines": [], "stdout": "24%", "stdout_lines": ["24%"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.011736", "end": "2025-12-15 19:00:18.289340", "msg": "", "rc": 0, "start": "2025-12-15 19:00:18.277604", "stderr": "", "stderr_lines": [], "stdout": "6%", "stdout_lines": ["6%"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.010528", "end": "2025-12-15 19:00:18.285633", "msg": "", "rc": 0, "start": "2025-12-15 19:00:18.275105", "stderr": "", "stderr_lines": [], "stdout": "3%", "stdout_lines": ["3%"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005819", "end": "2025-12-15 19:00:18.540395", "msg": "", "rc": 0, "start": "2025-12-15 19:00:18.534576", "stderr": "", "stderr_lines": [], "stdout": "1%", "stdout_lines": ["1%"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005521", "end": "2025-12-15 18:59:50.797982", "msg": "", "rc": 0, "start": "2025-12-15 18:59:50.792461", "stderr": "", "stderr_lines": [], "stdout": "28%", "stdout_lines": ["28%"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005494", "end": "2025-12-15 16:00:18.774699", "msg": "", "rc": 0, "start": "2025-12-15 16:00:18.769205", "stderr": "", "stderr_lines": [], "stdout": "10%", "stdout_lines": ["10%"]}
ok: [dev.prod.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005120", "end": "2025-12-15 18:59:56.810526", "msg": "", "rc": 0, "start": "2025-12-15 18:59:56.805406", "stderr": "", "stderr_lines": [], "stdout": "75%", "stdout_lines": ["75%"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.025054", "end": "2025-12-15 19:00:18.868208", "msg": "", "rc": 0, "start": "2025-12-15 19:00:18.843154", "stderr": "", "stderr_lines": [], "stdout": "21%", "stdout_lines": ["21%"]}
ok: [jump.point.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005389", "end": "2025-12-15 19:00:19.040965", "msg": "", "rc": 0, "start": "2025-12-15 19:00:19.035576", "stderr": "", "stderr_lines": [], "stdout": "79%", "stdout_lines": ["79%"]}
ok: [localhost] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.008530", "end": "2025-12-15 19:00:19.272824", "msg": "", "rc": 0, "start": "2025-12-15 19:00:19.264294", "stderr": "", "stderr_lines": [], "stdout": "1%", "stdout_lines": ["1%"]}
TASK [Get memory usage (Linux)] ************************************************
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004008", "end": "2025-12-15 19:00:19.564983", "msg": "", "rc": 0, "start": "2025-12-15 19:00:19.560975", "stderr": "", "stderr_lines": [], "stdout": "21.7%", "stdout_lines": ["21.7%"]}
ok: [hp.nas.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004483", "end": "2025-12-15 19:00:19.563315", "msg": "", "rc": 0, "start": "2025-12-15 19:00:19.558832", "stderr": "", "stderr_lines": [], "stdout": "80.3%", "stdout_lines": ["80.3%"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005023", "end": "2025-12-15 19:00:19.579792", "msg": "", "rc": 0, "start": "2025-12-15 19:00:19.574769", "stderr": "", "stderr_lines": [], "stdout": "49.2%", "stdout_lines": ["49.2%"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005724", "end": "2025-12-15 19:00:19.605476", "msg": "", "rc": 0, "start": "2025-12-15 19:00:19.599752", "stderr": "", "stderr_lines": [], "stdout": "59.4%", "stdout_lines": ["59.4%"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005161", "end": "2025-12-15 19:00:19.632069", "msg": "", "rc": 0, "start": "2025-12-15 19:00:19.626908", "stderr": "", "stderr_lines": [], "stdout": "8.9%", "stdout_lines": ["8.9%"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.003865", "end": "2025-12-15 18:59:55.463185", "msg": "", "rc": 0, "start": "2025-12-15 18:59:55.459320", "stderr": "", "stderr_lines": [], "stdout": "70.8%", "stdout_lines": ["70.8%"]}
ok: [media.labb.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004488", "end": "2025-12-15 18:59:49.632709", "msg": "", "rc": 0, "start": "2025-12-15 18:59:49.628221", "stderr": "", "stderr_lines": [], "stdout": "72.1%", "stdout_lines": ["72.1%"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.010995", "end": "2025-12-15 19:00:20.249924", "msg": "", "rc": 0, "start": "2025-12-15 19:00:20.238929", "stderr": "", "stderr_lines": [], "stdout": "6.8%", "stdout_lines": ["6.8%"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.011907", "end": "2025-12-15 19:00:20.299166", "msg": "", "rc": 0, "start": "2025-12-15 19:00:20.287259", "stderr": "", "stderr_lines": [], "stdout": "12.6%", "stdout_lines": ["12.6%"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005881", "end": "2025-12-15 19:00:20.550155", "msg": "", "rc": 0, "start": "2025-12-15 19:00:20.544274", "stderr": "", "stderr_lines": [], "stdout": "34.0%", "stdout_lines": ["34.0%"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004173", "end": "2025-12-15 18:59:52.814637", "msg": "", "rc": 0, "start": "2025-12-15 18:59:52.810464", "stderr": "", "stderr_lines": [], "stdout": "25.6%", "stdout_lines": ["25.6%"]}
ok: [dev.prod.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.003984", "end": "2025-12-15 18:59:58.820168", "msg": "", "rc": 0, "start": "2025-12-15 18:59:58.816184", "stderr": "", "stderr_lines": [], "stdout": "55.4%", "stdout_lines": ["55.4%"]}
fatal: [hp.truenas.home]: FAILED! => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005301", "end": "2025-12-15 16:00:20.854211", "msg": "non-zero return code", "rc": 2, "start": "2025-12-15 16:00:20.848910", "stderr": "cat: /proc/meminfo: No such file or directory\nawk: division by zero\n source line number 1", "stderr_lines": ["cat: /proc/meminfo: No such file or directory", "awk: division by zero", " source line number 1"], "stdout": "", "stdout_lines": []}
...ignoring
ok: [jump.point.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005476", "end": "2025-12-15 19:00:21.052770", "msg": "", "rc": 0, "start": "2025-12-15 19:00:21.047294", "stderr": "", "stderr_lines": [], "stdout": "13.4%", "stdout_lines": ["13.4%"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.025841", "end": "2025-12-15 19:00:20.967638", "msg": "", "rc": 0, "start": "2025-12-15 19:00:20.941797", "stderr": "", "stderr_lines": [], "stdout": "20.2%", "stdout_lines": ["20.2%"]}
ok: [localhost] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.019033", "end": "2025-12-15 19:00:21.279875", "msg": "", "rc": 0, "start": "2025-12-15 19:00:21.260842", "stderr": "", "stderr_lines": [], "stdout": "12.5%", "stdout_lines": ["12.5%"]}
TASK [Get CPU temperature (ARM/SBC)] *******************************************
ok: [hp.nas.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.005181", "end": "2025-12-15 19:00:21.599102", "msg": "", "rc": 0, "start": "2025-12-15 19:00:21.593921", "stderr": "", "stderr_lines": [], "stdout": "30.0°C", "stdout_lines": ["30.0°C"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.004896", "end": "2025-12-15 19:00:21.638589", "msg": "", "rc": 0, "start": "2025-12-15 19:00:21.633693", "stderr": "", "stderr_lines": [], "stdout": "45.0°C", "stdout_lines": ["45.0°C"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003032", "end": "2025-12-15 19:00:21.681949", "msg": "", "rc": 0, "start": "2025-12-15 19:00:21.678917", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.005777", "end": "2025-12-15 19:00:21.677603", "msg": "", "rc": 0, "start": "2025-12-15 19:00:21.671826", "stderr": "cat: /sys/class/thermal/thermal_zone0/temp: No data available", "stderr_lines": ["cat: /sys/class/thermal/thermal_zone0/temp: No data available"], "stdout": "0.0°C", "stdout_lines": ["0.0°C"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.006922", "end": "2025-12-15 19:00:21.692134", "msg": "", "rc": 0, "start": "2025-12-15 19:00:21.685212", "stderr": "", "stderr_lines": [], "stdout": "52.5°C", "stdout_lines": ["52.5°C"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.002581", "end": "2025-12-15 18:59:57.602603", "msg": "", "rc": 0, "start": "2025-12-15 18:59:57.600022", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [media.labb.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003058", "end": "2025-12-15 18:59:51.750933", "msg": "", "rc": 0, "start": "2025-12-15 18:59:51.747875", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.013234", "end": "2025-12-15 19:00:22.374290", "msg": "", "rc": 0, "start": "2025-12-15 19:00:22.361056", "stderr": "", "stderr_lines": [], "stdout": "36.0°C", "stdout_lines": ["36.0°C"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.011848", "end": "2025-12-15 19:00:22.391353", "msg": "", "rc": 0, "start": "2025-12-15 19:00:22.379505", "stderr": "", "stderr_lines": [], "stdout": "33.1°C", "stdout_lines": ["33.1°C"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003201", "end": "2025-12-15 19:00:22.660230", "msg": "", "rc": 0, "start": "2025-12-15 19:00:22.657029", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003009", "end": "2025-12-15 18:59:54.961322", "msg": "", "rc": 0, "start": "2025-12-15 18:59:54.958313", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.004129", "end": "2025-12-15 16:00:22.959200", "msg": "", "rc": 0, "start": "2025-12-15 16:00:22.955071", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [dev.prod.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.002395", "end": "2025-12-15 19:00:00.992210", "msg": "", "rc": 0, "start": "2025-12-15 19:00:00.989815", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [jump.point.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.002923", "end": "2025-12-15 19:00:23.142767", "msg": "", "rc": 0, "start": "2025-12-15 19:00:23.139844", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.028616", "end": "2025-12-15 19:00:23.027752", "msg": "", "rc": 0, "start": "2025-12-15 19:00:22.999136", "stderr": "", "stderr_lines": [], "stdout": "35.7°C", "stdout_lines": ["35.7°C"]}
ok: [localhost] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.017688", "end": "2025-12-15 19:00:23.431780", "msg": "", "rc": 0, "start": "2025-12-15 19:00:23.414092", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
TASK [Get CPU load] ************************************************************
ok: [hp.nas.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004269", "end": "2025-12-15 19:00:23.745740", "msg": "", "rc": 0, "start": "2025-12-15 19:00:23.741471", "stderr": "", "stderr_lines": [], "stdout": "0.19", "stdout_lines": ["0.19"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004216", "end": "2025-12-15 19:00:23.774932", "msg": "", "rc": 0, "start": "2025-12-15 19:00:23.770716", "stderr": "", "stderr_lines": [], "stdout": "0.47", "stdout_lines": ["0.47"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005603", "end": "2025-12-15 19:00:23.796380", "msg": "", "rc": 0, "start": "2025-12-15 19:00:23.790777", "stderr": "", "stderr_lines": [], "stdout": "0.76", "stdout_lines": ["0.76"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004873", "end": "2025-12-15 19:00:23.799509", "msg": "", "rc": 0, "start": "2025-12-15 19:00:23.794636", "stderr": "", "stderr_lines": [], "stdout": "0.74", "stdout_lines": ["0.74"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005006", "end": "2025-12-15 19:00:23.823861", "msg": "", "rc": 0, "start": "2025-12-15 19:00:23.818855", "stderr": "", "stderr_lines": [], "stdout": "0.10", "stdout_lines": ["0.10"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004122", "end": "2025-12-15 18:59:59.734247", "msg": "", "rc": 0, "start": "2025-12-15 18:59:59.730125", "stderr": "", "stderr_lines": [], "stdout": "0.04", "stdout_lines": ["0.04"]}
ok: [media.labb.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005401", "end": "2025-12-15 18:59:53.905223", "msg": "", "rc": 0, "start": "2025-12-15 18:59:53.899822", "stderr": "", "stderr_lines": [], "stdout": "0.00", "stdout_lines": ["0.00"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.010696", "end": "2025-12-15 19:00:24.637252", "msg": "", "rc": 0, "start": "2025-12-15 19:00:24.626556", "stderr": "", "stderr_lines": [], "stdout": "0.13", "stdout_lines": ["0.13"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.011324", "end": "2025-12-15 19:00:24.636507", "msg": "", "rc": 0, "start": "2025-12-15 19:00:24.625183", "stderr": "", "stderr_lines": [], "stdout": "0.37", "stdout_lines": ["0.37"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005707", "end": "2025-12-15 19:00:24.857973", "msg": "", "rc": 0, "start": "2025-12-15 19:00:24.852266", "stderr": "", "stderr_lines": [], "stdout": "0.10", "stdout_lines": ["0.10"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004717", "end": "2025-12-15 18:59:57.162752", "msg": "", "rc": 0, "start": "2025-12-15 18:59:57.158035", "stderr": "", "stderr_lines": [], "stdout": "0.42", "stdout_lines": ["0.42"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.006024", "end": "2025-12-15 16:00:25.141797", "msg": "", "rc": 0, "start": "2025-12-15 16:00:25.135773", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}
ok: [dev.prod.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004641", "end": "2025-12-15 19:00:03.189834", "msg": "", "rc": 0, "start": "2025-12-15 19:00:03.185193", "stderr": "", "stderr_lines": [], "stdout": "0.28", "stdout_lines": ["0.28"]}
ok: [jump.point.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005272", "end": "2025-12-15 19:00:25.299429", "msg": "", "rc": 0, "start": "2025-12-15 19:00:25.294157", "stderr": "", "stderr_lines": [], "stdout": "0.00", "stdout_lines": ["0.00"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.023976", "end": "2025-12-15 19:00:25.215750", "msg": "", "rc": 0, "start": "2025-12-15 19:00:25.191774", "stderr": "", "stderr_lines": [], "stdout": "0.39", "stdout_lines": ["0.39"]}
ok: [localhost] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.007176", "end": "2025-12-15 19:00:25.700292", "msg": "", "rc": 0, "start": "2025-12-15 19:00:25.693116", "stderr": "", "stderr_lines": [], "stdout": "1.61", "stdout_lines": ["1.61"]}
TASK [Display health status] ***************************************************
ok: [ali2v.xeon.home] => {
"msg": "═══════════════════════════════════════\nHost: ali2v.xeon.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:00:14 up 1 day, 8:32, 1 user, load average: 0.46, 0.48, 0.60\nDisk Usage: 22%\nMemory Usage: 21.7%\nCPU Load: 0.47\nCPU Temp: 45.0°C\n═══════════════════════════════════════\n"
}
ok: [hp.nas.home] => {
"msg": "═══════════════════════════════════════\nHost: hp.nas.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:00:14 up 20 days, 5:51, 1 user, load average: 0.13, 0.11, 0.12\nDisk Usage: 23%\nMemory Usage: 80.3%\nCPU Load: 0.19\nCPU Temp: 30.0°C\n═══════════════════════════════════════\n"
}
ok: [hp2.i7.home] => {
"msg": "═══════════════════════════════════════\nHost: hp2.i7.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:00:14 up 20 days, 6:11, 1 user, load average: 0.81, 0.77, 0.70\nDisk Usage: 14%\nMemory Usage: 49.2%\nCPU Load: 0.74\nCPU Temp: 0.0°C\n═══════════════════════════════════════\n"
}
ok: [hp3.i5.home] => {
"msg": "═══════════════════════════════════════\nHost: hp3.i5.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:00:14 up 20 days, 7:24, 1 user, load average: 0.81, 0.86, 0.80\nDisk Usage: 14%\nMemory Usage: 59.4%\nCPU Load: 0.76\nCPU Temp: 52.5°C\n═══════════════════════════════════════\n"
}
ok: [mimi.pc.home] => {
"msg": "═══════════════════════════════════════\nHost: mimi.pc.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:00:14 up 20 days, 8:10, 1 user, load average: 0.12, 0.12, 0.09\nDisk Usage: 9%\nMemory Usage: 8.9%\nCPU Load: 0.10\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [orangepi.pc.home] => {
"msg": "═══════════════════════════════════════\nHost: orangepi.pc.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:00:16 up 13 days, 8:26, 1 user, load average: 0.34, 0.17, 0.13\nDisk Usage: 21%\nMemory Usage: 20.2%\nCPU Load: 0.39\nCPU Temp: 35.7°C\n═══════════════════════════════════════\n"
}
ok: [raspi.4gb.home] => {
"msg": "═══════════════════════════════════════\nHost: raspi.4gb.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:00:15 up 192 days, 10:33, 1 user, load average: 0.31, 0.26, 0.27\nDisk Usage: 6%\nMemory Usage: 12.6%\nCPU Load: 0.37\nCPU Temp: 36.0°C\n═══════════════════════════════════════\n"
}
ok: [raspi.8gb.home] => {
"msg": "═══════════════════════════════════════\nHost: raspi.8gb.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:00:15 up 192 days, 10:33, 1 user, load average: 0.16, 0.13, 0.13\nDisk Usage: 3%\nMemory Usage: 6.8%\nCPU Load: 0.13\nCPU Temp: 33.1°C\n═══════════════════════════════════════\n"
}
ok: [dev.lab.home] => {
"msg": "═══════════════════════════════════════\nHost: dev.lab.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 18:59:51 up 9 days, 6:49, 0 user, load average: 0.04, 0.09, 0.12\nDisk Usage: 48%\nMemory Usage: 70.8%\nCPU Load: 0.04\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [media.labb.home] => {
"msg": "═══════════════════════════════════════\nHost: media.labb.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 18:59:45 up 16 days, 3:01, 0 user, load average: 0.00, 0.01, 0.00\nDisk Usage: 24%\nMemory Usage: 72.1%\nCPU Load: 0.00\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [ali2v.truenas.home] => {
"msg": "═══════════════════════════════════════\nHost: ali2v.truenas.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:00:16 up 1 day, 8:31, 1 user, load average: 0.11, 0.11, 0.04\nDisk Usage: 1%\nMemory Usage: 34.0%\nCPU Load: 0.10\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [automate.prod.home] => {
"msg": "═══════════════════════════════════════\nHost: automate.prod.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 18:59:48 up 18 days, 21:54, 0 user, load average: 0.41, 0.38, 0.40\nDisk Usage: 28%\nMemory Usage: 25.6%\nCPU Load: 0.42\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [dev.prod.home] => {
"msg": "═══════════════════════════════════════\nHost: dev.prod.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 18:59:54 up 15 days, 8:15, 0 user, load average: 0.07, 0.15, 0.13\nDisk Usage: 75%\nMemory Usage: 55.4%\nCPU Load: 0.28\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [hp.truenas.home] => {
"msg": "═══════════════════════════════════════\nHost: hp.truenas.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 4:00PM up 20 days, 5:50, 1 user, load averages: 0.38, 0.26, 0.24\nDisk Usage: 10%\nMemory Usage: \nCPU Load: \nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [jump.point.home] => {
"msg": "═══════════════════════════════════════\nHost: jump.point.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:00:16 up 1 day, 8:31, 1 user, load average: 0.00, 0.01, 0.04\nDisk Usage: 79%\nMemory Usage: 13.4%\nCPU Load: 0.00\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [localhost] => {
"msg": "═══════════════════════════════════════\nHost: localhost\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:00:17 up 5:35, 1 user, load average: 1.45, 1.26, 1.20\nDisk Usage: 1%\nMemory Usage: 12.5%\nCPU Load: 1.61\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
PLAY RECAP *********************************************************************
ali2v.truenas.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
ali2v.xeon.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
automate.prod.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
dev.lab.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
dev.prod.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
hp.nas.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
hp.truenas.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=1
hp2.i7.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
hp3.i5.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
jump.point.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
localhost : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
media.labb.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
mimi.pc.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
orangepi.pc.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
raspi.4gb.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
raspi.8gb.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
```
---
*Généré automatiquement par Homelab Automation Dashboard*
*Date: 2025-12-16T00:00:26.864747+00:00*

View File

@ -0,0 +1,224 @@
# ✅ [Planifié] Health-check-5min
## Informations
| Propriété | Valeur |
|-----------|--------|
| **ID** | `a0573bc2482d4026894a763815a7b656` |
| **Nom** | [Planifié] Health-check-5min |
| **Cible** | `all` |
| **Statut** | completed |
| **Type** | Planifié |
| **Progression** | 100% |
| **Début** | 2025-12-16T00:05:00.006446+00:00 |
| **Fin** | 2025-12-16T00:05:24.604586+00:00 |
| **Durée** | 24.6s |
## Sortie
```
Using /mnt/c/dev/git/python/homelab-automation-api-v2/ansible/ansible.cfg as config file
PLAY [Health check on target host] *********************************************
TASK [Check if host is reachable (ping)] ***************************************
ok: [hp.nas.home] => {"changed": false, "ping": "pong"}
ok: [hp2.i7.home] => {"changed": false, "ping": "pong"}
ok: [mimi.pc.home] => {"changed": false, "ping": "pong"}
ok: [ali2v.xeon.home] => {"changed": false, "ping": "pong"}
ok: [hp3.i5.home] => {"changed": false, "ping": "pong"}
ok: [dev.lab.home] => {"changed": false, "ping": "pong"}
ok: [media.labb.home] => {"changed": false, "ping": "pong"}
ok: [raspi.8gb.home] => {"changed": false, "ping": "pong"}
ok: [raspi.4gb.home] => {"changed": false, "ping": "pong"}
ok: [automate.prod.home] => {"changed": false, "ping": "pong"}
ok: [ali2v.truenas.home] => {"changed": false, "ping": "pong"}
ok: [hp.truenas.home] => {"changed": false, "ping": "pong"}
ok: [localhost] => {"changed": false, "ping": "pong"}
ok: [dev.prod.home] => {"changed": false, "ping": "pong"}
ok: [jump.point.home] => {"changed": false, "ping": "pong"}
ok: [orangepi.pc.home] => {"changed": false, "ping": "pong"}
TASK [Gather minimal facts] ****************************************************
ok: [hp.nas.home]
ok: [hp2.i7.home]
ok: [mimi.pc.home]
ok: [hp3.i5.home]
ok: [ali2v.xeon.home]
ok: [dev.lab.home]
ok: [media.labb.home]
ok: [raspi.8gb.home]
ok: [raspi.4gb.home]
ok: [ali2v.truenas.home]
ok: [automate.prod.home]
ok: [dev.prod.home]
ok: [hp.truenas.home]
ok: [jump.point.home]
ok: [localhost]
ok: [orangepi.pc.home]
TASK [Get system uptime] *******************************************************
ok: [hp2.i7.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003510", "end": "2025-12-15 19:05:12.508663", "msg": "", "rc": 0, "start": "2025-12-15 19:05:12.505153", "stderr": "", "stderr_lines": [], "stdout": " 19:05:12 up 20 days, 6:16, 1 user, load average: 0.53, 0.67, 0.67", "stdout_lines": [" 19:05:12 up 20 days, 6:16, 1 user, load average: 0.53, 0.67, 0.67"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003618", "end": "2025-12-15 19:05:12.500719", "msg": "", "rc": 0, "start": "2025-12-15 19:05:12.497101", "stderr": "", "stderr_lines": [], "stdout": " 19:05:12 up 20 days, 8:15, 1 user, load average: 0.06, 0.08, 0.08", "stdout_lines": [" 19:05:12 up 20 days, 8:15, 1 user, load average: 0.06, 0.08, 0.08"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.002810", "end": "2025-12-15 19:05:12.532729", "msg": "", "rc": 0, "start": "2025-12-15 19:05:12.529919", "stderr": "", "stderr_lines": [], "stdout": " 19:05:12 up 1 day, 8:37, 1 user, load average: 0.29, 0.41, 0.54", "stdout_lines": [" 19:05:12 up 1 day, 8:37, 1 user, load average: 0.29, 0.41, 0.54"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.008523", "end": "2025-12-15 19:05:13.248058", "msg": "", "rc": 0, "start": "2025-12-15 19:05:13.239535", "stderr": "", "stderr_lines": [], "stdout": " 19:05:13 up 192 days, 10:38, 1 user, load average: 0.14, 0.12, 0.11", "stdout_lines": [" 19:05:13 up 192 days, 10:38, 1 user, load average: 0.14, 0.12, 0.11"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.009595", "end": "2025-12-15 19:05:13.284779", "msg": "", "rc": 0, "start": "2025-12-15 19:05:13.275184", "stderr": "", "stderr_lines": [], "stdout": " 19:05:13 up 192 days, 10:38, 1 user, load average: 0.12, 0.17, 0.23", "stdout_lines": [" 19:05:13 up 192 days, 10:38, 1 user, load average: 0.12, 0.17, 0.23"]}
ok: [hp.nas.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:01.004194", "end": "2025-12-15 19:05:13.494342", "msg": "", "rc": 0, "start": "2025-12-15 19:05:12.490148", "stderr": "", "stderr_lines": [], "stdout": " 19:05:12 up 20 days, 5:56, 1 user, load average: 0.25, 0.15, 0.12", "stdout_lines": [" 19:05:12 up 20 days, 5:56, 1 user, load average: 0.25, 0.15, 0.12"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:01.005039", "end": "2025-12-15 19:05:13.525863", "msg": "", "rc": 0, "start": "2025-12-15 19:05:12.520824", "stderr": "", "stderr_lines": [], "stdout": " 19:05:12 up 20 days, 7:29, 1 user, load average: 0.63, 0.86, 0.82", "stdout_lines": [" 19:05:12 up 20 days, 7:29, 1 user, load average: 0.63, 0.86, 0.82"]}
ok: [dev.lab.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.002914", "end": "2025-12-15 19:04:49.250464", "msg": "", "rc": 0, "start": "2025-12-15 19:04:49.247550", "stderr": "", "stderr_lines": [], "stdout": " 19:04:49 up 9 days, 6:54, 0 user, load average: 0.10, 0.12, 0.11", "stdout_lines": [" 19:04:49 up 9 days, 6:54, 0 user, load average: 0.10, 0.12, 0.11"]}
ok: [media.labb.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.009053", "end": "2025-12-15 19:04:43.439521", "msg": "", "rc": 0, "start": "2025-12-15 19:04:43.430468", "stderr": "", "stderr_lines": [], "stdout": " 19:04:43 up 16 days, 3:06, 0 user, load average: 0.08, 0.03, 0.01", "stdout_lines": [" 19:04:43 up 16 days, 3:06, 0 user, load average: 0.08, 0.03, 0.01"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.004597", "end": "2025-12-15 19:05:14.025927", "msg": "", "rc": 0, "start": "2025-12-15 19:05:14.021330", "stderr": "", "stderr_lines": [], "stdout": " 19:05:14 up 1 day, 8:36, 1 user, load average: 0.01, 0.04, 0.01", "stdout_lines": [" 19:05:14 up 1 day, 8:36, 1 user, load average: 0.01, 0.04, 0.01"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.019701", "end": "2025-12-15 19:05:13.980686", "msg": "", "rc": 0, "start": "2025-12-15 19:05:13.960985", "stderr": "", "stderr_lines": [], "stdout": " 19:05:13 up 13 days, 8:31, 1 user, load average: 0.23, 0.15, 0.12", "stdout_lines": [" 19:05:13 up 13 days, 8:31, 1 user, load average: 0.23, 0.15, 0.12"]}
ok: [automate.prod.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.004377", "end": "2025-12-15 19:04:46.237913", "msg": "", "rc": 0, "start": "2025-12-15 19:04:46.233536", "stderr": "", "stderr_lines": [], "stdout": " 19:04:46 up 18 days, 21:59, 0 user, load average: 0.68, 0.60, 0.50", "stdout_lines": [" 19:04:46 up 18 days, 21:59, 0 user, load average: 0.68, 0.60, 0.50"]}
ok: [dev.prod.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.002802", "end": "2025-12-15 19:04:52.421697", "msg": "", "rc": 0, "start": "2025-12-15 19:04:52.418895", "stderr": "", "stderr_lines": [], "stdout": " 19:04:52 up 15 days, 8:20, 0 user, load average: 0.11, 0.20, 0.17", "stdout_lines": [" 19:04:52 up 15 days, 8:20, 0 user, load average: 0.11, 0.20, 0.17"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.004261", "end": "2025-12-15 16:05:14.513278", "msg": "", "rc": 0, "start": "2025-12-15 16:05:14.509017", "stderr": "", "stderr_lines": [], "stdout": " 4:05PM up 20 days, 5:55, 1 user, load averages: 0.25, 0.28, 0.25", "stdout_lines": [" 4:05PM up 20 days, 5:55, 1 user, load averages: 0.25, 0.28, 0.25"]}
ok: [jump.point.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003980", "end": "2025-12-15 19:05:14.566811", "msg": "", "rc": 0, "start": "2025-12-15 19:05:14.562831", "stderr": "", "stderr_lines": [], "stdout": " 19:05:14 up 1 day, 8:36, 1 user, load average: 0.37, 0.10, 0.05", "stdout_lines": [" 19:05:14 up 1 day, 8:36, 1 user, load average: 0.37, 0.10, 0.05"]}
ok: [localhost] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.004519", "end": "2025-12-15 19:05:14.818265", "msg": "", "rc": 0, "start": "2025-12-15 19:05:14.813746", "stderr": "", "stderr_lines": [], "stdout": " 19:05:14 up 5:40, 1 user, load average: 1.30, 1.21, 1.19", "stdout_lines": [" 19:05:14 up 5:40, 1 user, load average: 1.30, 1.21, 1.19"]}
TASK [Get disk usage] **********************************************************
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004110", "end": "2025-12-15 19:05:15.046434", "msg": "", "rc": 0, "start": "2025-12-15 19:05:15.042324", "stderr": "", "stderr_lines": [], "stdout": "22%", "stdout_lines": ["22%"]}
ok: [hp.nas.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004337", "end": "2025-12-15 19:05:15.058262", "msg": "", "rc": 0, "start": "2025-12-15 19:05:15.053925", "stderr": "", "stderr_lines": [], "stdout": "23%", "stdout_lines": ["23%"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004935", "end": "2025-12-15 19:05:15.094934", "msg": "", "rc": 0, "start": "2025-12-15 19:05:15.089999", "stderr": "", "stderr_lines": [], "stdout": "14%", "stdout_lines": ["14%"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.003962", "end": "2025-12-15 19:05:15.119753", "msg": "", "rc": 0, "start": "2025-12-15 19:05:15.115791", "stderr": "", "stderr_lines": [], "stdout": "9%", "stdout_lines": ["9%"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005818", "end": "2025-12-15 19:05:15.149553", "msg": "", "rc": 0, "start": "2025-12-15 19:05:15.143735", "stderr": "", "stderr_lines": [], "stdout": "14%", "stdout_lines": ["14%"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004769", "end": "2025-12-15 19:04:51.059396", "msg": "", "rc": 0, "start": "2025-12-15 19:04:51.054627", "stderr": "", "stderr_lines": [], "stdout": "48%", "stdout_lines": ["48%"]}
ok: [media.labb.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005860", "end": "2025-12-15 19:04:45.234729", "msg": "", "rc": 0, "start": "2025-12-15 19:04:45.228869", "stderr": "", "stderr_lines": [], "stdout": "24%", "stdout_lines": ["24%"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.010929", "end": "2025-12-15 19:05:15.911839", "msg": "", "rc": 0, "start": "2025-12-15 19:05:15.900910", "stderr": "", "stderr_lines": [], "stdout": "3%", "stdout_lines": ["3%"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.011673", "end": "2025-12-15 19:05:15.933916", "msg": "", "rc": 0, "start": "2025-12-15 19:05:15.922243", "stderr": "", "stderr_lines": [], "stdout": "6%", "stdout_lines": ["6%"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005942", "end": "2025-12-15 19:05:16.192011", "msg": "", "rc": 0, "start": "2025-12-15 19:05:16.186069", "stderr": "", "stderr_lines": [], "stdout": "1%", "stdout_lines": ["1%"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005911", "end": "2025-12-15 19:04:48.520256", "msg": "", "rc": 0, "start": "2025-12-15 19:04:48.514345", "stderr": "", "stderr_lines": [], "stdout": "28%", "stdout_lines": ["28%"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005661", "end": "2025-12-15 16:05:16.491370", "msg": "", "rc": 0, "start": "2025-12-15 16:05:16.485709", "stderr": "", "stderr_lines": [], "stdout": "10%", "stdout_lines": ["10%"]}
ok: [dev.prod.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005558", "end": "2025-12-15 19:04:54.534312", "msg": "", "rc": 0, "start": "2025-12-15 19:04:54.528754", "stderr": "", "stderr_lines": [], "stdout": "75%", "stdout_lines": ["75%"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.025452", "end": "2025-12-15 19:05:16.500558", "msg": "", "rc": 0, "start": "2025-12-15 19:05:16.475106", "stderr": "", "stderr_lines": [], "stdout": "21%", "stdout_lines": ["21%"]}
ok: [jump.point.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005503", "end": "2025-12-15 19:05:16.680526", "msg": "", "rc": 0, "start": "2025-12-15 19:05:16.675023", "stderr": "", "stderr_lines": [], "stdout": "79%", "stdout_lines": ["79%"]}
ok: [localhost] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.020086", "end": "2025-12-15 19:05:17.046005", "msg": "", "rc": 0, "start": "2025-12-15 19:05:17.025919", "stderr": "", "stderr_lines": [], "stdout": "1%", "stdout_lines": ["1%"]}
TASK [Get memory usage (Linux)] ************************************************
ok: [hp.nas.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004356", "end": "2025-12-15 19:05:17.318500", "msg": "", "rc": 0, "start": "2025-12-15 19:05:17.314144", "stderr": "", "stderr_lines": [], "stdout": "80.2%", "stdout_lines": ["80.2%"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004166", "end": "2025-12-15 19:05:17.329345", "msg": "", "rc": 0, "start": "2025-12-15 19:05:17.325179", "stderr": "", "stderr_lines": [], "stdout": "21.8%", "stdout_lines": ["21.8%"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004904", "end": "2025-12-15 19:05:17.351621", "msg": "", "rc": 0, "start": "2025-12-15 19:05:17.346717", "stderr": "", "stderr_lines": [], "stdout": "49.2%", "stdout_lines": ["49.2%"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005565", "end": "2025-12-15 19:05:17.391465", "msg": "", "rc": 0, "start": "2025-12-15 19:05:17.385900", "stderr": "", "stderr_lines": [], "stdout": "59.4%", "stdout_lines": ["59.4%"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004983", "end": "2025-12-15 19:05:17.391234", "msg": "", "rc": 0, "start": "2025-12-15 19:05:17.386251", "stderr": "", "stderr_lines": [], "stdout": "9.0%", "stdout_lines": ["9.0%"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004130", "end": "2025-12-15 19:04:53.324936", "msg": "", "rc": 0, "start": "2025-12-15 19:04:53.320806", "stderr": "", "stderr_lines": [], "stdout": "70.8%", "stdout_lines": ["70.8%"]}
ok: [media.labb.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004343", "end": "2025-12-15 19:04:47.469957", "msg": "", "rc": 0, "start": "2025-12-15 19:04:47.465614", "stderr": "", "stderr_lines": [], "stdout": "72.1%", "stdout_lines": ["72.1%"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.010994", "end": "2025-12-15 19:05:18.115181", "msg": "", "rc": 0, "start": "2025-12-15 19:05:18.104187", "stderr": "", "stderr_lines": [], "stdout": "6.7%", "stdout_lines": ["6.7%"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.011934", "end": "2025-12-15 19:05:18.108327", "msg": "", "rc": 0, "start": "2025-12-15 19:05:18.096393", "stderr": "", "stderr_lines": [], "stdout": "12.9%", "stdout_lines": ["12.9%"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005773", "end": "2025-12-15 19:05:18.409685", "msg": "", "rc": 0, "start": "2025-12-15 19:05:18.403912", "stderr": "", "stderr_lines": [], "stdout": "34.1%", "stdout_lines": ["34.1%"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004373", "end": "2025-12-15 19:04:50.659697", "msg": "", "rc": 0, "start": "2025-12-15 19:04:50.655324", "stderr": "", "stderr_lines": [], "stdout": "25.6%", "stdout_lines": ["25.6%"]}
ok: [dev.prod.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.003801", "end": "2025-12-15 19:04:56.675260", "msg": "", "rc": 0, "start": "2025-12-15 19:04:56.671459", "stderr": "", "stderr_lines": [], "stdout": "56.5%", "stdout_lines": ["56.5%"]}
fatal: [hp.truenas.home]: FAILED! => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005434", "end": "2025-12-15 16:05:18.676861", "msg": "non-zero return code", "rc": 2, "start": "2025-12-15 16:05:18.671427", "stderr": "cat: /proc/meminfo: No such file or directory\nawk: division by zero\n source line number 1", "stderr_lines": ["cat: /proc/meminfo: No such file or directory", "awk: division by zero", " source line number 1"], "stdout": "", "stdout_lines": []}
...ignoring
ok: [orangepi.pc.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.025800", "end": "2025-12-15 19:05:18.759865", "msg": "", "rc": 0, "start": "2025-12-15 19:05:18.734065", "stderr": "", "stderr_lines": [], "stdout": "18.8%", "stdout_lines": ["18.8%"]}
ok: [jump.point.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005766", "end": "2025-12-15 19:05:18.931535", "msg": "", "rc": 0, "start": "2025-12-15 19:05:18.925769", "stderr": "", "stderr_lines": [], "stdout": "13.4%", "stdout_lines": ["13.4%"]}
ok: [localhost] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.009862", "end": "2025-12-15 19:05:19.165634", "msg": "", "rc": 0, "start": "2025-12-15 19:05:19.155772", "stderr": "", "stderr_lines": [], "stdout": "12.4%", "stdout_lines": ["12.4%"]}
TASK [Get CPU temperature (ARM/SBC)] *******************************************
ok: [hp.nas.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.005200", "end": "2025-12-15 19:05:19.478855", "msg": "", "rc": 0, "start": "2025-12-15 19:05:19.473655", "stderr": "", "stderr_lines": [], "stdout": "30.0°C", "stdout_lines": ["30.0°C"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.004747", "end": "2025-12-15 19:05:19.513677", "msg": "", "rc": 0, "start": "2025-12-15 19:05:19.508930", "stderr": "", "stderr_lines": [], "stdout": "47.0°C", "stdout_lines": ["47.0°C"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.006422", "end": "2025-12-15 19:05:19.541126", "msg": "", "rc": 0, "start": "2025-12-15 19:05:19.534704", "stderr": "", "stderr_lines": [], "stdout": "52.5°C", "stdout_lines": ["52.5°C"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.005624", "end": "2025-12-15 19:05:19.545314", "msg": "", "rc": 0, "start": "2025-12-15 19:05:19.539690", "stderr": "cat: /sys/class/thermal/thermal_zone0/temp: No data available", "stderr_lines": ["cat: /sys/class/thermal/thermal_zone0/temp: No data available"], "stdout": "0.0°C", "stdout_lines": ["0.0°C"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003326", "end": "2025-12-15 19:05:19.561899", "msg": "", "rc": 0, "start": "2025-12-15 19:05:19.558573", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.002816", "end": "2025-12-15 19:04:55.415573", "msg": "", "rc": 0, "start": "2025-12-15 19:04:55.412757", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [media.labb.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003254", "end": "2025-12-15 19:04:49.554903", "msg": "", "rc": 0, "start": "2025-12-15 19:04:49.551649", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.012126", "end": "2025-12-15 19:05:20.199621", "msg": "", "rc": 0, "start": "2025-12-15 19:05:20.187495", "stderr": "", "stderr_lines": [], "stdout": "31.6°C", "stdout_lines": ["31.6°C"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.013148", "end": "2025-12-15 19:05:20.264589", "msg": "", "rc": 0, "start": "2025-12-15 19:05:20.251441", "stderr": "", "stderr_lines": [], "stdout": "37.0°C", "stdout_lines": ["37.0°C"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003107", "end": "2025-12-15 19:05:20.551270", "msg": "", "rc": 0, "start": "2025-12-15 19:05:20.548163", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.002789", "end": "2025-12-15 19:04:52.808139", "msg": "", "rc": 0, "start": "2025-12-15 19:04:52.805350", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [dev.prod.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.002395", "end": "2025-12-15 19:04:58.775299", "msg": "", "rc": 0, "start": "2025-12-15 19:04:58.772904", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003936", "end": "2025-12-15 16:05:20.770068", "msg": "", "rc": 0, "start": "2025-12-15 16:05:20.766132", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.028610", "end": "2025-12-15 19:05:20.896750", "msg": "", "rc": 0, "start": "2025-12-15 19:05:20.868140", "stderr": "", "stderr_lines": [], "stdout": "35.7°C", "stdout_lines": ["35.7°C"]}
ok: [jump.point.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003071", "end": "2025-12-15 19:05:21.022805", "msg": "", "rc": 0, "start": "2025-12-15 19:05:21.019734", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [localhost] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.004098", "end": "2025-12-15 19:05:21.494513", "msg": "", "rc": 0, "start": "2025-12-15 19:05:21.490415", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
TASK [Get CPU load] ************************************************************
ok: [hp.nas.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004236", "end": "2025-12-15 19:05:21.710915", "msg": "", "rc": 0, "start": "2025-12-15 19:05:21.706679", "stderr": "", "stderr_lines": [], "stdout": "0.21", "stdout_lines": ["0.21"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004015", "end": "2025-12-15 19:05:21.717258", "msg": "", "rc": 0, "start": "2025-12-15 19:05:21.713243", "stderr": "", "stderr_lines": [], "stdout": "0.24", "stdout_lines": ["0.24"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004888", "end": "2025-12-15 19:05:21.727467", "msg": "", "rc": 0, "start": "2025-12-15 19:05:21.722579", "stderr": "", "stderr_lines": [], "stdout": "0.89", "stdout_lines": ["0.89"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004711", "end": "2025-12-15 19:05:21.753068", "msg": "", "rc": 0, "start": "2025-12-15 19:05:21.748357", "stderr": "", "stderr_lines": [], "stdout": "0.05", "stdout_lines": ["0.05"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005761", "end": "2025-12-15 19:05:21.766464", "msg": "", "rc": 0, "start": "2025-12-15 19:05:21.760703", "stderr": "", "stderr_lines": [], "stdout": "0.76", "stdout_lines": ["0.76"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004466", "end": "2025-12-15 19:04:57.709512", "msg": "", "rc": 0, "start": "2025-12-15 19:04:57.705046", "stderr": "", "stderr_lines": [], "stdout": "0.24", "stdout_lines": ["0.24"]}
ok: [media.labb.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005271", "end": "2025-12-15 19:04:51.874459", "msg": "", "rc": 0, "start": "2025-12-15 19:04:51.869188", "stderr": "", "stderr_lines": [], "stdout": "0.07", "stdout_lines": ["0.07"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.010105", "end": "2025-12-15 19:05:22.571550", "msg": "", "rc": 0, "start": "2025-12-15 19:05:22.561445", "stderr": "", "stderr_lines": [], "stdout": "0.19", "stdout_lines": ["0.19"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.011800", "end": "2025-12-15 19:05:22.651771", "msg": "", "rc": 0, "start": "2025-12-15 19:05:22.639971", "stderr": "", "stderr_lines": [], "stdout": "0.26", "stdout_lines": ["0.26"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005490", "end": "2025-12-15 19:05:22.831950", "msg": "", "rc": 0, "start": "2025-12-15 19:05:22.826460", "stderr": "", "stderr_lines": [], "stdout": "0.00", "stdout_lines": ["0.00"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004784", "end": "2025-12-15 19:04:55.123162", "msg": "", "rc": 0, "start": "2025-12-15 19:04:55.118378", "stderr": "", "stderr_lines": [], "stdout": "0.63", "stdout_lines": ["0.63"]}
ok: [dev.prod.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004474", "end": "2025-12-15 19:05:01.155913", "msg": "", "rc": 0, "start": "2025-12-15 19:05:01.151439", "stderr": "", "stderr_lines": [], "stdout": "0.10", "stdout_lines": ["0.10"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005884", "end": "2025-12-15 16:05:23.194614", "msg": "", "rc": 0, "start": "2025-12-15 16:05:23.188730", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.024350", "end": "2025-12-15 19:05:23.192396", "msg": "", "rc": 0, "start": "2025-12-15 19:05:23.168046", "stderr": "", "stderr_lines": [], "stdout": "0.35", "stdout_lines": ["0.35"]}
ok: [jump.point.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005458", "end": "2025-12-15 19:05:23.344579", "msg": "", "rc": 0, "start": "2025-12-15 19:05:23.339121", "stderr": "", "stderr_lines": [], "stdout": "0.32", "stdout_lines": ["0.32"]}
ok: [localhost] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.007150", "end": "2025-12-15 19:05:23.595615", "msg": "", "rc": 0, "start": "2025-12-15 19:05:23.588465", "stderr": "", "stderr_lines": [], "stdout": "1.65", "stdout_lines": ["1.65"]}
TASK [Display health status] ***************************************************
ok: [ali2v.xeon.home] => {
"msg": "═══════════════════════════════════════\nHost: ali2v.xeon.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:05:12 up 1 day, 8:37, 1 user, load average: 0.29, 0.41, 0.54\nDisk Usage: 22%\nMemory Usage: 21.8%\nCPU Load: 0.24\nCPU Temp: 47.0°C\n═══════════════════════════════════════\n"
}
ok: [hp.nas.home] => {
"msg": "═══════════════════════════════════════\nHost: hp.nas.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:05:12 up 20 days, 5:56, 1 user, load average: 0.25, 0.15, 0.12\nDisk Usage: 23%\nMemory Usage: 80.2%\nCPU Load: 0.21\nCPU Temp: 30.0°C\n═══════════════════════════════════════\n"
}
ok: [hp2.i7.home] => {
"msg": "═══════════════════════════════════════\nHost: hp2.i7.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:05:12 up 20 days, 6:16, 1 user, load average: 0.53, 0.67, 0.67\nDisk Usage: 14%\nMemory Usage: 49.2%\nCPU Load: 0.89\nCPU Temp: 0.0°C\n═══════════════════════════════════════\n"
}
ok: [hp3.i5.home] => {
"msg": "═══════════════════════════════════════\nHost: hp3.i5.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:05:12 up 20 days, 7:29, 1 user, load average: 0.63, 0.86, 0.82\nDisk Usage: 14%\nMemory Usage: 59.4%\nCPU Load: 0.76\nCPU Temp: 52.5°C\n═══════════════════════════════════════\n"
}
ok: [mimi.pc.home] => {
"msg": "═══════════════════════════════════════\nHost: mimi.pc.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:05:12 up 20 days, 8:15, 1 user, load average: 0.06, 0.08, 0.08\nDisk Usage: 9%\nMemory Usage: 9.0%\nCPU Load: 0.05\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [orangepi.pc.home] => {
"msg": "═══════════════════════════════════════\nHost: orangepi.pc.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:05:13 up 13 days, 8:31, 1 user, load average: 0.23, 0.15, 0.12\nDisk Usage: 21%\nMemory Usage: 18.8%\nCPU Load: 0.35\nCPU Temp: 35.7°C\n═══════════════════════════════════════\n"
}
ok: [raspi.4gb.home] => {
"msg": "═══════════════════════════════════════\nHost: raspi.4gb.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:05:13 up 192 days, 10:38, 1 user, load average: 0.12, 0.17, 0.23\nDisk Usage: 6%\nMemory Usage: 12.9%\nCPU Load: 0.26\nCPU Temp: 37.0°C\n═══════════════════════════════════════\n"
}
ok: [raspi.8gb.home] => {
"msg": "═══════════════════════════════════════\nHost: raspi.8gb.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:05:13 up 192 days, 10:38, 1 user, load average: 0.14, 0.12, 0.11\nDisk Usage: 3%\nMemory Usage: 6.7%\nCPU Load: 0.19\nCPU Temp: 31.6°C\n═══════════════════════════════════════\n"
}
ok: [dev.lab.home] => {
"msg": "═══════════════════════════════════════\nHost: dev.lab.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:04:49 up 9 days, 6:54, 0 user, load average: 0.10, 0.12, 0.11\nDisk Usage: 48%\nMemory Usage: 70.8%\nCPU Load: 0.24\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [media.labb.home] => {
"msg": "═══════════════════════════════════════\nHost: media.labb.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:04:43 up 16 days, 3:06, 0 user, load average: 0.08, 0.03, 0.01\nDisk Usage: 24%\nMemory Usage: 72.1%\nCPU Load: 0.07\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [ali2v.truenas.home] => {
"msg": "═══════════════════════════════════════\nHost: ali2v.truenas.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:05:14 up 1 day, 8:36, 1 user, load average: 0.01, 0.04, 0.01\nDisk Usage: 1%\nMemory Usage: 34.1%\nCPU Load: 0.00\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [automate.prod.home] => {
"msg": "═══════════════════════════════════════\nHost: automate.prod.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:04:46 up 18 days, 21:59, 0 user, load average: 0.68, 0.60, 0.50\nDisk Usage: 28%\nMemory Usage: 25.6%\nCPU Load: 0.63\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [dev.prod.home] => {
"msg": "═══════════════════════════════════════\nHost: dev.prod.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:04:52 up 15 days, 8:20, 0 user, load average: 0.11, 0.20, 0.17\nDisk Usage: 75%\nMemory Usage: 56.5%\nCPU Load: 0.10\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [hp.truenas.home] => {
"msg": "═══════════════════════════════════════\nHost: hp.truenas.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 4:05PM up 20 days, 5:55, 1 user, load averages: 0.25, 0.28, 0.25\nDisk Usage: 10%\nMemory Usage: \nCPU Load: \nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [jump.point.home] => {
"msg": "═══════════════════════════════════════\nHost: jump.point.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:05:14 up 1 day, 8:36, 1 user, load average: 0.37, 0.10, 0.05\nDisk Usage: 79%\nMemory Usage: 13.4%\nCPU Load: 0.32\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [localhost] => {
"msg": "═══════════════════════════════════════\nHost: localhost\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:05:14 up 5:40, 1 user, load average: 1.30, 1.21, 1.19\nDisk Usage: 1%\nMemory Usage: 12.4%\nCPU Load: 1.65\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
PLAY RECAP *********************************************************************
ali2v.truenas.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
ali2v.xeon.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
automate.prod.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
dev.lab.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
dev.prod.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
hp.nas.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
hp.truenas.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=1
hp2.i7.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
hp3.i5.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
jump.point.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
localhost : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
media.labb.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
mimi.pc.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
orangepi.pc.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
raspi.4gb.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
raspi.8gb.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
```
---
*Généré automatiquement par Homelab Automation Dashboard*
*Date: 2025-12-16T00:05:24.675842+00:00*

View File

@ -0,0 +1,224 @@
# ✅ [Planifié] Health-check-5min
## Informations
| Propriété | Valeur |
|-----------|--------|
| **ID** | `c84635fedf0246209106d2f96a49eee3` |
| **Nom** | [Planifié] Health-check-5min |
| **Cible** | `all` |
| **Statut** | completed |
| **Type** | Planifié |
| **Progression** | 100% |
| **Début** | 2025-12-16T00:10:00.000978+00:00 |
| **Fin** | 2025-12-16T00:10:23.453424+00:00 |
| **Durée** | 23.5s |
## Sortie
```
Using /mnt/c/dev/git/python/homelab-automation-api-v2/ansible/ansible.cfg as config file
PLAY [Health check on target host] *********************************************
TASK [Check if host is reachable (ping)] ***************************************
ok: [hp2.i7.home] => {"changed": false, "ping": "pong"}
ok: [hp.nas.home] => {"changed": false, "ping": "pong"}
ok: [mimi.pc.home] => {"changed": false, "ping": "pong"}
ok: [hp3.i5.home] => {"changed": false, "ping": "pong"}
ok: [ali2v.xeon.home] => {"changed": false, "ping": "pong"}
ok: [dev.lab.home] => {"changed": false, "ping": "pong"}
ok: [media.labb.home] => {"changed": false, "ping": "pong"}
ok: [raspi.4gb.home] => {"changed": false, "ping": "pong"}
ok: [raspi.8gb.home] => {"changed": false, "ping": "pong"}
ok: [automate.prod.home] => {"changed": false, "ping": "pong"}
ok: [ali2v.truenas.home] => {"changed": false, "ping": "pong"}
ok: [hp.truenas.home] => {"changed": false, "ping": "pong"}
ok: [localhost] => {"changed": false, "ping": "pong"}
ok: [dev.prod.home] => {"changed": false, "ping": "pong"}
ok: [jump.point.home] => {"changed": false, "ping": "pong"}
ok: [orangepi.pc.home] => {"changed": false, "ping": "pong"}
TASK [Gather minimal facts] ****************************************************
ok: [hp.nas.home]
ok: [hp2.i7.home]
ok: [mimi.pc.home]
ok: [hp3.i5.home]
ok: [ali2v.xeon.home]
ok: [dev.lab.home]
ok: [media.labb.home]
ok: [raspi.8gb.home]
ok: [raspi.4gb.home]
ok: [ali2v.truenas.home]
ok: [automate.prod.home]
ok: [hp.truenas.home]
ok: [dev.prod.home]
ok: [jump.point.home]
ok: [localhost]
ok: [orangepi.pc.home]
TASK [Get system uptime] *******************************************************
ok: [hp.nas.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003470", "end": "2025-12-15 19:10:12.139229", "msg": "", "rc": 0, "start": "2025-12-15 19:10:12.135759", "stderr": "", "stderr_lines": [], "stdout": " 19:10:12 up 20 days, 6:01, 1 user, load average: 0.19, 0.10, 0.10", "stdout_lines": [" 19:10:12 up 20 days, 6:01, 1 user, load average: 0.19, 0.10, 0.10"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003807", "end": "2025-12-15 19:10:12.164908", "msg": "", "rc": 0, "start": "2025-12-15 19:10:12.161101", "stderr": "", "stderr_lines": [], "stdout": " 19:10:12 up 20 days, 8:20, 1 user, load average: 0.19, 0.11, 0.09", "stdout_lines": [" 19:10:12 up 20 days, 8:20, 1 user, load average: 0.19, 0.11, 0.09"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.004059", "end": "2025-12-15 19:10:12.174113", "msg": "", "rc": 0, "start": "2025-12-15 19:10:12.170054", "stderr": "", "stderr_lines": [], "stdout": " 19:10:12 up 20 days, 7:34, 1 user, load average: 0.74, 0.82, 0.83", "stdout_lines": [" 19:10:12 up 20 days, 7:34, 1 user, load average: 0.74, 0.82, 0.83"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.002916", "end": "2025-12-15 19:10:12.183458", "msg": "", "rc": 0, "start": "2025-12-15 19:10:12.180542", "stderr": "", "stderr_lines": [], "stdout": " 19:10:12 up 1 day, 8:42, 1 user, load average: 0.29, 0.34, 0.47", "stdout_lines": [" 19:10:12 up 1 day, 8:42, 1 user, load average: 0.29, 0.34, 0.47"]}
ok: [dev.lab.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.002817", "end": "2025-12-15 19:09:48.055269", "msg": "", "rc": 0, "start": "2025-12-15 19:09:48.052452", "stderr": "", "stderr_lines": [], "stdout": " 19:09:48 up 9 days, 6:59, 0 user, load average: 0.04, 0.14, 0.13", "stdout_lines": [" 19:09:48 up 9 days, 6:59, 0 user, load average: 0.04, 0.14, 0.13"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.008575", "end": "2025-12-15 19:10:12.879186", "msg": "", "rc": 0, "start": "2025-12-15 19:10:12.870611", "stderr": "", "stderr_lines": [], "stdout": " 19:10:12 up 192 days, 10:43, 1 user, load average: 0.09, 0.09, 0.09", "stdout_lines": [" 19:10:12 up 192 days, 10:43, 1 user, load average: 0.09, 0.09, 0.09"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.009352", "end": "2025-12-15 19:10:12.938432", "msg": "", "rc": 0, "start": "2025-12-15 19:10:12.929080", "stderr": "", "stderr_lines": [], "stdout": " 19:10:12 up 192 days, 10:43, 1 user, load average: 0.15, 0.18, 0.22", "stdout_lines": [" 19:10:12 up 192 days, 10:43, 1 user, load average: 0.15, 0.18, 0.22"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:01.004759", "end": "2025-12-15 19:10:13.152064", "msg": "", "rc": 0, "start": "2025-12-15 19:10:12.147305", "stderr": "", "stderr_lines": [], "stdout": " 19:10:12 up 20 days, 6:21, 1 user, load average: 0.62, 0.65, 0.66", "stdout_lines": [" 19:10:12 up 20 days, 6:21, 1 user, load average: 0.62, 0.65, 0.66"]}
ok: [media.labb.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003331", "end": "2025-12-15 19:09:42.655880", "msg": "", "rc": 0, "start": "2025-12-15 19:09:42.652549", "stderr": "", "stderr_lines": [], "stdout": " 19:09:42 up 16 days, 3:11, 0 user, load average: 0.00, 0.02, 0.00", "stdout_lines": [" 19:09:42 up 16 days, 3:11, 0 user, load average: 0.00, 0.02, 0.00"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.004973", "end": "2025-12-15 19:10:13.381595", "msg": "", "rc": 0, "start": "2025-12-15 19:10:13.376622", "stderr": "", "stderr_lines": [], "stdout": " 19:10:13 up 1 day, 8:41, 1 user, load average: 0.13, 0.08, 0.02", "stdout_lines": [" 19:10:13 up 1 day, 8:41, 1 user, load average: 0.13, 0.08, 0.02"]}
ok: [automate.prod.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003250", "end": "2025-12-15 19:09:45.593635", "msg": "", "rc": 0, "start": "2025-12-15 19:09:45.590385", "stderr": "", "stderr_lines": [], "stdout": " 19:09:45 up 18 days, 22:04, 0 user, load average: 0.31, 0.46, 0.46", "stdout_lines": [" 19:09:45 up 18 days, 22:04, 0 user, load average: 0.31, 0.46, 0.46"]}
ok: [dev.prod.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.002889", "end": "2025-12-15 19:09:51.675363", "msg": "", "rc": 0, "start": "2025-12-15 19:09:51.672474", "stderr": "", "stderr_lines": [], "stdout": " 19:09:51 up 15 days, 8:25, 0 user, load average: 0.08, 0.15, 0.16", "stdout_lines": [" 19:09:51 up 15 days, 8:25, 0 user, load average: 0.08, 0.15, 0.16"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.019383", "end": "2025-12-15 19:10:13.558510", "msg": "", "rc": 0, "start": "2025-12-15 19:10:13.539127", "stderr": "", "stderr_lines": [], "stdout": " 19:10:13 up 13 days, 8:36, 1 user, load average: 0.23, 0.14, 0.11", "stdout_lines": [" 19:10:13 up 13 days, 8:36, 1 user, load average: 0.23, 0.14, 0.11"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.004328", "end": "2025-12-15 16:10:13.703662", "msg": "", "rc": 0, "start": "2025-12-15 16:10:13.699334", "stderr": "", "stderr_lines": [], "stdout": " 4:10PM up 20 days, 6 hrs, 1 user, load averages: 0.19, 0.22, 0.23", "stdout_lines": [" 4:10PM up 20 days, 6 hrs, 1 user, load averages: 0.19, 0.22, 0.23"]}
ok: [localhost] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.005143", "end": "2025-12-15 19:10:14.118878", "msg": "", "rc": 0, "start": "2025-12-15 19:10:14.113735", "stderr": "", "stderr_lines": [], "stdout": " 19:10:14 up 5:45, 1 user, load average: 1.20, 1.19, 1.18", "stdout_lines": [" 19:10:14 up 5:45, 1 user, load average: 1.20, 1.19, 1.18"]}
ok: [jump.point.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003754", "end": "2025-12-15 19:10:13.903487", "msg": "", "rc": 0, "start": "2025-12-15 19:10:13.899733", "stderr": "", "stderr_lines": [], "stdout": " 19:10:13 up 1 day, 8:41, 1 user, load average: 0.14, 0.06, 0.04", "stdout_lines": [" 19:10:13 up 1 day, 8:41, 1 user, load average: 0.14, 0.06, 0.04"]}
TASK [Get disk usage] **********************************************************
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004151", "end": "2025-12-15 19:10:14.385047", "msg": "", "rc": 0, "start": "2025-12-15 19:10:14.380896", "stderr": "", "stderr_lines": [], "stdout": "22%", "stdout_lines": ["22%"]}
ok: [hp.nas.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004438", "end": "2025-12-15 19:10:14.397259", "msg": "", "rc": 0, "start": "2025-12-15 19:10:14.392821", "stderr": "", "stderr_lines": [], "stdout": "23%", "stdout_lines": ["23%"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004664", "end": "2025-12-15 19:10:14.411961", "msg": "", "rc": 0, "start": "2025-12-15 19:10:14.407297", "stderr": "", "stderr_lines": [], "stdout": "14%", "stdout_lines": ["14%"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.006365", "end": "2025-12-15 19:10:14.443910", "msg": "", "rc": 0, "start": "2025-12-15 19:10:14.437545", "stderr": "", "stderr_lines": [], "stdout": "14%", "stdout_lines": ["14%"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004905", "end": "2025-12-15 19:10:14.471154", "msg": "", "rc": 0, "start": "2025-12-15 19:10:14.466249", "stderr": "", "stderr_lines": [], "stdout": "9%", "stdout_lines": ["9%"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005166", "end": "2025-12-15 19:09:50.348888", "msg": "", "rc": 0, "start": "2025-12-15 19:09:50.343722", "stderr": "", "stderr_lines": [], "stdout": "48%", "stdout_lines": ["48%"]}
ok: [media.labb.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005968", "end": "2025-12-15 19:09:44.516272", "msg": "", "rc": 0, "start": "2025-12-15 19:09:44.510304", "stderr": "", "stderr_lines": [], "stdout": "24%", "stdout_lines": ["24%"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.010844", "end": "2025-12-15 19:10:15.172974", "msg": "", "rc": 0, "start": "2025-12-15 19:10:15.162130", "stderr": "", "stderr_lines": [], "stdout": "3%", "stdout_lines": ["3%"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.011644", "end": "2025-12-15 19:10:15.203825", "msg": "", "rc": 0, "start": "2025-12-15 19:10:15.192181", "stderr": "", "stderr_lines": [], "stdout": "6%", "stdout_lines": ["6%"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005734", "end": "2025-12-15 19:10:15.470083", "msg": "", "rc": 0, "start": "2025-12-15 19:10:15.464349", "stderr": "", "stderr_lines": [], "stdout": "1%", "stdout_lines": ["1%"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005366", "end": "2025-12-15 19:09:47.771113", "msg": "", "rc": 0, "start": "2025-12-15 19:09:47.765747", "stderr": "", "stderr_lines": [], "stdout": "28%", "stdout_lines": ["28%"]}
ok: [dev.prod.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004709", "end": "2025-12-15 19:09:53.702023", "msg": "", "rc": 0, "start": "2025-12-15 19:09:53.697314", "stderr": "", "stderr_lines": [], "stdout": "75%", "stdout_lines": ["75%"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005978", "end": "2025-12-15 16:10:15.720815", "msg": "", "rc": 0, "start": "2025-12-15 16:10:15.714837", "stderr": "", "stderr_lines": [], "stdout": "10%", "stdout_lines": ["10%"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.025518", "end": "2025-12-15 19:10:15.803595", "msg": "", "rc": 0, "start": "2025-12-15 19:10:15.778077", "stderr": "", "stderr_lines": [], "stdout": "21%", "stdout_lines": ["21%"]}
ok: [jump.point.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005461", "end": "2025-12-15 19:10:15.926470", "msg": "", "rc": 0, "start": "2025-12-15 19:10:15.921009", "stderr": "", "stderr_lines": [], "stdout": "79%", "stdout_lines": ["79%"]}
ok: [localhost] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.017810", "end": "2025-12-15 19:10:16.323065", "msg": "", "rc": 0, "start": "2025-12-15 19:10:16.305255", "stderr": "", "stderr_lines": [], "stdout": "1%", "stdout_lines": ["1%"]}
TASK [Get memory usage (Linux)] ************************************************
ok: [hp.nas.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004459", "end": "2025-12-15 19:10:16.498409", "msg": "", "rc": 0, "start": "2025-12-15 19:10:16.493950", "stderr": "", "stderr_lines": [], "stdout": "80.2%", "stdout_lines": ["80.2%"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004214", "end": "2025-12-15 19:10:16.527102", "msg": "", "rc": 0, "start": "2025-12-15 19:10:16.522888", "stderr": "", "stderr_lines": [], "stdout": "21.7%", "stdout_lines": ["21.7%"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004806", "end": "2025-12-15 19:10:16.549405", "msg": "", "rc": 0, "start": "2025-12-15 19:10:16.544599", "stderr": "", "stderr_lines": [], "stdout": "49.3%", "stdout_lines": ["49.3%"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005030", "end": "2025-12-15 19:10:16.577244", "msg": "", "rc": 0, "start": "2025-12-15 19:10:16.572214", "stderr": "", "stderr_lines": [], "stdout": "9.0%", "stdout_lines": ["9.0%"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005579", "end": "2025-12-15 19:10:16.582728", "msg": "", "rc": 0, "start": "2025-12-15 19:10:16.577149", "stderr": "", "stderr_lines": [], "stdout": "59.4%", "stdout_lines": ["59.4%"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004080", "end": "2025-12-15 19:09:52.459510", "msg": "", "rc": 0, "start": "2025-12-15 19:09:52.455430", "stderr": "", "stderr_lines": [], "stdout": "71.0%", "stdout_lines": ["71.0%"]}
ok: [media.labb.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005817", "end": "2025-12-15 19:09:46.643417", "msg": "", "rc": 0, "start": "2025-12-15 19:09:46.637600", "stderr": "", "stderr_lines": [], "stdout": "72.2%", "stdout_lines": ["72.2%"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.011038", "end": "2025-12-15 19:10:17.264117", "msg": "", "rc": 0, "start": "2025-12-15 19:10:17.253079", "stderr": "", "stderr_lines": [], "stdout": "6.7%", "stdout_lines": ["6.7%"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.012358", "end": "2025-12-15 19:10:17.261385", "msg": "", "rc": 0, "start": "2025-12-15 19:10:17.249027", "stderr": "", "stderr_lines": [], "stdout": "12.3%", "stdout_lines": ["12.3%"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005938", "end": "2025-12-15 19:10:17.582369", "msg": "", "rc": 0, "start": "2025-12-15 19:10:17.576431", "stderr": "", "stderr_lines": [], "stdout": "34.1%", "stdout_lines": ["34.1%"]}
fatal: [hp.truenas.home]: FAILED! => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005337", "end": "2025-12-15 16:10:17.771141", "msg": "non-zero return code", "rc": 2, "start": "2025-12-15 16:10:17.765804", "stderr": "cat: /proc/meminfo: No such file or directory\nawk: division by zero\n source line number 1", "stderr_lines": ["cat: /proc/meminfo: No such file or directory", "awk: division by zero", " source line number 1"], "stdout": "", "stdout_lines": []}
...ignoring
ok: [dev.prod.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.003501", "end": "2025-12-15 19:09:55.806227", "msg": "", "rc": 0, "start": "2025-12-15 19:09:55.802726", "stderr": "", "stderr_lines": [], "stdout": "57.3%", "stdout_lines": ["57.3%"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004290", "end": "2025-12-15 19:09:49.878039", "msg": "", "rc": 0, "start": "2025-12-15 19:09:49.873749", "stderr": "", "stderr_lines": [], "stdout": "25.7%", "stdout_lines": ["25.7%"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.026024", "end": "2025-12-15 19:10:17.913273", "msg": "", "rc": 0, "start": "2025-12-15 19:10:17.887249", "stderr": "", "stderr_lines": [], "stdout": "18.9%", "stdout_lines": ["18.9%"]}
ok: [jump.point.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005497", "end": "2025-12-15 19:10:18.092560", "msg": "", "rc": 0, "start": "2025-12-15 19:10:18.087063", "stderr": "", "stderr_lines": [], "stdout": "13.5%", "stdout_lines": ["13.5%"]}
ok: [localhost] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.007797", "end": "2025-12-15 19:10:18.426101", "msg": "", "rc": 0, "start": "2025-12-15 19:10:18.418304", "stderr": "", "stderr_lines": [], "stdout": "12.5%", "stdout_lines": ["12.5%"]}
TASK [Get CPU temperature (ARM/SBC)] *******************************************
ok: [hp.nas.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.005525", "end": "2025-12-15 19:10:18.577693", "msg": "", "rc": 0, "start": "2025-12-15 19:10:18.572168", "stderr": "", "stderr_lines": [], "stdout": "30.0°C", "stdout_lines": ["30.0°C"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.005130", "end": "2025-12-15 19:10:18.594655", "msg": "", "rc": 0, "start": "2025-12-15 19:10:18.589525", "stderr": "", "stderr_lines": [], "stdout": "45.0°C", "stdout_lines": ["45.0°C"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003146", "end": "2025-12-15 19:10:18.629932", "msg": "", "rc": 0, "start": "2025-12-15 19:10:18.626786", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.005897", "end": "2025-12-15 19:10:18.653488", "msg": "", "rc": 0, "start": "2025-12-15 19:10:18.647591", "stderr": "cat: /sys/class/thermal/thermal_zone0/temp: No data available", "stderr_lines": ["cat: /sys/class/thermal/thermal_zone0/temp: No data available"], "stdout": "0.0°C", "stdout_lines": ["0.0°C"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.006307", "end": "2025-12-15 19:10:18.664673", "msg": "", "rc": 0, "start": "2025-12-15 19:10:18.658366", "stderr": "", "stderr_lines": [], "stdout": "52.5°C", "stdout_lines": ["52.5°C"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003041", "end": "2025-12-15 19:09:54.616266", "msg": "", "rc": 0, "start": "2025-12-15 19:09:54.613225", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [media.labb.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003073", "end": "2025-12-15 19:09:48.737372", "msg": "", "rc": 0, "start": "2025-12-15 19:09:48.734299", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.011818", "end": "2025-12-15 19:10:19.391665", "msg": "", "rc": 0, "start": "2025-12-15 19:10:19.379847", "stderr": "", "stderr_lines": [], "stdout": "32.6°C", "stdout_lines": ["32.6°C"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.013056", "end": "2025-12-15 19:10:19.390678", "msg": "", "rc": 0, "start": "2025-12-15 19:10:19.377622", "stderr": "", "stderr_lines": [], "stdout": "35.0°C", "stdout_lines": ["35.0°C"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003101", "end": "2025-12-15 19:10:19.706533", "msg": "", "rc": 0, "start": "2025-12-15 19:10:19.703432", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.002881", "end": "2025-12-15 19:09:51.958378", "msg": "", "rc": 0, "start": "2025-12-15 19:09:51.955497", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [dev.prod.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.002923", "end": "2025-12-15 19:09:57.978222", "msg": "", "rc": 0, "start": "2025-12-15 19:09:57.975299", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003878", "end": "2025-12-15 16:10:19.960940", "msg": "", "rc": 0, "start": "2025-12-15 16:10:19.957062", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [jump.point.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.002986", "end": "2025-12-15 19:10:20.166420", "msg": "", "rc": 0, "start": "2025-12-15 19:10:20.163434", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.028420", "end": "2025-12-15 19:10:20.051927", "msg": "", "rc": 0, "start": "2025-12-15 19:10:20.023507", "stderr": "", "stderr_lines": [], "stdout": "35.4°C", "stdout_lines": ["35.4°C"]}
ok: [localhost] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003967", "end": "2025-12-15 19:10:20.501180", "msg": "", "rc": 0, "start": "2025-12-15 19:10:20.497213", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
TASK [Get CPU load] ************************************************************
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004061", "end": "2025-12-15 19:10:20.674725", "msg": "", "rc": 0, "start": "2025-12-15 19:10:20.670664", "stderr": "", "stderr_lines": [], "stdout": "0.33", "stdout_lines": ["0.33"]}
ok: [hp.nas.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004262", "end": "2025-12-15 19:10:20.700239", "msg": "", "rc": 0, "start": "2025-12-15 19:10:20.695977", "stderr": "", "stderr_lines": [], "stdout": "0.17", "stdout_lines": ["0.17"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004745", "end": "2025-12-15 19:10:20.731132", "msg": "", "rc": 0, "start": "2025-12-15 19:10:20.726387", "stderr": "", "stderr_lines": [], "stdout": "0.60", "stdout_lines": ["0.60"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004822", "end": "2025-12-15 19:10:20.750540", "msg": "", "rc": 0, "start": "2025-12-15 19:10:20.745718", "stderr": "", "stderr_lines": [], "stdout": "0.31", "stdout_lines": ["0.31"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005425", "end": "2025-12-15 19:10:20.769721", "msg": "", "rc": 0, "start": "2025-12-15 19:10:20.764296", "stderr": "", "stderr_lines": [], "stdout": "0.86", "stdout_lines": ["0.86"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004265", "end": "2025-12-15 19:09:56.623033", "msg": "", "rc": 0, "start": "2025-12-15 19:09:56.618768", "stderr": "", "stderr_lines": [], "stdout": "0.11", "stdout_lines": ["0.11"]}
ok: [media.labb.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004922", "end": "2025-12-15 19:09:50.795409", "msg": "", "rc": 0, "start": "2025-12-15 19:09:50.790487", "stderr": "", "stderr_lines": [], "stdout": "0.08", "stdout_lines": ["0.08"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.011335", "end": "2025-12-15 19:10:21.504550", "msg": "", "rc": 0, "start": "2025-12-15 19:10:21.493215", "stderr": "", "stderr_lines": [], "stdout": "0.13", "stdout_lines": ["0.13"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.010090", "end": "2025-12-15 19:10:21.530522", "msg": "", "rc": 0, "start": "2025-12-15 19:10:21.520432", "stderr": "", "stderr_lines": [], "stdout": "0.24", "stdout_lines": ["0.24"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005667", "end": "2025-12-15 19:10:21.770338", "msg": "", "rc": 0, "start": "2025-12-15 19:10:21.764671", "stderr": "", "stderr_lines": [], "stdout": "0.20", "stdout_lines": ["0.20"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004920", "end": "2025-12-15 19:09:54.001057", "msg": "", "rc": 0, "start": "2025-12-15 19:09:53.996137", "stderr": "", "stderr_lines": [], "stdout": "0.41", "stdout_lines": ["0.41"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005930", "end": "2025-12-15 16:10:21.997413", "msg": "", "rc": 0, "start": "2025-12-15 16:10:21.991483", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}
ok: [dev.prod.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004292", "end": "2025-12-15 19:10:00.082181", "msg": "", "rc": 0, "start": "2025-12-15 19:10:00.077889", "stderr": "", "stderr_lines": [], "stdout": "0.07", "stdout_lines": ["0.07"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.024497", "end": "2025-12-15 19:10:22.091144", "msg": "", "rc": 0, "start": "2025-12-15 19:10:22.066647", "stderr": "", "stderr_lines": [], "stdout": "0.27", "stdout_lines": ["0.27"]}
ok: [jump.point.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005308", "end": "2025-12-15 19:10:22.246530", "msg": "", "rc": 0, "start": "2025-12-15 19:10:22.241222", "stderr": "", "stderr_lines": [], "stdout": "0.11", "stdout_lines": ["0.11"]}
ok: [localhost] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.007663", "end": "2025-12-15 19:10:22.438720", "msg": "", "rc": 0, "start": "2025-12-15 19:10:22.431057", "stderr": "", "stderr_lines": [], "stdout": "1.32", "stdout_lines": ["1.32"]}
TASK [Display health status] ***************************************************
ok: [ali2v.xeon.home] => {
"msg": "═══════════════════════════════════════\nHost: ali2v.xeon.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:10:12 up 1 day, 8:42, 1 user, load average: 0.29, 0.34, 0.47\nDisk Usage: 22%\nMemory Usage: 21.7%\nCPU Load: 0.33\nCPU Temp: 45.0°C\n═══════════════════════════════════════\n"
}
ok: [hp.nas.home] => {
"msg": "═══════════════════════════════════════\nHost: hp.nas.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:10:12 up 20 days, 6:01, 1 user, load average: 0.19, 0.10, 0.10\nDisk Usage: 23%\nMemory Usage: 80.2%\nCPU Load: 0.17\nCPU Temp: 30.0°C\n═══════════════════════════════════════\n"
}
ok: [hp2.i7.home] => {
"msg": "═══════════════════════════════════════\nHost: hp2.i7.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:10:12 up 20 days, 6:21, 1 user, load average: 0.62, 0.65, 0.66\nDisk Usage: 14%\nMemory Usage: 49.3%\nCPU Load: 0.60\nCPU Temp: 0.0°C\n═══════════════════════════════════════\n"
}
ok: [hp3.i5.home] => {
"msg": "═══════════════════════════════════════\nHost: hp3.i5.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:10:12 up 20 days, 7:34, 1 user, load average: 0.74, 0.82, 0.83\nDisk Usage: 14%\nMemory Usage: 59.4%\nCPU Load: 0.86\nCPU Temp: 52.5°C\n═══════════════════════════════════════\n"
}
ok: [mimi.pc.home] => {
"msg": "═══════════════════════════════════════\nHost: mimi.pc.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:10:12 up 20 days, 8:20, 1 user, load average: 0.19, 0.11, 0.09\nDisk Usage: 9%\nMemory Usage: 9.0%\nCPU Load: 0.31\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [orangepi.pc.home] => {
"msg": "═══════════════════════════════════════\nHost: orangepi.pc.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:10:13 up 13 days, 8:36, 1 user, load average: 0.23, 0.14, 0.11\nDisk Usage: 21%\nMemory Usage: 18.9%\nCPU Load: 0.27\nCPU Temp: 35.4°C\n═══════════════════════════════════════\n"
}
ok: [raspi.4gb.home] => {
"msg": "═══════════════════════════════════════\nHost: raspi.4gb.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:10:12 up 192 days, 10:43, 1 user, load average: 0.15, 0.18, 0.22\nDisk Usage: 6%\nMemory Usage: 12.3%\nCPU Load: 0.13\nCPU Temp: 35.0°C\n═══════════════════════════════════════\n"
}
ok: [raspi.8gb.home] => {
"msg": "═══════════════════════════════════════\nHost: raspi.8gb.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:10:12 up 192 days, 10:43, 1 user, load average: 0.09, 0.09, 0.09\nDisk Usage: 3%\nMemory Usage: 6.7%\nCPU Load: 0.24\nCPU Temp: 32.6°C\n═══════════════════════════════════════\n"
}
ok: [dev.lab.home] => {
"msg": "═══════════════════════════════════════\nHost: dev.lab.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:09:48 up 9 days, 6:59, 0 user, load average: 0.04, 0.14, 0.13\nDisk Usage: 48%\nMemory Usage: 71.0%\nCPU Load: 0.11\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [media.labb.home] => {
"msg": "═══════════════════════════════════════\nHost: media.labb.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:09:42 up 16 days, 3:11, 0 user, load average: 0.00, 0.02, 0.00\nDisk Usage: 24%\nMemory Usage: 72.2%\nCPU Load: 0.08\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [ali2v.truenas.home] => {
"msg": "═══════════════════════════════════════\nHost: ali2v.truenas.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:10:13 up 1 day, 8:41, 1 user, load average: 0.13, 0.08, 0.02\nDisk Usage: 1%\nMemory Usage: 34.1%\nCPU Load: 0.20\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [automate.prod.home] => {
"msg": "═══════════════════════════════════════\nHost: automate.prod.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:09:45 up 18 days, 22:04, 0 user, load average: 0.31, 0.46, 0.46\nDisk Usage: 28%\nMemory Usage: 25.7%\nCPU Load: 0.41\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [dev.prod.home] => {
"msg": "═══════════════════════════════════════\nHost: dev.prod.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:09:51 up 15 days, 8:25, 0 user, load average: 0.08, 0.15, 0.16\nDisk Usage: 75%\nMemory Usage: 57.3%\nCPU Load: 0.07\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [hp.truenas.home] => {
"msg": "═══════════════════════════════════════\nHost: hp.truenas.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 4:10PM up 20 days, 6 hrs, 1 user, load averages: 0.19, 0.22, 0.23\nDisk Usage: 10%\nMemory Usage: \nCPU Load: \nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [jump.point.home] => {
"msg": "═══════════════════════════════════════\nHost: jump.point.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:10:13 up 1 day, 8:41, 1 user, load average: 0.14, 0.06, 0.04\nDisk Usage: 79%\nMemory Usage: 13.5%\nCPU Load: 0.11\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [localhost] => {
"msg": "═══════════════════════════════════════\nHost: localhost\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:10:14 up 5:45, 1 user, load average: 1.20, 1.19, 1.18\nDisk Usage: 1%\nMemory Usage: 12.5%\nCPU Load: 1.32\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
PLAY RECAP *********************************************************************
ali2v.truenas.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
ali2v.xeon.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
automate.prod.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
dev.lab.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
dev.prod.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
hp.nas.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
hp.truenas.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=1
hp2.i7.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
hp3.i5.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
jump.point.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
localhost : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
media.labb.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
mimi.pc.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
orangepi.pc.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
raspi.4gb.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
raspi.8gb.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
```
---
*Généré automatiquement par Homelab Automation Dashboard*
*Date: 2025-12-16T00:10:23.498567+00:00*

View File

@ -0,0 +1,224 @@
# ✅ [Planifié] Health-check-5min
## Informations
| Propriété | Valeur |
|-----------|--------|
| **ID** | `64da8f1ba21e4ee68194766e93e2df3b` |
| **Nom** | [Planifié] Health-check-5min |
| **Cible** | `all` |
| **Statut** | completed |
| **Type** | Planifié |
| **Progression** | 100% |
| **Début** | 2025-12-16T00:15:00.005162+00:00 |
| **Fin** | 2025-12-16T00:15:33.020020+00:00 |
| **Durée** | 33.0s |
## Sortie
```
Using /mnt/c/dev/git/python/homelab-automation-api-v2/ansible/ansible.cfg as config file
PLAY [Health check on target host] *********************************************
TASK [Check if host is reachable (ping)] ***************************************
ok: [hp.nas.home] => {"changed": false, "ping": "pong"}
ok: [hp2.i7.home] => {"changed": false, "ping": "pong"}
ok: [mimi.pc.home] => {"changed": false, "ping": "pong"}
ok: [hp3.i5.home] => {"changed": false, "ping": "pong"}
ok: [ali2v.xeon.home] => {"changed": false, "ping": "pong"}
ok: [dev.lab.home] => {"changed": false, "ping": "pong"}
ok: [media.labb.home] => {"changed": false, "ping": "pong"}
ok: [raspi.8gb.home] => {"changed": false, "ping": "pong"}
ok: [raspi.4gb.home] => {"changed": false, "ping": "pong"}
ok: [automate.prod.home] => {"changed": false, "ping": "pong"}
ok: [ali2v.truenas.home] => {"changed": false, "ping": "pong"}
ok: [hp.truenas.home] => {"changed": false, "ping": "pong"}
ok: [dev.prod.home] => {"changed": false, "ping": "pong"}
ok: [localhost] => {"changed": false, "ping": "pong"}
ok: [jump.point.home] => {"changed": false, "ping": "pong"}
ok: [orangepi.pc.home] => {"changed": false, "ping": "pong"}
TASK [Gather minimal facts] ****************************************************
ok: [hp.nas.home]
ok: [hp2.i7.home]
ok: [mimi.pc.home]
ok: [hp3.i5.home]
ok: [ali2v.xeon.home]
ok: [dev.lab.home]
ok: [media.labb.home]
ok: [raspi.8gb.home]
ok: [raspi.4gb.home]
ok: [ali2v.truenas.home]
ok: [automate.prod.home]
ok: [dev.prod.home]
ok: [hp.truenas.home]
ok: [jump.point.home]
ok: [orangepi.pc.home]
ok: [localhost]
TASK [Get system uptime] *******************************************************
ok: [mimi.pc.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003502", "end": "2025-12-15 19:15:16.643497", "msg": "", "rc": 0, "start": "2025-12-15 19:15:16.639995", "stderr": "", "stderr_lines": [], "stdout": " 19:15:16 up 20 days, 8:25, 1 user, load average: 0.05, 0.08, 0.08", "stdout_lines": [" 19:15:16 up 20 days, 8:25, 1 user, load average: 0.05, 0.08, 0.08"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003190", "end": "2025-12-15 19:15:16.645134", "msg": "", "rc": 0, "start": "2025-12-15 19:15:16.641944", "stderr": "", "stderr_lines": [], "stdout": " 19:15:16 up 20 days, 6:26, 1 user, load average: 0.93, 0.67, 0.65", "stdout_lines": [" 19:15:16 up 20 days, 6:26, 1 user, load average: 0.93, 0.67, 0.65"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003080", "end": "2025-12-15 19:15:16.669225", "msg": "", "rc": 0, "start": "2025-12-15 19:15:16.666145", "stderr": "", "stderr_lines": [], "stdout": " 19:15:16 up 1 day, 8:47, 1 user, load average: 0.58, 0.39, 0.45", "stdout_lines": [" 19:15:16 up 1 day, 8:47, 1 user, load average: 0.58, 0.39, 0.45"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003957", "end": "2025-12-15 19:15:16.674511", "msg": "", "rc": 0, "start": "2025-12-15 19:15:16.670554", "stderr": "", "stderr_lines": [], "stdout": " 19:15:16 up 20 days, 7:39, 1 user, load average: 0.70, 0.69, 0.77", "stdout_lines": [" 19:15:16 up 20 days, 7:39, 1 user, load average: 0.70, 0.69, 0.77"]}
ok: [dev.lab.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.002726", "end": "2025-12-15 19:14:52.719649", "msg": "", "rc": 0, "start": "2025-12-15 19:14:52.716923", "stderr": "", "stderr_lines": [], "stdout": " 19:14:52 up 9 days, 7:04, 0 user, load average: 0.18, 0.31, 0.21", "stdout_lines": [" 19:14:52 up 9 days, 7:04, 0 user, load average: 0.18, 0.31, 0.21"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.008506", "end": "2025-12-15 19:15:17.549561", "msg": "", "rc": 0, "start": "2025-12-15 19:15:17.541055", "stderr": "", "stderr_lines": [], "stdout": " 19:15:17 up 192 days, 10:48, 1 user, load average: 0.09, 0.09, 0.09", "stdout_lines": [" 19:15:17 up 192 days, 10:48, 1 user, load average: 0.09, 0.09, 0.09"]}
ok: [hp.nas.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:01.004294", "end": "2025-12-15 19:15:17.635706", "msg": "", "rc": 0, "start": "2025-12-15 19:15:16.631412", "stderr": "", "stderr_lines": [], "stdout": " 19:15:16 up 20 days, 6:06, 1 user, load average: 0.26, 0.14, 0.10", "stdout_lines": [" 19:15:16 up 20 days, 6:06, 1 user, load average: 0.26, 0.14, 0.10"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.009379", "end": "2025-12-15 19:15:17.592349", "msg": "", "rc": 0, "start": "2025-12-15 19:15:17.582970", "stderr": "", "stderr_lines": [], "stdout": " 19:15:17 up 192 days, 10:48, 1 user, load average: 0.05, 0.13, 0.18", "stdout_lines": [" 19:15:17 up 192 days, 10:48, 1 user, load average: 0.05, 0.13, 0.18"]}
ok: [media.labb.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.004388", "end": "2025-12-15 19:14:47.534438", "msg": "", "rc": 0, "start": "2025-12-15 19:14:47.530050", "stderr": "", "stderr_lines": [], "stdout": " 19:14:47 up 16 days, 3:16, 0 user, load average: 0.00, 0.03, 0.00", "stdout_lines": [" 19:14:47 up 16 days, 3:16, 0 user, load average: 0.00, 0.03, 0.00"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.005048", "end": "2025-12-15 19:15:18.286318", "msg": "", "rc": 0, "start": "2025-12-15 19:15:18.281270", "stderr": "", "stderr_lines": [], "stdout": " 19:15:18 up 1 day, 8:46, 1 user, load average: 0.07, 0.06, 0.01", "stdout_lines": [" 19:15:18 up 1 day, 8:46, 1 user, load average: 0.07, 0.06, 0.01"]}
ok: [dev.prod.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.002807", "end": "2025-12-15 19:14:56.336569", "msg": "", "rc": 0, "start": "2025-12-15 19:14:56.333762", "stderr": "", "stderr_lines": [], "stdout": " 19:14:56 up 15 days, 8:30, 0 user, load average: 0.13, 0.12, 0.14", "stdout_lines": [" 19:14:56 up 15 days, 8:30, 0 user, load average: 0.13, 0.12, 0.14"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.019486", "end": "2025-12-15 19:15:18.289372", "msg": "", "rc": 0, "start": "2025-12-15 19:15:18.269886", "stderr": "", "stderr_lines": [], "stdout": " 19:15:18 up 13 days, 8:41, 1 user, load average: 0.07, 0.11, 0.10", "stdout_lines": [" 19:15:18 up 13 days, 8:41, 1 user, load average: 0.07, 0.11, 0.10"]}
ok: [automate.prod.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003728", "end": "2025-12-15 19:14:50.495711", "msg": "", "rc": 0, "start": "2025-12-15 19:14:50.491983", "stderr": "", "stderr_lines": [], "stdout": " 19:14:50 up 18 days, 22:09, 0 user, load average: 0.45, 0.50, 0.47", "stdout_lines": [" 19:14:50 up 18 days, 22:09, 0 user, load average: 0.45, 0.50, 0.47"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.004591", "end": "2025-12-15 16:15:18.683155", "msg": "", "rc": 0, "start": "2025-12-15 16:15:18.678564", "stderr": "", "stderr_lines": [], "stdout": " 4:15PM up 20 days, 6:05, 1 user, load averages: 0.38, 0.30, 0.26", "stdout_lines": [" 4:15PM up 20 days, 6:05, 1 user, load averages: 0.38, 0.30, 0.26"]}
ok: [jump.point.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003913", "end": "2025-12-15 19:15:18.878681", "msg": "", "rc": 0, "start": "2025-12-15 19:15:18.874768", "stderr": "", "stderr_lines": [], "stdout": " 19:15:18 up 1 day, 8:46, 1 user, load average: 0.00, 0.01, 0.01", "stdout_lines": [" 19:15:18 up 1 day, 8:46, 1 user, load average: 0.00, 0.01, 0.01"]}
ok: [localhost] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.008099", "end": "2025-12-15 19:15:19.163130", "msg": "", "rc": 0, "start": "2025-12-15 19:15:19.155031", "stderr": "", "stderr_lines": [], "stdout": " 19:15:19 up 5:50, 1 user, load average: 1.45, 1.25, 1.20", "stdout_lines": [" 19:15:19 up 5:50, 1 user, load average: 1.45, 1.25, 1.20"]}
TASK [Get disk usage] **********************************************************
ok: [hp.nas.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004440", "end": "2025-12-15 19:15:19.641042", "msg": "", "rc": 0, "start": "2025-12-15 19:15:19.636602", "stderr": "", "stderr_lines": [], "stdout": "23%", "stdout_lines": ["23%"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004262", "end": "2025-12-15 19:15:19.653876", "msg": "", "rc": 0, "start": "2025-12-15 19:15:19.649614", "stderr": "", "stderr_lines": [], "stdout": "22%", "stdout_lines": ["22%"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004832", "end": "2025-12-15 19:15:19.689628", "msg": "", "rc": 0, "start": "2025-12-15 19:15:19.684796", "stderr": "", "stderr_lines": [], "stdout": "14%", "stdout_lines": ["14%"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005415", "end": "2025-12-15 19:15:19.757759", "msg": "", "rc": 0, "start": "2025-12-15 19:15:19.752344", "stderr": "", "stderr_lines": [], "stdout": "9%", "stdout_lines": ["9%"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005629", "end": "2025-12-15 19:15:19.768567", "msg": "", "rc": 0, "start": "2025-12-15 19:15:19.762938", "stderr": "", "stderr_lines": [], "stdout": "14%", "stdout_lines": ["14%"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004995", "end": "2025-12-15 19:14:55.863914", "msg": "", "rc": 0, "start": "2025-12-15 19:14:55.858919", "stderr": "", "stderr_lines": [], "stdout": "48%", "stdout_lines": ["48%"]}
ok: [media.labb.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005304", "end": "2025-12-15 19:14:49.988072", "msg": "", "rc": 0, "start": "2025-12-15 19:14:49.982768", "stderr": "", "stderr_lines": [], "stdout": "24%", "stdout_lines": ["24%"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.010734", "end": "2025-12-15 19:15:20.640862", "msg": "", "rc": 0, "start": "2025-12-15 19:15:20.630128", "stderr": "", "stderr_lines": [], "stdout": "3%", "stdout_lines": ["3%"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.011616", "end": "2025-12-15 19:15:20.678280", "msg": "", "rc": 0, "start": "2025-12-15 19:15:20.666664", "stderr": "", "stderr_lines": [], "stdout": "6%", "stdout_lines": ["6%"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.006559", "end": "2025-12-15 19:15:21.105393", "msg": "", "rc": 0, "start": "2025-12-15 19:15:21.098834", "stderr": "", "stderr_lines": [], "stdout": "1%", "stdout_lines": ["1%"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005283", "end": "2025-12-15 19:14:53.297126", "msg": "", "rc": 0, "start": "2025-12-15 19:14:53.291843", "stderr": "", "stderr_lines": [], "stdout": "28%", "stdout_lines": ["28%"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005723", "end": "2025-12-15 16:15:21.237496", "msg": "", "rc": 0, "start": "2025-12-15 16:15:21.231773", "stderr": "", "stderr_lines": [], "stdout": "10%", "stdout_lines": ["10%"]}
ok: [dev.prod.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005483", "end": "2025-12-15 19:14:59.260509", "msg": "", "rc": 0, "start": "2025-12-15 19:14:59.255026", "stderr": "", "stderr_lines": [], "stdout": "75%", "stdout_lines": ["75%"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.025200", "end": "2025-12-15 19:15:21.223979", "msg": "", "rc": 0, "start": "2025-12-15 19:15:21.198779", "stderr": "", "stderr_lines": [], "stdout": "21%", "stdout_lines": ["21%"]}
ok: [jump.point.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005377", "end": "2025-12-15 19:15:21.669952", "msg": "", "rc": 0, "start": "2025-12-15 19:15:21.664575", "stderr": "", "stderr_lines": [], "stdout": "79%", "stdout_lines": ["79%"]}
ok: [localhost] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.019359", "end": "2025-12-15 19:15:22.129525", "msg": "", "rc": 0, "start": "2025-12-15 19:15:22.110166", "stderr": "", "stderr_lines": [], "stdout": "1%", "stdout_lines": ["1%"]}
TASK [Get memory usage (Linux)] ************************************************
ok: [hp.nas.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004738", "end": "2025-12-15 19:15:22.594387", "msg": "", "rc": 0, "start": "2025-12-15 19:15:22.589649", "stderr": "", "stderr_lines": [], "stdout": "80.2%", "stdout_lines": ["80.2%"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004130", "end": "2025-12-15 19:15:22.592930", "msg": "", "rc": 0, "start": "2025-12-15 19:15:22.588800", "stderr": "", "stderr_lines": [], "stdout": "21.7%", "stdout_lines": ["21.7%"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005363", "end": "2025-12-15 19:15:22.655477", "msg": "", "rc": 0, "start": "2025-12-15 19:15:22.650114", "stderr": "", "stderr_lines": [], "stdout": "49.3%", "stdout_lines": ["49.3%"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004579", "end": "2025-12-15 19:15:22.714813", "msg": "", "rc": 0, "start": "2025-12-15 19:15:22.710234", "stderr": "", "stderr_lines": [], "stdout": "8.9%", "stdout_lines": ["8.9%"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005906", "end": "2025-12-15 19:15:22.718183", "msg": "", "rc": 0, "start": "2025-12-15 19:15:22.712277", "stderr": "", "stderr_lines": [], "stdout": "59.4%", "stdout_lines": ["59.4%"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.003638", "end": "2025-12-15 19:14:58.744405", "msg": "", "rc": 0, "start": "2025-12-15 19:14:58.740767", "stderr": "", "stderr_lines": [], "stdout": "71.3%", "stdout_lines": ["71.3%"]}
ok: [media.labb.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004373", "end": "2025-12-15 19:14:52.889414", "msg": "", "rc": 0, "start": "2025-12-15 19:14:52.885041", "stderr": "", "stderr_lines": [], "stdout": "72.0%", "stdout_lines": ["72.0%"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.012209", "end": "2025-12-15 19:15:23.493126", "msg": "", "rc": 0, "start": "2025-12-15 19:15:23.480917", "stderr": "", "stderr_lines": [], "stdout": "12.4%", "stdout_lines": ["12.4%"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.011091", "end": "2025-12-15 19:15:23.522287", "msg": "", "rc": 0, "start": "2025-12-15 19:15:23.511196", "stderr": "", "stderr_lines": [], "stdout": "6.8%", "stdout_lines": ["6.8%"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005856", "end": "2025-12-15 19:15:23.962086", "msg": "", "rc": 0, "start": "2025-12-15 19:15:23.956230", "stderr": "", "stderr_lines": [], "stdout": "34.0%", "stdout_lines": ["34.0%"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004001", "end": "2025-12-15 19:14:56.191103", "msg": "", "rc": 0, "start": "2025-12-15 19:14:56.187102", "stderr": "", "stderr_lines": [], "stdout": "25.7%", "stdout_lines": ["25.7%"]}
fatal: [hp.truenas.home]: FAILED! => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005548", "end": "2025-12-15 16:15:24.163329", "msg": "non-zero return code", "rc": 2, "start": "2025-12-15 16:15:24.157781", "stderr": "cat: /proc/meminfo: No such file or directory\nawk: division by zero\n source line number 1", "stderr_lines": ["cat: /proc/meminfo: No such file or directory", "awk: division by zero", " source line number 1"], "stdout": "", "stdout_lines": []}
...ignoring
ok: [dev.prod.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004556", "end": "2025-12-15 19:15:02.192974", "msg": "", "rc": 0, "start": "2025-12-15 19:15:02.188418", "stderr": "", "stderr_lines": [], "stdout": "57.4%", "stdout_lines": ["57.4%"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.026054", "end": "2025-12-15 19:15:24.160510", "msg": "", "rc": 0, "start": "2025-12-15 19:15:24.134456", "stderr": "", "stderr_lines": [], "stdout": "19.2%", "stdout_lines": ["19.2%"]}
ok: [jump.point.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005569", "end": "2025-12-15 19:15:24.527832", "msg": "", "rc": 0, "start": "2025-12-15 19:15:24.522263", "stderr": "", "stderr_lines": [], "stdout": "13.5%", "stdout_lines": ["13.5%"]}
ok: [localhost] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.014785", "end": "2025-12-15 19:15:25.046280", "msg": "", "rc": 0, "start": "2025-12-15 19:15:25.031495", "stderr": "", "stderr_lines": [], "stdout": "12.5%", "stdout_lines": ["12.5%"]}
TASK [Get CPU temperature (ARM/SBC)] *******************************************
ok: [hp.nas.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.005146", "end": "2025-12-15 19:15:25.465308", "msg": "", "rc": 0, "start": "2025-12-15 19:15:25.460162", "stderr": "", "stderr_lines": [], "stdout": "30.0°C", "stdout_lines": ["30.0°C"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.004982", "end": "2025-12-15 19:15:25.485120", "msg": "", "rc": 0, "start": "2025-12-15 19:15:25.480138", "stderr": "", "stderr_lines": [], "stdout": "45.0°C", "stdout_lines": ["45.0°C"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.006147", "end": "2025-12-15 19:15:25.537121", "msg": "", "rc": 0, "start": "2025-12-15 19:15:25.530974", "stderr": "cat: /sys/class/thermal/thermal_zone0/temp: No data available", "stderr_lines": ["cat: /sys/class/thermal/thermal_zone0/temp: No data available"], "stdout": "0.0°C", "stdout_lines": ["0.0°C"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003354", "end": "2025-12-15 19:15:25.554196", "msg": "", "rc": 0, "start": "2025-12-15 19:15:25.550842", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.006462", "end": "2025-12-15 19:15:25.554640", "msg": "", "rc": 0, "start": "2025-12-15 19:15:25.548178", "stderr": "", "stderr_lines": [], "stdout": "53.0°C", "stdout_lines": ["53.0°C"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003004", "end": "2025-12-15 19:15:01.718271", "msg": "", "rc": 0, "start": "2025-12-15 19:15:01.715267", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [media.labb.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003091", "end": "2025-12-15 19:14:55.832488", "msg": "", "rc": 0, "start": "2025-12-15 19:14:55.829397", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.013174", "end": "2025-12-15 19:15:26.554162", "msg": "", "rc": 0, "start": "2025-12-15 19:15:26.540988", "stderr": "", "stderr_lines": [], "stdout": "36.5°C", "stdout_lines": ["36.5°C"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.011952", "end": "2025-12-15 19:15:26.614767", "msg": "", "rc": 0, "start": "2025-12-15 19:15:26.602815", "stderr": "", "stderr_lines": [], "stdout": "31.2°C", "stdout_lines": ["31.2°C"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003115", "end": "2025-12-15 19:15:26.924097", "msg": "", "rc": 0, "start": "2025-12-15 19:15:26.920982", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.002941", "end": "2025-12-15 19:14:59.144960", "msg": "", "rc": 0, "start": "2025-12-15 19:14:59.142019", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [dev.prod.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.002581", "end": "2025-12-15 19:15:05.211422", "msg": "", "rc": 0, "start": "2025-12-15 19:15:05.208841", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.004829", "end": "2025-12-15 16:15:27.197649", "msg": "", "rc": 0, "start": "2025-12-15 16:15:27.192820", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.028479", "end": "2025-12-15 19:15:27.204348", "msg": "", "rc": 0, "start": "2025-12-15 19:15:27.175869", "stderr": "", "stderr_lines": [], "stdout": "35.2°C", "stdout_lines": ["35.2°C"]}
ok: [jump.point.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.002927", "end": "2025-12-15 19:15:27.502563", "msg": "", "rc": 0, "start": "2025-12-15 19:15:27.499636", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [localhost] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.008957", "end": "2025-12-15 19:15:27.939140", "msg": "", "rc": 0, "start": "2025-12-15 19:15:27.930183", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
TASK [Get CPU load] ************************************************************
ok: [hp.nas.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004185", "end": "2025-12-15 19:15:28.373194", "msg": "", "rc": 0, "start": "2025-12-15 19:15:28.369009", "stderr": "", "stderr_lines": [], "stdout": "0.22", "stdout_lines": ["0.22"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004139", "end": "2025-12-15 19:15:28.377627", "msg": "", "rc": 0, "start": "2025-12-15 19:15:28.373488", "stderr": "", "stderr_lines": [], "stdout": "0.57", "stdout_lines": ["0.57"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004956", "end": "2025-12-15 19:15:28.437073", "msg": "", "rc": 0, "start": "2025-12-15 19:15:28.432117", "stderr": "", "stderr_lines": [], "stdout": "0.86", "stdout_lines": ["0.86"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.006084", "end": "2025-12-15 19:15:28.472295", "msg": "", "rc": 0, "start": "2025-12-15 19:15:28.466211", "stderr": "", "stderr_lines": [], "stdout": "0.75", "stdout_lines": ["0.75"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005080", "end": "2025-12-15 19:15:28.485319", "msg": "", "rc": 0, "start": "2025-12-15 19:15:28.480239", "stderr": "", "stderr_lines": [], "stdout": "0.04", "stdout_lines": ["0.04"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004291", "end": "2025-12-15 19:15:04.482357", "msg": "", "rc": 0, "start": "2025-12-15 19:15:04.478066", "stderr": "", "stderr_lines": [], "stdout": "0.22", "stdout_lines": ["0.22"]}
ok: [media.labb.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005236", "end": "2025-12-15 19:14:58.676518", "msg": "", "rc": 0, "start": "2025-12-15 19:14:58.671282", "stderr": "", "stderr_lines": [], "stdout": "0.00", "stdout_lines": ["0.00"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.010191", "end": "2025-12-15 19:15:29.285510", "msg": "", "rc": 0, "start": "2025-12-15 19:15:29.275319", "stderr": "", "stderr_lines": [], "stdout": "0.24", "stdout_lines": ["0.24"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.011448", "end": "2025-12-15 19:15:29.298079", "msg": "", "rc": 0, "start": "2025-12-15 19:15:29.286631", "stderr": "", "stderr_lines": [], "stdout": "0.04", "stdout_lines": ["0.04"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.006126", "end": "2025-12-15 19:15:29.715561", "msg": "", "rc": 0, "start": "2025-12-15 19:15:29.709435", "stderr": "", "stderr_lines": [], "stdout": "0.06", "stdout_lines": ["0.06"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005184", "end": "2025-12-15 19:15:01.990376", "msg": "", "rc": 0, "start": "2025-12-15 19:15:01.985192", "stderr": "", "stderr_lines": [], "stdout": "0.41", "stdout_lines": ["0.41"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.006024", "end": "2025-12-15 16:15:29.923215", "msg": "", "rc": 0, "start": "2025-12-15 16:15:29.917191", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}
ok: [dev.prod.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005103", "end": "2025-12-15 19:15:07.961479", "msg": "", "rc": 0, "start": "2025-12-15 19:15:07.956376", "stderr": "", "stderr_lines": [], "stdout": "0.17", "stdout_lines": ["0.17"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.024035", "end": "2025-12-15 19:15:29.911817", "msg": "", "rc": 0, "start": "2025-12-15 19:15:29.887782", "stderr": "", "stderr_lines": [], "stdout": "0.21", "stdout_lines": ["0.21"]}
ok: [jump.point.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005304", "end": "2025-12-15 19:15:30.294887", "msg": "", "rc": 0, "start": "2025-12-15 19:15:30.289583", "stderr": "", "stderr_lines": [], "stdout": "0.00", "stdout_lines": ["0.00"]}
ok: [localhost] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.019118", "end": "2025-12-15 19:15:30.836039", "msg": "", "rc": 0, "start": "2025-12-15 19:15:30.816921", "stderr": "", "stderr_lines": [], "stdout": "1.46", "stdout_lines": ["1.46"]}
TASK [Display health status] ***************************************************
ok: [ali2v.xeon.home] => {
"msg": "═══════════════════════════════════════\nHost: ali2v.xeon.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:15:16 up 1 day, 8:47, 1 user, load average: 0.58, 0.39, 0.45\nDisk Usage: 22%\nMemory Usage: 21.7%\nCPU Load: 0.57\nCPU Temp: 45.0°C\n═══════════════════════════════════════\n"
}
ok: [hp.nas.home] => {
"msg": "═══════════════════════════════════════\nHost: hp.nas.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:15:16 up 20 days, 6:06, 1 user, load average: 0.26, 0.14, 0.10\nDisk Usage: 23%\nMemory Usage: 80.2%\nCPU Load: 0.22\nCPU Temp: 30.0°C\n═══════════════════════════════════════\n"
}
ok: [hp2.i7.home] => {
"msg": "═══════════════════════════════════════\nHost: hp2.i7.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:15:16 up 20 days, 6:26, 1 user, load average: 0.93, 0.67, 0.65\nDisk Usage: 14%\nMemory Usage: 49.3%\nCPU Load: 0.86\nCPU Temp: 0.0°C\n═══════════════════════════════════════\n"
}
ok: [hp3.i5.home] => {
"msg": "═══════════════════════════════════════\nHost: hp3.i5.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:15:16 up 20 days, 7:39, 1 user, load average: 0.70, 0.69, 0.77\nDisk Usage: 14%\nMemory Usage: 59.4%\nCPU Load: 0.75\nCPU Temp: 53.0°C\n═══════════════════════════════════════\n"
}
ok: [mimi.pc.home] => {
"msg": "═══════════════════════════════════════\nHost: mimi.pc.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:15:16 up 20 days, 8:25, 1 user, load average: 0.05, 0.08, 0.08\nDisk Usage: 9%\nMemory Usage: 8.9%\nCPU Load: 0.04\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [orangepi.pc.home] => {
"msg": "═══════════════════════════════════════\nHost: orangepi.pc.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:15:18 up 13 days, 8:41, 1 user, load average: 0.07, 0.11, 0.10\nDisk Usage: 21%\nMemory Usage: 19.2%\nCPU Load: 0.21\nCPU Temp: 35.2°C\n═══════════════════════════════════════\n"
}
ok: [raspi.4gb.home] => {
"msg": "═══════════════════════════════════════\nHost: raspi.4gb.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:15:17 up 192 days, 10:48, 1 user, load average: 0.05, 0.13, 0.18\nDisk Usage: 6%\nMemory Usage: 12.4%\nCPU Load: 0.04\nCPU Temp: 36.5°C\n═══════════════════════════════════════\n"
}
ok: [raspi.8gb.home] => {
"msg": "═══════════════════════════════════════\nHost: raspi.8gb.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:15:17 up 192 days, 10:48, 1 user, load average: 0.09, 0.09, 0.09\nDisk Usage: 3%\nMemory Usage: 6.8%\nCPU Load: 0.24\nCPU Temp: 31.2°C\n═══════════════════════════════════════\n"
}
ok: [dev.lab.home] => {
"msg": "═══════════════════════════════════════\nHost: dev.lab.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:14:52 up 9 days, 7:04, 0 user, load average: 0.18, 0.31, 0.21\nDisk Usage: 48%\nMemory Usage: 71.3%\nCPU Load: 0.22\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [media.labb.home] => {
"msg": "═══════════════════════════════════════\nHost: media.labb.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:14:47 up 16 days, 3:16, 0 user, load average: 0.00, 0.03, 0.00\nDisk Usage: 24%\nMemory Usage: 72.0%\nCPU Load: 0.00\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [ali2v.truenas.home] => {
"msg": "═══════════════════════════════════════\nHost: ali2v.truenas.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:15:18 up 1 day, 8:46, 1 user, load average: 0.07, 0.06, 0.01\nDisk Usage: 1%\nMemory Usage: 34.0%\nCPU Load: 0.06\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [automate.prod.home] => {
"msg": "═══════════════════════════════════════\nHost: automate.prod.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:14:50 up 18 days, 22:09, 0 user, load average: 0.45, 0.50, 0.47\nDisk Usage: 28%\nMemory Usage: 25.7%\nCPU Load: 0.41\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [dev.prod.home] => {
"msg": "═══════════════════════════════════════\nHost: dev.prod.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:14:56 up 15 days, 8:30, 0 user, load average: 0.13, 0.12, 0.14\nDisk Usage: 75%\nMemory Usage: 57.4%\nCPU Load: 0.17\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [hp.truenas.home] => {
"msg": "═══════════════════════════════════════\nHost: hp.truenas.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 4:15PM up 20 days, 6:05, 1 user, load averages: 0.38, 0.30, 0.26\nDisk Usage: 10%\nMemory Usage: \nCPU Load: \nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [jump.point.home] => {
"msg": "═══════════════════════════════════════\nHost: jump.point.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:15:18 up 1 day, 8:46, 1 user, load average: 0.00, 0.01, 0.01\nDisk Usage: 79%\nMemory Usage: 13.5%\nCPU Load: 0.00\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [localhost] => {
"msg": "═══════════════════════════════════════\nHost: localhost\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:15:19 up 5:50, 1 user, load average: 1.45, 1.25, 1.20\nDisk Usage: 1%\nMemory Usage: 12.5%\nCPU Load: 1.46\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
PLAY RECAP *********************************************************************
ali2v.truenas.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
ali2v.xeon.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
automate.prod.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
dev.lab.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
dev.prod.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
hp.nas.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
hp.truenas.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=1
hp2.i7.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
hp3.i5.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
jump.point.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
localhost : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
media.labb.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
mimi.pc.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
orangepi.pc.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
raspi.4gb.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
raspi.8gb.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
```
---
*Généré automatiquement par Homelab Automation Dashboard*
*Date: 2025-12-16T00:15:33.088592+00:00*

View File

@ -0,0 +1,224 @@
# ✅ [Planifié] Health-check-5min
## Informations
| Propriété | Valeur |
|-----------|--------|
| **ID** | `09c0e8e9ea6643f9b503174ae3e97b31` |
| **Nom** | [Planifié] Health-check-5min |
| **Cible** | `all` |
| **Statut** | completed |
| **Type** | Planifié |
| **Progression** | 100% |
| **Début** | 2025-12-16T00:20:00.003039+00:00 |
| **Fin** | 2025-12-16T00:20:32.083832+00:00 |
| **Durée** | 32.1s |
## Sortie
```
Using /mnt/c/dev/git/python/homelab-automation-api-v2/ansible/ansible.cfg as config file
PLAY [Health check on target host] *********************************************
TASK [Check if host is reachable (ping)] ***************************************
ok: [hp.nas.home] => {"changed": false, "ping": "pong"}
ok: [hp2.i7.home] => {"changed": false, "ping": "pong"}
ok: [mimi.pc.home] => {"changed": false, "ping": "pong"}
ok: [ali2v.xeon.home] => {"changed": false, "ping": "pong"}
ok: [hp3.i5.home] => {"changed": false, "ping": "pong"}
ok: [dev.lab.home] => {"changed": false, "ping": "pong"}
ok: [media.labb.home] => {"changed": false, "ping": "pong"}
ok: [raspi.8gb.home] => {"changed": false, "ping": "pong"}
ok: [raspi.4gb.home] => {"changed": false, "ping": "pong"}
ok: [automate.prod.home] => {"changed": false, "ping": "pong"}
ok: [ali2v.truenas.home] => {"changed": false, "ping": "pong"}
ok: [hp.truenas.home] => {"changed": false, "ping": "pong"}
ok: [dev.prod.home] => {"changed": false, "ping": "pong"}
ok: [localhost] => {"changed": false, "ping": "pong"}
ok: [jump.point.home] => {"changed": false, "ping": "pong"}
ok: [orangepi.pc.home] => {"changed": false, "ping": "pong"}
TASK [Gather minimal facts] ****************************************************
ok: [hp.nas.home]
ok: [mimi.pc.home]
ok: [hp2.i7.home]
ok: [hp3.i5.home]
ok: [ali2v.xeon.home]
ok: [dev.lab.home]
ok: [media.labb.home]
ok: [raspi.8gb.home]
ok: [raspi.4gb.home]
ok: [ali2v.truenas.home]
ok: [automate.prod.home]
ok: [hp.truenas.home]
ok: [dev.prod.home]
ok: [jump.point.home]
ok: [orangepi.pc.home]
ok: [localhost]
TASK [Get system uptime] *******************************************************
ok: [hp.nas.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003195", "end": "2025-12-15 19:20:15.794908", "msg": "", "rc": 0, "start": "2025-12-15 19:20:15.791713", "stderr": "", "stderr_lines": [], "stdout": " 19:20:15 up 20 days, 6:11, 1 user, load average: 0.07, 0.12, 0.09", "stdout_lines": [" 19:20:15 up 20 days, 6:11, 1 user, load average: 0.07, 0.12, 0.09"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003477", "end": "2025-12-15 19:20:15.787290", "msg": "", "rc": 0, "start": "2025-12-15 19:20:15.783813", "stderr": "", "stderr_lines": [], "stdout": " 19:20:15 up 20 days, 6:31, 1 user, load average: 0.46, 0.62, 0.63", "stdout_lines": [" 19:20:15 up 20 days, 6:31, 1 user, load average: 0.46, 0.62, 0.63"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003751", "end": "2025-12-15 19:20:15.797736", "msg": "", "rc": 0, "start": "2025-12-15 19:20:15.793985", "stderr": "", "stderr_lines": [], "stdout": " 19:20:15 up 20 days, 8:30, 1 user, load average: 0.14, 0.10, 0.09", "stdout_lines": [" 19:20:15 up 20 days, 8:30, 1 user, load average: 0.14, 0.10, 0.09"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.004279", "end": "2025-12-15 19:20:15.816313", "msg": "", "rc": 0, "start": "2025-12-15 19:20:15.812034", "stderr": "", "stderr_lines": [], "stdout": " 19:20:15 up 20 days, 7:44, 1 user, load average: 1.16, 0.76, 0.76", "stdout_lines": [" 19:20:15 up 20 days, 7:44, 1 user, load average: 1.16, 0.76, 0.76"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.002881", "end": "2025-12-15 19:20:15.824498", "msg": "", "rc": 0, "start": "2025-12-15 19:20:15.821617", "stderr": "", "stderr_lines": [], "stdout": " 19:20:15 up 1 day, 8:52, 1 user, load average: 0.57, 0.40, 0.43", "stdout_lines": [" 19:20:15 up 1 day, 8:52, 1 user, load average: 0.57, 0.40, 0.43"]}
ok: [dev.lab.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.002904", "end": "2025-12-15 19:19:51.877490", "msg": "", "rc": 0, "start": "2025-12-15 19:19:51.874586", "stderr": "", "stderr_lines": [], "stdout": " 19:19:51 up 9 days, 7:09, 0 user, load average: 0.16, 0.18, 0.17", "stdout_lines": [" 19:19:51 up 9 days, 7:09, 0 user, load average: 0.16, 0.18, 0.17"]}
ok: [media.labb.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003718", "end": "2025-12-15 19:19:46.038919", "msg": "", "rc": 0, "start": "2025-12-15 19:19:46.035201", "stderr": "", "stderr_lines": [], "stdout": " 19:19:46 up 16 days, 3:21, 0 user, load average: 0.00, 0.02, 0.00", "stdout_lines": [" 19:19:46 up 16 days, 3:21, 0 user, load average: 0.00, 0.02, 0.00"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.008601", "end": "2025-12-15 19:20:16.688498", "msg": "", "rc": 0, "start": "2025-12-15 19:20:16.679897", "stderr": "", "stderr_lines": [], "stdout": " 19:20:16 up 192 days, 10:53, 1 user, load average: 0.04, 0.09, 0.08", "stdout_lines": [" 19:20:16 up 192 days, 10:53, 1 user, load average: 0.04, 0.09, 0.08"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.009381", "end": "2025-12-15 19:20:16.699742", "msg": "", "rc": 0, "start": "2025-12-15 19:20:16.690361", "stderr": "", "stderr_lines": [], "stdout": " 19:20:16 up 192 days, 10:53, 1 user, load average: 0.21, 0.18, 0.18", "stdout_lines": [" 19:20:16 up 192 days, 10:53, 1 user, load average: 0.21, 0.18, 0.18"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.004805", "end": "2025-12-15 19:20:17.113689", "msg": "", "rc": 0, "start": "2025-12-15 19:20:17.108884", "stderr": "", "stderr_lines": [], "stdout": " 19:20:17 up 1 day, 8:51, 1 user, load average: 0.08, 0.03, 0.01", "stdout_lines": [" 19:20:17 up 1 day, 8:51, 1 user, load average: 0.08, 0.03, 0.01"]}
ok: [automate.prod.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003412", "end": "2025-12-15 19:19:49.349681", "msg": "", "rc": 0, "start": "2025-12-15 19:19:49.346269", "stderr": "", "stderr_lines": [], "stdout": " 19:19:49 up 18 days, 22:14, 0 user, load average: 0.38, 0.45, 0.45", "stdout_lines": [" 19:19:49 up 18 days, 22:14, 0 user, load average: 0.38, 0.45, 0.45"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.004283", "end": "2025-12-15 16:20:17.325475", "msg": "", "rc": 0, "start": "2025-12-15 16:20:17.321192", "stderr": "", "stderr_lines": [], "stdout": " 4:20PM up 20 days, 6:10, 1 user, load averages: 0.20, 0.27, 0.24", "stdout_lines": [" 4:20PM up 20 days, 6:10, 1 user, load averages: 0.20, 0.27, 0.24"]}
ok: [dev.prod.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003238", "end": "2025-12-15 19:19:55.330386", "msg": "", "rc": 0, "start": "2025-12-15 19:19:55.327148", "stderr": "", "stderr_lines": [], "stdout": " 19:19:55 up 15 days, 8:35, 0 user, load average: 0.23, 0.22, 0.18", "stdout_lines": [" 19:19:55 up 15 days, 8:35, 0 user, load average: 0.23, 0.22, 0.18"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.019660", "end": "2025-12-15 19:20:17.320660", "msg": "", "rc": 0, "start": "2025-12-15 19:20:17.301000", "stderr": "", "stderr_lines": [], "stdout": " 19:20:17 up 13 days, 8:46, 1 user, load average: 0.22, 0.13, 0.10", "stdout_lines": [" 19:20:17 up 13 days, 8:46, 1 user, load average: 0.22, 0.13, 0.10"]}
ok: [jump.point.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003682", "end": "2025-12-15 19:20:17.692061", "msg": "", "rc": 0, "start": "2025-12-15 19:20:17.688379", "stderr": "", "stderr_lines": [], "stdout": " 19:20:17 up 1 day, 8:51, 1 user, load average: 0.01, 0.05, 0.01", "stdout_lines": [" 19:20:17 up 1 day, 8:51, 1 user, load average: 0.01, 0.05, 0.01"]}
ok: [localhost] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.010003", "end": "2025-12-15 19:20:18.222021", "msg": "", "rc": 0, "start": "2025-12-15 19:20:18.212018", "stderr": "", "stderr_lines": [], "stdout": " 19:20:18 up 5:55, 1 user, load average: 1.21, 1.20, 1.18", "stdout_lines": [" 19:20:18 up 5:55, 1 user, load average: 1.21, 1.20, 1.18"]}
TASK [Get disk usage] **********************************************************
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004064", "end": "2025-12-15 19:20:18.651520", "msg": "", "rc": 0, "start": "2025-12-15 19:20:18.647456", "stderr": "", "stderr_lines": [], "stdout": "22%", "stdout_lines": ["22%"]}
ok: [hp.nas.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004366", "end": "2025-12-15 19:20:18.652719", "msg": "", "rc": 0, "start": "2025-12-15 19:20:18.648353", "stderr": "", "stderr_lines": [], "stdout": "23%", "stdout_lines": ["23%"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004821", "end": "2025-12-15 19:20:18.703074", "msg": "", "rc": 0, "start": "2025-12-15 19:20:18.698253", "stderr": "", "stderr_lines": [], "stdout": "14%", "stdout_lines": ["14%"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004966", "end": "2025-12-15 19:20:18.766531", "msg": "", "rc": 0, "start": "2025-12-15 19:20:18.761565", "stderr": "", "stderr_lines": [], "stdout": "9%", "stdout_lines": ["9%"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005759", "end": "2025-12-15 19:20:18.773875", "msg": "", "rc": 0, "start": "2025-12-15 19:20:18.768116", "stderr": "", "stderr_lines": [], "stdout": "14%", "stdout_lines": ["14%"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005451", "end": "2025-12-15 19:19:54.861272", "msg": "", "rc": 0, "start": "2025-12-15 19:19:54.855821", "stderr": "", "stderr_lines": [], "stdout": "48%", "stdout_lines": ["48%"]}
ok: [media.labb.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.008395", "end": "2025-12-15 19:19:49.052108", "msg": "", "rc": 0, "start": "2025-12-15 19:19:49.043713", "stderr": "", "stderr_lines": [], "stdout": "24%", "stdout_lines": ["24%"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.010630", "end": "2025-12-15 19:20:19.711237", "msg": "", "rc": 0, "start": "2025-12-15 19:20:19.700607", "stderr": "", "stderr_lines": [], "stdout": "3%", "stdout_lines": ["3%"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.011686", "end": "2025-12-15 19:20:19.740140", "msg": "", "rc": 0, "start": "2025-12-15 19:20:19.728454", "stderr": "", "stderr_lines": [], "stdout": "6%", "stdout_lines": ["6%"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005672", "end": "2025-12-15 19:20:20.106739", "msg": "", "rc": 0, "start": "2025-12-15 19:20:20.101067", "stderr": "", "stderr_lines": [], "stdout": "1%", "stdout_lines": ["1%"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.006042", "end": "2025-12-15 16:20:20.340402", "msg": "", "rc": 0, "start": "2025-12-15 16:20:20.334360", "stderr": "", "stderr_lines": [], "stdout": "10%", "stdout_lines": ["10%"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.025141", "end": "2025-12-15 19:20:20.228990", "msg": "", "rc": 0, "start": "2025-12-15 19:20:20.203849", "stderr": "", "stderr_lines": [], "stdout": "21%", "stdout_lines": ["21%"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.006524", "end": "2025-12-15 19:19:52.428268", "msg": "", "rc": 0, "start": "2025-12-15 19:19:52.421744", "stderr": "", "stderr_lines": [], "stdout": "28%", "stdout_lines": ["28%"]}
ok: [dev.prod.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004947", "end": "2025-12-15 19:19:58.420412", "msg": "", "rc": 0, "start": "2025-12-15 19:19:58.415465", "stderr": "", "stderr_lines": [], "stdout": "75%", "stdout_lines": ["75%"]}
ok: [jump.point.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005348", "end": "2025-12-15 19:20:20.663782", "msg": "", "rc": 0, "start": "2025-12-15 19:20:20.658434", "stderr": "", "stderr_lines": [], "stdout": "79%", "stdout_lines": ["79%"]}
ok: [localhost] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.022858", "end": "2025-12-15 19:20:21.297946", "msg": "", "rc": 0, "start": "2025-12-15 19:20:21.275088", "stderr": "", "stderr_lines": [], "stdout": "1%", "stdout_lines": ["1%"]}
TASK [Get memory usage (Linux)] ************************************************
ok: [hp.nas.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004351", "end": "2025-12-15 19:20:21.704625", "msg": "", "rc": 0, "start": "2025-12-15 19:20:21.700274", "stderr": "", "stderr_lines": [], "stdout": "80.2%", "stdout_lines": ["80.2%"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004312", "end": "2025-12-15 19:20:21.738455", "msg": "", "rc": 0, "start": "2025-12-15 19:20:21.734143", "stderr": "", "stderr_lines": [], "stdout": "21.8%", "stdout_lines": ["21.8%"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004877", "end": "2025-12-15 19:20:21.805175", "msg": "", "rc": 0, "start": "2025-12-15 19:20:21.800298", "stderr": "", "stderr_lines": [], "stdout": "49.3%", "stdout_lines": ["49.3%"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005533", "end": "2025-12-15 19:20:21.830498", "msg": "", "rc": 0, "start": "2025-12-15 19:20:21.824965", "stderr": "", "stderr_lines": [], "stdout": "8.9%", "stdout_lines": ["8.9%"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005743", "end": "2025-12-15 19:20:21.848737", "msg": "", "rc": 0, "start": "2025-12-15 19:20:21.842994", "stderr": "", "stderr_lines": [], "stdout": "59.4%", "stdout_lines": ["59.4%"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.003987", "end": "2025-12-15 19:19:57.899701", "msg": "", "rc": 0, "start": "2025-12-15 19:19:57.895714", "stderr": "", "stderr_lines": [], "stdout": "71.0%", "stdout_lines": ["71.0%"]}
ok: [media.labb.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004605", "end": "2025-12-15 19:19:52.054879", "msg": "", "rc": 0, "start": "2025-12-15 19:19:52.050274", "stderr": "", "stderr_lines": [], "stdout": "72.2%", "stdout_lines": ["72.2%"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.012104", "end": "2025-12-15 19:20:22.601564", "msg": "", "rc": 0, "start": "2025-12-15 19:20:22.589460", "stderr": "", "stderr_lines": [], "stdout": "12.3%", "stdout_lines": ["12.3%"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.011144", "end": "2025-12-15 19:20:22.685368", "msg": "", "rc": 0, "start": "2025-12-15 19:20:22.674224", "stderr": "", "stderr_lines": [], "stdout": "6.8%", "stdout_lines": ["6.8%"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.006863", "end": "2025-12-15 19:20:23.115477", "msg": "", "rc": 0, "start": "2025-12-15 19:20:23.108614", "stderr": "", "stderr_lines": [], "stdout": "34.0%", "stdout_lines": ["34.0%"]}
fatal: [hp.truenas.home]: FAILED! => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005083", "end": "2025-12-15 16:20:23.257636", "msg": "non-zero return code", "rc": 2, "start": "2025-12-15 16:20:23.252553", "stderr": "cat: /proc/meminfo: No such file or directory\nawk: division by zero\n source line number 1", "stderr_lines": ["cat: /proc/meminfo: No such file or directory", "awk: division by zero", " source line number 1"], "stdout": "", "stdout_lines": []}
...ignoring
ok: [dev.prod.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.003906", "end": "2025-12-15 19:20:01.270196", "msg": "", "rc": 0, "start": "2025-12-15 19:20:01.266290", "stderr": "", "stderr_lines": [], "stdout": "58.4%", "stdout_lines": ["58.4%"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004315", "end": "2025-12-15 19:19:55.366287", "msg": "", "rc": 0, "start": "2025-12-15 19:19:55.361972", "stderr": "", "stderr_lines": [], "stdout": "25.7%", "stdout_lines": ["25.7%"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.026259", "end": "2025-12-15 19:20:23.272284", "msg": "", "rc": 0, "start": "2025-12-15 19:20:23.246025", "stderr": "", "stderr_lines": [], "stdout": "19.2%", "stdout_lines": ["19.2%"]}
ok: [jump.point.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005387", "end": "2025-12-15 19:20:23.673030", "msg": "", "rc": 0, "start": "2025-12-15 19:20:23.667643", "stderr": "", "stderr_lines": [], "stdout": "13.2%", "stdout_lines": ["13.2%"]}
ok: [localhost] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.020698", "end": "2025-12-15 19:20:24.237274", "msg": "", "rc": 0, "start": "2025-12-15 19:20:24.216576", "stderr": "", "stderr_lines": [], "stdout": "12.4%", "stdout_lines": ["12.4%"]}
TASK [Get CPU temperature (ARM/SBC)] *******************************************
ok: [hp.nas.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.005194", "end": "2025-12-15 19:20:24.645256", "msg": "", "rc": 0, "start": "2025-12-15 19:20:24.640062", "stderr": "", "stderr_lines": [], "stdout": "30.0°C", "stdout_lines": ["30.0°C"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.004864", "end": "2025-12-15 19:20:24.653406", "msg": "", "rc": 0, "start": "2025-12-15 19:20:24.648542", "stderr": "", "stderr_lines": [], "stdout": "45.0°C", "stdout_lines": ["45.0°C"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.005702", "end": "2025-12-15 19:20:24.707495", "msg": "", "rc": 0, "start": "2025-12-15 19:20:24.701793", "stderr": "cat: /sys/class/thermal/thermal_zone0/temp: No data available", "stderr_lines": ["cat: /sys/class/thermal/thermal_zone0/temp: No data available"], "stdout": "0.0°C", "stdout_lines": ["0.0°C"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003154", "end": "2025-12-15 19:20:24.775140", "msg": "", "rc": 0, "start": "2025-12-15 19:20:24.771986", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.006299", "end": "2025-12-15 19:20:24.774482", "msg": "", "rc": 0, "start": "2025-12-15 19:20:24.768183", "stderr": "", "stderr_lines": [], "stdout": "52.5°C", "stdout_lines": ["52.5°C"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.002889", "end": "2025-12-15 19:20:00.736784", "msg": "", "rc": 0, "start": "2025-12-15 19:20:00.733895", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [media.labb.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003266", "end": "2025-12-15 19:19:54.885427", "msg": "", "rc": 0, "start": "2025-12-15 19:19:54.882161", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.011852", "end": "2025-12-15 19:20:25.591080", "msg": "", "rc": 0, "start": "2025-12-15 19:20:25.579228", "stderr": "", "stderr_lines": [], "stdout": "31.6°C", "stdout_lines": ["31.6°C"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.012989", "end": "2025-12-15 19:20:25.607972", "msg": "", "rc": 0, "start": "2025-12-15 19:20:25.594983", "stderr": "", "stderr_lines": [], "stdout": "36.5°C", "stdout_lines": ["36.5°C"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003176", "end": "2025-12-15 19:20:25.990821", "msg": "", "rc": 0, "start": "2025-12-15 19:20:25.987645", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.002672", "end": "2025-12-15 19:19:58.238195", "msg": "", "rc": 0, "start": "2025-12-15 19:19:58.235523", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003966", "end": "2025-12-15 16:20:26.211457", "msg": "", "rc": 0, "start": "2025-12-15 16:20:26.207491", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [dev.prod.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.002588", "end": "2025-12-15 19:20:04.240743", "msg": "", "rc": 0, "start": "2025-12-15 19:20:04.238155", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.028611", "end": "2025-12-15 19:20:26.221052", "msg": "", "rc": 0, "start": "2025-12-15 19:20:26.192441", "stderr": "", "stderr_lines": [], "stdout": "36.2°C", "stdout_lines": ["36.2°C"]}
ok: [jump.point.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003209", "end": "2025-12-15 19:20:26.545283", "msg": "", "rc": 0, "start": "2025-12-15 19:20:26.542074", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [localhost] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.018576", "end": "2025-12-15 19:20:27.132697", "msg": "", "rc": 0, "start": "2025-12-15 19:20:27.114121", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
TASK [Get CPU load] ************************************************************
ok: [hp.nas.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004306", "end": "2025-12-15 19:20:27.494654", "msg": "", "rc": 0, "start": "2025-12-15 19:20:27.490348", "stderr": "", "stderr_lines": [], "stdout": "0.05", "stdout_lines": ["0.05"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004084", "end": "2025-12-15 19:20:27.511446", "msg": "", "rc": 0, "start": "2025-12-15 19:20:27.507362", "stderr": "", "stderr_lines": [], "stdout": "0.56", "stdout_lines": ["0.56"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004771", "end": "2025-12-15 19:20:27.581135", "msg": "", "rc": 0, "start": "2025-12-15 19:20:27.576364", "stderr": "", "stderr_lines": [], "stdout": "0.85", "stdout_lines": ["0.85"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005400", "end": "2025-12-15 19:20:27.634042", "msg": "", "rc": 0, "start": "2025-12-15 19:20:27.628642", "stderr": "", "stderr_lines": [], "stdout": "0.12", "stdout_lines": ["0.12"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005694", "end": "2025-12-15 19:20:27.635185", "msg": "", "rc": 0, "start": "2025-12-15 19:20:27.629491", "stderr": "", "stderr_lines": [], "stdout": "1.14", "stdout_lines": ["1.14"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004360", "end": "2025-12-15 19:20:03.569060", "msg": "", "rc": 0, "start": "2025-12-15 19:20:03.564700", "stderr": "", "stderr_lines": [], "stdout": "0.14", "stdout_lines": ["0.14"]}
ok: [media.labb.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005170", "end": "2025-12-15 19:19:57.772505", "msg": "", "rc": 0, "start": "2025-12-15 19:19:57.767335", "stderr": "", "stderr_lines": [], "stdout": "0.08", "stdout_lines": ["0.08"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.010266", "end": "2025-12-15 19:20:28.370701", "msg": "", "rc": 0, "start": "2025-12-15 19:20:28.360435", "stderr": "", "stderr_lines": [], "stdout": "0.03", "stdout_lines": ["0.03"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.011172", "end": "2025-12-15 19:20:28.384140", "msg": "", "rc": 0, "start": "2025-12-15 19:20:28.372968", "stderr": "", "stderr_lines": [], "stdout": "0.18", "stdout_lines": ["0.18"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.006309", "end": "2025-12-15 19:20:28.792637", "msg": "", "rc": 0, "start": "2025-12-15 19:20:28.786328", "stderr": "", "stderr_lines": [], "stdout": "0.14", "stdout_lines": ["0.14"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.006131", "end": "2025-12-15 16:20:28.994145", "msg": "", "rc": 0, "start": "2025-12-15 16:20:28.988014", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}
ok: [automate.prod.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005113", "end": "2025-12-15 19:20:01.064226", "msg": "", "rc": 0, "start": "2025-12-15 19:20:01.059113", "stderr": "", "stderr_lines": [], "stdout": "0.39", "stdout_lines": ["0.39"]}
ok: [dev.prod.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004429", "end": "2025-12-15 19:20:07.024289", "msg": "", "rc": 0, "start": "2025-12-15 19:20:07.019860", "stderr": "", "stderr_lines": [], "stdout": "0.27", "stdout_lines": ["0.27"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.024259", "end": "2025-12-15 19:20:29.008962", "msg": "", "rc": 0, "start": "2025-12-15 19:20:28.984703", "stderr": "", "stderr_lines": [], "stdout": "0.18", "stdout_lines": ["0.18"]}
ok: [jump.point.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005406", "end": "2025-12-15 19:20:29.310571", "msg": "", "rc": 0, "start": "2025-12-15 19:20:29.305165", "stderr": "", "stderr_lines": [], "stdout": "0.01", "stdout_lines": ["0.01"]}
ok: [localhost] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.021502", "end": "2025-12-15 19:20:29.989461", "msg": "", "rc": 0, "start": "2025-12-15 19:20:29.967959", "stderr": "", "stderr_lines": [], "stdout": "1.57", "stdout_lines": ["1.57"]}
TASK [Display health status] ***************************************************
ok: [ali2v.xeon.home] => {
"msg": "═══════════════════════════════════════\nHost: ali2v.xeon.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:20:15 up 1 day, 8:52, 1 user, load average: 0.57, 0.40, 0.43\nDisk Usage: 22%\nMemory Usage: 21.8%\nCPU Load: 0.56\nCPU Temp: 45.0°C\n═══════════════════════════════════════\n"
}
ok: [hp.nas.home] => {
"msg": "═══════════════════════════════════════\nHost: hp.nas.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:20:15 up 20 days, 6:11, 1 user, load average: 0.07, 0.12, 0.09\nDisk Usage: 23%\nMemory Usage: 80.2%\nCPU Load: 0.05\nCPU Temp: 30.0°C\n═══════════════════════════════════════\n"
}
ok: [hp2.i7.home] => {
"msg": "═══════════════════════════════════════\nHost: hp2.i7.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:20:15 up 20 days, 6:31, 1 user, load average: 0.46, 0.62, 0.63\nDisk Usage: 14%\nMemory Usage: 49.3%\nCPU Load: 0.85\nCPU Temp: 0.0°C\n═══════════════════════════════════════\n"
}
ok: [hp3.i5.home] => {
"msg": "═══════════════════════════════════════\nHost: hp3.i5.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:20:15 up 20 days, 7:44, 1 user, load average: 1.16, 0.76, 0.76\nDisk Usage: 14%\nMemory Usage: 59.4%\nCPU Load: 1.14\nCPU Temp: 52.5°C\n═══════════════════════════════════════\n"
}
ok: [mimi.pc.home] => {
"msg": "═══════════════════════════════════════\nHost: mimi.pc.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:20:15 up 20 days, 8:30, 1 user, load average: 0.14, 0.10, 0.09\nDisk Usage: 9%\nMemory Usage: 8.9%\nCPU Load: 0.12\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [orangepi.pc.home] => {
"msg": "═══════════════════════════════════════\nHost: orangepi.pc.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:20:17 up 13 days, 8:46, 1 user, load average: 0.22, 0.13, 0.10\nDisk Usage: 21%\nMemory Usage: 19.2%\nCPU Load: 0.18\nCPU Temp: 36.2°C\n═══════════════════════════════════════\n"
}
ok: [raspi.4gb.home] => {
"msg": "═══════════════════════════════════════\nHost: raspi.4gb.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:20:16 up 192 days, 10:53, 1 user, load average: 0.21, 0.18, 0.18\nDisk Usage: 6%\nMemory Usage: 12.3%\nCPU Load: 0.18\nCPU Temp: 36.5°C\n═══════════════════════════════════════\n"
}
ok: [raspi.8gb.home] => {
"msg": "═══════════════════════════════════════\nHost: raspi.8gb.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:20:16 up 192 days, 10:53, 1 user, load average: 0.04, 0.09, 0.08\nDisk Usage: 3%\nMemory Usage: 6.8%\nCPU Load: 0.03\nCPU Temp: 31.6°C\n═══════════════════════════════════════\n"
}
ok: [dev.lab.home] => {
"msg": "═══════════════════════════════════════\nHost: dev.lab.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:19:51 up 9 days, 7:09, 0 user, load average: 0.16, 0.18, 0.17\nDisk Usage: 48%\nMemory Usage: 71.0%\nCPU Load: 0.14\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [media.labb.home] => {
"msg": "═══════════════════════════════════════\nHost: media.labb.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:19:46 up 16 days, 3:21, 0 user, load average: 0.00, 0.02, 0.00\nDisk Usage: 24%\nMemory Usage: 72.2%\nCPU Load: 0.08\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [ali2v.truenas.home] => {
"msg": "═══════════════════════════════════════\nHost: ali2v.truenas.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:20:17 up 1 day, 8:51, 1 user, load average: 0.08, 0.03, 0.01\nDisk Usage: 1%\nMemory Usage: 34.0%\nCPU Load: 0.14\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [automate.prod.home] => {
"msg": "═══════════════════════════════════════\nHost: automate.prod.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:19:49 up 18 days, 22:14, 0 user, load average: 0.38, 0.45, 0.45\nDisk Usage: 28%\nMemory Usage: 25.7%\nCPU Load: 0.39\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [dev.prod.home] => {
"msg": "═══════════════════════════════════════\nHost: dev.prod.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:19:55 up 15 days, 8:35, 0 user, load average: 0.23, 0.22, 0.18\nDisk Usage: 75%\nMemory Usage: 58.4%\nCPU Load: 0.27\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [hp.truenas.home] => {
"msg": "═══════════════════════════════════════\nHost: hp.truenas.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 4:20PM up 20 days, 6:10, 1 user, load averages: 0.20, 0.27, 0.24\nDisk Usage: 10%\nMemory Usage: \nCPU Load: \nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [jump.point.home] => {
"msg": "═══════════════════════════════════════\nHost: jump.point.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:20:17 up 1 day, 8:51, 1 user, load average: 0.01, 0.05, 0.01\nDisk Usage: 79%\nMemory Usage: 13.2%\nCPU Load: 0.01\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [localhost] => {
"msg": "═══════════════════════════════════════\nHost: localhost\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:20:18 up 5:55, 1 user, load average: 1.21, 1.20, 1.18\nDisk Usage: 1%\nMemory Usage: 12.4%\nCPU Load: 1.57\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
PLAY RECAP *********************************************************************
ali2v.truenas.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
ali2v.xeon.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
automate.prod.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
dev.lab.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
dev.prod.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
hp.nas.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
hp.truenas.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=1
hp2.i7.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
hp3.i5.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
jump.point.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
localhost : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
media.labb.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
mimi.pc.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
orangepi.pc.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
raspi.4gb.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
raspi.8gb.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
```
---
*Généré automatiquement par Homelab Automation Dashboard*
*Date: 2025-12-16T00:20:32.159480+00:00*

View File

@ -0,0 +1,224 @@
# ✅ [Planifié] Health-check-5min
## Informations
| Propriété | Valeur |
|-----------|--------|
| **ID** | `7b714215599b4100a5161a14a9e93bf0` |
| **Nom** | [Planifié] Health-check-5min |
| **Cible** | `all` |
| **Statut** | completed |
| **Type** | Planifié |
| **Progression** | 100% |
| **Début** | 2025-12-16T00:25:00.004602+00:00 |
| **Fin** | 2025-12-16T00:25:31.208064+00:00 |
| **Durée** | 31.2s |
## Sortie
```
Using /mnt/c/dev/git/python/homelab-automation-api-v2/ansible/ansible.cfg as config file
PLAY [Health check on target host] *********************************************
TASK [Check if host is reachable (ping)] ***************************************
ok: [hp.nas.home] => {"changed": false, "ping": "pong"}
ok: [mimi.pc.home] => {"changed": false, "ping": "pong"}
ok: [hp2.i7.home] => {"changed": false, "ping": "pong"}
ok: [ali2v.xeon.home] => {"changed": false, "ping": "pong"}
ok: [hp3.i5.home] => {"changed": false, "ping": "pong"}
ok: [dev.lab.home] => {"changed": false, "ping": "pong"}
ok: [media.labb.home] => {"changed": false, "ping": "pong"}
ok: [raspi.8gb.home] => {"changed": false, "ping": "pong"}
ok: [raspi.4gb.home] => {"changed": false, "ping": "pong"}
ok: [automate.prod.home] => {"changed": false, "ping": "pong"}
ok: [ali2v.truenas.home] => {"changed": false, "ping": "pong"}
ok: [hp.truenas.home] => {"changed": false, "ping": "pong"}
ok: [dev.prod.home] => {"changed": false, "ping": "pong"}
ok: [localhost] => {"changed": false, "ping": "pong"}
ok: [jump.point.home] => {"changed": false, "ping": "pong"}
ok: [orangepi.pc.home] => {"changed": false, "ping": "pong"}
TASK [Gather minimal facts] ****************************************************
ok: [hp.nas.home]
ok: [mimi.pc.home]
ok: [hp2.i7.home]
ok: [hp3.i5.home]
ok: [ali2v.xeon.home]
ok: [dev.lab.home]
ok: [media.labb.home]
ok: [raspi.8gb.home]
ok: [raspi.4gb.home]
ok: [ali2v.truenas.home]
ok: [automate.prod.home]
ok: [hp.truenas.home]
ok: [dev.prod.home]
ok: [jump.point.home]
ok: [orangepi.pc.home]
ok: [localhost]
TASK [Get system uptime] *******************************************************
ok: [hp.nas.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003058", "end": "2025-12-15 19:25:15.261310", "msg": "", "rc": 0, "start": "2025-12-15 19:25:15.258252", "stderr": "", "stderr_lines": [], "stdout": " 19:25:15 up 20 days, 6:16, 1 user, load average: 0.11, 0.07, 0.07", "stdout_lines": [" 19:25:15 up 20 days, 6:16, 1 user, load average: 0.11, 0.07, 0.07"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003638", "end": "2025-12-15 19:25:15.285190", "msg": "", "rc": 0, "start": "2025-12-15 19:25:15.281552", "stderr": "", "stderr_lines": [], "stdout": " 19:25:15 up 20 days, 8:35, 1 user, load average: 0.06, 0.09, 0.09", "stdout_lines": [" 19:25:15 up 20 days, 8:35, 1 user, load average: 0.06, 0.09, 0.09"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.002828", "end": "2025-12-15 19:25:15.282893", "msg": "", "rc": 0, "start": "2025-12-15 19:25:15.280065", "stderr": "", "stderr_lines": [], "stdout": " 19:25:15 up 1 day, 8:57, 1 user, load average: 0.27, 0.39, 0.43", "stdout_lines": [" 19:25:15 up 1 day, 8:57, 1 user, load average: 0.27, 0.39, 0.43"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003879", "end": "2025-12-15 19:25:15.295432", "msg": "", "rc": 0, "start": "2025-12-15 19:25:15.291553", "stderr": "", "stderr_lines": [], "stdout": " 19:25:15 up 20 days, 7:49, 1 user, load average: 0.48, 0.56, 0.67", "stdout_lines": [" 19:25:15 up 20 days, 7:49, 1 user, load average: 0.48, 0.56, 0.67"]}
ok: [dev.lab.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003422", "end": "2025-12-15 19:24:51.340787", "msg": "", "rc": 0, "start": "2025-12-15 19:24:51.337365", "stderr": "", "stderr_lines": [], "stdout": " 19:24:51 up 9 days, 7:14, 0 user, load average: 0.04, 0.08, 0.13", "stdout_lines": [" 19:24:51 up 9 days, 7:14, 0 user, load average: 0.04, 0.08, 0.13"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.009358", "end": "2025-12-15 19:25:16.142836", "msg": "", "rc": 0, "start": "2025-12-15 19:25:16.133478", "stderr": "", "stderr_lines": [], "stdout": " 19:25:16 up 192 days, 10:58, 1 user, load average: 0.42, 0.26, 0.20", "stdout_lines": [" 19:25:16 up 192 days, 10:58, 1 user, load average: 0.42, 0.26, 0.20"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.008595", "end": "2025-12-15 19:25:16.143604", "msg": "", "rc": 0, "start": "2025-12-15 19:25:16.135009", "stderr": "", "stderr_lines": [], "stdout": " 19:25:16 up 192 days, 10:58, 1 user, load average: 0.17, 0.13, 0.10", "stdout_lines": [" 19:25:16 up 192 days, 10:58, 1 user, load average: 0.17, 0.13, 0.10"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:01.004191", "end": "2025-12-15 19:25:16.290811", "msg": "", "rc": 0, "start": "2025-12-15 19:25:15.286620", "stderr": "", "stderr_lines": [], "stdout": " 19:25:15 up 20 days, 6:36, 1 user, load average: 0.58, 0.64, 0.64", "stdout_lines": [" 19:25:15 up 20 days, 6:36, 1 user, load average: 0.58, 0.64, 0.64"]}
ok: [media.labb.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003685", "end": "2025-12-15 19:24:46.059250", "msg": "", "rc": 0, "start": "2025-12-15 19:24:46.055565", "stderr": "", "stderr_lines": [], "stdout": " 19:24:46 up 16 days, 3:26, 0 user, load average: 0.03, 0.04, 0.00", "stdout_lines": [" 19:24:46 up 16 days, 3:26, 0 user, load average: 0.03, 0.04, 0.00"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.004786", "end": "2025-12-15 19:25:16.795995", "msg": "", "rc": 0, "start": "2025-12-15 19:25:16.791209", "stderr": "", "stderr_lines": [], "stdout": " 19:25:16 up 1 day, 8:56, 1 user, load average: 0.01, 0.03, 0.00", "stdout_lines": [" 19:25:16 up 1 day, 8:56, 1 user, load average: 0.01, 0.03, 0.00"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.019803", "end": "2025-12-15 19:25:16.801665", "msg": "", "rc": 0, "start": "2025-12-15 19:25:16.781862", "stderr": "", "stderr_lines": [], "stdout": " 19:25:16 up 13 days, 8:51, 1 user, load average: 0.23, 0.14, 0.10", "stdout_lines": [" 19:25:16 up 13 days, 8:51, 1 user, load average: 0.23, 0.14, 0.10"]}
ok: [dev.prod.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.002754", "end": "2025-12-15 19:24:54.939749", "msg": "", "rc": 0, "start": "2025-12-15 19:24:54.936995", "stderr": "", "stderr_lines": [], "stdout": " 19:24:54 up 15 days, 8:40, 0 user, load average: 0.12, 0.14, 0.16", "stdout_lines": [" 19:24:54 up 15 days, 8:40, 0 user, load average: 0.12, 0.14, 0.16"]}
ok: [automate.prod.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003889", "end": "2025-12-15 19:24:48.999875", "msg": "", "rc": 0, "start": "2025-12-15 19:24:48.995986", "stderr": "", "stderr_lines": [], "stdout": " 19:24:48 up 18 days, 22:19, 0 user, load average: 0.29, 0.37, 0.42", "stdout_lines": [" 19:24:48 up 18 days, 22:19, 0 user, load average: 0.29, 0.37, 0.42"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.004296", "end": "2025-12-15 16:25:17.160732", "msg": "", "rc": 0, "start": "2025-12-15 16:25:17.156436", "stderr": "", "stderr_lines": [], "stdout": " 4:25PM up 20 days, 6:15, 1 user, load averages: 0.26, 0.24, 0.24", "stdout_lines": [" 4:25PM up 20 days, 6:15, 1 user, load averages: 0.26, 0.24, 0.24"]}
ok: [jump.point.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003958", "end": "2025-12-15 19:25:17.345861", "msg": "", "rc": 0, "start": "2025-12-15 19:25:17.341903", "stderr": "", "stderr_lines": [], "stdout": " 19:25:17 up 1 day, 8:56, 1 user, load average: 0.16, 0.07, 0.02", "stdout_lines": [" 19:25:17 up 1 day, 8:56, 1 user, load average: 0.16, 0.07, 0.02"]}
ok: [localhost] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.005507", "end": "2025-12-15 19:25:17.848777", "msg": "", "rc": 0, "start": "2025-12-15 19:25:17.843270", "stderr": "", "stderr_lines": [], "stdout": " 19:25:17 up 6:00, 1 user, load average: 1.36, 1.23, 1.19", "stdout_lines": [" 19:25:17 up 6:00, 1 user, load average: 1.36, 1.23, 1.19"]}
TASK [Get disk usage] **********************************************************
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004144", "end": "2025-12-15 19:25:18.185754", "msg": "", "rc": 0, "start": "2025-12-15 19:25:18.181610", "stderr": "", "stderr_lines": [], "stdout": "22%", "stdout_lines": ["22%"]}
ok: [hp.nas.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004352", "end": "2025-12-15 19:25:18.188583", "msg": "", "rc": 0, "start": "2025-12-15 19:25:18.184231", "stderr": "", "stderr_lines": [], "stdout": "23%", "stdout_lines": ["23%"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005033", "end": "2025-12-15 19:25:18.230687", "msg": "", "rc": 0, "start": "2025-12-15 19:25:18.225654", "stderr": "", "stderr_lines": [], "stdout": "14%", "stdout_lines": ["14%"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005652", "end": "2025-12-15 19:25:18.276034", "msg": "", "rc": 0, "start": "2025-12-15 19:25:18.270382", "stderr": "", "stderr_lines": [], "stdout": "14%", "stdout_lines": ["14%"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005188", "end": "2025-12-15 19:25:18.283902", "msg": "", "rc": 0, "start": "2025-12-15 19:25:18.278714", "stderr": "", "stderr_lines": [], "stdout": "9%", "stdout_lines": ["9%"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004839", "end": "2025-12-15 19:24:54.234515", "msg": "", "rc": 0, "start": "2025-12-15 19:24:54.229676", "stderr": "", "stderr_lines": [], "stdout": "48%", "stdout_lines": ["48%"]}
ok: [media.labb.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005588", "end": "2025-12-15 19:24:48.433895", "msg": "", "rc": 0, "start": "2025-12-15 19:24:48.428307", "stderr": "", "stderr_lines": [], "stdout": "24%", "stdout_lines": ["24%"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.010600", "end": "2025-12-15 19:25:19.105693", "msg": "", "rc": 0, "start": "2025-12-15 19:25:19.095093", "stderr": "", "stderr_lines": [], "stdout": "3%", "stdout_lines": ["3%"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.011680", "end": "2025-12-15 19:25:19.123267", "msg": "", "rc": 0, "start": "2025-12-15 19:25:19.111587", "stderr": "", "stderr_lines": [], "stdout": "6%", "stdout_lines": ["6%"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005774", "end": "2025-12-15 19:25:19.444721", "msg": "", "rc": 0, "start": "2025-12-15 19:25:19.438947", "stderr": "", "stderr_lines": [], "stdout": "1%", "stdout_lines": ["1%"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005399", "end": "2025-12-15 16:25:19.708640", "msg": "", "rc": 0, "start": "2025-12-15 16:25:19.703241", "stderr": "", "stderr_lines": [], "stdout": "10%", "stdout_lines": ["10%"]}
ok: [dev.prod.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004757", "end": "2025-12-15 19:24:57.719652", "msg": "", "rc": 0, "start": "2025-12-15 19:24:57.714895", "stderr": "", "stderr_lines": [], "stdout": "75%", "stdout_lines": ["75%"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005512", "end": "2025-12-15 19:24:51.801003", "msg": "", "rc": 0, "start": "2025-12-15 19:24:51.795491", "stderr": "", "stderr_lines": [], "stdout": "28%", "stdout_lines": ["28%"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.025313", "end": "2025-12-15 19:25:19.729007", "msg": "", "rc": 0, "start": "2025-12-15 19:25:19.703694", "stderr": "", "stderr_lines": [], "stdout": "21%", "stdout_lines": ["21%"]}
ok: [jump.point.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005393", "end": "2025-12-15 19:25:20.002033", "msg": "", "rc": 0, "start": "2025-12-15 19:25:19.996640", "stderr": "", "stderr_lines": [], "stdout": "79%", "stdout_lines": ["79%"]}
ok: [localhost] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.018582", "end": "2025-12-15 19:25:20.675904", "msg": "", "rc": 0, "start": "2025-12-15 19:25:20.657322", "stderr": "", "stderr_lines": [], "stdout": "1%", "stdout_lines": ["1%"]}
TASK [Get memory usage (Linux)] ************************************************
ok: [hp.nas.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004454", "end": "2025-12-15 19:25:20.989764", "msg": "", "rc": 0, "start": "2025-12-15 19:25:20.985310", "stderr": "", "stderr_lines": [], "stdout": "80.0%", "stdout_lines": ["80.0%"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004172", "end": "2025-12-15 19:25:21.007956", "msg": "", "rc": 0, "start": "2025-12-15 19:25:21.003784", "stderr": "", "stderr_lines": [], "stdout": "21.8%", "stdout_lines": ["21.8%"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004660", "end": "2025-12-15 19:25:21.051054", "msg": "", "rc": 0, "start": "2025-12-15 19:25:21.046394", "stderr": "", "stderr_lines": [], "stdout": "49.2%", "stdout_lines": ["49.2%"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004402", "end": "2025-12-15 19:25:21.111416", "msg": "", "rc": 0, "start": "2025-12-15 19:25:21.107014", "stderr": "", "stderr_lines": [], "stdout": "9.0%", "stdout_lines": ["9.0%"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.006077", "end": "2025-12-15 19:25:21.145034", "msg": "", "rc": 0, "start": "2025-12-15 19:25:21.138957", "stderr": "", "stderr_lines": [], "stdout": "59.5%", "stdout_lines": ["59.5%"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.003845", "end": "2025-12-15 19:24:57.141160", "msg": "", "rc": 0, "start": "2025-12-15 19:24:57.137315", "stderr": "", "stderr_lines": [], "stdout": "70.7%", "stdout_lines": ["70.7%"]}
ok: [media.labb.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005202", "end": "2025-12-15 19:24:51.342070", "msg": "", "rc": 0, "start": "2025-12-15 19:24:51.336868", "stderr": "", "stderr_lines": [], "stdout": "72.1%", "stdout_lines": ["72.1%"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.011118", "end": "2025-12-15 19:25:21.895100", "msg": "", "rc": 0, "start": "2025-12-15 19:25:21.883982", "stderr": "", "stderr_lines": [], "stdout": "6.7%", "stdout_lines": ["6.7%"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.012201", "end": "2025-12-15 19:25:21.920092", "msg": "", "rc": 0, "start": "2025-12-15 19:25:21.907891", "stderr": "", "stderr_lines": [], "stdout": "12.2%", "stdout_lines": ["12.2%"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005864", "end": "2025-12-15 19:25:22.355099", "msg": "", "rc": 0, "start": "2025-12-15 19:25:22.349235", "stderr": "", "stderr_lines": [], "stdout": "34.2%", "stdout_lines": ["34.2%"]}
fatal: [hp.truenas.home]: FAILED! => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005194", "end": "2025-12-15 16:25:22.496040", "msg": "non-zero return code", "rc": 2, "start": "2025-12-15 16:25:22.490846", "stderr": "cat: /proc/meminfo: No such file or directory\nawk: division by zero\n source line number 1", "stderr_lines": ["cat: /proc/meminfo: No such file or directory", "awk: division by zero", " source line number 1"], "stdout": "", "stdout_lines": []}
...ignoring
ok: [dev.prod.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.003612", "end": "2025-12-15 19:25:00.525710", "msg": "", "rc": 0, "start": "2025-12-15 19:25:00.522098", "stderr": "", "stderr_lines": [], "stdout": "59.4%", "stdout_lines": ["59.4%"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004443", "end": "2025-12-15 19:24:54.648655", "msg": "", "rc": 0, "start": "2025-12-15 19:24:54.644212", "stderr": "", "stderr_lines": [], "stdout": "25.5%", "stdout_lines": ["25.5%"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.025593", "end": "2025-12-15 19:25:22.549873", "msg": "", "rc": 0, "start": "2025-12-15 19:25:22.524280", "stderr": "", "stderr_lines": [], "stdout": "20.1%", "stdout_lines": ["20.1%"]}
ok: [jump.point.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005681", "end": "2025-12-15 19:25:22.884099", "msg": "", "rc": 0, "start": "2025-12-15 19:25:22.878418", "stderr": "", "stderr_lines": [], "stdout": "13.3%", "stdout_lines": ["13.3%"]}
ok: [localhost] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.019809", "end": "2025-12-15 19:25:23.514422", "msg": "", "rc": 0, "start": "2025-12-15 19:25:23.494613", "stderr": "", "stderr_lines": [], "stdout": "12.4%", "stdout_lines": ["12.4%"]}
TASK [Get CPU temperature (ARM/SBC)] *******************************************
ok: [hp.nas.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.005129", "end": "2025-12-15 19:25:23.922166", "msg": "", "rc": 0, "start": "2025-12-15 19:25:23.917037", "stderr": "", "stderr_lines": [], "stdout": "30.0°C", "stdout_lines": ["30.0°C"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.005980", "end": "2025-12-15 19:25:23.956154", "msg": "", "rc": 0, "start": "2025-12-15 19:25:23.950174", "stderr": "cat: /sys/class/thermal/thermal_zone0/temp: No data available", "stderr_lines": ["cat: /sys/class/thermal/thermal_zone0/temp: No data available"], "stdout": "0.0°C", "stdout_lines": ["0.0°C"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.004919", "end": "2025-12-15 19:25:23.945218", "msg": "", "rc": 0, "start": "2025-12-15 19:25:23.940299", "stderr": "", "stderr_lines": [], "stdout": "45.0°C", "stdout_lines": ["45.0°C"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003514", "end": "2025-12-15 19:25:24.022456", "msg": "", "rc": 0, "start": "2025-12-15 19:25:24.018942", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.007033", "end": "2025-12-15 19:25:24.011014", "msg": "", "rc": 0, "start": "2025-12-15 19:25:24.003981", "stderr": "", "stderr_lines": [], "stdout": "52.5°C", "stdout_lines": ["52.5°C"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.002698", "end": "2025-12-15 19:25:00.092484", "msg": "", "rc": 0, "start": "2025-12-15 19:25:00.089786", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [media.labb.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003256", "end": "2025-12-15 19:24:54.230625", "msg": "", "rc": 0, "start": "2025-12-15 19:24:54.227369", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.011934", "end": "2025-12-15 19:25:24.903976", "msg": "", "rc": 0, "start": "2025-12-15 19:25:24.892042", "stderr": "", "stderr_lines": [], "stdout": "32.1°C", "stdout_lines": ["32.1°C"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.013102", "end": "2025-12-15 19:25:24.923824", "msg": "", "rc": 0, "start": "2025-12-15 19:25:24.910722", "stderr": "", "stderr_lines": [], "stdout": "36.0°C", "stdout_lines": ["36.0°C"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003805", "end": "2025-12-15 19:25:25.329469", "msg": "", "rc": 0, "start": "2025-12-15 19:25:25.325664", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003040", "end": "2025-12-15 19:24:57.541684", "msg": "", "rc": 0, "start": "2025-12-15 19:24:57.538644", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003991", "end": "2025-12-15 16:25:25.524458", "msg": "", "rc": 0, "start": "2025-12-15 16:25:25.520467", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [dev.prod.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.002553", "end": "2025-12-15 19:25:03.543353", "msg": "", "rc": 0, "start": "2025-12-15 19:25:03.540800", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.028517", "end": "2025-12-15 19:25:25.594113", "msg": "", "rc": 0, "start": "2025-12-15 19:25:25.565596", "stderr": "", "stderr_lines": [], "stdout": "35.2°C", "stdout_lines": ["35.2°C"]}
ok: [jump.point.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.002990", "end": "2025-12-15 19:25:25.923174", "msg": "", "rc": 0, "start": "2025-12-15 19:25:25.920184", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [localhost] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.019301", "end": "2025-12-15 19:25:26.435952", "msg": "", "rc": 0, "start": "2025-12-15 19:25:26.416651", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
TASK [Get CPU load] ************************************************************
ok: [hp.nas.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004353", "end": "2025-12-15 19:25:26.894707", "msg": "", "rc": 0, "start": "2025-12-15 19:25:26.890354", "stderr": "", "stderr_lines": [], "stdout": "0.08", "stdout_lines": ["0.08"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.003943", "end": "2025-12-15 19:25:26.916775", "msg": "", "rc": 0, "start": "2025-12-15 19:25:26.912832", "stderr": "", "stderr_lines": [], "stdout": "0.38", "stdout_lines": ["0.38"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004536", "end": "2025-12-15 19:25:26.957452", "msg": "", "rc": 0, "start": "2025-12-15 19:25:26.952916", "stderr": "", "stderr_lines": [], "stdout": "0.63", "stdout_lines": ["0.63"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005436", "end": "2025-12-15 19:25:27.006471", "msg": "", "rc": 0, "start": "2025-12-15 19:25:27.001035", "stderr": "", "stderr_lines": [], "stdout": "0.49", "stdout_lines": ["0.49"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005362", "end": "2025-12-15 19:25:27.050091", "msg": "", "rc": 0, "start": "2025-12-15 19:25:27.044729", "stderr": "", "stderr_lines": [], "stdout": "0.20", "stdout_lines": ["0.20"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004392", "end": "2025-12-15 19:25:02.968390", "msg": "", "rc": 0, "start": "2025-12-15 19:25:02.963998", "stderr": "", "stderr_lines": [], "stdout": "0.03", "stdout_lines": ["0.03"]}
ok: [media.labb.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005017", "end": "2025-12-15 19:24:57.136624", "msg": "", "rc": 0, "start": "2025-12-15 19:24:57.131607", "stderr": "", "stderr_lines": [], "stdout": "0.11", "stdout_lines": ["0.11"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.010220", "end": "2025-12-15 19:25:27.781307", "msg": "", "rc": 0, "start": "2025-12-15 19:25:27.771087", "stderr": "", "stderr_lines": [], "stdout": "0.13", "stdout_lines": ["0.13"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.011222", "end": "2025-12-15 19:25:27.786665", "msg": "", "rc": 0, "start": "2025-12-15 19:25:27.775443", "stderr": "", "stderr_lines": [], "stdout": "0.32", "stdout_lines": ["0.32"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005650", "end": "2025-12-15 19:25:28.178840", "msg": "", "rc": 0, "start": "2025-12-15 19:25:28.173190", "stderr": "", "stderr_lines": [], "stdout": "0.00", "stdout_lines": ["0.00"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004986", "end": "2025-12-15 19:25:00.452661", "msg": "", "rc": 0, "start": "2025-12-15 19:25:00.447675", "stderr": "", "stderr_lines": [], "stdout": "0.54", "stdout_lines": ["0.54"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.006033", "end": "2025-12-15 16:25:28.392670", "msg": "", "rc": 0, "start": "2025-12-15 16:25:28.386637", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}
ok: [dev.prod.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004160", "end": "2025-12-15 19:25:06.432976", "msg": "", "rc": 0, "start": "2025-12-15 19:25:06.428816", "stderr": "", "stderr_lines": [], "stdout": "0.10", "stdout_lines": ["0.10"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.024901", "end": "2025-12-15 19:25:28.413461", "msg": "", "rc": 0, "start": "2025-12-15 19:25:28.388560", "stderr": "", "stderr_lines": [], "stdout": "0.27", "stdout_lines": ["0.27"]}
ok: [jump.point.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005264", "end": "2025-12-15 19:25:28.728724", "msg": "", "rc": 0, "start": "2025-12-15 19:25:28.723460", "stderr": "", "stderr_lines": [], "stdout": "0.14", "stdout_lines": ["0.14"]}
ok: [localhost] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.021142", "end": "2025-12-15 19:25:29.306935", "msg": "", "rc": 0, "start": "2025-12-15 19:25:29.285793", "stderr": "", "stderr_lines": [], "stdout": "1.65", "stdout_lines": ["1.65"]}
TASK [Display health status] ***************************************************
ok: [ali2v.xeon.home] => {
"msg": "═══════════════════════════════════════\nHost: ali2v.xeon.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:25:15 up 1 day, 8:57, 1 user, load average: 0.27, 0.39, 0.43\nDisk Usage: 22%\nMemory Usage: 21.8%\nCPU Load: 0.38\nCPU Temp: 45.0°C\n═══════════════════════════════════════\n"
}
ok: [hp.nas.home] => {
"msg": "═══════════════════════════════════════\nHost: hp.nas.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:25:15 up 20 days, 6:16, 1 user, load average: 0.11, 0.07, 0.07\nDisk Usage: 23%\nMemory Usage: 80.0%\nCPU Load: 0.08\nCPU Temp: 30.0°C\n═══════════════════════════════════════\n"
}
ok: [hp2.i7.home] => {
"msg": "═══════════════════════════════════════\nHost: hp2.i7.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:25:15 up 20 days, 6:36, 1 user, load average: 0.58, 0.64, 0.64\nDisk Usage: 14%\nMemory Usage: 49.2%\nCPU Load: 0.63\nCPU Temp: 0.0°C\n═══════════════════════════════════════\n"
}
ok: [hp3.i5.home] => {
"msg": "═══════════════════════════════════════\nHost: hp3.i5.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:25:15 up 20 days, 7:49, 1 user, load average: 0.48, 0.56, 0.67\nDisk Usage: 14%\nMemory Usage: 59.5%\nCPU Load: 0.49\nCPU Temp: 52.5°C\n═══════════════════════════════════════\n"
}
ok: [mimi.pc.home] => {
"msg": "═══════════════════════════════════════\nHost: mimi.pc.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:25:15 up 20 days, 8:35, 1 user, load average: 0.06, 0.09, 0.09\nDisk Usage: 9%\nMemory Usage: 9.0%\nCPU Load: 0.20\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [orangepi.pc.home] => {
"msg": "═══════════════════════════════════════\nHost: orangepi.pc.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:25:16 up 13 days, 8:51, 1 user, load average: 0.23, 0.14, 0.10\nDisk Usage: 21%\nMemory Usage: 20.1%\nCPU Load: 0.27\nCPU Temp: 35.2°C\n═══════════════════════════════════════\n"
}
ok: [raspi.4gb.home] => {
"msg": "═══════════════════════════════════════\nHost: raspi.4gb.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:25:16 up 192 days, 10:58, 1 user, load average: 0.42, 0.26, 0.20\nDisk Usage: 6%\nMemory Usage: 12.2%\nCPU Load: 0.32\nCPU Temp: 36.0°C\n═══════════════════════════════════════\n"
}
ok: [raspi.8gb.home] => {
"msg": "═══════════════════════════════════════\nHost: raspi.8gb.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:25:16 up 192 days, 10:58, 1 user, load average: 0.17, 0.13, 0.10\nDisk Usage: 3%\nMemory Usage: 6.7%\nCPU Load: 0.13\nCPU Temp: 32.1°C\n═══════════════════════════════════════\n"
}
ok: [dev.lab.home] => {
"msg": "═══════════════════════════════════════\nHost: dev.lab.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:24:51 up 9 days, 7:14, 0 user, load average: 0.04, 0.08, 0.13\nDisk Usage: 48%\nMemory Usage: 70.7%\nCPU Load: 0.03\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [media.labb.home] => {
"msg": "═══════════════════════════════════════\nHost: media.labb.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:24:46 up 16 days, 3:26, 0 user, load average: 0.03, 0.04, 0.00\nDisk Usage: 24%\nMemory Usage: 72.1%\nCPU Load: 0.11\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [ali2v.truenas.home] => {
"msg": "═══════════════════════════════════════\nHost: ali2v.truenas.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:25:16 up 1 day, 8:56, 1 user, load average: 0.01, 0.03, 0.00\nDisk Usage: 1%\nMemory Usage: 34.2%\nCPU Load: 0.00\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [automate.prod.home] => {
"msg": "═══════════════════════════════════════\nHost: automate.prod.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:24:48 up 18 days, 22:19, 0 user, load average: 0.29, 0.37, 0.42\nDisk Usage: 28%\nMemory Usage: 25.5%\nCPU Load: 0.54\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [dev.prod.home] => {
"msg": "═══════════════════════════════════════\nHost: dev.prod.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:24:54 up 15 days, 8:40, 0 user, load average: 0.12, 0.14, 0.16\nDisk Usage: 75%\nMemory Usage: 59.4%\nCPU Load: 0.10\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [hp.truenas.home] => {
"msg": "═══════════════════════════════════════\nHost: hp.truenas.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 4:25PM up 20 days, 6:15, 1 user, load averages: 0.26, 0.24, 0.24\nDisk Usage: 10%\nMemory Usage: \nCPU Load: \nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [jump.point.home] => {
"msg": "═══════════════════════════════════════\nHost: jump.point.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:25:17 up 1 day, 8:56, 1 user, load average: 0.16, 0.07, 0.02\nDisk Usage: 79%\nMemory Usage: 13.3%\nCPU Load: 0.14\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [localhost] => {
"msg": "═══════════════════════════════════════\nHost: localhost\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:25:17 up 6:00, 1 user, load average: 1.36, 1.23, 1.19\nDisk Usage: 1%\nMemory Usage: 12.4%\nCPU Load: 1.65\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
PLAY RECAP *********************************************************************
ali2v.truenas.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
ali2v.xeon.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
automate.prod.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
dev.lab.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
dev.prod.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
hp.nas.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
hp.truenas.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=1
hp2.i7.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
hp3.i5.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
jump.point.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
localhost : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
media.labb.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
mimi.pc.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
orangepi.pc.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
raspi.4gb.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
raspi.8gb.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
```
---
*Généré automatiquement par Homelab Automation Dashboard*
*Date: 2025-12-16T00:25:31.280813+00:00*

View File

@ -0,0 +1,224 @@
# ✅ [Planifié] Health-check-5min
## Informations
| Propriété | Valeur |
|-----------|--------|
| **ID** | `e04ac3936e0244f39537ed3c9c136872` |
| **Nom** | [Planifié] Health-check-5min |
| **Cible** | `all` |
| **Statut** | completed |
| **Type** | Planifié |
| **Progression** | 100% |
| **Début** | 2025-12-16T00:30:00.001906+00:00 |
| **Fin** | 2025-12-16T00:30:32.010698+00:00 |
| **Durée** | 32.0s |
## Sortie
```
Using /mnt/c/dev/git/python/homelab-automation-api-v2/ansible/ansible.cfg as config file
PLAY [Health check on target host] *********************************************
TASK [Check if host is reachable (ping)] ***************************************
ok: [hp.nas.home] => {"changed": false, "ping": "pong"}
ok: [mimi.pc.home] => {"changed": false, "ping": "pong"}
ok: [hp2.i7.home] => {"changed": false, "ping": "pong"}
ok: [ali2v.xeon.home] => {"changed": false, "ping": "pong"}
ok: [hp3.i5.home] => {"changed": false, "ping": "pong"}
ok: [dev.lab.home] => {"changed": false, "ping": "pong"}
ok: [media.labb.home] => {"changed": false, "ping": "pong"}
ok: [raspi.8gb.home] => {"changed": false, "ping": "pong"}
ok: [raspi.4gb.home] => {"changed": false, "ping": "pong"}
ok: [automate.prod.home] => {"changed": false, "ping": "pong"}
ok: [ali2v.truenas.home] => {"changed": false, "ping": "pong"}
ok: [hp.truenas.home] => {"changed": false, "ping": "pong"}
ok: [dev.prod.home] => {"changed": false, "ping": "pong"}
ok: [localhost] => {"changed": false, "ping": "pong"}
ok: [jump.point.home] => {"changed": false, "ping": "pong"}
ok: [orangepi.pc.home] => {"changed": false, "ping": "pong"}
TASK [Gather minimal facts] ****************************************************
ok: [hp.nas.home]
ok: [hp2.i7.home]
ok: [mimi.pc.home]
ok: [hp3.i5.home]
ok: [ali2v.xeon.home]
ok: [dev.lab.home]
ok: [media.labb.home]
ok: [raspi.8gb.home]
ok: [raspi.4gb.home]
ok: [ali2v.truenas.home]
ok: [automate.prod.home]
ok: [dev.prod.home]
ok: [hp.truenas.home]
ok: [jump.point.home]
ok: [orangepi.pc.home]
ok: [localhost]
TASK [Get system uptime] *******************************************************
ok: [hp.nas.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003082", "end": "2025-12-15 19:30:16.112659", "msg": "", "rc": 0, "start": "2025-12-15 19:30:16.109577", "stderr": "", "stderr_lines": [], "stdout": " 19:30:16 up 20 days, 6:21, 1 user, load average: 0.12, 0.09, 0.08", "stdout_lines": [" 19:30:16 up 20 days, 6:21, 1 user, load average: 0.12, 0.09, 0.08"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003693", "end": "2025-12-15 19:30:16.127758", "msg": "", "rc": 0, "start": "2025-12-15 19:30:16.124065", "stderr": "", "stderr_lines": [], "stdout": " 19:30:16 up 20 days, 8:40, 1 user, load average: 0.06, 0.09, 0.08", "stdout_lines": [" 19:30:16 up 20 days, 8:40, 1 user, load average: 0.06, 0.09, 0.08"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003360", "end": "2025-12-15 19:30:16.122126", "msg": "", "rc": 0, "start": "2025-12-15 19:30:16.118766", "stderr": "", "stderr_lines": [], "stdout": " 19:30:16 up 20 days, 6:41, 1 user, load average: 0.71, 0.67, 0.65", "stdout_lines": [" 19:30:16 up 20 days, 6:41, 1 user, load average: 0.71, 0.67, 0.65"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003888", "end": "2025-12-15 19:30:16.145330", "msg": "", "rc": 0, "start": "2025-12-15 19:30:16.141442", "stderr": "", "stderr_lines": [], "stdout": " 19:30:16 up 20 days, 7:54, 1 user, load average: 0.78, 0.64, 0.66", "stdout_lines": [" 19:30:16 up 20 days, 7:54, 1 user, load average: 0.78, 0.64, 0.66"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.002918", "end": "2025-12-15 19:30:16.153964", "msg": "", "rc": 0, "start": "2025-12-15 19:30:16.151046", "stderr": "", "stderr_lines": [], "stdout": " 19:30:16 up 1 day, 9:02, 1 user, load average: 0.35, 0.36, 0.40", "stdout_lines": [" 19:30:16 up 1 day, 9:02, 1 user, load average: 0.35, 0.36, 0.40"]}
ok: [dev.lab.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.002918", "end": "2025-12-15 19:29:52.257040", "msg": "", "rc": 0, "start": "2025-12-15 19:29:52.254122", "stderr": "", "stderr_lines": [], "stdout": " 19:29:52 up 9 days, 7:19, 0 user, load average: 0.05, 0.08, 0.10", "stdout_lines": [" 19:29:52 up 9 days, 7:19, 0 user, load average: 0.05, 0.08, 0.10"]}
ok: [media.labb.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003506", "end": "2025-12-15 19:29:46.419629", "msg": "", "rc": 0, "start": "2025-12-15 19:29:46.416123", "stderr": "", "stderr_lines": [], "stdout": " 19:29:46 up 16 days, 3:31, 0 user, load average: 0.10, 0.06, 0.01", "stdout_lines": [" 19:29:46 up 16 days, 3:31, 0 user, load average: 0.10, 0.06, 0.01"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.008644", "end": "2025-12-15 19:30:17.044297", "msg": "", "rc": 0, "start": "2025-12-15 19:30:17.035653", "stderr": "", "stderr_lines": [], "stdout": " 19:30:17 up 192 days, 11:03, 1 user, load average: 0.16, 0.12, 0.09", "stdout_lines": [" 19:30:17 up 192 days, 11:03, 1 user, load average: 0.16, 0.12, 0.09"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.009456", "end": "2025-12-15 19:30:17.045148", "msg": "", "rc": 0, "start": "2025-12-15 19:30:17.035692", "stderr": "", "stderr_lines": [], "stdout": " 19:30:17 up 192 days, 11:03, 1 user, load average: 0.49, 0.35, 0.25", "stdout_lines": [" 19:30:17 up 192 days, 11:03, 1 user, load average: 0.49, 0.35, 0.25"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.005065", "end": "2025-12-15 19:30:17.436283", "msg": "", "rc": 0, "start": "2025-12-15 19:30:17.431218", "stderr": "", "stderr_lines": [], "stdout": " 19:30:17 up 1 day, 9:01, 1 user, load average: 0.04, 0.04, 0.00", "stdout_lines": [" 19:30:17 up 1 day, 9:01, 1 user, load average: 0.04, 0.04, 0.00"]}
ok: [automate.prod.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003367", "end": "2025-12-15 19:29:49.735140", "msg": "", "rc": 0, "start": "2025-12-15 19:29:49.731773", "stderr": "", "stderr_lines": [], "stdout": " 19:29:49 up 18 days, 22:24, 0 user, load average: 0.45, 0.39, 0.41", "stdout_lines": [" 19:29:49 up 18 days, 22:24, 0 user, load average: 0.45, 0.39, 0.41"]}
ok: [dev.prod.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.002824", "end": "2025-12-15 19:29:55.672255", "msg": "", "rc": 0, "start": "2025-12-15 19:29:55.669431", "stderr": "", "stderr_lines": [], "stdout": " 19:29:55 up 15 days, 8:45, 0 user, load average: 0.06, 0.11, 0.14", "stdout_lines": [" 19:29:55 up 15 days, 8:45, 0 user, load average: 0.06, 0.11, 0.14"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.004352", "end": "2025-12-15 16:30:17.686878", "msg": "", "rc": 0, "start": "2025-12-15 16:30:17.682526", "stderr": "", "stderr_lines": [], "stdout": " 4:30PM up 20 days, 6:20, 1 user, load averages: 0.23, 0.22, 0.23", "stdout_lines": [" 4:30PM up 20 days, 6:20, 1 user, load averages: 0.23, 0.22, 0.23"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.019394", "end": "2025-12-15 19:30:17.770872", "msg": "", "rc": 0, "start": "2025-12-15 19:30:17.751478", "stderr": "", "stderr_lines": [], "stdout": " 19:30:17 up 13 days, 8:56, 1 user, load average: 0.29, 0.15, 0.10", "stdout_lines": [" 19:30:17 up 13 days, 8:56, 1 user, load average: 0.29, 0.15, 0.10"]}
ok: [jump.point.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003711", "end": "2025-12-15 19:30:18.023295", "msg": "", "rc": 0, "start": "2025-12-15 19:30:18.019584", "stderr": "", "stderr_lines": [], "stdout": " 19:30:18 up 1 day, 9:01, 1 user, load average: 0.05, 0.05, 0.00", "stdout_lines": [" 19:30:18 up 1 day, 9:01, 1 user, load average: 0.05, 0.05, 0.00"]}
ok: [localhost] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.018025", "end": "2025-12-15 19:30:18.631188", "msg": "", "rc": 0, "start": "2025-12-15 19:30:18.613163", "stderr": "", "stderr_lines": [], "stdout": " 19:30:18 up 6:05, 1 user, load average: 1.43, 1.26, 1.20", "stdout_lines": [" 19:30:18 up 6:05, 1 user, load average: 1.43, 1.26, 1.20"]}
TASK [Get disk usage] **********************************************************
ok: [hp.nas.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004405", "end": "2025-12-15 19:30:19.058154", "msg": "", "rc": 0, "start": "2025-12-15 19:30:19.053749", "stderr": "", "stderr_lines": [], "stdout": "23%", "stdout_lines": ["23%"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004066", "end": "2025-12-15 19:30:19.076871", "msg": "", "rc": 0, "start": "2025-12-15 19:30:19.072805", "stderr": "", "stderr_lines": [], "stdout": "22%", "stdout_lines": ["22%"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004843", "end": "2025-12-15 19:30:19.099158", "msg": "", "rc": 0, "start": "2025-12-15 19:30:19.094315", "stderr": "", "stderr_lines": [], "stdout": "14%", "stdout_lines": ["14%"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005653", "end": "2025-12-15 19:30:19.161457", "msg": "", "rc": 0, "start": "2025-12-15 19:30:19.155804", "stderr": "", "stderr_lines": [], "stdout": "14%", "stdout_lines": ["14%"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005007", "end": "2025-12-15 19:30:19.207594", "msg": "", "rc": 0, "start": "2025-12-15 19:30:19.202587", "stderr": "", "stderr_lines": [], "stdout": "9%", "stdout_lines": ["9%"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005091", "end": "2025-12-15 19:29:55.205690", "msg": "", "rc": 0, "start": "2025-12-15 19:29:55.200599", "stderr": "", "stderr_lines": [], "stdout": "48%", "stdout_lines": ["48%"]}
ok: [media.labb.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005636", "end": "2025-12-15 19:29:49.395562", "msg": "", "rc": 0, "start": "2025-12-15 19:29:49.389926", "stderr": "", "stderr_lines": [], "stdout": "24%", "stdout_lines": ["24%"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.011001", "end": "2025-12-15 19:30:20.078397", "msg": "", "rc": 0, "start": "2025-12-15 19:30:20.067396", "stderr": "", "stderr_lines": [], "stdout": "3%", "stdout_lines": ["3%"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.011819", "end": "2025-12-15 19:30:20.113204", "msg": "", "rc": 0, "start": "2025-12-15 19:30:20.101385", "stderr": "", "stderr_lines": [], "stdout": "6%", "stdout_lines": ["6%"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.006238", "end": "2025-12-15 19:30:20.458068", "msg": "", "rc": 0, "start": "2025-12-15 19:30:20.451830", "stderr": "", "stderr_lines": [], "stdout": "1%", "stdout_lines": ["1%"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005296", "end": "2025-12-15 19:29:52.738239", "msg": "", "rc": 0, "start": "2025-12-15 19:29:52.732943", "stderr": "", "stderr_lines": [], "stdout": "28%", "stdout_lines": ["28%"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005556", "end": "2025-12-15 16:30:20.721739", "msg": "", "rc": 0, "start": "2025-12-15 16:30:20.716183", "stderr": "", "stderr_lines": [], "stdout": "10%", "stdout_lines": ["10%"]}
ok: [dev.prod.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004737", "end": "2025-12-15 19:29:58.733288", "msg": "", "rc": 0, "start": "2025-12-15 19:29:58.728551", "stderr": "", "stderr_lines": [], "stdout": "75%", "stdout_lines": ["75%"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.025083", "end": "2025-12-15 19:30:20.638244", "msg": "", "rc": 0, "start": "2025-12-15 19:30:20.613161", "stderr": "", "stderr_lines": [], "stdout": "21%", "stdout_lines": ["21%"]}
ok: [jump.point.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005192", "end": "2025-12-15 19:30:21.033213", "msg": "", "rc": 0, "start": "2025-12-15 19:30:21.028021", "stderr": "", "stderr_lines": [], "stdout": "79%", "stdout_lines": ["79%"]}
ok: [localhost] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.015997", "end": "2025-12-15 19:30:21.544512", "msg": "", "rc": 0, "start": "2025-12-15 19:30:21.528515", "stderr": "", "stderr_lines": [], "stdout": "1%", "stdout_lines": ["1%"]}
TASK [Get memory usage (Linux)] ************************************************
ok: [hp.nas.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004385", "end": "2025-12-15 19:30:21.982469", "msg": "", "rc": 0, "start": "2025-12-15 19:30:21.978084", "stderr": "", "stderr_lines": [], "stdout": "80.1%", "stdout_lines": ["80.1%"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004159", "end": "2025-12-15 19:30:22.011952", "msg": "", "rc": 0, "start": "2025-12-15 19:30:22.007793", "stderr": "", "stderr_lines": [], "stdout": "21.8%", "stdout_lines": ["21.8%"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005641", "end": "2025-12-15 19:30:22.024009", "msg": "", "rc": 0, "start": "2025-12-15 19:30:22.018368", "stderr": "", "stderr_lines": [], "stdout": "49.3%", "stdout_lines": ["49.3%"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004993", "end": "2025-12-15 19:30:22.112791", "msg": "", "rc": 0, "start": "2025-12-15 19:30:22.107798", "stderr": "", "stderr_lines": [], "stdout": "8.9%", "stdout_lines": ["8.9%"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005719", "end": "2025-12-15 19:30:22.111045", "msg": "", "rc": 0, "start": "2025-12-15 19:30:22.105326", "stderr": "", "stderr_lines": [], "stdout": "59.5%", "stdout_lines": ["59.5%"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004093", "end": "2025-12-15 19:29:58.098304", "msg": "", "rc": 0, "start": "2025-12-15 19:29:58.094211", "stderr": "", "stderr_lines": [], "stdout": "70.8%", "stdout_lines": ["70.8%"]}
ok: [media.labb.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005405", "end": "2025-12-15 19:29:52.264843", "msg": "", "rc": 0, "start": "2025-12-15 19:29:52.259438", "stderr": "", "stderr_lines": [], "stdout": "72.1%", "stdout_lines": ["72.1%"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.011952", "end": "2025-12-15 19:30:22.860075", "msg": "", "rc": 0, "start": "2025-12-15 19:30:22.848123", "stderr": "", "stderr_lines": [], "stdout": "6.8%", "stdout_lines": ["6.8%"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.012066", "end": "2025-12-15 19:30:22.872972", "msg": "", "rc": 0, "start": "2025-12-15 19:30:22.860906", "stderr": "", "stderr_lines": [], "stdout": "12.3%", "stdout_lines": ["12.3%"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005818", "end": "2025-12-15 19:30:23.310636", "msg": "", "rc": 0, "start": "2025-12-15 19:30:23.304818", "stderr": "", "stderr_lines": [], "stdout": "34.0%", "stdout_lines": ["34.0%"]}
fatal: [hp.truenas.home]: FAILED! => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005399", "end": "2025-12-15 16:30:23.480239", "msg": "non-zero return code", "rc": 2, "start": "2025-12-15 16:30:23.474840", "stderr": "cat: /proc/meminfo: No such file or directory\nawk: division by zero\n source line number 1", "stderr_lines": ["cat: /proc/meminfo: No such file or directory", "awk: division by zero", " source line number 1"], "stdout": "", "stdout_lines": []}
...ignoring
ok: [dev.prod.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.003621", "end": "2025-12-15 19:30:01.498502", "msg": "", "rc": 0, "start": "2025-12-15 19:30:01.494881", "stderr": "", "stderr_lines": [], "stdout": "58.8%", "stdout_lines": ["58.8%"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.006487", "end": "2025-12-15 19:29:55.603132", "msg": "", "rc": 0, "start": "2025-12-15 19:29:55.596645", "stderr": "", "stderr_lines": [], "stdout": "25.4%", "stdout_lines": ["25.4%"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.025935", "end": "2025-12-15 19:30:23.492375", "msg": "", "rc": 0, "start": "2025-12-15 19:30:23.466440", "stderr": "", "stderr_lines": [], "stdout": "18.8%", "stdout_lines": ["18.8%"]}
ok: [jump.point.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005401", "end": "2025-12-15 19:30:23.875880", "msg": "", "rc": 0, "start": "2025-12-15 19:30:23.870479", "stderr": "", "stderr_lines": [], "stdout": "13.7%", "stdout_lines": ["13.7%"]}
ok: [localhost] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.018374", "end": "2025-12-15 19:30:24.366880", "msg": "", "rc": 0, "start": "2025-12-15 19:30:24.348506", "stderr": "", "stderr_lines": [], "stdout": "12.4%", "stdout_lines": ["12.4%"]}
TASK [Get CPU temperature (ARM/SBC)] *******************************************
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.004890", "end": "2025-12-15 19:30:24.786274", "msg": "", "rc": 0, "start": "2025-12-15 19:30:24.781384", "stderr": "", "stderr_lines": [], "stdout": "45.0°C", "stdout_lines": ["45.0°C"]}
ok: [hp.nas.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.005154", "end": "2025-12-15 19:30:24.799116", "msg": "", "rc": 0, "start": "2025-12-15 19:30:24.793962", "stderr": "", "stderr_lines": [], "stdout": "30.0°C", "stdout_lines": ["30.0°C"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.005612", "end": "2025-12-15 19:30:24.843292", "msg": "", "rc": 0, "start": "2025-12-15 19:30:24.837680", "stderr": "cat: /sys/class/thermal/thermal_zone0/temp: No data available", "stderr_lines": ["cat: /sys/class/thermal/thermal_zone0/temp: No data available"], "stdout": "0.0°C", "stdout_lines": ["0.0°C"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003214", "end": "2025-12-15 19:30:24.909735", "msg": "", "rc": 0, "start": "2025-12-15 19:30:24.906521", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.007227", "end": "2025-12-15 19:30:24.921368", "msg": "", "rc": 0, "start": "2025-12-15 19:30:24.914141", "stderr": "", "stderr_lines": [], "stdout": "52.5°C", "stdout_lines": ["52.5°C"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.002618", "end": "2025-12-15 19:30:00.946515", "msg": "", "rc": 0, "start": "2025-12-15 19:30:00.943897", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [media.labb.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003051", "end": "2025-12-15 19:29:55.085353", "msg": "", "rc": 0, "start": "2025-12-15 19:29:55.082302", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.013135", "end": "2025-12-15 19:30:25.727747", "msg": "", "rc": 0, "start": "2025-12-15 19:30:25.714612", "stderr": "", "stderr_lines": [], "stdout": "36.0°C", "stdout_lines": ["36.0°C"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.011866", "end": "2025-12-15 19:30:25.765731", "msg": "", "rc": 0, "start": "2025-12-15 19:30:25.753865", "stderr": "", "stderr_lines": [], "stdout": "32.1°C", "stdout_lines": ["32.1°C"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003175", "end": "2025-12-15 19:30:26.156372", "msg": "", "rc": 0, "start": "2025-12-15 19:30:26.153197", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.002647", "end": "2025-12-15 19:29:58.391544", "msg": "", "rc": 0, "start": "2025-12-15 19:29:58.388897", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [dev.prod.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.002447", "end": "2025-12-15 19:30:04.339744", "msg": "", "rc": 0, "start": "2025-12-15 19:30:04.337297", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.004016", "end": "2025-12-15 16:30:26.362766", "msg": "", "rc": 0, "start": "2025-12-15 16:30:26.358750", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.028471", "end": "2025-12-15 19:30:26.299709", "msg": "", "rc": 0, "start": "2025-12-15 19:30:26.271238", "stderr": "", "stderr_lines": [], "stdout": "35.8°C", "stdout_lines": ["35.8°C"]}
ok: [jump.point.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.002946", "end": "2025-12-15 19:30:26.688068", "msg": "", "rc": 0, "start": "2025-12-15 19:30:26.685122", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [localhost] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.005969", "end": "2025-12-15 19:30:27.197648", "msg": "", "rc": 0, "start": "2025-12-15 19:30:27.191679", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
TASK [Get CPU load] ************************************************************
ok: [hp.nas.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004319", "end": "2025-12-15 19:30:27.643950", "msg": "", "rc": 0, "start": "2025-12-15 19:30:27.639631", "stderr": "", "stderr_lines": [], "stdout": "0.31", "stdout_lines": ["0.31"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004099", "end": "2025-12-15 19:30:27.639855", "msg": "", "rc": 0, "start": "2025-12-15 19:30:27.635756", "stderr": "", "stderr_lines": [], "stdout": "0.38", "stdout_lines": ["0.38"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004575", "end": "2025-12-15 19:30:27.693217", "msg": "", "rc": 0, "start": "2025-12-15 19:30:27.688642", "stderr": "", "stderr_lines": [], "stdout": "0.83", "stdout_lines": ["0.83"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005034", "end": "2025-12-15 19:30:27.747690", "msg": "", "rc": 0, "start": "2025-12-15 19:30:27.742656", "stderr": "", "stderr_lines": [], "stdout": "0.05", "stdout_lines": ["0.05"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005134", "end": "2025-12-15 19:30:27.758730", "msg": "", "rc": 0, "start": "2025-12-15 19:30:27.753596", "stderr": "", "stderr_lines": [], "stdout": "0.82", "stdout_lines": ["0.82"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004749", "end": "2025-12-15 19:30:03.745136", "msg": "", "rc": 0, "start": "2025-12-15 19:30:03.740387", "stderr": "", "stderr_lines": [], "stdout": "0.12", "stdout_lines": ["0.12"]}
ok: [media.labb.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005051", "end": "2025-12-15 19:29:57.839483", "msg": "", "rc": 0, "start": "2025-12-15 19:29:57.834432", "stderr": "", "stderr_lines": [], "stdout": "0.16", "stdout_lines": ["0.16"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.010223", "end": "2025-12-15 19:30:28.461780", "msg": "", "rc": 0, "start": "2025-12-15 19:30:28.451557", "stderr": "", "stderr_lines": [], "stdout": "0.12", "stdout_lines": ["0.12"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.011230", "end": "2025-12-15 19:30:28.521957", "msg": "", "rc": 0, "start": "2025-12-15 19:30:28.510727", "stderr": "", "stderr_lines": [], "stdout": "0.41", "stdout_lines": ["0.41"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005483", "end": "2025-12-15 19:30:28.953169", "msg": "", "rc": 0, "start": "2025-12-15 19:30:28.947686", "stderr": "", "stderr_lines": [], "stdout": "0.03", "stdout_lines": ["0.03"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005030", "end": "2025-12-15 19:30:01.153033", "msg": "", "rc": 0, "start": "2025-12-15 19:30:01.148003", "stderr": "", "stderr_lines": [], "stdout": "0.46", "stdout_lines": ["0.46"]}
ok: [dev.prod.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004437", "end": "2025-12-15 19:30:07.088408", "msg": "", "rc": 0, "start": "2025-12-15 19:30:07.083971", "stderr": "", "stderr_lines": [], "stdout": "0.05", "stdout_lines": ["0.05"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.006346", "end": "2025-12-15 16:30:29.090788", "msg": "", "rc": 0, "start": "2025-12-15 16:30:29.084442", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.024561", "end": "2025-12-15 19:30:29.162265", "msg": "", "rc": 0, "start": "2025-12-15 19:30:29.137704", "stderr": "", "stderr_lines": [], "stdout": "0.25", "stdout_lines": ["0.25"]}
ok: [jump.point.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005259", "end": "2025-12-15 19:30:29.512094", "msg": "", "rc": 0, "start": "2025-12-15 19:30:29.506835", "stderr": "", "stderr_lines": [], "stdout": "0.04", "stdout_lines": ["0.04"]}
ok: [localhost] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.015760", "end": "2025-12-15 19:30:29.945775", "msg": "", "rc": 0, "start": "2025-12-15 19:30:29.930015", "stderr": "", "stderr_lines": [], "stdout": "1.51", "stdout_lines": ["1.51"]}
TASK [Display health status] ***************************************************
ok: [ali2v.xeon.home] => {
"msg": "═══════════════════════════════════════\nHost: ali2v.xeon.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:30:16 up 1 day, 9:02, 1 user, load average: 0.35, 0.36, 0.40\nDisk Usage: 22%\nMemory Usage: 21.8%\nCPU Load: 0.38\nCPU Temp: 45.0°C\n═══════════════════════════════════════\n"
}
ok: [hp.nas.home] => {
"msg": "═══════════════════════════════════════\nHost: hp.nas.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:30:16 up 20 days, 6:21, 1 user, load average: 0.12, 0.09, 0.08\nDisk Usage: 23%\nMemory Usage: 80.1%\nCPU Load: 0.31\nCPU Temp: 30.0°C\n═══════════════════════════════════════\n"
}
ok: [hp2.i7.home] => {
"msg": "═══════════════════════════════════════\nHost: hp2.i7.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:30:16 up 20 days, 6:41, 1 user, load average: 0.71, 0.67, 0.65\nDisk Usage: 14%\nMemory Usage: 49.3%\nCPU Load: 0.83\nCPU Temp: 0.0°C\n═══════════════════════════════════════\n"
}
ok: [hp3.i5.home] => {
"msg": "═══════════════════════════════════════\nHost: hp3.i5.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:30:16 up 20 days, 7:54, 1 user, load average: 0.78, 0.64, 0.66\nDisk Usage: 14%\nMemory Usage: 59.5%\nCPU Load: 0.82\nCPU Temp: 52.5°C\n═══════════════════════════════════════\n"
}
ok: [mimi.pc.home] => {
"msg": "═══════════════════════════════════════\nHost: mimi.pc.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:30:16 up 20 days, 8:40, 1 user, load average: 0.06, 0.09, 0.08\nDisk Usage: 9%\nMemory Usage: 8.9%\nCPU Load: 0.05\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [orangepi.pc.home] => {
"msg": "═══════════════════════════════════════\nHost: orangepi.pc.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:30:17 up 13 days, 8:56, 1 user, load average: 0.29, 0.15, 0.10\nDisk Usage: 21%\nMemory Usage: 18.8%\nCPU Load: 0.25\nCPU Temp: 35.8°C\n═══════════════════════════════════════\n"
}
ok: [raspi.4gb.home] => {
"msg": "═══════════════════════════════════════\nHost: raspi.4gb.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:30:17 up 192 days, 11:03, 1 user, load average: 0.49, 0.35, 0.25\nDisk Usage: 6%\nMemory Usage: 12.3%\nCPU Load: 0.41\nCPU Temp: 36.0°C\n═══════════════════════════════════════\n"
}
ok: [raspi.8gb.home] => {
"msg": "═══════════════════════════════════════\nHost: raspi.8gb.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:30:17 up 192 days, 11:03, 1 user, load average: 0.16, 0.12, 0.09\nDisk Usage: 3%\nMemory Usage: 6.8%\nCPU Load: 0.12\nCPU Temp: 32.1°C\n═══════════════════════════════════════\n"
}
ok: [dev.lab.home] => {
"msg": "═══════════════════════════════════════\nHost: dev.lab.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:29:52 up 9 days, 7:19, 0 user, load average: 0.05, 0.08, 0.10\nDisk Usage: 48%\nMemory Usage: 70.8%\nCPU Load: 0.12\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [media.labb.home] => {
"msg": "═══════════════════════════════════════\nHost: media.labb.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:29:46 up 16 days, 3:31, 0 user, load average: 0.10, 0.06, 0.01\nDisk Usage: 24%\nMemory Usage: 72.1%\nCPU Load: 0.16\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [ali2v.truenas.home] => {
"msg": "═══════════════════════════════════════\nHost: ali2v.truenas.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:30:17 up 1 day, 9:01, 1 user, load average: 0.04, 0.04, 0.00\nDisk Usage: 1%\nMemory Usage: 34.0%\nCPU Load: 0.03\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [automate.prod.home] => {
"msg": "═══════════════════════════════════════\nHost: automate.prod.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:29:49 up 18 days, 22:24, 0 user, load average: 0.45, 0.39, 0.41\nDisk Usage: 28%\nMemory Usage: 25.4%\nCPU Load: 0.46\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [dev.prod.home] => {
"msg": "═══════════════════════════════════════\nHost: dev.prod.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:29:55 up 15 days, 8:45, 0 user, load average: 0.06, 0.11, 0.14\nDisk Usage: 75%\nMemory Usage: 58.8%\nCPU Load: 0.05\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [hp.truenas.home] => {
"msg": "═══════════════════════════════════════\nHost: hp.truenas.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 4:30PM up 20 days, 6:20, 1 user, load averages: 0.23, 0.22, 0.23\nDisk Usage: 10%\nMemory Usage: \nCPU Load: \nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [jump.point.home] => {
"msg": "═══════════════════════════════════════\nHost: jump.point.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:30:18 up 1 day, 9:01, 1 user, load average: 0.05, 0.05, 0.00\nDisk Usage: 79%\nMemory Usage: 13.7%\nCPU Load: 0.04\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [localhost] => {
"msg": "═══════════════════════════════════════\nHost: localhost\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:30:18 up 6:05, 1 user, load average: 1.43, 1.26, 1.20\nDisk Usage: 1%\nMemory Usage: 12.4%\nCPU Load: 1.51\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
PLAY RECAP *********************************************************************
ali2v.truenas.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
ali2v.xeon.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
automate.prod.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
dev.lab.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
dev.prod.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
hp.nas.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
hp.truenas.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=1
hp2.i7.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
hp3.i5.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
jump.point.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
localhost : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
media.labb.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
mimi.pc.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
orangepi.pc.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
raspi.4gb.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
raspi.8gb.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
```
---
*Généré automatiquement par Homelab Automation Dashboard*
*Date: 2025-12-16T00:30:32.091037+00:00*

View File

@ -0,0 +1,224 @@
# ✅ [Planifié] Health-check-5min
## Informations
| Propriété | Valeur |
|-----------|--------|
| **ID** | `b38046d03c47466ca2e08ffafd2da046` |
| **Nom** | [Planifié] Health-check-5min |
| **Cible** | `all` |
| **Statut** | completed |
| **Type** | Planifié |
| **Progression** | 100% |
| **Début** | 2025-12-16T00:35:00.001694+00:00 |
| **Fin** | 2025-12-16T00:35:31.454701+00:00 |
| **Durée** | 31.5s |
## Sortie
```
Using /mnt/c/dev/git/python/homelab-automation-api-v2/ansible/ansible.cfg as config file
PLAY [Health check on target host] *********************************************
TASK [Check if host is reachable (ping)] ***************************************
ok: [hp.nas.home] => {"changed": false, "ping": "pong"}
ok: [hp2.i7.home] => {"changed": false, "ping": "pong"}
ok: [mimi.pc.home] => {"changed": false, "ping": "pong"}
ok: [hp3.i5.home] => {"changed": false, "ping": "pong"}
ok: [ali2v.xeon.home] => {"changed": false, "ping": "pong"}
ok: [dev.lab.home] => {"changed": false, "ping": "pong"}
ok: [media.labb.home] => {"changed": false, "ping": "pong"}
ok: [raspi.8gb.home] => {"changed": false, "ping": "pong"}
ok: [raspi.4gb.home] => {"changed": false, "ping": "pong"}
ok: [automate.prod.home] => {"changed": false, "ping": "pong"}
ok: [ali2v.truenas.home] => {"changed": false, "ping": "pong"}
ok: [hp.truenas.home] => {"changed": false, "ping": "pong"}
ok: [dev.prod.home] => {"changed": false, "ping": "pong"}
ok: [localhost] => {"changed": false, "ping": "pong"}
ok: [jump.point.home] => {"changed": false, "ping": "pong"}
ok: [orangepi.pc.home] => {"changed": false, "ping": "pong"}
TASK [Gather minimal facts] ****************************************************
ok: [hp.nas.home]
ok: [hp2.i7.home]
ok: [mimi.pc.home]
ok: [hp3.i5.home]
ok: [ali2v.xeon.home]
ok: [dev.lab.home]
ok: [media.labb.home]
ok: [raspi.8gb.home]
ok: [raspi.4gb.home]
ok: [ali2v.truenas.home]
ok: [automate.prod.home]
ok: [dev.prod.home]
ok: [hp.truenas.home]
ok: [jump.point.home]
ok: [orangepi.pc.home]
ok: [localhost]
TASK [Get system uptime] *******************************************************
ok: [hp.nas.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003204", "end": "2025-12-15 19:35:15.665266", "msg": "", "rc": 0, "start": "2025-12-15 19:35:15.662062", "stderr": "", "stderr_lines": [], "stdout": " 19:35:15 up 20 days, 6:26, 1 user, load average: 0.10, 0.10, 0.09", "stdout_lines": [" 19:35:15 up 20 days, 6:26, 1 user, load average: 0.10, 0.10, 0.09"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003036", "end": "2025-12-15 19:35:15.684696", "msg": "", "rc": 0, "start": "2025-12-15 19:35:15.681660", "stderr": "", "stderr_lines": [], "stdout": " 19:35:15 up 20 days, 8:45, 1 user, load average: 0.12, 0.08, 0.08", "stdout_lines": [" 19:35:15 up 20 days, 8:45, 1 user, load average: 0.12, 0.08, 0.08"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.002807", "end": "2025-12-15 19:35:15.701191", "msg": "", "rc": 0, "start": "2025-12-15 19:35:15.698384", "stderr": "", "stderr_lines": [], "stdout": " 19:35:15 up 1 day, 9:07, 1 user, load average: 0.55, 0.38, 0.39", "stdout_lines": [" 19:35:15 up 1 day, 9:07, 1 user, load average: 0.55, 0.38, 0.39"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.004029", "end": "2025-12-15 19:35:15.696809", "msg": "", "rc": 0, "start": "2025-12-15 19:35:15.692780", "stderr": "", "stderr_lines": [], "stdout": " 19:35:15 up 20 days, 7:59, 1 user, load average: 0.80, 0.57, 0.62", "stdout_lines": [" 19:35:15 up 20 days, 7:59, 1 user, load average: 0.80, 0.57, 0.62"]}
ok: [dev.lab.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.002795", "end": "2025-12-15 19:34:51.721574", "msg": "", "rc": 0, "start": "2025-12-15 19:34:51.718779", "stderr": "", "stderr_lines": [], "stdout": " 19:34:51 up 9 days, 7:24, 0 user, load average: 0.06, 0.09, 0.09", "stdout_lines": [" 19:34:51 up 9 days, 7:24, 0 user, load average: 0.06, 0.09, 0.09"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.008471", "end": "2025-12-15 19:35:16.496288", "msg": "", "rc": 0, "start": "2025-12-15 19:35:16.487817", "stderr": "", "stderr_lines": [], "stdout": " 19:35:16 up 192 days, 11:08, 1 user, load average: 0.19, 0.12, 0.10", "stdout_lines": [" 19:35:16 up 192 days, 11:08, 1 user, load average: 0.19, 0.12, 0.10"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.009481", "end": "2025-12-15 19:35:16.531953", "msg": "", "rc": 0, "start": "2025-12-15 19:35:16.522472", "stderr": "", "stderr_lines": [], "stdout": " 19:35:16 up 192 days, 11:08, 1 user, load average: 0.93, 0.47, 0.30", "stdout_lines": [" 19:35:16 up 192 days, 11:08, 1 user, load average: 0.93, 0.47, 0.30"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:01.003748", "end": "2025-12-15 19:35:16.684490", "msg": "", "rc": 0, "start": "2025-12-15 19:35:15.680742", "stderr": "", "stderr_lines": [], "stdout": " 19:35:15 up 20 days, 6:46, 1 user, load average: 0.96, 0.73, 0.66", "stdout_lines": [" 19:35:15 up 20 days, 6:46, 1 user, load average: 0.96, 0.73, 0.66"]}
ok: [media.labb.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003366", "end": "2025-12-15 19:34:46.427625", "msg": "", "rc": 0, "start": "2025-12-15 19:34:46.424259", "stderr": "", "stderr_lines": [], "stdout": " 19:34:46 up 16 days, 3:36, 0 user, load average: 0.01, 0.03, 0.00", "stdout_lines": [" 19:34:46 up 16 days, 3:36, 0 user, load average: 0.01, 0.03, 0.00"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.004803", "end": "2025-12-15 19:35:17.165466", "msg": "", "rc": 0, "start": "2025-12-15 19:35:17.160663", "stderr": "", "stderr_lines": [], "stdout": " 19:35:17 up 1 day, 9:06, 1 user, load average: 0.02, 0.04, 0.00", "stdout_lines": [" 19:35:17 up 1 day, 9:06, 1 user, load average: 0.02, 0.04, 0.00"]}
ok: [dev.prod.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.002632", "end": "2025-12-15 19:34:55.275511", "msg": "", "rc": 0, "start": "2025-12-15 19:34:55.272879", "stderr": "", "stderr_lines": [], "stdout": " 19:34:55 up 15 days, 8:50, 0 user, load average: 0.25, 0.14, 0.13", "stdout_lines": [" 19:34:55 up 15 days, 8:50, 0 user, load average: 0.25, 0.14, 0.13"]}
ok: [automate.prod.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003309", "end": "2025-12-15 19:34:49.337921", "msg": "", "rc": 0, "start": "2025-12-15 19:34:49.334612", "stderr": "", "stderr_lines": [], "stdout": " 19:34:49 up 18 days, 22:29, 0 user, load average: 0.35, 0.40, 0.42", "stdout_lines": [" 19:34:49 up 18 days, 22:29, 0 user, load average: 0.35, 0.40, 0.42"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.019307", "end": "2025-12-15 19:35:17.160546", "msg": "", "rc": 0, "start": "2025-12-15 19:35:17.141239", "stderr": "", "stderr_lines": [], "stdout": " 19:35:17 up 13 days, 9:01, 1 user, load average: 0.31, 0.16, 0.11", "stdout_lines": [" 19:35:17 up 13 days, 9:01, 1 user, load average: 0.31, 0.16, 0.11"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.004316", "end": "2025-12-15 16:35:17.529581", "msg": "", "rc": 0, "start": "2025-12-15 16:35:17.525265", "stderr": "", "stderr_lines": [], "stdout": " 4:35PM up 20 days, 6:25, 1 user, load averages: 0.23, 0.28, 0.25", "stdout_lines": [" 4:35PM up 20 days, 6:25, 1 user, load averages: 0.23, 0.28, 0.25"]}
ok: [jump.point.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003939", "end": "2025-12-15 19:35:17.742075", "msg": "", "rc": 0, "start": "2025-12-15 19:35:17.738136", "stderr": "", "stderr_lines": [], "stdout": " 19:35:17 up 1 day, 9:06, 1 user, load average: 0.00, 0.01, 0.00", "stdout_lines": [" 19:35:17 up 1 day, 9:06, 1 user, load average: 0.00, 0.01, 0.00"]}
ok: [localhost] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.009898", "end": "2025-12-15 19:35:18.188557", "msg": "", "rc": 0, "start": "2025-12-15 19:35:18.178659", "stderr": "", "stderr_lines": [], "stdout": " 19:35:18 up 6:10, 1 user, load average: 1.47, 1.31, 1.23", "stdout_lines": [" 19:35:18 up 6:10, 1 user, load average: 1.47, 1.31, 1.23"]}
TASK [Get disk usage] **********************************************************
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004159", "end": "2025-12-15 19:35:18.598230", "msg": "", "rc": 0, "start": "2025-12-15 19:35:18.594071", "stderr": "", "stderr_lines": [], "stdout": "22%", "stdout_lines": ["22%"]}
ok: [hp.nas.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004645", "end": "2025-12-15 19:35:18.603492", "msg": "", "rc": 0, "start": "2025-12-15 19:35:18.598847", "stderr": "", "stderr_lines": [], "stdout": "23%", "stdout_lines": ["23%"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004998", "end": "2025-12-15 19:35:18.645291", "msg": "", "rc": 0, "start": "2025-12-15 19:35:18.640293", "stderr": "", "stderr_lines": [], "stdout": "14%", "stdout_lines": ["14%"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005339", "end": "2025-12-15 19:35:18.680017", "msg": "", "rc": 0, "start": "2025-12-15 19:35:18.674678", "stderr": "", "stderr_lines": [], "stdout": "14%", "stdout_lines": ["14%"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005050", "end": "2025-12-15 19:35:18.690322", "msg": "", "rc": 0, "start": "2025-12-15 19:35:18.685272", "stderr": "", "stderr_lines": [], "stdout": "9%", "stdout_lines": ["9%"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005083", "end": "2025-12-15 19:34:54.696954", "msg": "", "rc": 0, "start": "2025-12-15 19:34:54.691871", "stderr": "", "stderr_lines": [], "stdout": "48%", "stdout_lines": ["48%"]}
ok: [media.labb.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005397", "end": "2025-12-15 19:34:48.826249", "msg": "", "rc": 0, "start": "2025-12-15 19:34:48.820852", "stderr": "", "stderr_lines": [], "stdout": "24%", "stdout_lines": ["24%"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.010752", "end": "2025-12-15 19:35:19.558354", "msg": "", "rc": 0, "start": "2025-12-15 19:35:19.547602", "stderr": "", "stderr_lines": [], "stdout": "3%", "stdout_lines": ["3%"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.011559", "end": "2025-12-15 19:35:19.591868", "msg": "", "rc": 0, "start": "2025-12-15 19:35:19.580309", "stderr": "", "stderr_lines": [], "stdout": "6%", "stdout_lines": ["6%"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005756", "end": "2025-12-15 19:35:19.921404", "msg": "", "rc": 0, "start": "2025-12-15 19:35:19.915648", "stderr": "", "stderr_lines": [], "stdout": "1%", "stdout_lines": ["1%"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005347", "end": "2025-12-15 19:34:52.139484", "msg": "", "rc": 0, "start": "2025-12-15 19:34:52.134137", "stderr": "", "stderr_lines": [], "stdout": "28%", "stdout_lines": ["28%"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005460", "end": "2025-12-15 16:35:20.156639", "msg": "", "rc": 0, "start": "2025-12-15 16:35:20.151179", "stderr": "", "stderr_lines": [], "stdout": "10%", "stdout_lines": ["10%"]}
ok: [dev.prod.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005016", "end": "2025-12-15 19:34:58.155951", "msg": "", "rc": 0, "start": "2025-12-15 19:34:58.150935", "stderr": "", "stderr_lines": [], "stdout": "75%", "stdout_lines": ["75%"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.025268", "end": "2025-12-15 19:35:20.105645", "msg": "", "rc": 0, "start": "2025-12-15 19:35:20.080377", "stderr": "", "stderr_lines": [], "stdout": "21%", "stdout_lines": ["21%"]}
ok: [jump.point.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005437", "end": "2025-12-15 19:35:20.487641", "msg": "", "rc": 0, "start": "2025-12-15 19:35:20.482204", "stderr": "", "stderr_lines": [], "stdout": "79%", "stdout_lines": ["79%"]}
ok: [localhost] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.017219", "end": "2025-12-15 19:35:20.958021", "msg": "", "rc": 0, "start": "2025-12-15 19:35:20.940802", "stderr": "", "stderr_lines": [], "stdout": "1%", "stdout_lines": ["1%"]}
TASK [Get memory usage (Linux)] ************************************************
ok: [hp.nas.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004741", "end": "2025-12-15 19:35:21.423659", "msg": "", "rc": 0, "start": "2025-12-15 19:35:21.418918", "stderr": "", "stderr_lines": [], "stdout": "80.2%", "stdout_lines": ["80.2%"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004226", "end": "2025-12-15 19:35:21.436404", "msg": "", "rc": 0, "start": "2025-12-15 19:35:21.432178", "stderr": "", "stderr_lines": [], "stdout": "21.8%", "stdout_lines": ["21.8%"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005327", "end": "2025-12-15 19:35:21.494928", "msg": "", "rc": 0, "start": "2025-12-15 19:35:21.489601", "stderr": "", "stderr_lines": [], "stdout": "59.4%", "stdout_lines": ["59.4%"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004897", "end": "2025-12-15 19:35:21.508165", "msg": "", "rc": 0, "start": "2025-12-15 19:35:21.503268", "stderr": "", "stderr_lines": [], "stdout": "9.0%", "stdout_lines": ["9.0%"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004956", "end": "2025-12-15 19:35:21.505079", "msg": "", "rc": 0, "start": "2025-12-15 19:35:21.500123", "stderr": "", "stderr_lines": [], "stdout": "49.3%", "stdout_lines": ["49.3%"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004731", "end": "2025-12-15 19:34:57.637775", "msg": "", "rc": 0, "start": "2025-12-15 19:34:57.633044", "stderr": "", "stderr_lines": [], "stdout": "71.0%", "stdout_lines": ["71.0%"]}
ok: [media.labb.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004778", "end": "2025-12-15 19:34:51.696790", "msg": "", "rc": 0, "start": "2025-12-15 19:34:51.692012", "stderr": "", "stderr_lines": [], "stdout": "72.1%", "stdout_lines": ["72.1%"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.011014", "end": "2025-12-15 19:35:22.316512", "msg": "", "rc": 0, "start": "2025-12-15 19:35:22.305498", "stderr": "", "stderr_lines": [], "stdout": "6.8%", "stdout_lines": ["6.8%"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.012299", "end": "2025-12-15 19:35:22.335106", "msg": "", "rc": 0, "start": "2025-12-15 19:35:22.322807", "stderr": "", "stderr_lines": [], "stdout": "12.5%", "stdout_lines": ["12.5%"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.006038", "end": "2025-12-15 19:35:22.857201", "msg": "", "rc": 0, "start": "2025-12-15 19:35:22.851163", "stderr": "", "stderr_lines": [], "stdout": "34.1%", "stdout_lines": ["34.1%"]}
fatal: [hp.truenas.home]: FAILED! => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005661", "end": "2025-12-15 16:35:22.943586", "msg": "non-zero return code", "rc": 2, "start": "2025-12-15 16:35:22.937925", "stderr": "cat: /proc/meminfo: No such file or directory\nawk: division by zero\n source line number 1", "stderr_lines": ["cat: /proc/meminfo: No such file or directory", "awk: division by zero", " source line number 1"], "stdout": "", "stdout_lines": []}
...ignoring
ok: [automate.prod.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.003992", "end": "2025-12-15 19:34:55.079106", "msg": "", "rc": 0, "start": "2025-12-15 19:34:55.075114", "stderr": "", "stderr_lines": [], "stdout": "24.6%", "stdout_lines": ["24.6%"]}
ok: [dev.prod.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005180", "end": "2025-12-15 19:35:01.034189", "msg": "", "rc": 0, "start": "2025-12-15 19:35:01.029009", "stderr": "", "stderr_lines": [], "stdout": "60.0%", "stdout_lines": ["60.0%"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.025552", "end": "2025-12-15 19:35:22.996809", "msg": "", "rc": 0, "start": "2025-12-15 19:35:22.971257", "stderr": "", "stderr_lines": [], "stdout": "19.4%", "stdout_lines": ["19.4%"]}
ok: [jump.point.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005425", "end": "2025-12-15 19:35:23.447519", "msg": "", "rc": 0, "start": "2025-12-15 19:35:23.442094", "stderr": "", "stderr_lines": [], "stdout": "13.4%", "stdout_lines": ["13.4%"]}
ok: [localhost] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.009557", "end": "2025-12-15 19:35:23.830751", "msg": "", "rc": 0, "start": "2025-12-15 19:35:23.821194", "stderr": "", "stderr_lines": [], "stdout": "12.4%", "stdout_lines": ["12.4%"]}
TASK [Get CPU temperature (ARM/SBC)] *******************************************
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.004803", "end": "2025-12-15 19:35:24.269454", "msg": "", "rc": 0, "start": "2025-12-15 19:35:24.264651", "stderr": "", "stderr_lines": [], "stdout": "46.0°C", "stdout_lines": ["46.0°C"]}
ok: [hp.nas.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.005403", "end": "2025-12-15 19:35:24.289950", "msg": "", "rc": 0, "start": "2025-12-15 19:35:24.284547", "stderr": "", "stderr_lines": [], "stdout": "30.0°C", "stdout_lines": ["30.0°C"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.005497", "end": "2025-12-15 19:35:24.317835", "msg": "", "rc": 0, "start": "2025-12-15 19:35:24.312338", "stderr": "cat: /sys/class/thermal/thermal_zone0/temp: No data available", "stderr_lines": ["cat: /sys/class/thermal/thermal_zone0/temp: No data available"], "stdout": "0.0°C", "stdout_lines": ["0.0°C"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.006658", "end": "2025-12-15 19:35:24.351695", "msg": "", "rc": 0, "start": "2025-12-15 19:35:24.345037", "stderr": "", "stderr_lines": [], "stdout": "52.5°C", "stdout_lines": ["52.5°C"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003092", "end": "2025-12-15 19:35:24.366102", "msg": "", "rc": 0, "start": "2025-12-15 19:35:24.363010", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.002676", "end": "2025-12-15 19:35:00.310726", "msg": "", "rc": 0, "start": "2025-12-15 19:35:00.308050", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [media.labb.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003567", "end": "2025-12-15 19:34:54.485010", "msg": "", "rc": 0, "start": "2025-12-15 19:34:54.481443", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.011931", "end": "2025-12-15 19:35:25.187967", "msg": "", "rc": 0, "start": "2025-12-15 19:35:25.176036", "stderr": "", "stderr_lines": [], "stdout": "31.6°C", "stdout_lines": ["31.6°C"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.013477", "end": "2025-12-15 19:35:25.216339", "msg": "", "rc": 0, "start": "2025-12-15 19:35:25.202862", "stderr": "", "stderr_lines": [], "stdout": "35.0°C", "stdout_lines": ["35.0°C"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003143", "end": "2025-12-15 19:35:25.504910", "msg": "", "rc": 0, "start": "2025-12-15 19:35:25.501767", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.004400", "end": "2025-12-15 19:34:57.797898", "msg": "", "rc": 0, "start": "2025-12-15 19:34:57.793498", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.004095", "end": "2025-12-15 16:35:25.796246", "msg": "", "rc": 0, "start": "2025-12-15 16:35:25.792151", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [dev.prod.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.002713", "end": "2025-12-15 19:35:03.803788", "msg": "", "rc": 0, "start": "2025-12-15 19:35:03.801075", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.028860", "end": "2025-12-15 19:35:25.861290", "msg": "", "rc": 0, "start": "2025-12-15 19:35:25.832430", "stderr": "", "stderr_lines": [], "stdout": "35.4°C", "stdout_lines": ["35.4°C"]}
ok: [jump.point.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.002945", "end": "2025-12-15 19:35:26.030488", "msg": "", "rc": 0, "start": "2025-12-15 19:35:26.027543", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [localhost] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.005449", "end": "2025-12-15 19:35:26.669396", "msg": "", "rc": 0, "start": "2025-12-15 19:35:26.663947", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
TASK [Get CPU load] ************************************************************
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004181", "end": "2025-12-15 19:35:27.102040", "msg": "", "rc": 0, "start": "2025-12-15 19:35:27.097859", "stderr": "", "stderr_lines": [], "stdout": "0.54", "stdout_lines": ["0.54"]}
ok: [hp.nas.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004473", "end": "2025-12-15 19:35:27.107538", "msg": "", "rc": 0, "start": "2025-12-15 19:35:27.103065", "stderr": "", "stderr_lines": [], "stdout": "0.46", "stdout_lines": ["0.46"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005175", "end": "2025-12-15 19:35:27.164273", "msg": "", "rc": 0, "start": "2025-12-15 19:35:27.159098", "stderr": "", "stderr_lines": [], "stdout": "0.81", "stdout_lines": ["0.81"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005397", "end": "2025-12-15 19:35:27.221771", "msg": "", "rc": 0, "start": "2025-12-15 19:35:27.216374", "stderr": "", "stderr_lines": [], "stdout": "0.10", "stdout_lines": ["0.10"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005676", "end": "2025-12-15 19:35:27.226747", "msg": "", "rc": 0, "start": "2025-12-15 19:35:27.221071", "stderr": "", "stderr_lines": [], "stdout": "1.08", "stdout_lines": ["1.08"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004222", "end": "2025-12-15 19:35:03.261824", "msg": "", "rc": 0, "start": "2025-12-15 19:35:03.257602", "stderr": "", "stderr_lines": [], "stdout": "0.21", "stdout_lines": ["0.21"]}
ok: [media.labb.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005300", "end": "2025-12-15 19:34:57.383958", "msg": "", "rc": 0, "start": "2025-12-15 19:34:57.378658", "stderr": "", "stderr_lines": [], "stdout": "0.09", "stdout_lines": ["0.09"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.010159", "end": "2025-12-15 19:35:28.003073", "msg": "", "rc": 0, "start": "2025-12-15 19:35:27.992914", "stderr": "", "stderr_lines": [], "stdout": "0.15", "stdout_lines": ["0.15"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.011203", "end": "2025-12-15 19:35:28.020881", "msg": "", "rc": 0, "start": "2025-12-15 19:35:28.009678", "stderr": "", "stderr_lines": [], "stdout": "0.80", "stdout_lines": ["0.80"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005878", "end": "2025-12-15 19:35:28.480873", "msg": "", "rc": 0, "start": "2025-12-15 19:35:28.474995", "stderr": "", "stderr_lines": [], "stdout": "0.02", "stdout_lines": ["0.02"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005947", "end": "2025-12-15 16:35:28.606483", "msg": "", "rc": 0, "start": "2025-12-15 16:35:28.600536", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}
ok: [automate.prod.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005030", "end": "2025-12-15 19:35:00.662945", "msg": "", "rc": 0, "start": "2025-12-15 19:35:00.657915", "stderr": "", "stderr_lines": [], "stdout": "0.45", "stdout_lines": ["0.45"]}
ok: [dev.prod.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004108", "end": "2025-12-15 19:35:06.620071", "msg": "", "rc": 0, "start": "2025-12-15 19:35:06.615963", "stderr": "", "stderr_lines": [], "stdout": "0.21", "stdout_lines": ["0.21"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.023925", "end": "2025-12-15 19:35:28.680467", "msg": "", "rc": 0, "start": "2025-12-15 19:35:28.656542", "stderr": "", "stderr_lines": [], "stdout": "0.34", "stdout_lines": ["0.34"]}
ok: [jump.point.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005295", "end": "2025-12-15 19:35:29.050591", "msg": "", "rc": 0, "start": "2025-12-15 19:35:29.045296", "stderr": "", "stderr_lines": [], "stdout": "0.00", "stdout_lines": ["0.00"]}
ok: [localhost] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.021673", "end": "2025-12-15 19:35:29.546348", "msg": "", "rc": 0, "start": "2025-12-15 19:35:29.524675", "stderr": "", "stderr_lines": [], "stdout": "2.10", "stdout_lines": ["2.10"]}
TASK [Display health status] ***************************************************
ok: [ali2v.xeon.home] => {
"msg": "═══════════════════════════════════════\nHost: ali2v.xeon.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:35:15 up 1 day, 9:07, 1 user, load average: 0.55, 0.38, 0.39\nDisk Usage: 22%\nMemory Usage: 21.8%\nCPU Load: 0.54\nCPU Temp: 46.0°C\n═══════════════════════════════════════\n"
}
ok: [hp.nas.home] => {
"msg": "═══════════════════════════════════════\nHost: hp.nas.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:35:15 up 20 days, 6:26, 1 user, load average: 0.10, 0.10, 0.09\nDisk Usage: 23%\nMemory Usage: 80.2%\nCPU Load: 0.46\nCPU Temp: 30.0°C\n═══════════════════════════════════════\n"
}
ok: [hp2.i7.home] => {
"msg": "═══════════════════════════════════════\nHost: hp2.i7.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:35:15 up 20 days, 6:46, 1 user, load average: 0.96, 0.73, 0.66\nDisk Usage: 14%\nMemory Usage: 49.3%\nCPU Load: 0.81\nCPU Temp: 0.0°C\n═══════════════════════════════════════\n"
}
ok: [hp3.i5.home] => {
"msg": "═══════════════════════════════════════\nHost: hp3.i5.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:35:15 up 20 days, 7:59, 1 user, load average: 0.80, 0.57, 0.62\nDisk Usage: 14%\nMemory Usage: 59.4%\nCPU Load: 1.08\nCPU Temp: 52.5°C\n═══════════════════════════════════════\n"
}
ok: [mimi.pc.home] => {
"msg": "═══════════════════════════════════════\nHost: mimi.pc.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:35:15 up 20 days, 8:45, 1 user, load average: 0.12, 0.08, 0.08\nDisk Usage: 9%\nMemory Usage: 9.0%\nCPU Load: 0.10\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [orangepi.pc.home] => {
"msg": "═══════════════════════════════════════\nHost: orangepi.pc.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:35:17 up 13 days, 9:01, 1 user, load average: 0.31, 0.16, 0.11\nDisk Usage: 21%\nMemory Usage: 19.4%\nCPU Load: 0.34\nCPU Temp: 35.4°C\n═══════════════════════════════════════\n"
}
ok: [raspi.4gb.home] => {
"msg": "═══════════════════════════════════════\nHost: raspi.4gb.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:35:16 up 192 days, 11:08, 1 user, load average: 0.93, 0.47, 0.30\nDisk Usage: 6%\nMemory Usage: 12.5%\nCPU Load: 0.80\nCPU Temp: 35.0°C\n═══════════════════════════════════════\n"
}
ok: [raspi.8gb.home] => {
"msg": "═══════════════════════════════════════\nHost: raspi.8gb.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:35:16 up 192 days, 11:08, 1 user, load average: 0.19, 0.12, 0.10\nDisk Usage: 3%\nMemory Usage: 6.8%\nCPU Load: 0.15\nCPU Temp: 31.6°C\n═══════════════════════════════════════\n"
}
ok: [dev.lab.home] => {
"msg": "═══════════════════════════════════════\nHost: dev.lab.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:34:51 up 9 days, 7:24, 0 user, load average: 0.06, 0.09, 0.09\nDisk Usage: 48%\nMemory Usage: 71.0%\nCPU Load: 0.21\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [media.labb.home] => {
"msg": "═══════════════════════════════════════\nHost: media.labb.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:34:46 up 16 days, 3:36, 0 user, load average: 0.01, 0.03, 0.00\nDisk Usage: 24%\nMemory Usage: 72.1%\nCPU Load: 0.09\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [ali2v.truenas.home] => {
"msg": "═══════════════════════════════════════\nHost: ali2v.truenas.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:35:17 up 1 day, 9:06, 1 user, load average: 0.02, 0.04, 0.00\nDisk Usage: 1%\nMemory Usage: 34.1%\nCPU Load: 0.02\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [automate.prod.home] => {
"msg": "═══════════════════════════════════════\nHost: automate.prod.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:34:49 up 18 days, 22:29, 0 user, load average: 0.35, 0.40, 0.42\nDisk Usage: 28%\nMemory Usage: 24.6%\nCPU Load: 0.45\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [dev.prod.home] => {
"msg": "═══════════════════════════════════════\nHost: dev.prod.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:34:55 up 15 days, 8:50, 0 user, load average: 0.25, 0.14, 0.13\nDisk Usage: 75%\nMemory Usage: 60.0%\nCPU Load: 0.21\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [hp.truenas.home] => {
"msg": "═══════════════════════════════════════\nHost: hp.truenas.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 4:35PM up 20 days, 6:25, 1 user, load averages: 0.23, 0.28, 0.25\nDisk Usage: 10%\nMemory Usage: \nCPU Load: \nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [jump.point.home] => {
"msg": "═══════════════════════════════════════\nHost: jump.point.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:35:17 up 1 day, 9:06, 1 user, load average: 0.00, 0.01, 0.00\nDisk Usage: 79%\nMemory Usage: 13.4%\nCPU Load: 0.00\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [localhost] => {
"msg": "═══════════════════════════════════════\nHost: localhost\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:35:18 up 6:10, 1 user, load average: 1.47, 1.31, 1.23\nDisk Usage: 1%\nMemory Usage: 12.4%\nCPU Load: 2.10\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
PLAY RECAP *********************************************************************
ali2v.truenas.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
ali2v.xeon.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
automate.prod.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
dev.lab.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
dev.prod.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
hp.nas.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
hp.truenas.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=1
hp2.i7.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
hp3.i5.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
jump.point.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
localhost : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
media.labb.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
mimi.pc.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
orangepi.pc.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
raspi.4gb.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
raspi.8gb.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
```
---
*Généré automatiquement par Homelab Automation Dashboard*
*Date: 2025-12-16T00:35:31.522754+00:00*

View File

@ -0,0 +1,224 @@
# ✅ [Planifié] Health-check-5min
## Informations
| Propriété | Valeur |
|-----------|--------|
| **ID** | `8ce551dd943947d186041dcbcf391587` |
| **Nom** | [Planifié] Health-check-5min |
| **Cible** | `all` |
| **Statut** | completed |
| **Type** | Planifié |
| **Progression** | 100% |
| **Début** | 2025-12-16T00:40:00.004787+00:00 |
| **Fin** | 2025-12-16T00:40:32.539048+00:00 |
| **Durée** | 32.5s |
## Sortie
```
Using /mnt/c/dev/git/python/homelab-automation-api-v2/ansible/ansible.cfg as config file
PLAY [Health check on target host] *********************************************
TASK [Check if host is reachable (ping)] ***************************************
ok: [hp.nas.home] => {"changed": false, "ping": "pong"}
ok: [hp2.i7.home] => {"changed": false, "ping": "pong"}
ok: [mimi.pc.home] => {"changed": false, "ping": "pong"}
ok: [ali2v.xeon.home] => {"changed": false, "ping": "pong"}
ok: [hp3.i5.home] => {"changed": false, "ping": "pong"}
ok: [dev.lab.home] => {"changed": false, "ping": "pong"}
ok: [media.labb.home] => {"changed": false, "ping": "pong"}
ok: [raspi.8gb.home] => {"changed": false, "ping": "pong"}
ok: [raspi.4gb.home] => {"changed": false, "ping": "pong"}
ok: [automate.prod.home] => {"changed": false, "ping": "pong"}
ok: [ali2v.truenas.home] => {"changed": false, "ping": "pong"}
ok: [hp.truenas.home] => {"changed": false, "ping": "pong"}
ok: [dev.prod.home] => {"changed": false, "ping": "pong"}
ok: [localhost] => {"changed": false, "ping": "pong"}
ok: [jump.point.home] => {"changed": false, "ping": "pong"}
ok: [orangepi.pc.home] => {"changed": false, "ping": "pong"}
TASK [Gather minimal facts] ****************************************************
ok: [hp.nas.home]
ok: [mimi.pc.home]
ok: [hp2.i7.home]
ok: [ali2v.xeon.home]
ok: [hp3.i5.home]
ok: [dev.lab.home]
ok: [media.labb.home]
ok: [raspi.8gb.home]
ok: [raspi.4gb.home]
ok: [ali2v.truenas.home]
ok: [automate.prod.home]
ok: [hp.truenas.home]
ok: [dev.prod.home]
ok: [jump.point.home]
ok: [orangepi.pc.home]
ok: [localhost]
TASK [Get system uptime] *******************************************************
ok: [mimi.pc.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003408", "end": "2025-12-15 19:40:15.429940", "msg": "", "rc": 0, "start": "2025-12-15 19:40:15.426532", "stderr": "", "stderr_lines": [], "stdout": " 19:40:15 up 20 days, 8:50, 1 user, load average: 0.05, 0.06, 0.08", "stdout_lines": [" 19:40:15 up 20 days, 8:50, 1 user, load average: 0.05, 0.06, 0.08"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003359", "end": "2025-12-15 19:40:15.424979", "msg": "", "rc": 0, "start": "2025-12-15 19:40:15.421620", "stderr": "", "stderr_lines": [], "stdout": " 19:40:15 up 20 days, 6:51, 1 user, load average: 0.80, 0.60, 0.62", "stdout_lines": [" 19:40:15 up 20 days, 6:51, 1 user, load average: 0.80, 0.60, 0.62"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.004511", "end": "2025-12-15 19:40:15.447224", "msg": "", "rc": 0, "start": "2025-12-15 19:40:15.442713", "stderr": "", "stderr_lines": [], "stdout": " 19:40:15 up 20 days, 8:04, 1 user, load average: 0.64, 0.63, 0.63", "stdout_lines": [" 19:40:15 up 20 days, 8:04, 1 user, load average: 0.64, 0.63, 0.63"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.002925", "end": "2025-12-15 19:40:15.453051", "msg": "", "rc": 0, "start": "2025-12-15 19:40:15.450126", "stderr": "", "stderr_lines": [], "stdout": " 19:40:15 up 1 day, 9:12, 1 user, load average: 0.36, 0.34, 0.36", "stdout_lines": [" 19:40:15 up 1 day, 9:12, 1 user, load average: 0.36, 0.34, 0.36"]}
ok: [dev.lab.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003088", "end": "2025-12-15 19:39:51.514799", "msg": "", "rc": 0, "start": "2025-12-15 19:39:51.511711", "stderr": "", "stderr_lines": [], "stdout": " 19:39:51 up 9 days, 7:29, 0 user, load average: 0.08, 0.08, 0.09", "stdout_lines": [" 19:39:51 up 9 days, 7:29, 0 user, load average: 0.08, 0.08, 0.09"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.009709", "end": "2025-12-15 19:40:16.296149", "msg": "", "rc": 0, "start": "2025-12-15 19:40:16.286440", "stderr": "", "stderr_lines": [], "stdout": " 19:40:16 up 192 days, 11:13, 1 user, load average: 0.33, 0.37, 0.30", "stdout_lines": [" 19:40:16 up 192 days, 11:13, 1 user, load average: 0.33, 0.37, 0.30"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.008513", "end": "2025-12-15 19:40:16.311685", "msg": "", "rc": 0, "start": "2025-12-15 19:40:16.303172", "stderr": "", "stderr_lines": [], "stdout": " 19:40:16 up 192 days, 11:13, 1 user, load average: 0.17, 0.12, 0.09", "stdout_lines": [" 19:40:16 up 192 days, 11:13, 1 user, load average: 0.17, 0.12, 0.09"]}
ok: [hp.nas.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:01.003948", "end": "2025-12-15 19:40:16.559986", "msg": "", "rc": 0, "start": "2025-12-15 19:40:15.556038", "stderr": "", "stderr_lines": [], "stdout": " 19:40:15 up 20 days, 6:31, 1 user, load average: 0.39, 0.27, 0.17", "stdout_lines": [" 19:40:15 up 20 days, 6:31, 1 user, load average: 0.39, 0.27, 0.17"]}
ok: [media.labb.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003967", "end": "2025-12-15 19:39:46.244445", "msg": "", "rc": 0, "start": "2025-12-15 19:39:46.240478", "stderr": "", "stderr_lines": [], "stdout": " 19:39:46 up 16 days, 3:41, 0 user, load average: 0.02, 0.04, 0.00", "stdout_lines": [" 19:39:46 up 16 days, 3:41, 0 user, load average: 0.02, 0.04, 0.00"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.004641", "end": "2025-12-15 19:40:16.917508", "msg": "", "rc": 0, "start": "2025-12-15 19:40:16.912867", "stderr": "", "stderr_lines": [], "stdout": " 19:40:16 up 1 day, 9:11, 1 user, load average: 0.02, 0.02, 0.00", "stdout_lines": [" 19:40:16 up 1 day, 9:11, 1 user, load average: 0.02, 0.02, 0.00"]}
ok: [automate.prod.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003453", "end": "2025-12-15 19:39:49.094673", "msg": "", "rc": 0, "start": "2025-12-15 19:39:49.091220", "stderr": "", "stderr_lines": [], "stdout": " 19:39:49 up 18 days, 22:34, 0 user, load average: 0.35, 0.44, 0.44", "stdout_lines": [" 19:39:49 up 18 days, 22:34, 0 user, load average: 0.35, 0.44, 0.44"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.019496", "end": "2025-12-15 19:40:16.971366", "msg": "", "rc": 0, "start": "2025-12-15 19:40:16.951870", "stderr": "", "stderr_lines": [], "stdout": " 19:40:16 up 13 days, 9:06, 1 user, load average: 0.29, 0.16, 0.10", "stdout_lines": [" 19:40:16 up 13 days, 9:06, 1 user, load average: 0.29, 0.16, 0.10"]}
ok: [dev.prod.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003904", "end": "2025-12-15 19:39:55.153235", "msg": "", "rc": 0, "start": "2025-12-15 19:39:55.149331", "stderr": "", "stderr_lines": [], "stdout": " 19:39:55 up 15 days, 8:55, 0 user, load average: 0.08, 0.14, 0.12", "stdout_lines": [" 19:39:55 up 15 days, 8:55, 0 user, load average: 0.08, 0.14, 0.12"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.004195", "end": "2025-12-15 16:40:17.351992", "msg": "", "rc": 0, "start": "2025-12-15 16:40:17.347797", "stderr": "", "stderr_lines": [], "stdout": " 4:40PM up 20 days, 6:30, 1 user, load averages: 0.14, 0.20, 0.22", "stdout_lines": [" 4:40PM up 20 days, 6:30, 1 user, load averages: 0.14, 0.20, 0.22"]}
ok: [localhost] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.012326", "end": "2025-12-15 19:40:17.926563", "msg": "", "rc": 0, "start": "2025-12-15 19:40:17.914237", "stderr": "", "stderr_lines": [], "stdout": " 19:40:17 up 6:15, 1 user, load average: 1.44, 1.37, 1.28", "stdout_lines": [" 19:40:17 up 6:15, 1 user, load average: 1.44, 1.37, 1.28"]}
ok: [jump.point.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:01.004919", "end": "2025-12-15 19:40:18.458885", "msg": "", "rc": 0, "start": "2025-12-15 19:40:17.453966", "stderr": "", "stderr_lines": [], "stdout": " 19:40:17 up 1 day, 9:11, 1 user, load average: 0.03, 0.01, 0.00", "stdout_lines": [" 19:40:17 up 1 day, 9:11, 1 user, load average: 0.03, 0.01, 0.00"]}
TASK [Get disk usage] **********************************************************
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004077", "end": "2025-12-15 19:40:19.048100", "msg": "", "rc": 0, "start": "2025-12-15 19:40:19.044023", "stderr": "", "stderr_lines": [], "stdout": "22%", "stdout_lines": ["22%"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004822", "end": "2025-12-15 19:40:19.110721", "msg": "", "rc": 0, "start": "2025-12-15 19:40:19.105899", "stderr": "", "stderr_lines": [], "stdout": "14%", "stdout_lines": ["14%"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004901", "end": "2025-12-15 19:40:19.143417", "msg": "", "rc": 0, "start": "2025-12-15 19:40:19.138516", "stderr": "", "stderr_lines": [], "stdout": "9%", "stdout_lines": ["9%"]}
ok: [hp.nas.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004327", "end": "2025-12-15 19:40:19.148743", "msg": "", "rc": 0, "start": "2025-12-15 19:40:19.144416", "stderr": "", "stderr_lines": [], "stdout": "23%", "stdout_lines": ["23%"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005698", "end": "2025-12-15 19:40:19.160746", "msg": "", "rc": 0, "start": "2025-12-15 19:40:19.155048", "stderr": "", "stderr_lines": [], "stdout": "14%", "stdout_lines": ["14%"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005123", "end": "2025-12-15 19:39:55.143894", "msg": "", "rc": 0, "start": "2025-12-15 19:39:55.138771", "stderr": "", "stderr_lines": [], "stdout": "48%", "stdout_lines": ["48%"]}
ok: [media.labb.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005558", "end": "2025-12-15 19:39:49.292226", "msg": "", "rc": 0, "start": "2025-12-15 19:39:49.286668", "stderr": "", "stderr_lines": [], "stdout": "24%", "stdout_lines": ["24%"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.010689", "end": "2025-12-15 19:40:20.011108", "msg": "", "rc": 0, "start": "2025-12-15 19:40:20.000419", "stderr": "", "stderr_lines": [], "stdout": "3%", "stdout_lines": ["3%"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.011942", "end": "2025-12-15 19:40:20.039967", "msg": "", "rc": 0, "start": "2025-12-15 19:40:20.028025", "stderr": "", "stderr_lines": [], "stdout": "6%", "stdout_lines": ["6%"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.006440", "end": "2025-12-15 19:40:20.353777", "msg": "", "rc": 0, "start": "2025-12-15 19:40:20.347337", "stderr": "", "stderr_lines": [], "stdout": "1%", "stdout_lines": ["1%"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005199", "end": "2025-12-15 19:39:52.577623", "msg": "", "rc": 0, "start": "2025-12-15 19:39:52.572424", "stderr": "", "stderr_lines": [], "stdout": "28%", "stdout_lines": ["28%"]}
ok: [dev.prod.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004794", "end": "2025-12-15 19:39:58.587813", "msg": "", "rc": 0, "start": "2025-12-15 19:39:58.583019", "stderr": "", "stderr_lines": [], "stdout": "75%", "stdout_lines": ["75%"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005466", "end": "2025-12-15 16:40:20.638200", "msg": "", "rc": 0, "start": "2025-12-15 16:40:20.632734", "stderr": "", "stderr_lines": [], "stdout": "10%", "stdout_lines": ["10%"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.025033", "end": "2025-12-15 19:40:20.620549", "msg": "", "rc": 0, "start": "2025-12-15 19:40:20.595516", "stderr": "", "stderr_lines": [], "stdout": "21%", "stdout_lines": ["21%"]}
ok: [jump.point.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005294", "end": "2025-12-15 19:40:20.888002", "msg": "", "rc": 0, "start": "2025-12-15 19:40:20.882708", "stderr": "", "stderr_lines": [], "stdout": "79%", "stdout_lines": ["79%"]}
ok: [localhost] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.022468", "end": "2025-12-15 19:40:21.451404", "msg": "", "rc": 0, "start": "2025-12-15 19:40:21.428936", "stderr": "", "stderr_lines": [], "stdout": "1%", "stdout_lines": ["1%"]}
TASK [Get memory usage (Linux)] ************************************************
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004447", "end": "2025-12-15 19:40:21.797803", "msg": "", "rc": 0, "start": "2025-12-15 19:40:21.793356", "stderr": "", "stderr_lines": [], "stdout": "21.8%", "stdout_lines": ["21.8%"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005093", "end": "2025-12-15 19:40:21.841395", "msg": "", "rc": 0, "start": "2025-12-15 19:40:21.836302", "stderr": "", "stderr_lines": [], "stdout": "49.3%", "stdout_lines": ["49.3%"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005144", "end": "2025-12-15 19:40:21.887392", "msg": "", "rc": 0, "start": "2025-12-15 19:40:21.882248", "stderr": "", "stderr_lines": [], "stdout": "8.8%", "stdout_lines": ["8.8%"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005696", "end": "2025-12-15 19:40:21.878891", "msg": "", "rc": 0, "start": "2025-12-15 19:40:21.873195", "stderr": "", "stderr_lines": [], "stdout": "59.4%", "stdout_lines": ["59.4%"]}
ok: [hp.nas.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004275", "end": "2025-12-15 19:40:22.184593", "msg": "", "rc": 0, "start": "2025-12-15 19:40:22.180318", "stderr": "", "stderr_lines": [], "stdout": "80.4%", "stdout_lines": ["80.4%"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.003871", "end": "2025-12-15 19:39:57.873719", "msg": "", "rc": 0, "start": "2025-12-15 19:39:57.869848", "stderr": "", "stderr_lines": [], "stdout": "70.8%", "stdout_lines": ["70.8%"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.011075", "end": "2025-12-15 19:40:22.671477", "msg": "", "rc": 0, "start": "2025-12-15 19:40:22.660402", "stderr": "", "stderr_lines": [], "stdout": "6.7%", "stdout_lines": ["6.7%"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.012139", "end": "2025-12-15 19:40:22.729836", "msg": "", "rc": 0, "start": "2025-12-15 19:40:22.717697", "stderr": "", "stderr_lines": [], "stdout": "12.3%", "stdout_lines": ["12.3%"]}
ok: [media.labb.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004558", "end": "2025-12-15 19:39:52.254255", "msg": "", "rc": 0, "start": "2025-12-15 19:39:52.249697", "stderr": "", "stderr_lines": [], "stdout": "72.0%", "stdout_lines": ["72.0%"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005787", "end": "2025-12-15 19:40:23.090349", "msg": "", "rc": 0, "start": "2025-12-15 19:40:23.084562", "stderr": "", "stderr_lines": [], "stdout": "34.1%", "stdout_lines": ["34.1%"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.003996", "end": "2025-12-15 19:39:55.487387", "msg": "", "rc": 0, "start": "2025-12-15 19:39:55.483391", "stderr": "", "stderr_lines": [], "stdout": "26.1%", "stdout_lines": ["26.1%"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.025659", "end": "2025-12-15 19:40:23.313759", "msg": "", "rc": 0, "start": "2025-12-15 19:40:23.288100", "stderr": "", "stderr_lines": [], "stdout": "19.1%", "stdout_lines": ["19.1%"]}
ok: [dev.prod.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.003982", "end": "2025-12-15 19:40:01.473425", "msg": "", "rc": 0, "start": "2025-12-15 19:40:01.469443", "stderr": "", "stderr_lines": [], "stdout": "60.0%", "stdout_lines": ["60.0%"]}
fatal: [hp.truenas.home]: FAILED! => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005148", "end": "2025-12-15 16:40:23.514678", "msg": "non-zero return code", "rc": 2, "start": "2025-12-15 16:40:23.509530", "stderr": "cat: /proc/meminfo: No such file or directory\nawk: division by zero\n source line number 1", "stderr_lines": ["cat: /proc/meminfo: No such file or directory", "awk: division by zero", " source line number 1"], "stdout": "", "stdout_lines": []}
...ignoring
ok: [jump.point.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005438", "end": "2025-12-15 19:40:23.745640", "msg": "", "rc": 0, "start": "2025-12-15 19:40:23.740202", "stderr": "", "stderr_lines": [], "stdout": "13.7%", "stdout_lines": ["13.7%"]}
ok: [localhost] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.020255", "end": "2025-12-15 19:40:24.401967", "msg": "", "rc": 0, "start": "2025-12-15 19:40:24.381712", "stderr": "", "stderr_lines": [], "stdout": "12.5%", "stdout_lines": ["12.5%"]}
TASK [Get CPU temperature (ARM/SBC)] *******************************************
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.004855", "end": "2025-12-15 19:40:24.725765", "msg": "", "rc": 0, "start": "2025-12-15 19:40:24.720910", "stderr": "", "stderr_lines": [], "stdout": "45.0°C", "stdout_lines": ["45.0°C"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.006022", "end": "2025-12-15 19:40:24.762260", "msg": "", "rc": 0, "start": "2025-12-15 19:40:24.756238", "stderr": "cat: /sys/class/thermal/thermal_zone0/temp: No data available", "stderr_lines": ["cat: /sys/class/thermal/thermal_zone0/temp: No data available"], "stdout": "0.0°C", "stdout_lines": ["0.0°C"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.011314", "end": "2025-12-15 19:40:24.809944", "msg": "", "rc": 0, "start": "2025-12-15 19:40:24.798630", "stderr": "", "stderr_lines": [], "stdout": "52.5°C", "stdout_lines": ["52.5°C"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003159", "end": "2025-12-15 19:40:24.821322", "msg": "", "rc": 0, "start": "2025-12-15 19:40:24.818163", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [hp.nas.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.005335", "end": "2025-12-15 19:40:24.963698", "msg": "", "rc": 0, "start": "2025-12-15 19:40:24.958363", "stderr": "", "stderr_lines": [], "stdout": "30.0°C", "stdout_lines": ["30.0°C"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.002926", "end": "2025-12-15 19:40:00.874104", "msg": "", "rc": 0, "start": "2025-12-15 19:40:00.871178", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [media.labb.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003334", "end": "2025-12-15 19:39:55.141445", "msg": "", "rc": 0, "start": "2025-12-15 19:39:55.138111", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.011907", "end": "2025-12-15 19:40:25.752505", "msg": "", "rc": 0, "start": "2025-12-15 19:40:25.740598", "stderr": "", "stderr_lines": [], "stdout": "31.6°C", "stdout_lines": ["31.6°C"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.013480", "end": "2025-12-15 19:40:25.758538", "msg": "", "rc": 0, "start": "2025-12-15 19:40:25.745058", "stderr": "", "stderr_lines": [], "stdout": "36.0°C", "stdout_lines": ["36.0°C"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003253", "end": "2025-12-15 19:40:26.088934", "msg": "", "rc": 0, "start": "2025-12-15 19:40:26.085681", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003953", "end": "2025-12-15 16:40:26.396342", "msg": "", "rc": 0, "start": "2025-12-15 16:40:26.392389", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [dev.prod.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.002593", "end": "2025-12-15 19:40:04.401592", "msg": "", "rc": 0, "start": "2025-12-15 19:40:04.398999", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003068", "end": "2025-12-15 19:39:58.498285", "msg": "", "rc": 0, "start": "2025-12-15 19:39:58.495217", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.028073", "end": "2025-12-15 19:40:26.404864", "msg": "", "rc": 0, "start": "2025-12-15 19:40:26.376791", "stderr": "", "stderr_lines": [], "stdout": "36.1°C", "stdout_lines": ["36.1°C"]}
ok: [jump.point.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.002964", "end": "2025-12-15 19:40:26.630974", "msg": "", "rc": 0, "start": "2025-12-15 19:40:26.628010", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [localhost] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.007084", "end": "2025-12-15 19:40:27.360614", "msg": "", "rc": 0, "start": "2025-12-15 19:40:27.353530", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
TASK [Get CPU load] ************************************************************
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.003940", "end": "2025-12-15 19:40:27.753582", "msg": "", "rc": 0, "start": "2025-12-15 19:40:27.749642", "stderr": "", "stderr_lines": [], "stdout": "0.62", "stdout_lines": ["0.62"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004798", "end": "2025-12-15 19:40:27.827219", "msg": "", "rc": 0, "start": "2025-12-15 19:40:27.822421", "stderr": "", "stderr_lines": [], "stdout": "0.83", "stdout_lines": ["0.83"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005816", "end": "2025-12-15 19:40:27.889709", "msg": "", "rc": 0, "start": "2025-12-15 19:40:27.883893", "stderr": "", "stderr_lines": [], "stdout": "0.12", "stdout_lines": ["0.12"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005720", "end": "2025-12-15 19:40:27.894382", "msg": "", "rc": 0, "start": "2025-12-15 19:40:27.888662", "stderr": "", "stderr_lines": [], "stdout": "0.54", "stdout_lines": ["0.54"]}
ok: [hp.nas.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004287", "end": "2025-12-15 19:40:27.993157", "msg": "", "rc": 0, "start": "2025-12-15 19:40:27.988870", "stderr": "", "stderr_lines": [], "stdout": "0.45", "stdout_lines": ["0.45"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004285", "end": "2025-12-15 19:40:04.044158", "msg": "", "rc": 0, "start": "2025-12-15 19:40:04.039873", "stderr": "", "stderr_lines": [], "stdout": "0.06", "stdout_lines": ["0.06"]}
ok: [media.labb.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005790", "end": "2025-12-15 19:39:58.223987", "msg": "", "rc": 0, "start": "2025-12-15 19:39:58.218197", "stderr": "", "stderr_lines": [], "stdout": "0.02", "stdout_lines": ["0.02"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.011202", "end": "2025-12-15 19:40:28.794655", "msg": "", "rc": 0, "start": "2025-12-15 19:40:28.783453", "stderr": "", "stderr_lines": [], "stdout": "0.41", "stdout_lines": ["0.41"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.010300", "end": "2025-12-15 19:40:28.830036", "msg": "", "rc": 0, "start": "2025-12-15 19:40:28.819736", "stderr": "", "stderr_lines": [], "stdout": "0.28", "stdout_lines": ["0.28"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005721", "end": "2025-12-15 19:40:29.297588", "msg": "", "rc": 0, "start": "2025-12-15 19:40:29.291867", "stderr": "", "stderr_lines": [], "stdout": "0.09", "stdout_lines": ["0.09"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.024724", "end": "2025-12-15 19:40:29.316852", "msg": "", "rc": 0, "start": "2025-12-15 19:40:29.292128", "stderr": "", "stderr_lines": [], "stdout": "0.30", "stdout_lines": ["0.30"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.006144", "end": "2025-12-15 16:40:29.475258", "msg": "", "rc": 0, "start": "2025-12-15 16:40:29.469114", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}
ok: [dev.prod.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004179", "end": "2025-12-15 19:40:07.504205", "msg": "", "rc": 0, "start": "2025-12-15 19:40:07.500026", "stderr": "", "stderr_lines": [], "stdout": "0.14", "stdout_lines": ["0.14"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004782", "end": "2025-12-15 19:40:01.598427", "msg": "", "rc": 0, "start": "2025-12-15 19:40:01.593645", "stderr": "", "stderr_lines": [], "stdout": "0.45", "stdout_lines": ["0.45"]}
ok: [jump.point.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005300", "end": "2025-12-15 19:40:29.832698", "msg": "", "rc": 0, "start": "2025-12-15 19:40:29.827398", "stderr": "", "stderr_lines": [], "stdout": "0.32", "stdout_lines": ["0.32"]}
ok: [localhost] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.022580", "end": "2025-12-15 19:40:30.356743", "msg": "", "rc": 0, "start": "2025-12-15 19:40:30.334163", "stderr": "", "stderr_lines": [], "stdout": "1.86", "stdout_lines": ["1.86"]}
TASK [Display health status] ***************************************************
ok: [ali2v.xeon.home] => {
"msg": "═══════════════════════════════════════\nHost: ali2v.xeon.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:40:15 up 1 day, 9:12, 1 user, load average: 0.36, 0.34, 0.36\nDisk Usage: 22%\nMemory Usage: 21.8%\nCPU Load: 0.62\nCPU Temp: 45.0°C\n═══════════════════════════════════════\n"
}
ok: [hp.nas.home] => {
"msg": "═══════════════════════════════════════\nHost: hp.nas.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:40:15 up 20 days, 6:31, 1 user, load average: 0.39, 0.27, 0.17\nDisk Usage: 23%\nMemory Usage: 80.4%\nCPU Load: 0.45\nCPU Temp: 30.0°C\n═══════════════════════════════════════\n"
}
ok: [hp2.i7.home] => {
"msg": "═══════════════════════════════════════\nHost: hp2.i7.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:40:15 up 20 days, 6:51, 1 user, load average: 0.80, 0.60, 0.62\nDisk Usage: 14%\nMemory Usage: 49.3%\nCPU Load: 0.83\nCPU Temp: 0.0°C\n═══════════════════════════════════════\n"
}
ok: [hp3.i5.home] => {
"msg": "═══════════════════════════════════════\nHost: hp3.i5.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:40:15 up 20 days, 8:04, 1 user, load average: 0.64, 0.63, 0.63\nDisk Usage: 14%\nMemory Usage: 59.4%\nCPU Load: 0.54\nCPU Temp: 52.5°C\n═══════════════════════════════════════\n"
}
ok: [mimi.pc.home] => {
"msg": "═══════════════════════════════════════\nHost: mimi.pc.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:40:15 up 20 days, 8:50, 1 user, load average: 0.05, 0.06, 0.08\nDisk Usage: 9%\nMemory Usage: 8.8%\nCPU Load: 0.12\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [orangepi.pc.home] => {
"msg": "═══════════════════════════════════════\nHost: orangepi.pc.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:40:16 up 13 days, 9:06, 1 user, load average: 0.29, 0.16, 0.10\nDisk Usage: 21%\nMemory Usage: 19.1%\nCPU Load: 0.30\nCPU Temp: 36.1°C\n═══════════════════════════════════════\n"
}
ok: [raspi.4gb.home] => {
"msg": "═══════════════════════════════════════\nHost: raspi.4gb.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:40:16 up 192 days, 11:13, 1 user, load average: 0.33, 0.37, 0.30\nDisk Usage: 6%\nMemory Usage: 12.3%\nCPU Load: 0.41\nCPU Temp: 36.0°C\n═══════════════════════════════════════\n"
}
ok: [raspi.8gb.home] => {
"msg": "═══════════════════════════════════════\nHost: raspi.8gb.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:40:16 up 192 days, 11:13, 1 user, load average: 0.17, 0.12, 0.09\nDisk Usage: 3%\nMemory Usage: 6.7%\nCPU Load: 0.28\nCPU Temp: 31.6°C\n═══════════════════════════════════════\n"
}
ok: [dev.lab.home] => {
"msg": "═══════════════════════════════════════\nHost: dev.lab.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:39:51 up 9 days, 7:29, 0 user, load average: 0.08, 0.08, 0.09\nDisk Usage: 48%\nMemory Usage: 70.8%\nCPU Load: 0.06\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [media.labb.home] => {
"msg": "═══════════════════════════════════════\nHost: media.labb.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:39:46 up 16 days, 3:41, 0 user, load average: 0.02, 0.04, 0.00\nDisk Usage: 24%\nMemory Usage: 72.0%\nCPU Load: 0.02\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [ali2v.truenas.home] => {
"msg": "═══════════════════════════════════════\nHost: ali2v.truenas.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:40:16 up 1 day, 9:11, 1 user, load average: 0.02, 0.02, 0.00\nDisk Usage: 1%\nMemory Usage: 34.1%\nCPU Load: 0.09\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [automate.prod.home] => {
"msg": "═══════════════════════════════════════\nHost: automate.prod.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:39:49 up 18 days, 22:34, 0 user, load average: 0.35, 0.44, 0.44\nDisk Usage: 28%\nMemory Usage: 26.1%\nCPU Load: 0.45\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [dev.prod.home] => {
"msg": "═══════════════════════════════════════\nHost: dev.prod.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:39:55 up 15 days, 8:55, 0 user, load average: 0.08, 0.14, 0.12\nDisk Usage: 75%\nMemory Usage: 60.0%\nCPU Load: 0.14\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [hp.truenas.home] => {
"msg": "═══════════════════════════════════════\nHost: hp.truenas.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 4:40PM up 20 days, 6:30, 1 user, load averages: 0.14, 0.20, 0.22\nDisk Usage: 10%\nMemory Usage: \nCPU Load: \nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [jump.point.home] => {
"msg": "═══════════════════════════════════════\nHost: jump.point.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:40:17 up 1 day, 9:11, 1 user, load average: 0.03, 0.01, 0.00\nDisk Usage: 79%\nMemory Usage: 13.7%\nCPU Load: 0.32\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [localhost] => {
"msg": "═══════════════════════════════════════\nHost: localhost\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:40:17 up 6:15, 1 user, load average: 1.44, 1.37, 1.28\nDisk Usage: 1%\nMemory Usage: 12.5%\nCPU Load: 1.86\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
PLAY RECAP *********************************************************************
ali2v.truenas.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
ali2v.xeon.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
automate.prod.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
dev.lab.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
dev.prod.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
hp.nas.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
hp.truenas.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=1
hp2.i7.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
hp3.i5.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
jump.point.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
localhost : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
media.labb.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
mimi.pc.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
orangepi.pc.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
raspi.4gb.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
raspi.8gb.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
```
---
*Généré automatiquement par Homelab Automation Dashboard*
*Date: 2025-12-16T00:40:32.612009+00:00*

View File

@ -0,0 +1,224 @@
# ✅ [Planifié] Health-check-5min
## Informations
| Propriété | Valeur |
|-----------|--------|
| **ID** | `0c76a6e5733b4cd3abfd9df108c2002c` |
| **Nom** | [Planifié] Health-check-5min |
| **Cible** | `all` |
| **Statut** | completed |
| **Type** | Planifié |
| **Progression** | 100% |
| **Début** | 2025-12-16T00:45:00.003307+00:00 |
| **Fin** | 2025-12-16T00:45:31.400595+00:00 |
| **Durée** | 31.4s |
## Sortie
```
Using /mnt/c/dev/git/python/homelab-automation-api-v2/ansible/ansible.cfg as config file
PLAY [Health check on target host] *********************************************
TASK [Check if host is reachable (ping)] ***************************************
ok: [hp.nas.home] => {"changed": false, "ping": "pong"}
ok: [hp2.i7.home] => {"changed": false, "ping": "pong"}
ok: [mimi.pc.home] => {"changed": false, "ping": "pong"}
ok: [hp3.i5.home] => {"changed": false, "ping": "pong"}
ok: [ali2v.xeon.home] => {"changed": false, "ping": "pong"}
ok: [dev.lab.home] => {"changed": false, "ping": "pong"}
ok: [media.labb.home] => {"changed": false, "ping": "pong"}
ok: [raspi.8gb.home] => {"changed": false, "ping": "pong"}
ok: [raspi.4gb.home] => {"changed": false, "ping": "pong"}
ok: [automate.prod.home] => {"changed": false, "ping": "pong"}
ok: [ali2v.truenas.home] => {"changed": false, "ping": "pong"}
ok: [hp.truenas.home] => {"changed": false, "ping": "pong"}
ok: [dev.prod.home] => {"changed": false, "ping": "pong"}
ok: [localhost] => {"changed": false, "ping": "pong"}
ok: [jump.point.home] => {"changed": false, "ping": "pong"}
ok: [orangepi.pc.home] => {"changed": false, "ping": "pong"}
TASK [Gather minimal facts] ****************************************************
ok: [hp.nas.home]
ok: [mimi.pc.home]
ok: [ali2v.xeon.home]
ok: [hp3.i5.home]
ok: [hp2.i7.home]
ok: [dev.lab.home]
ok: [media.labb.home]
ok: [raspi.8gb.home]
ok: [raspi.4gb.home]
ok: [ali2v.truenas.home]
ok: [automate.prod.home]
ok: [hp.truenas.home]
ok: [dev.prod.home]
ok: [jump.point.home]
ok: [orangepi.pc.home]
ok: [localhost]
TASK [Get system uptime] *******************************************************
ok: [mimi.pc.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003386", "end": "2025-12-15 19:45:15.729299", "msg": "", "rc": 0, "start": "2025-12-15 19:45:15.725913", "stderr": "", "stderr_lines": [], "stdout": " 19:45:15 up 20 days, 8:55, 1 user, load average: 0.00, 0.03, 0.06", "stdout_lines": [" 19:45:15 up 20 days, 8:55, 1 user, load average: 0.00, 0.03, 0.06"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003387", "end": "2025-12-15 19:45:15.732198", "msg": "", "rc": 0, "start": "2025-12-15 19:45:15.728811", "stderr": "", "stderr_lines": [], "stdout": " 19:45:15 up 20 days, 6:56, 1 user, load average: 0.98, 0.78, 0.69", "stdout_lines": [" 19:45:15 up 20 days, 6:56, 1 user, load average: 0.98, 0.78, 0.69"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003788", "end": "2025-12-15 19:45:15.753333", "msg": "", "rc": 0, "start": "2025-12-15 19:45:15.749545", "stderr": "", "stderr_lines": [], "stdout": " 19:45:15 up 20 days, 8:09, 1 user, load average: 0.74, 0.64, 0.64", "stdout_lines": [" 19:45:15 up 20 days, 8:09, 1 user, load average: 0.74, 0.64, 0.64"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.002942", "end": "2025-12-15 19:45:15.765152", "msg": "", "rc": 0, "start": "2025-12-15 19:45:15.762210", "stderr": "", "stderr_lines": [], "stdout": " 19:45:15 up 1 day, 9:17, 1 user, load average: 0.40, 0.32, 0.34", "stdout_lines": [" 19:45:15 up 1 day, 9:17, 1 user, load average: 0.40, 0.32, 0.34"]}
ok: [dev.lab.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.002959", "end": "2025-12-15 19:44:51.777685", "msg": "", "rc": 0, "start": "2025-12-15 19:44:51.774726", "stderr": "", "stderr_lines": [], "stdout": " 19:44:51 up 9 days, 7:34, 0 user, load average: 0.03, 0.08, 0.08", "stdout_lines": [" 19:44:51 up 9 days, 7:34, 0 user, load average: 0.03, 0.08, 0.08"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.008573", "end": "2025-12-15 19:45:16.555078", "msg": "", "rc": 0, "start": "2025-12-15 19:45:16.546505", "stderr": "", "stderr_lines": [], "stdout": " 19:45:16 up 192 days, 11:18, 1 user, load average: 0.14, 0.12, 0.09", "stdout_lines": [" 19:45:16 up 192 days, 11:18, 1 user, load average: 0.14, 0.12, 0.09"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.009353", "end": "2025-12-15 19:45:16.594594", "msg": "", "rc": 0, "start": "2025-12-15 19:45:16.585241", "stderr": "", "stderr_lines": [], "stdout": " 19:45:16 up 192 days, 11:18, 1 user, load average: 0.33, 0.31, 0.28", "stdout_lines": [" 19:45:16 up 192 days, 11:18, 1 user, load average: 0.33, 0.31, 0.28"]}
ok: [hp.nas.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:01.003557", "end": "2025-12-15 19:45:16.718050", "msg": "", "rc": 0, "start": "2025-12-15 19:45:15.714493", "stderr": "", "stderr_lines": [], "stdout": " 19:45:15 up 20 days, 6:36, 1 user, load average: 0.24, 0.24, 0.18", "stdout_lines": [" 19:45:15 up 20 days, 6:36, 1 user, load average: 0.24, 0.24, 0.18"]}
ok: [media.labb.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003714", "end": "2025-12-15 19:44:46.498473", "msg": "", "rc": 0, "start": "2025-12-15 19:44:46.494759", "stderr": "", "stderr_lines": [], "stdout": " 19:44:46 up 16 days, 3:46, 0 user, load average: 0.07, 0.03, 0.00", "stdout_lines": [" 19:44:46 up 16 days, 3:46, 0 user, load average: 0.07, 0.03, 0.00"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.004728", "end": "2025-12-15 19:45:17.199499", "msg": "", "rc": 0, "start": "2025-12-15 19:45:17.194771", "stderr": "", "stderr_lines": [], "stdout": " 19:45:17 up 1 day, 9:16, 1 user, load average: 0.13, 0.05, 0.01", "stdout_lines": [" 19:45:17 up 1 day, 9:16, 1 user, load average: 0.13, 0.05, 0.01"]}
ok: [dev.prod.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003309", "end": "2025-12-15 19:44:55.305915", "msg": "", "rc": 0, "start": "2025-12-15 19:44:55.302606", "stderr": "", "stderr_lines": [], "stdout": " 19:44:55 up 15 days, 9:00, 0 user, load average: 0.26, 0.29, 0.20", "stdout_lines": [" 19:44:55 up 15 days, 9:00, 0 user, load average: 0.26, 0.29, 0.20"]}
ok: [automate.prod.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003286", "end": "2025-12-15 19:44:49.384094", "msg": "", "rc": 0, "start": "2025-12-15 19:44:49.380808", "stderr": "", "stderr_lines": [], "stdout": " 19:44:49 up 18 days, 22:39, 0 user, load average: 0.32, 0.38, 0.42", "stdout_lines": [" 19:44:49 up 18 days, 22:39, 0 user, load average: 0.32, 0.38, 0.42"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.019481", "end": "2025-12-15 19:45:17.226021", "msg": "", "rc": 0, "start": "2025-12-15 19:45:17.206540", "stderr": "", "stderr_lines": [], "stdout": " 19:45:17 up 13 days, 9:11, 1 user, load average: 0.23, 0.13, 0.10", "stdout_lines": [" 19:45:17 up 13 days, 9:11, 1 user, load average: 0.23, 0.13, 0.10"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.004250", "end": "2025-12-15 16:45:17.635178", "msg": "", "rc": 0, "start": "2025-12-15 16:45:17.630928", "stderr": "", "stderr_lines": [], "stdout": " 4:45PM up 20 days, 6:35, 1 user, load averages: 0.17, 0.20, 0.21", "stdout_lines": [" 4:45PM up 20 days, 6:35, 1 user, load averages: 0.17, 0.20, 0.21"]}
ok: [jump.point.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003788", "end": "2025-12-15 19:45:17.764479", "msg": "", "rc": 0, "start": "2025-12-15 19:45:17.760691", "stderr": "", "stderr_lines": [], "stdout": " 19:45:17 up 1 day, 9:16, 1 user, load average: 0.27, 0.09, 0.02", "stdout_lines": [" 19:45:17 up 1 day, 9:16, 1 user, load average: 0.27, 0.09, 0.02"]}
ok: [localhost] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.010006", "end": "2025-12-15 19:45:18.235812", "msg": "", "rc": 0, "start": "2025-12-15 19:45:18.225806", "stderr": "", "stderr_lines": [], "stdout": " 19:45:18 up 6:20, 1 user, load average: 1.77, 1.43, 1.32", "stdout_lines": [" 19:45:18 up 6:20, 1 user, load average: 1.77, 1.43, 1.32"]}
TASK [Get disk usage] **********************************************************
ok: [hp.nas.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004351", "end": "2025-12-15 19:45:18.582943", "msg": "", "rc": 0, "start": "2025-12-15 19:45:18.578592", "stderr": "", "stderr_lines": [], "stdout": "23%", "stdout_lines": ["23%"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004253", "end": "2025-12-15 19:45:18.592880", "msg": "", "rc": 0, "start": "2025-12-15 19:45:18.588627", "stderr": "", "stderr_lines": [], "stdout": "22%", "stdout_lines": ["22%"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004972", "end": "2025-12-15 19:45:18.633858", "msg": "", "rc": 0, "start": "2025-12-15 19:45:18.628886", "stderr": "", "stderr_lines": [], "stdout": "14%", "stdout_lines": ["14%"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004875", "end": "2025-12-15 19:45:18.686725", "msg": "", "rc": 0, "start": "2025-12-15 19:45:18.681850", "stderr": "", "stderr_lines": [], "stdout": "9%", "stdout_lines": ["9%"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005572", "end": "2025-12-15 19:45:18.682145", "msg": "", "rc": 0, "start": "2025-12-15 19:45:18.676573", "stderr": "", "stderr_lines": [], "stdout": "14%", "stdout_lines": ["14%"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004897", "end": "2025-12-15 19:44:54.699407", "msg": "", "rc": 0, "start": "2025-12-15 19:44:54.694510", "stderr": "", "stderr_lines": [], "stdout": "48%", "stdout_lines": ["48%"]}
ok: [media.labb.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005428", "end": "2025-12-15 19:44:48.855736", "msg": "", "rc": 0, "start": "2025-12-15 19:44:48.850308", "stderr": "", "stderr_lines": [], "stdout": "24%", "stdout_lines": ["24%"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.010488", "end": "2025-12-15 19:45:19.582854", "msg": "", "rc": 0, "start": "2025-12-15 19:45:19.572366", "stderr": "", "stderr_lines": [], "stdout": "3%", "stdout_lines": ["3%"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.011566", "end": "2025-12-15 19:45:19.583286", "msg": "", "rc": 0, "start": "2025-12-15 19:45:19.571720", "stderr": "", "stderr_lines": [], "stdout": "6%", "stdout_lines": ["6%"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005789", "end": "2025-12-15 19:45:19.962515", "msg": "", "rc": 0, "start": "2025-12-15 19:45:19.956726", "stderr": "", "stderr_lines": [], "stdout": "1%", "stdout_lines": ["1%"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005508", "end": "2025-12-15 19:44:52.201137", "msg": "", "rc": 0, "start": "2025-12-15 19:44:52.195629", "stderr": "", "stderr_lines": [], "stdout": "28%", "stdout_lines": ["28%"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005415", "end": "2025-12-15 16:45:20.236915", "msg": "", "rc": 0, "start": "2025-12-15 16:45:20.231500", "stderr": "", "stderr_lines": [], "stdout": "10%", "stdout_lines": ["10%"]}
ok: [dev.prod.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004823", "end": "2025-12-15 19:44:58.240087", "msg": "", "rc": 0, "start": "2025-12-15 19:44:58.235264", "stderr": "", "stderr_lines": [], "stdout": "75%", "stdout_lines": ["75%"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.025620", "end": "2025-12-15 19:45:20.163131", "msg": "", "rc": 0, "start": "2025-12-15 19:45:20.137511", "stderr": "", "stderr_lines": [], "stdout": "21%", "stdout_lines": ["21%"]}
ok: [jump.point.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005597", "end": "2025-12-15 19:45:20.500919", "msg": "", "rc": 0, "start": "2025-12-15 19:45:20.495322", "stderr": "", "stderr_lines": [], "stdout": "79%", "stdout_lines": ["79%"]}
ok: [localhost] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.009191", "end": "2025-12-15 19:45:21.088874", "msg": "", "rc": 0, "start": "2025-12-15 19:45:21.079683", "stderr": "", "stderr_lines": [], "stdout": "1%", "stdout_lines": ["1%"]}
TASK [Get memory usage (Linux)] ************************************************
ok: [hp.nas.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004433", "end": "2025-12-15 19:45:21.515163", "msg": "", "rc": 0, "start": "2025-12-15 19:45:21.510730", "stderr": "", "stderr_lines": [], "stdout": "80.5%", "stdout_lines": ["80.5%"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004234", "end": "2025-12-15 19:45:21.525555", "msg": "", "rc": 0, "start": "2025-12-15 19:45:21.521321", "stderr": "", "stderr_lines": [], "stdout": "21.7%", "stdout_lines": ["21.7%"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004697", "end": "2025-12-15 19:45:21.550974", "msg": "", "rc": 0, "start": "2025-12-15 19:45:21.546277", "stderr": "", "stderr_lines": [], "stdout": "49.3%", "stdout_lines": ["49.3%"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005905", "end": "2025-12-15 19:45:21.605882", "msg": "", "rc": 0, "start": "2025-12-15 19:45:21.599977", "stderr": "", "stderr_lines": [], "stdout": "59.4%", "stdout_lines": ["59.4%"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005096", "end": "2025-12-15 19:45:21.662859", "msg": "", "rc": 0, "start": "2025-12-15 19:45:21.657763", "stderr": "", "stderr_lines": [], "stdout": "9.0%", "stdout_lines": ["9.0%"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.003872", "end": "2025-12-15 19:44:57.600783", "msg": "", "rc": 0, "start": "2025-12-15 19:44:57.596911", "stderr": "", "stderr_lines": [], "stdout": "71.1%", "stdout_lines": ["71.1%"]}
ok: [media.labb.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004487", "end": "2025-12-15 19:44:51.785884", "msg": "", "rc": 0, "start": "2025-12-15 19:44:51.781397", "stderr": "", "stderr_lines": [], "stdout": "72.1%", "stdout_lines": ["72.1%"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.011006", "end": "2025-12-15 19:45:22.394695", "msg": "", "rc": 0, "start": "2025-12-15 19:45:22.383689", "stderr": "", "stderr_lines": [], "stdout": "6.9%", "stdout_lines": ["6.9%"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.012035", "end": "2025-12-15 19:45:22.422268", "msg": "", "rc": 0, "start": "2025-12-15 19:45:22.410233", "stderr": "", "stderr_lines": [], "stdout": "12.3%", "stdout_lines": ["12.3%"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005795", "end": "2025-12-15 19:45:22.827106", "msg": "", "rc": 0, "start": "2025-12-15 19:45:22.821311", "stderr": "", "stderr_lines": [], "stdout": "34.0%", "stdout_lines": ["34.0%"]}
fatal: [hp.truenas.home]: FAILED! => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005393", "end": "2025-12-15 16:45:23.009040", "msg": "non-zero return code", "rc": 2, "start": "2025-12-15 16:45:23.003647", "stderr": "cat: /proc/meminfo: No such file or directory\nawk: division by zero\n source line number 1", "stderr_lines": ["cat: /proc/meminfo: No such file or directory", "awk: division by zero", " source line number 1"], "stdout": "", "stdout_lines": []}
...ignoring
ok: [automate.prod.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004349", "end": "2025-12-15 19:44:55.076770", "msg": "", "rc": 0, "start": "2025-12-15 19:44:55.072421", "stderr": "", "stderr_lines": [], "stdout": "25.8%", "stdout_lines": ["25.8%"]}
ok: [dev.prod.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005354", "end": "2025-12-15 19:45:01.047680", "msg": "", "rc": 0, "start": "2025-12-15 19:45:01.042326", "stderr": "", "stderr_lines": [], "stdout": "63.0%", "stdout_lines": ["63.0%"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.025689", "end": "2025-12-15 19:45:23.063503", "msg": "", "rc": 0, "start": "2025-12-15 19:45:23.037814", "stderr": "", "stderr_lines": [], "stdout": "19.2%", "stdout_lines": ["19.2%"]}
ok: [jump.point.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005443", "end": "2025-12-15 19:45:23.393136", "msg": "", "rc": 0, "start": "2025-12-15 19:45:23.387693", "stderr": "", "stderr_lines": [], "stdout": "13.5%", "stdout_lines": ["13.5%"]}
ok: [localhost] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.011480", "end": "2025-12-15 19:45:23.905370", "msg": "", "rc": 0, "start": "2025-12-15 19:45:23.893890", "stderr": "", "stderr_lines": [], "stdout": "12.5%", "stdout_lines": ["12.5%"]}
TASK [Get CPU temperature (ARM/SBC)] *******************************************
ok: [hp.nas.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.005089", "end": "2025-12-15 19:45:24.325928", "msg": "", "rc": 0, "start": "2025-12-15 19:45:24.320839", "stderr": "", "stderr_lines": [], "stdout": "30.0°C", "stdout_lines": ["30.0°C"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.005011", "end": "2025-12-15 19:45:24.324739", "msg": "", "rc": 0, "start": "2025-12-15 19:45:24.319728", "stderr": "", "stderr_lines": [], "stdout": "46.0°C", "stdout_lines": ["46.0°C"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.006065", "end": "2025-12-15 19:45:24.384278", "msg": "", "rc": 0, "start": "2025-12-15 19:45:24.378213", "stderr": "cat: /sys/class/thermal/thermal_zone0/temp: No data available", "stderr_lines": ["cat: /sys/class/thermal/thermal_zone0/temp: No data available"], "stdout": "0.0°C", "stdout_lines": ["0.0°C"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003178", "end": "2025-12-15 19:45:24.423829", "msg": "", "rc": 0, "start": "2025-12-15 19:45:24.420651", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.006154", "end": "2025-12-15 19:45:24.448730", "msg": "", "rc": 0, "start": "2025-12-15 19:45:24.442576", "stderr": "", "stderr_lines": [], "stdout": "52.5°C", "stdout_lines": ["52.5°C"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.002733", "end": "2025-12-15 19:45:00.431801", "msg": "", "rc": 0, "start": "2025-12-15 19:45:00.429068", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [media.labb.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003276", "end": "2025-12-15 19:44:54.593962", "msg": "", "rc": 0, "start": "2025-12-15 19:44:54.590686", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.011863", "end": "2025-12-15 19:45:25.291803", "msg": "", "rc": 0, "start": "2025-12-15 19:45:25.279940", "stderr": "", "stderr_lines": [], "stdout": "32.1°C", "stdout_lines": ["32.1°C"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.013184", "end": "2025-12-15 19:45:25.284907", "msg": "", "rc": 0, "start": "2025-12-15 19:45:25.271723", "stderr": "", "stderr_lines": [], "stdout": "36.5°C", "stdout_lines": ["36.5°C"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003170", "end": "2025-12-15 19:45:25.656294", "msg": "", "rc": 0, "start": "2025-12-15 19:45:25.653124", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003061", "end": "2025-12-15 19:44:57.905571", "msg": "", "rc": 0, "start": "2025-12-15 19:44:57.902510", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003981", "end": "2025-12-15 16:45:25.882575", "msg": "", "rc": 0, "start": "2025-12-15 16:45:25.878594", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [dev.prod.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.008958", "end": "2025-12-15 19:45:03.909566", "msg": "", "rc": 0, "start": "2025-12-15 19:45:03.900608", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.028423", "end": "2025-12-15 19:45:25.960045", "msg": "", "rc": 0, "start": "2025-12-15 19:45:25.931622", "stderr": "", "stderr_lines": [], "stdout": "35.6°C", "stdout_lines": ["35.6°C"]}
ok: [jump.point.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.002982", "end": "2025-12-15 19:45:26.207337", "msg": "", "rc": 0, "start": "2025-12-15 19:45:26.204355", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [localhost] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.018216", "end": "2025-12-15 19:45:26.697159", "msg": "", "rc": 0, "start": "2025-12-15 19:45:26.678943", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
TASK [Get CPU load] ************************************************************
ok: [hp.nas.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004226", "end": "2025-12-15 19:45:27.161474", "msg": "", "rc": 0, "start": "2025-12-15 19:45:27.157248", "stderr": "", "stderr_lines": [], "stdout": "0.19", "stdout_lines": ["0.19"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004141", "end": "2025-12-15 19:45:27.167271", "msg": "", "rc": 0, "start": "2025-12-15 19:45:27.163130", "stderr": "", "stderr_lines": [], "stdout": "0.42", "stdout_lines": ["0.42"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004354", "end": "2025-12-15 19:45:27.250330", "msg": "", "rc": 0, "start": "2025-12-15 19:45:27.245976", "stderr": "", "stderr_lines": [], "stdout": "1.14", "stdout_lines": ["1.14"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005078", "end": "2025-12-15 19:45:27.273839", "msg": "", "rc": 0, "start": "2025-12-15 19:45:27.268761", "stderr": "", "stderr_lines": [], "stdout": "0.00", "stdout_lines": ["0.00"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005601", "end": "2025-12-15 19:45:27.276858", "msg": "", "rc": 0, "start": "2025-12-15 19:45:27.271257", "stderr": "", "stderr_lines": [], "stdout": "0.77", "stdout_lines": ["0.77"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005274", "end": "2025-12-15 19:45:03.263659", "msg": "", "rc": 0, "start": "2025-12-15 19:45:03.258385", "stderr": "", "stderr_lines": [], "stdout": "0.09", "stdout_lines": ["0.09"]}
ok: [media.labb.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005023", "end": "2025-12-15 19:44:57.432349", "msg": "", "rc": 0, "start": "2025-12-15 19:44:57.427326", "stderr": "", "stderr_lines": [], "stdout": "0.13", "stdout_lines": ["0.13"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.011356", "end": "2025-12-15 19:45:28.018977", "msg": "", "rc": 0, "start": "2025-12-15 19:45:28.007621", "stderr": "", "stderr_lines": [], "stdout": "0.40", "stdout_lines": ["0.40"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.010247", "end": "2025-12-15 19:45:28.043862", "msg": "", "rc": 0, "start": "2025-12-15 19:45:28.033615", "stderr": "", "stderr_lines": [], "stdout": "0.26", "stdout_lines": ["0.26"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005770", "end": "2025-12-15 19:45:28.486626", "msg": "", "rc": 0, "start": "2025-12-15 19:45:28.480856", "stderr": "", "stderr_lines": [], "stdout": "0.11", "stdout_lines": ["0.11"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005918", "end": "2025-12-15 16:45:28.644968", "msg": "", "rc": 0, "start": "2025-12-15 16:45:28.639050", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}
ok: [dev.prod.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004812", "end": "2025-12-15 19:45:06.680895", "msg": "", "rc": 0, "start": "2025-12-15 19:45:06.676083", "stderr": "", "stderr_lines": [], "stdout": "0.30", "stdout_lines": ["0.30"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005001", "end": "2025-12-15 19:45:00.757462", "msg": "", "rc": 0, "start": "2025-12-15 19:45:00.752461", "stderr": "", "stderr_lines": [], "stdout": "0.27", "stdout_lines": ["0.27"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.024318", "end": "2025-12-15 19:45:28.679661", "msg": "", "rc": 0, "start": "2025-12-15 19:45:28.655343", "stderr": "", "stderr_lines": [], "stdout": "0.25", "stdout_lines": ["0.25"]}
ok: [jump.point.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005317", "end": "2025-12-15 19:45:29.020442", "msg": "", "rc": 0, "start": "2025-12-15 19:45:29.015125", "stderr": "", "stderr_lines": [], "stdout": "0.23", "stdout_lines": ["0.23"]}
ok: [localhost] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.012039", "end": "2025-12-15 19:45:29.469946", "msg": "", "rc": 0, "start": "2025-12-15 19:45:29.457907", "stderr": "", "stderr_lines": [], "stdout": "1.89", "stdout_lines": ["1.89"]}
TASK [Display health status] ***************************************************
ok: [ali2v.xeon.home] => {
"msg": "═══════════════════════════════════════\nHost: ali2v.xeon.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:45:15 up 1 day, 9:17, 1 user, load average: 0.40, 0.32, 0.34\nDisk Usage: 22%\nMemory Usage: 21.7%\nCPU Load: 0.42\nCPU Temp: 46.0°C\n═══════════════════════════════════════\n"
}
ok: [hp.nas.home] => {
"msg": "═══════════════════════════════════════\nHost: hp.nas.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:45:15 up 20 days, 6:36, 1 user, load average: 0.24, 0.24, 0.18\nDisk Usage: 23%\nMemory Usage: 80.5%\nCPU Load: 0.19\nCPU Temp: 30.0°C\n═══════════════════════════════════════\n"
}
ok: [hp2.i7.home] => {
"msg": "═══════════════════════════════════════\nHost: hp2.i7.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:45:15 up 20 days, 6:56, 1 user, load average: 0.98, 0.78, 0.69\nDisk Usage: 14%\nMemory Usage: 49.3%\nCPU Load: 1.14\nCPU Temp: 0.0°C\n═══════════════════════════════════════\n"
}
ok: [hp3.i5.home] => {
"msg": "═══════════════════════════════════════\nHost: hp3.i5.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:45:15 up 20 days, 8:09, 1 user, load average: 0.74, 0.64, 0.64\nDisk Usage: 14%\nMemory Usage: 59.4%\nCPU Load: 0.77\nCPU Temp: 52.5°C\n═══════════════════════════════════════\n"
}
ok: [mimi.pc.home] => {
"msg": "═══════════════════════════════════════\nHost: mimi.pc.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:45:15 up 20 days, 8:55, 1 user, load average: 0.00, 0.03, 0.06\nDisk Usage: 9%\nMemory Usage: 9.0%\nCPU Load: 0.00\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [orangepi.pc.home] => {
"msg": "═══════════════════════════════════════\nHost: orangepi.pc.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:45:17 up 13 days, 9:11, 1 user, load average: 0.23, 0.13, 0.10\nDisk Usage: 21%\nMemory Usage: 19.2%\nCPU Load: 0.25\nCPU Temp: 35.6°C\n═══════════════════════════════════════\n"
}
ok: [raspi.4gb.home] => {
"msg": "═══════════════════════════════════════\nHost: raspi.4gb.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:45:16 up 192 days, 11:18, 1 user, load average: 0.33, 0.31, 0.28\nDisk Usage: 6%\nMemory Usage: 12.3%\nCPU Load: 0.40\nCPU Temp: 36.5°C\n═══════════════════════════════════════\n"
}
ok: [raspi.8gb.home] => {
"msg": "═══════════════════════════════════════\nHost: raspi.8gb.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:45:16 up 192 days, 11:18, 1 user, load average: 0.14, 0.12, 0.09\nDisk Usage: 3%\nMemory Usage: 6.9%\nCPU Load: 0.26\nCPU Temp: 32.1°C\n═══════════════════════════════════════\n"
}
ok: [dev.lab.home] => {
"msg": "═══════════════════════════════════════\nHost: dev.lab.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:44:51 up 9 days, 7:34, 0 user, load average: 0.03, 0.08, 0.08\nDisk Usage: 48%\nMemory Usage: 71.1%\nCPU Load: 0.09\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [media.labb.home] => {
"msg": "═══════════════════════════════════════\nHost: media.labb.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:44:46 up 16 days, 3:46, 0 user, load average: 0.07, 0.03, 0.00\nDisk Usage: 24%\nMemory Usage: 72.1%\nCPU Load: 0.13\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [ali2v.truenas.home] => {
"msg": "═══════════════════════════════════════\nHost: ali2v.truenas.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:45:17 up 1 day, 9:16, 1 user, load average: 0.13, 0.05, 0.01\nDisk Usage: 1%\nMemory Usage: 34.0%\nCPU Load: 0.11\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [automate.prod.home] => {
"msg": "═══════════════════════════════════════\nHost: automate.prod.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:44:49 up 18 days, 22:39, 0 user, load average: 0.32, 0.38, 0.42\nDisk Usage: 28%\nMemory Usage: 25.8%\nCPU Load: 0.27\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [dev.prod.home] => {
"msg": "═══════════════════════════════════════\nHost: dev.prod.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:44:55 up 15 days, 9:00, 0 user, load average: 0.26, 0.29, 0.20\nDisk Usage: 75%\nMemory Usage: 63.0%\nCPU Load: 0.30\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [hp.truenas.home] => {
"msg": "═══════════════════════════════════════\nHost: hp.truenas.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 4:45PM up 20 days, 6:35, 1 user, load averages: 0.17, 0.20, 0.21\nDisk Usage: 10%\nMemory Usage: \nCPU Load: \nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [jump.point.home] => {
"msg": "═══════════════════════════════════════\nHost: jump.point.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:45:17 up 1 day, 9:16, 1 user, load average: 0.27, 0.09, 0.02\nDisk Usage: 79%\nMemory Usage: 13.5%\nCPU Load: 0.23\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [localhost] => {
"msg": "═══════════════════════════════════════\nHost: localhost\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:45:18 up 6:20, 1 user, load average: 1.77, 1.43, 1.32\nDisk Usage: 1%\nMemory Usage: 12.5%\nCPU Load: 1.89\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
PLAY RECAP *********************************************************************
ali2v.truenas.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
ali2v.xeon.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
automate.prod.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
dev.lab.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
dev.prod.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
hp.nas.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
hp.truenas.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=1
hp2.i7.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
hp3.i5.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
jump.point.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
localhost : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
media.labb.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
mimi.pc.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
orangepi.pc.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
raspi.4gb.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
raspi.8gb.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
```
---
*Généré automatiquement par Homelab Automation Dashboard*
*Date: 2025-12-16T00:45:31.488547+00:00*

View File

@ -0,0 +1,224 @@
# ✅ [Planifié] Health-check-5min
## Informations
| Propriété | Valeur |
|-----------|--------|
| **ID** | `5af40b2890cd4ae48d6d690607291c2a` |
| **Nom** | [Planifié] Health-check-5min |
| **Cible** | `all` |
| **Statut** | completed |
| **Type** | Planifié |
| **Progression** | 100% |
| **Début** | 2025-12-16T00:50:00.002572+00:00 |
| **Fin** | 2025-12-16T00:50:31.397910+00:00 |
| **Durée** | 31.4s |
## Sortie
```
Using /mnt/c/dev/git/python/homelab-automation-api-v2/ansible/ansible.cfg as config file
PLAY [Health check on target host] *********************************************
TASK [Check if host is reachable (ping)] ***************************************
ok: [hp.nas.home] => {"changed": false, "ping": "pong"}
ok: [hp2.i7.home] => {"changed": false, "ping": "pong"}
ok: [mimi.pc.home] => {"changed": false, "ping": "pong"}
ok: [ali2v.xeon.home] => {"changed": false, "ping": "pong"}
ok: [hp3.i5.home] => {"changed": false, "ping": "pong"}
ok: [dev.lab.home] => {"changed": false, "ping": "pong"}
ok: [media.labb.home] => {"changed": false, "ping": "pong"}
ok: [raspi.8gb.home] => {"changed": false, "ping": "pong"}
ok: [raspi.4gb.home] => {"changed": false, "ping": "pong"}
ok: [automate.prod.home] => {"changed": false, "ping": "pong"}
ok: [ali2v.truenas.home] => {"changed": false, "ping": "pong"}
ok: [hp.truenas.home] => {"changed": false, "ping": "pong"}
ok: [dev.prod.home] => {"changed": false, "ping": "pong"}
ok: [localhost] => {"changed": false, "ping": "pong"}
ok: [jump.point.home] => {"changed": false, "ping": "pong"}
ok: [orangepi.pc.home] => {"changed": false, "ping": "pong"}
TASK [Gather minimal facts] ****************************************************
ok: [hp.nas.home]
ok: [hp2.i7.home]
ok: [mimi.pc.home]
ok: [ali2v.xeon.home]
ok: [hp3.i5.home]
ok: [dev.lab.home]
ok: [media.labb.home]
ok: [raspi.8gb.home]
ok: [raspi.4gb.home]
ok: [ali2v.truenas.home]
ok: [automate.prod.home]
ok: [dev.prod.home]
ok: [hp.truenas.home]
ok: [jump.point.home]
ok: [orangepi.pc.home]
ok: [localhost]
TASK [Get system uptime] *******************************************************
ok: [hp.nas.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003092", "end": "2025-12-15 19:50:15.763946", "msg": "", "rc": 0, "start": "2025-12-15 19:50:15.760854", "stderr": "", "stderr_lines": [], "stdout": " 19:50:15 up 20 days, 6:41, 1 user, load average: 0.31, 0.26, 0.19", "stdout_lines": [" 19:50:15 up 20 days, 6:41, 1 user, load average: 0.31, 0.26, 0.19"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003738", "end": "2025-12-15 19:50:15.779886", "msg": "", "rc": 0, "start": "2025-12-15 19:50:15.776148", "stderr": "", "stderr_lines": [], "stdout": " 19:50:15 up 20 days, 9:00, 1 user, load average: 0.00, 0.00, 0.03", "stdout_lines": [" 19:50:15 up 20 days, 9:00, 1 user, load average: 0.00, 0.00, 0.03"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003328", "end": "2025-12-15 19:50:15.776344", "msg": "", "rc": 0, "start": "2025-12-15 19:50:15.773016", "stderr": "", "stderr_lines": [], "stdout": " 19:50:15 up 20 days, 7:01, 1 user, load average: 0.87, 0.90, 0.77", "stdout_lines": [" 19:50:15 up 20 days, 7:01, 1 user, load average: 0.87, 0.90, 0.77"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.002881", "end": "2025-12-15 19:50:15.795115", "msg": "", "rc": 0, "start": "2025-12-15 19:50:15.792234", "stderr": "", "stderr_lines": [], "stdout": " 19:50:15 up 1 day, 9:22, 1 user, load average: 0.28, 0.29, 0.33", "stdout_lines": [" 19:50:15 up 1 day, 9:22, 1 user, load average: 0.28, 0.29, 0.33"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.004211", "end": "2025-12-15 19:50:15.805725", "msg": "", "rc": 0, "start": "2025-12-15 19:50:15.801514", "stderr": "", "stderr_lines": [], "stdout": " 19:50:15 up 20 days, 8:14, 1 user, load average: 0.83, 0.65, 0.64", "stdout_lines": [" 19:50:15 up 20 days, 8:14, 1 user, load average: 0.83, 0.65, 0.64"]}
ok: [dev.lab.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.002763", "end": "2025-12-15 19:49:51.799047", "msg": "", "rc": 0, "start": "2025-12-15 19:49:51.796284", "stderr": "", "stderr_lines": [], "stdout": " 19:49:51 up 9 days, 7:39, 0 user, load average: 0.24, 0.36, 0.21", "stdout_lines": [" 19:49:51 up 9 days, 7:39, 0 user, load average: 0.24, 0.36, 0.21"]}
ok: [media.labb.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003525", "end": "2025-12-15 19:49:45.968106", "msg": "", "rc": 0, "start": "2025-12-15 19:49:45.964581", "stderr": "", "stderr_lines": [], "stdout": " 19:49:45 up 16 days, 3:51, 0 user, load average: 0.11, 0.05, 0.01", "stdout_lines": [" 19:49:45 up 16 days, 3:51, 0 user, load average: 0.11, 0.05, 0.01"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.009427", "end": "2025-12-15 19:50:16.626741", "msg": "", "rc": 0, "start": "2025-12-15 19:50:16.617314", "stderr": "", "stderr_lines": [], "stdout": " 19:50:16 up 192 days, 11:23, 1 user, load average: 0.27, 0.31, 0.28", "stdout_lines": [" 19:50:16 up 192 days, 11:23, 1 user, load average: 0.27, 0.31, 0.28"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.008549", "end": "2025-12-15 19:50:16.675496", "msg": "", "rc": 0, "start": "2025-12-15 19:50:16.666947", "stderr": "", "stderr_lines": [], "stdout": " 19:50:16 up 192 days, 11:23, 1 user, load average: 0.10, 0.10, 0.09", "stdout_lines": [" 19:50:16 up 192 days, 11:23, 1 user, load average: 0.10, 0.10, 0.09"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.004822", "end": "2025-12-15 19:50:17.052605", "msg": "", "rc": 0, "start": "2025-12-15 19:50:17.047783", "stderr": "", "stderr_lines": [], "stdout": " 19:50:17 up 1 day, 9:21, 1 user, load average: 0.10, 0.07, 0.01", "stdout_lines": [" 19:50:17 up 1 day, 9:21, 1 user, load average: 0.10, 0.07, 0.01"]}
ok: [automate.prod.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003124", "end": "2025-12-15 19:49:49.301650", "msg": "", "rc": 0, "start": "2025-12-15 19:49:49.298526", "stderr": "", "stderr_lines": [], "stdout": " 19:49:49 up 18 days, 22:44, 0 user, load average: 0.35, 0.41, 0.42", "stdout_lines": [" 19:49:49 up 18 days, 22:44, 0 user, load average: 0.35, 0.41, 0.42"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.004290", "end": "2025-12-15 16:50:17.257392", "msg": "", "rc": 0, "start": "2025-12-15 16:50:17.253102", "stderr": "", "stderr_lines": [], "stdout": " 4:50PM up 20 days, 6:40, 1 user, load averages: 0.30, 0.24, 0.22", "stdout_lines": [" 4:50PM up 20 days, 6:40, 1 user, load averages: 0.30, 0.24, 0.22"]}
ok: [dev.prod.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.005445", "end": "2025-12-15 19:49:55.286867", "msg": "", "rc": 0, "start": "2025-12-15 19:49:55.281422", "stderr": "", "stderr_lines": [], "stdout": " 19:49:55 up 15 days, 9:05, 0 user, load average: 0.19, 0.22, 0.18", "stdout_lines": [" 19:49:55 up 15 days, 9:05, 0 user, load average: 0.19, 0.22, 0.18"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.019654", "end": "2025-12-15 19:50:17.274231", "msg": "", "rc": 0, "start": "2025-12-15 19:50:17.254577", "stderr": "", "stderr_lines": [], "stdout": " 19:50:17 up 13 days, 9:16, 1 user, load average: 0.22, 0.12, 0.10", "stdout_lines": [" 19:50:17 up 13 days, 9:16, 1 user, load average: 0.22, 0.12, 0.10"]}
ok: [jump.point.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003807", "end": "2025-12-15 19:50:17.580012", "msg": "", "rc": 0, "start": "2025-12-15 19:50:17.576205", "stderr": "", "stderr_lines": [], "stdout": " 19:50:17 up 1 day, 9:21, 1 user, load average: 0.00, 0.02, 0.00", "stdout_lines": [" 19:50:17 up 1 day, 9:21, 1 user, load average: 0.00, 0.02, 0.00"]}
ok: [localhost] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.016450", "end": "2025-12-15 19:50:18.098637", "msg": "", "rc": 0, "start": "2025-12-15 19:50:18.082187", "stderr": "", "stderr_lines": [], "stdout": " 19:50:18 up 6:25, 1 user, load average: 1.24, 1.27, 1.28", "stdout_lines": [" 19:50:18 up 6:25, 1 user, load average: 1.24, 1.27, 1.28"]}
TASK [Get disk usage] **********************************************************
ok: [hp.nas.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004438", "end": "2025-12-15 19:50:18.527479", "msg": "", "rc": 0, "start": "2025-12-15 19:50:18.523041", "stderr": "", "stderr_lines": [], "stdout": "23%", "stdout_lines": ["23%"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004265", "end": "2025-12-15 19:50:18.550011", "msg": "", "rc": 0, "start": "2025-12-15 19:50:18.545746", "stderr": "", "stderr_lines": [], "stdout": "22%", "stdout_lines": ["22%"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004358", "end": "2025-12-15 19:50:18.576654", "msg": "", "rc": 0, "start": "2025-12-15 19:50:18.572296", "stderr": "", "stderr_lines": [], "stdout": "14%", "stdout_lines": ["14%"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005398", "end": "2025-12-15 19:50:18.617865", "msg": "", "rc": 0, "start": "2025-12-15 19:50:18.612467", "stderr": "", "stderr_lines": [], "stdout": "14%", "stdout_lines": ["14%"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004751", "end": "2025-12-15 19:50:18.636559", "msg": "", "rc": 0, "start": "2025-12-15 19:50:18.631808", "stderr": "", "stderr_lines": [], "stdout": "9%", "stdout_lines": ["9%"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005360", "end": "2025-12-15 19:49:54.577896", "msg": "", "rc": 0, "start": "2025-12-15 19:49:54.572536", "stderr": "", "stderr_lines": [], "stdout": "48%", "stdout_lines": ["48%"]}
ok: [media.labb.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005807", "end": "2025-12-15 19:49:48.734592", "msg": "", "rc": 0, "start": "2025-12-15 19:49:48.728785", "stderr": "", "stderr_lines": [], "stdout": "24%", "stdout_lines": ["24%"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.010849", "end": "2025-12-15 19:50:19.383668", "msg": "", "rc": 0, "start": "2025-12-15 19:50:19.372819", "stderr": "", "stderr_lines": [], "stdout": "3%", "stdout_lines": ["3%"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.011582", "end": "2025-12-15 19:50:19.489190", "msg": "", "rc": 0, "start": "2025-12-15 19:50:19.477608", "stderr": "", "stderr_lines": [], "stdout": "6%", "stdout_lines": ["6%"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005662", "end": "2025-12-15 19:50:19.815077", "msg": "", "rc": 0, "start": "2025-12-15 19:50:19.809415", "stderr": "", "stderr_lines": [], "stdout": "1%", "stdout_lines": ["1%"]}
ok: [dev.prod.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005427", "end": "2025-12-15 19:49:57.976162", "msg": "", "rc": 0, "start": "2025-12-15 19:49:57.970735", "stderr": "", "stderr_lines": [], "stdout": "75%", "stdout_lines": ["75%"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005565", "end": "2025-12-15 19:49:52.054401", "msg": "", "rc": 0, "start": "2025-12-15 19:49:52.048836", "stderr": "", "stderr_lines": [], "stdout": "28%", "stdout_lines": ["28%"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005566", "end": "2025-12-15 16:50:20.049559", "msg": "", "rc": 0, "start": "2025-12-15 16:50:20.043993", "stderr": "", "stderr_lines": [], "stdout": "10%", "stdout_lines": ["10%"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.024968", "end": "2025-12-15 19:50:20.044563", "msg": "", "rc": 0, "start": "2025-12-15 19:50:20.019595", "stderr": "", "stderr_lines": [], "stdout": "21%", "stdout_lines": ["21%"]}
ok: [jump.point.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005380", "end": "2025-12-15 19:50:20.383085", "msg": "", "rc": 0, "start": "2025-12-15 19:50:20.377705", "stderr": "", "stderr_lines": [], "stdout": "79%", "stdout_lines": ["79%"]}
ok: [localhost] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.020645", "end": "2025-12-15 19:50:20.893233", "msg": "", "rc": 0, "start": "2025-12-15 19:50:20.872588", "stderr": "", "stderr_lines": [], "stdout": "1%", "stdout_lines": ["1%"]}
TASK [Get memory usage (Linux)] ************************************************
ok: [hp.nas.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004814", "end": "2025-12-15 19:50:21.344671", "msg": "", "rc": 0, "start": "2025-12-15 19:50:21.339857", "stderr": "", "stderr_lines": [], "stdout": "80.6%", "stdout_lines": ["80.6%"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004211", "end": "2025-12-15 19:50:21.374650", "msg": "", "rc": 0, "start": "2025-12-15 19:50:21.370439", "stderr": "", "stderr_lines": [], "stdout": "21.8%", "stdout_lines": ["21.8%"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004742", "end": "2025-12-15 19:50:21.421916", "msg": "", "rc": 0, "start": "2025-12-15 19:50:21.417174", "stderr": "", "stderr_lines": [], "stdout": "48.8%", "stdout_lines": ["48.8%"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004742", "end": "2025-12-15 19:50:21.475417", "msg": "", "rc": 0, "start": "2025-12-15 19:50:21.470675", "stderr": "", "stderr_lines": [], "stdout": "8.9%", "stdout_lines": ["8.9%"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005732", "end": "2025-12-15 19:50:21.494287", "msg": "", "rc": 0, "start": "2025-12-15 19:50:21.488555", "stderr": "", "stderr_lines": [], "stdout": "59.4%", "stdout_lines": ["59.4%"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.003689", "end": "2025-12-15 19:49:57.419876", "msg": "", "rc": 0, "start": "2025-12-15 19:49:57.416187", "stderr": "", "stderr_lines": [], "stdout": "71.0%", "stdout_lines": ["71.0%"]}
ok: [media.labb.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004217", "end": "2025-12-15 19:49:51.564392", "msg": "", "rc": 0, "start": "2025-12-15 19:49:51.560175", "stderr": "", "stderr_lines": [], "stdout": "72.1%", "stdout_lines": ["72.1%"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.012078", "end": "2025-12-15 19:50:22.220220", "msg": "", "rc": 0, "start": "2025-12-15 19:50:22.208142", "stderr": "", "stderr_lines": [], "stdout": "12.6%", "stdout_lines": ["12.6%"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.011145", "end": "2025-12-15 19:50:22.305707", "msg": "", "rc": 0, "start": "2025-12-15 19:50:22.294562", "stderr": "", "stderr_lines": [], "stdout": "6.7%", "stdout_lines": ["6.7%"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005773", "end": "2025-12-15 19:50:22.646051", "msg": "", "rc": 0, "start": "2025-12-15 19:50:22.640278", "stderr": "", "stderr_lines": [], "stdout": "34.1%", "stdout_lines": ["34.1%"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004185", "end": "2025-12-15 19:49:54.871752", "msg": "", "rc": 0, "start": "2025-12-15 19:49:54.867567", "stderr": "", "stderr_lines": [], "stdout": "25.6%", "stdout_lines": ["25.6%"]}
fatal: [hp.truenas.home]: FAILED! => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005811", "end": "2025-12-15 16:50:22.877265", "msg": "non-zero return code", "rc": 2, "start": "2025-12-15 16:50:22.871454", "stderr": "cat: /proc/meminfo: No such file or directory\nawk: division by zero\n source line number 1", "stderr_lines": ["cat: /proc/meminfo: No such file or directory", "awk: division by zero", " source line number 1"], "stdout": "", "stdout_lines": []}
...ignoring
ok: [dev.prod.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.007112", "end": "2025-12-15 19:50:00.871314", "msg": "", "rc": 0, "start": "2025-12-15 19:50:00.864202", "stderr": "", "stderr_lines": [], "stdout": "55.7%", "stdout_lines": ["55.7%"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.025786", "end": "2025-12-15 19:50:22.878233", "msg": "", "rc": 0, "start": "2025-12-15 19:50:22.852447", "stderr": "", "stderr_lines": [], "stdout": "19.1%", "stdout_lines": ["19.1%"]}
ok: [jump.point.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005452", "end": "2025-12-15 19:50:23.202474", "msg": "", "rc": 0, "start": "2025-12-15 19:50:23.197022", "stderr": "", "stderr_lines": [], "stdout": "13.8%", "stdout_lines": ["13.8%"]}
ok: [localhost] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.019223", "end": "2025-12-15 19:50:23.752255", "msg": "", "rc": 0, "start": "2025-12-15 19:50:23.733032", "stderr": "", "stderr_lines": [], "stdout": "12.4%", "stdout_lines": ["12.4%"]}
TASK [Get CPU temperature (ARM/SBC)] *******************************************
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.004826", "end": "2025-12-15 19:50:24.165397", "msg": "", "rc": 0, "start": "2025-12-15 19:50:24.160571", "stderr": "", "stderr_lines": [], "stdout": "45.0°C", "stdout_lines": ["45.0°C"]}
ok: [hp.nas.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.005057", "end": "2025-12-15 19:50:24.156712", "msg": "", "rc": 0, "start": "2025-12-15 19:50:24.151655", "stderr": "", "stderr_lines": [], "stdout": "30.0°C", "stdout_lines": ["30.0°C"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.005467", "end": "2025-12-15 19:50:24.221336", "msg": "", "rc": 0, "start": "2025-12-15 19:50:24.215869", "stderr": "cat: /sys/class/thermal/thermal_zone0/temp: No data available", "stderr_lines": ["cat: /sys/class/thermal/thermal_zone0/temp: No data available"], "stdout": "0.0°C", "stdout_lines": ["0.0°C"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.006251", "end": "2025-12-15 19:50:24.264897", "msg": "", "rc": 0, "start": "2025-12-15 19:50:24.258646", "stderr": "", "stderr_lines": [], "stdout": "52.5°C", "stdout_lines": ["52.5°C"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003496", "end": "2025-12-15 19:50:24.277528", "msg": "", "rc": 0, "start": "2025-12-15 19:50:24.274032", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.002400", "end": "2025-12-15 19:50:00.206915", "msg": "", "rc": 0, "start": "2025-12-15 19:50:00.204515", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [media.labb.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.002845", "end": "2025-12-15 19:49:54.384255", "msg": "", "rc": 0, "start": "2025-12-15 19:49:54.381410", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.011930", "end": "2025-12-15 19:50:25.039370", "msg": "", "rc": 0, "start": "2025-12-15 19:50:25.027440", "stderr": "", "stderr_lines": [], "stdout": "31.6°C", "stdout_lines": ["31.6°C"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.012982", "end": "2025-12-15 19:50:25.036594", "msg": "", "rc": 0, "start": "2025-12-15 19:50:25.023612", "stderr": "", "stderr_lines": [], "stdout": "36.5°C", "stdout_lines": ["36.5°C"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003202", "end": "2025-12-15 19:50:25.438581", "msg": "", "rc": 0, "start": "2025-12-15 19:50:25.435379", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003440", "end": "2025-12-15 19:49:57.676751", "msg": "", "rc": 0, "start": "2025-12-15 19:49:57.673311", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003949", "end": "2025-12-15 16:50:25.660814", "msg": "", "rc": 0, "start": "2025-12-15 16:50:25.656865", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [dev.prod.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.002679", "end": "2025-12-15 19:50:03.661262", "msg": "", "rc": 0, "start": "2025-12-15 19:50:03.658583", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.028334", "end": "2025-12-15 19:50:25.758739", "msg": "", "rc": 0, "start": "2025-12-15 19:50:25.730405", "stderr": "", "stderr_lines": [], "stdout": "35.5°C", "stdout_lines": ["35.5°C"]}
ok: [jump.point.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003117", "end": "2025-12-15 19:50:26.107169", "msg": "", "rc": 0, "start": "2025-12-15 19:50:26.104052", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [localhost] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.012410", "end": "2025-12-15 19:50:26.554603", "msg": "", "rc": 0, "start": "2025-12-15 19:50:26.542193", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
TASK [Get CPU load] ************************************************************
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004150", "end": "2025-12-15 19:50:26.943521", "msg": "", "rc": 0, "start": "2025-12-15 19:50:26.939371", "stderr": "", "stderr_lines": [], "stdout": "0.39", "stdout_lines": ["0.39"]}
ok: [hp.nas.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004358", "end": "2025-12-15 19:50:26.961230", "msg": "", "rc": 0, "start": "2025-12-15 19:50:26.956872", "stderr": "", "stderr_lines": [], "stdout": "0.39", "stdout_lines": ["0.39"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004699", "end": "2025-12-15 19:50:27.024659", "msg": "", "rc": 0, "start": "2025-12-15 19:50:27.019960", "stderr": "", "stderr_lines": [], "stdout": "0.82", "stdout_lines": ["0.82"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005614", "end": "2025-12-15 19:50:27.061012", "msg": "", "rc": 0, "start": "2025-12-15 19:50:27.055398", "stderr": "", "stderr_lines": [], "stdout": "0.78", "stdout_lines": ["0.78"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005359", "end": "2025-12-15 19:50:27.072921", "msg": "", "rc": 0, "start": "2025-12-15 19:50:27.067562", "stderr": "", "stderr_lines": [], "stdout": "0.00", "stdout_lines": ["0.00"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004247", "end": "2025-12-15 19:50:03.053020", "msg": "", "rc": 0, "start": "2025-12-15 19:50:03.048773", "stderr": "", "stderr_lines": [], "stdout": "0.19", "stdout_lines": ["0.19"]}
ok: [media.labb.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005126", "end": "2025-12-15 19:49:57.196865", "msg": "", "rc": 0, "start": "2025-12-15 19:49:57.191739", "stderr": "", "stderr_lines": [], "stdout": "0.10", "stdout_lines": ["0.10"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.011114", "end": "2025-12-15 19:50:27.833334", "msg": "", "rc": 0, "start": "2025-12-15 19:50:27.822220", "stderr": "", "stderr_lines": [], "stdout": "0.29", "stdout_lines": ["0.29"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.010058", "end": "2025-12-15 19:50:27.931107", "msg": "", "rc": 0, "start": "2025-12-15 19:50:27.921049", "stderr": "", "stderr_lines": [], "stdout": "0.16", "stdout_lines": ["0.16"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005960", "end": "2025-12-15 19:50:28.304585", "msg": "", "rc": 0, "start": "2025-12-15 19:50:28.298625", "stderr": "", "stderr_lines": [], "stdout": "0.16", "stdout_lines": ["0.16"]}
ok: [dev.prod.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004431", "end": "2025-12-15 19:50:06.471306", "msg": "", "rc": 0, "start": "2025-12-15 19:50:06.466875", "stderr": "", "stderr_lines": [], "stdout": "0.16", "stdout_lines": ["0.16"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.006179", "end": "2025-12-15 16:50:28.504079", "msg": "", "rc": 0, "start": "2025-12-15 16:50:28.497900", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}
ok: [automate.prod.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005147", "end": "2025-12-15 19:50:00.581239", "msg": "", "rc": 0, "start": "2025-12-15 19:50:00.576092", "stderr": "", "stderr_lines": [], "stdout": "0.85", "stdout_lines": ["0.85"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.024329", "end": "2025-12-15 19:50:28.481875", "msg": "", "rc": 0, "start": "2025-12-15 19:50:28.457546", "stderr": "", "stderr_lines": [], "stdout": "0.33", "stdout_lines": ["0.33"]}
ok: [jump.point.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005321", "end": "2025-12-15 19:50:28.864546", "msg": "", "rc": 0, "start": "2025-12-15 19:50:28.859225", "stderr": "", "stderr_lines": [], "stdout": "0.00", "stdout_lines": ["0.00"]}
ok: [localhost] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.017766", "end": "2025-12-15 19:50:29.417810", "msg": "", "rc": 0, "start": "2025-12-15 19:50:29.400044", "stderr": "", "stderr_lines": [], "stdout": "1.76", "stdout_lines": ["1.76"]}
TASK [Display health status] ***************************************************
ok: [ali2v.xeon.home] => {
"msg": "═══════════════════════════════════════\nHost: ali2v.xeon.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:50:15 up 1 day, 9:22, 1 user, load average: 0.28, 0.29, 0.33\nDisk Usage: 22%\nMemory Usage: 21.8%\nCPU Load: 0.39\nCPU Temp: 45.0°C\n═══════════════════════════════════════\n"
}
ok: [hp.nas.home] => {
"msg": "═══════════════════════════════════════\nHost: hp.nas.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:50:15 up 20 days, 6:41, 1 user, load average: 0.31, 0.26, 0.19\nDisk Usage: 23%\nMemory Usage: 80.6%\nCPU Load: 0.39\nCPU Temp: 30.0°C\n═══════════════════════════════════════\n"
}
ok: [hp2.i7.home] => {
"msg": "═══════════════════════════════════════\nHost: hp2.i7.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:50:15 up 20 days, 7:01, 1 user, load average: 0.87, 0.90, 0.77\nDisk Usage: 14%\nMemory Usage: 48.8%\nCPU Load: 0.82\nCPU Temp: 0.0°C\n═══════════════════════════════════════\n"
}
ok: [hp3.i5.home] => {
"msg": "═══════════════════════════════════════\nHost: hp3.i5.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:50:15 up 20 days, 8:14, 1 user, load average: 0.83, 0.65, 0.64\nDisk Usage: 14%\nMemory Usage: 59.4%\nCPU Load: 0.78\nCPU Temp: 52.5°C\n═══════════════════════════════════════\n"
}
ok: [mimi.pc.home] => {
"msg": "═══════════════════════════════════════\nHost: mimi.pc.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:50:15 up 20 days, 9:00, 1 user, load average: 0.00, 0.00, 0.03\nDisk Usage: 9%\nMemory Usage: 8.9%\nCPU Load: 0.00\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [orangepi.pc.home] => {
"msg": "═══════════════════════════════════════\nHost: orangepi.pc.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:50:17 up 13 days, 9:16, 1 user, load average: 0.22, 0.12, 0.10\nDisk Usage: 21%\nMemory Usage: 19.1%\nCPU Load: 0.33\nCPU Temp: 35.5°C\n═══════════════════════════════════════\n"
}
ok: [raspi.4gb.home] => {
"msg": "═══════════════════════════════════════\nHost: raspi.4gb.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:50:16 up 192 days, 11:23, 1 user, load average: 0.27, 0.31, 0.28\nDisk Usage: 6%\nMemory Usage: 12.6%\nCPU Load: 0.29\nCPU Temp: 36.5°C\n═══════════════════════════════════════\n"
}
ok: [raspi.8gb.home] => {
"msg": "═══════════════════════════════════════\nHost: raspi.8gb.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:50:16 up 192 days, 11:23, 1 user, load average: 0.10, 0.10, 0.09\nDisk Usage: 3%\nMemory Usage: 6.7%\nCPU Load: 0.16\nCPU Temp: 31.6°C\n═══════════════════════════════════════\n"
}
ok: [dev.lab.home] => {
"msg": "═══════════════════════════════════════\nHost: dev.lab.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:49:51 up 9 days, 7:39, 0 user, load average: 0.24, 0.36, 0.21\nDisk Usage: 48%\nMemory Usage: 71.0%\nCPU Load: 0.19\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [media.labb.home] => {
"msg": "═══════════════════════════════════════\nHost: media.labb.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:49:45 up 16 days, 3:51, 0 user, load average: 0.11, 0.05, 0.01\nDisk Usage: 24%\nMemory Usage: 72.1%\nCPU Load: 0.10\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [ali2v.truenas.home] => {
"msg": "═══════════════════════════════════════\nHost: ali2v.truenas.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:50:17 up 1 day, 9:21, 1 user, load average: 0.10, 0.07, 0.01\nDisk Usage: 1%\nMemory Usage: 34.1%\nCPU Load: 0.16\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [automate.prod.home] => {
"msg": "═══════════════════════════════════════\nHost: automate.prod.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:49:49 up 18 days, 22:44, 0 user, load average: 0.35, 0.41, 0.42\nDisk Usage: 28%\nMemory Usage: 25.6%\nCPU Load: 0.85\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [dev.prod.home] => {
"msg": "═══════════════════════════════════════\nHost: dev.prod.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:49:55 up 15 days, 9:05, 0 user, load average: 0.19, 0.22, 0.18\nDisk Usage: 75%\nMemory Usage: 55.7%\nCPU Load: 0.16\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [hp.truenas.home] => {
"msg": "═══════════════════════════════════════\nHost: hp.truenas.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 4:50PM up 20 days, 6:40, 1 user, load averages: 0.30, 0.24, 0.22\nDisk Usage: 10%\nMemory Usage: \nCPU Load: \nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [jump.point.home] => {
"msg": "═══════════════════════════════════════\nHost: jump.point.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:50:17 up 1 day, 9:21, 1 user, load average: 0.00, 0.02, 0.00\nDisk Usage: 79%\nMemory Usage: 13.8%\nCPU Load: 0.00\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [localhost] => {
"msg": "═══════════════════════════════════════\nHost: localhost\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:50:18 up 6:25, 1 user, load average: 1.24, 1.27, 1.28\nDisk Usage: 1%\nMemory Usage: 12.4%\nCPU Load: 1.76\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
PLAY RECAP *********************************************************************
ali2v.truenas.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
ali2v.xeon.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
automate.prod.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
dev.lab.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
dev.prod.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
hp.nas.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
hp.truenas.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=1
hp2.i7.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
hp3.i5.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
jump.point.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
localhost : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
media.labb.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
mimi.pc.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
orangepi.pc.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
raspi.4gb.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
raspi.8gb.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
```
---
*Généré automatiquement par Homelab Automation Dashboard*
*Date: 2025-12-16T00:50:31.473778+00:00*

View File

@ -0,0 +1,224 @@
# ✅ [Planifié] Health-check-5min
## Informations
| Propriété | Valeur |
|-----------|--------|
| **ID** | `dc79e9f01624477e963714f52197d49e` |
| **Nom** | [Planifié] Health-check-5min |
| **Cible** | `all` |
| **Statut** | completed |
| **Type** | Planifié |
| **Progression** | 100% |
| **Début** | 2025-12-16T00:55:00.003017+00:00 |
| **Fin** | 2025-12-16T00:55:31.764800+00:00 |
| **Durée** | 31.8s |
## Sortie
```
Using /mnt/c/dev/git/python/homelab-automation-api-v2/ansible/ansible.cfg as config file
PLAY [Health check on target host] *********************************************
TASK [Check if host is reachable (ping)] ***************************************
ok: [hp.nas.home] => {"changed": false, "ping": "pong"}
ok: [hp2.i7.home] => {"changed": false, "ping": "pong"}
ok: [mimi.pc.home] => {"changed": false, "ping": "pong"}
ok: [hp3.i5.home] => {"changed": false, "ping": "pong"}
ok: [ali2v.xeon.home] => {"changed": false, "ping": "pong"}
ok: [dev.lab.home] => {"changed": false, "ping": "pong"}
ok: [media.labb.home] => {"changed": false, "ping": "pong"}
ok: [raspi.8gb.home] => {"changed": false, "ping": "pong"}
ok: [raspi.4gb.home] => {"changed": false, "ping": "pong"}
ok: [automate.prod.home] => {"changed": false, "ping": "pong"}
ok: [ali2v.truenas.home] => {"changed": false, "ping": "pong"}
ok: [hp.truenas.home] => {"changed": false, "ping": "pong"}
ok: [dev.prod.home] => {"changed": false, "ping": "pong"}
ok: [localhost] => {"changed": false, "ping": "pong"}
ok: [jump.point.home] => {"changed": false, "ping": "pong"}
ok: [orangepi.pc.home] => {"changed": false, "ping": "pong"}
TASK [Gather minimal facts] ****************************************************
ok: [hp.nas.home]
ok: [hp2.i7.home]
ok: [ali2v.xeon.home]
ok: [mimi.pc.home]
ok: [hp3.i5.home]
ok: [dev.lab.home]
ok: [media.labb.home]
ok: [raspi.8gb.home]
ok: [raspi.4gb.home]
ok: [ali2v.truenas.home]
ok: [automate.prod.home]
ok: [dev.prod.home]
ok: [hp.truenas.home]
ok: [jump.point.home]
ok: [orangepi.pc.home]
ok: [localhost]
TASK [Get system uptime] *******************************************************
ok: [hp.nas.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003093", "end": "2025-12-15 19:55:16.044053", "msg": "", "rc": 0, "start": "2025-12-15 19:55:16.040960", "stderr": "", "stderr_lines": [], "stdout": " 19:55:16 up 20 days, 6:46, 1 user, load average: 0.27, 0.28, 0.21", "stdout_lines": [" 19:55:16 up 20 days, 6:46, 1 user, load average: 0.27, 0.28, 0.21"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003227", "end": "2025-12-15 19:55:16.071981", "msg": "", "rc": 0, "start": "2025-12-15 19:55:16.068754", "stderr": "", "stderr_lines": [], "stdout": " 19:55:16 up 20 days, 7:06, 1 user, load average: 0.63, 0.78, 0.75", "stdout_lines": [" 19:55:16 up 20 days, 7:06, 1 user, load average: 0.63, 0.78, 0.75"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003891", "end": "2025-12-15 19:55:16.076467", "msg": "", "rc": 0, "start": "2025-12-15 19:55:16.072576", "stderr": "", "stderr_lines": [], "stdout": " 19:55:16 up 20 days, 9:05, 1 user, load average: 0.01, 0.01, 0.01", "stdout_lines": [" 19:55:16 up 20 days, 9:05, 1 user, load average: 0.01, 0.01, 0.01"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003040", "end": "2025-12-15 19:55:16.095096", "msg": "", "rc": 0, "start": "2025-12-15 19:55:16.092056", "stderr": "", "stderr_lines": [], "stdout": " 19:55:16 up 1 day, 9:27, 1 user, load average: 0.11, 0.18, 0.27", "stdout_lines": [" 19:55:16 up 1 day, 9:27, 1 user, load average: 0.11, 0.18, 0.27"]}
ok: [dev.lab.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.002866", "end": "2025-12-15 19:54:52.078809", "msg": "", "rc": 0, "start": "2025-12-15 19:54:52.075943", "stderr": "", "stderr_lines": [], "stdout": " 19:54:52 up 9 days, 7:44, 0 user, load average: 0.04, 0.14, 0.15", "stdout_lines": [" 19:54:52 up 9 days, 7:44, 0 user, load average: 0.04, 0.14, 0.15"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.008665", "end": "2025-12-15 19:55:16.888537", "msg": "", "rc": 0, "start": "2025-12-15 19:55:16.879872", "stderr": "", "stderr_lines": [], "stdout": " 19:55:16 up 192 days, 11:28, 1 user, load average: 0.04, 0.08, 0.08", "stdout_lines": [" 19:55:16 up 192 days, 11:28, 1 user, load average: 0.04, 0.08, 0.08"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.009353", "end": "2025-12-15 19:55:16.920389", "msg": "", "rc": 0, "start": "2025-12-15 19:55:16.911036", "stderr": "", "stderr_lines": [], "stdout": " 19:55:16 up 192 days, 11:28, 1 user, load average: 0.23, 0.31, 0.28", "stdout_lines": [" 19:55:16 up 192 days, 11:28, 1 user, load average: 0.23, 0.31, 0.28"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:01.006924", "end": "2025-12-15 19:55:17.116378", "msg": "", "rc": 0, "start": "2025-12-15 19:55:16.109454", "stderr": "", "stderr_lines": [], "stdout": " 19:55:16 up 20 days, 8:19, 1 user, load average: 0.74, 0.58, 0.61", "stdout_lines": [" 19:55:16 up 20 days, 8:19, 1 user, load average: 0.74, 0.58, 0.61"]}
ok: [media.labb.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003680", "end": "2025-12-15 19:54:46.793430", "msg": "", "rc": 0, "start": "2025-12-15 19:54:46.789750", "stderr": "", "stderr_lines": [], "stdout": " 19:54:46 up 16 days, 3:56, 0 user, load average: 0.08, 0.04, 0.00", "stdout_lines": [" 19:54:46 up 16 days, 3:56, 0 user, load average: 0.08, 0.04, 0.00"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.004792", "end": "2025-12-15 19:55:17.533523", "msg": "", "rc": 0, "start": "2025-12-15 19:55:17.528731", "stderr": "", "stderr_lines": [], "stdout": " 19:55:17 up 1 day, 9:26, 1 user, load average: 0.08, 0.07, 0.02", "stdout_lines": [" 19:55:17 up 1 day, 9:26, 1 user, load average: 0.08, 0.07, 0.02"]}
ok: [automate.prod.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003064", "end": "2025-12-15 19:54:49.687641", "msg": "", "rc": 0, "start": "2025-12-15 19:54:49.684577", "stderr": "", "stderr_lines": [], "stdout": " 19:54:49 up 18 days, 22:49, 0 user, load average: 0.39, 0.47, 0.45", "stdout_lines": [" 19:54:49 up 18 days, 22:49, 0 user, load average: 0.39, 0.47, 0.45"]}
ok: [dev.prod.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003324", "end": "2025-12-15 19:54:55.722421", "msg": "", "rc": 0, "start": "2025-12-15 19:54:55.719097", "stderr": "", "stderr_lines": [], "stdout": " 19:54:55 up 15 days, 9:10, 0 user, load average: 0.16, 0.23, 0.19", "stdout_lines": [" 19:54:55 up 15 days, 9:10, 0 user, load average: 0.16, 0.23, 0.19"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.019520", "end": "2025-12-15 19:55:17.667355", "msg": "", "rc": 0, "start": "2025-12-15 19:55:17.647835", "stderr": "", "stderr_lines": [], "stdout": " 19:55:17 up 13 days, 9:21, 1 user, load average: 0.21, 0.11, 0.09", "stdout_lines": [" 19:55:17 up 13 days, 9:21, 1 user, load average: 0.21, 0.11, 0.09"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.004146", "end": "2025-12-15 16:55:17.934779", "msg": "", "rc": 0, "start": "2025-12-15 16:55:17.930633", "stderr": "", "stderr_lines": [], "stdout": " 4:55PM up 20 days, 6:45, 1 user, load averages: 0.39, 0.29, 0.24", "stdout_lines": [" 4:55PM up 20 days, 6:45, 1 user, load averages: 0.39, 0.29, 0.24"]}
ok: [jump.point.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003734", "end": "2025-12-15 19:55:18.108077", "msg": "", "rc": 0, "start": "2025-12-15 19:55:18.104343", "stderr": "", "stderr_lines": [], "stdout": " 19:55:18 up 1 day, 9:26, 1 user, load average: 0.04, 0.05, 0.01", "stdout_lines": [" 19:55:18 up 1 day, 9:26, 1 user, load average: 0.04, 0.05, 0.01"]}
ok: [localhost] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.010151", "end": "2025-12-15 19:55:18.599930", "msg": "", "rc": 0, "start": "2025-12-15 19:55:18.589779", "stderr": "", "stderr_lines": [], "stdout": " 19:55:18 up 6:30, 1 user, load average: 1.40, 1.27, 1.27", "stdout_lines": [" 19:55:18 up 6:30, 1 user, load average: 1.40, 1.27, 1.27"]}
TASK [Get disk usage] **********************************************************
ok: [hp.nas.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004349", "end": "2025-12-15 19:55:19.018111", "msg": "", "rc": 0, "start": "2025-12-15 19:55:19.013762", "stderr": "", "stderr_lines": [], "stdout": "23%", "stdout_lines": ["23%"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004259", "end": "2025-12-15 19:55:19.017936", "msg": "", "rc": 0, "start": "2025-12-15 19:55:19.013677", "stderr": "", "stderr_lines": [], "stdout": "22%", "stdout_lines": ["22%"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004714", "end": "2025-12-15 19:55:19.064228", "msg": "", "rc": 0, "start": "2025-12-15 19:55:19.059514", "stderr": "", "stderr_lines": [], "stdout": "14%", "stdout_lines": ["14%"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004821", "end": "2025-12-15 19:55:19.095694", "msg": "", "rc": 0, "start": "2025-12-15 19:55:19.090873", "stderr": "", "stderr_lines": [], "stdout": "9%", "stdout_lines": ["9%"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005744", "end": "2025-12-15 19:55:19.114355", "msg": "", "rc": 0, "start": "2025-12-15 19:55:19.108611", "stderr": "", "stderr_lines": [], "stdout": "14%", "stdout_lines": ["14%"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005063", "end": "2025-12-15 19:54:55.118940", "msg": "", "rc": 0, "start": "2025-12-15 19:54:55.113877", "stderr": "", "stderr_lines": [], "stdout": "48%", "stdout_lines": ["48%"]}
ok: [media.labb.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005695", "end": "2025-12-15 19:54:49.268255", "msg": "", "rc": 0, "start": "2025-12-15 19:54:49.262560", "stderr": "", "stderr_lines": [], "stdout": "24%", "stdout_lines": ["24%"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.011539", "end": "2025-12-15 19:55:19.915240", "msg": "", "rc": 0, "start": "2025-12-15 19:55:19.903701", "stderr": "", "stderr_lines": [], "stdout": "6%", "stdout_lines": ["6%"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.010694", "end": "2025-12-15 19:55:19.999432", "msg": "", "rc": 0, "start": "2025-12-15 19:55:19.988738", "stderr": "", "stderr_lines": [], "stdout": "3%", "stdout_lines": ["3%"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005756", "end": "2025-12-15 19:55:20.338005", "msg": "", "rc": 0, "start": "2025-12-15 19:55:20.332249", "stderr": "", "stderr_lines": [], "stdout": "1%", "stdout_lines": ["1%"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005417", "end": "2025-12-15 19:54:52.566815", "msg": "", "rc": 0, "start": "2025-12-15 19:54:52.561398", "stderr": "", "stderr_lines": [], "stdout": "28%", "stdout_lines": ["28%"]}
ok: [dev.prod.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004557", "end": "2025-12-15 19:54:58.537615", "msg": "", "rc": 0, "start": "2025-12-15 19:54:58.533058", "stderr": "", "stderr_lines": [], "stdout": "75%", "stdout_lines": ["75%"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005503", "end": "2025-12-15 16:55:20.558627", "msg": "", "rc": 0, "start": "2025-12-15 16:55:20.553124", "stderr": "", "stderr_lines": [], "stdout": "10%", "stdout_lines": ["10%"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.025468", "end": "2025-12-15 19:55:20.587735", "msg": "", "rc": 0, "start": "2025-12-15 19:55:20.562267", "stderr": "", "stderr_lines": [], "stdout": "21%", "stdout_lines": ["21%"]}
ok: [jump.point.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005326", "end": "2025-12-15 19:55:20.908127", "msg": "", "rc": 0, "start": "2025-12-15 19:55:20.902801", "stderr": "", "stderr_lines": [], "stdout": "79%", "stdout_lines": ["79%"]}
ok: [localhost] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.022547", "end": "2025-12-15 19:55:21.494387", "msg": "", "rc": 0, "start": "2025-12-15 19:55:21.471840", "stderr": "", "stderr_lines": [], "stdout": "1%", "stdout_lines": ["1%"]}
TASK [Get memory usage (Linux)] ************************************************
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004178", "end": "2025-12-15 19:55:21.879141", "msg": "", "rc": 0, "start": "2025-12-15 19:55:21.874963", "stderr": "", "stderr_lines": [], "stdout": "21.8%", "stdout_lines": ["21.8%"]}
ok: [hp.nas.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004394", "end": "2025-12-15 19:55:21.879806", "msg": "", "rc": 0, "start": "2025-12-15 19:55:21.875412", "stderr": "", "stderr_lines": [], "stdout": "80.7%", "stdout_lines": ["80.7%"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004861", "end": "2025-12-15 19:55:21.915144", "msg": "", "rc": 0, "start": "2025-12-15 19:55:21.910283", "stderr": "", "stderr_lines": [], "stdout": "48.8%", "stdout_lines": ["48.8%"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005383", "end": "2025-12-15 19:55:21.966941", "msg": "", "rc": 0, "start": "2025-12-15 19:55:21.961558", "stderr": "", "stderr_lines": [], "stdout": "59.4%", "stdout_lines": ["59.4%"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005316", "end": "2025-12-15 19:55:21.975150", "msg": "", "rc": 0, "start": "2025-12-15 19:55:21.969834", "stderr": "", "stderr_lines": [], "stdout": "8.9%", "stdout_lines": ["8.9%"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004343", "end": "2025-12-15 19:54:57.916038", "msg": "", "rc": 0, "start": "2025-12-15 19:54:57.911695", "stderr": "", "stderr_lines": [], "stdout": "71.0%", "stdout_lines": ["71.0%"]}
ok: [media.labb.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004876", "end": "2025-12-15 19:54:52.054637", "msg": "", "rc": 0, "start": "2025-12-15 19:54:52.049761", "stderr": "", "stderr_lines": [], "stdout": "72.1%", "stdout_lines": ["72.1%"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.010787", "end": "2025-12-15 19:55:22.735492", "msg": "", "rc": 0, "start": "2025-12-15 19:55:22.724705", "stderr": "", "stderr_lines": [], "stdout": "6.9%", "stdout_lines": ["6.9%"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.011981", "end": "2025-12-15 19:55:22.753980", "msg": "", "rc": 0, "start": "2025-12-15 19:55:22.741999", "stderr": "", "stderr_lines": [], "stdout": "12.8%", "stdout_lines": ["12.8%"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005806", "end": "2025-12-15 19:55:23.176396", "msg": "", "rc": 0, "start": "2025-12-15 19:55:23.170590", "stderr": "", "stderr_lines": [], "stdout": "34.2%", "stdout_lines": ["34.2%"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004343", "end": "2025-12-15 19:54:55.390043", "msg": "", "rc": 0, "start": "2025-12-15 19:54:55.385700", "stderr": "", "stderr_lines": [], "stdout": "26.0%", "stdout_lines": ["26.0%"]}
fatal: [hp.truenas.home]: FAILED! => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005258", "end": "2025-12-15 16:55:23.376937", "msg": "non-zero return code", "rc": 2, "start": "2025-12-15 16:55:23.371679", "stderr": "cat: /proc/meminfo: No such file or directory\nawk: division by zero\n source line number 1", "stderr_lines": ["cat: /proc/meminfo: No such file or directory", "awk: division by zero", " source line number 1"], "stdout": "", "stdout_lines": []}
...ignoring
ok: [dev.prod.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.003922", "end": "2025-12-15 19:55:01.397642", "msg": "", "rc": 0, "start": "2025-12-15 19:55:01.393720", "stderr": "", "stderr_lines": [], "stdout": "55.8%", "stdout_lines": ["55.8%"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.025661", "end": "2025-12-15 19:55:23.393353", "msg": "", "rc": 0, "start": "2025-12-15 19:55:23.367692", "stderr": "", "stderr_lines": [], "stdout": "19.3%", "stdout_lines": ["19.3%"]}
ok: [jump.point.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005344", "end": "2025-12-15 19:55:23.748834", "msg": "", "rc": 0, "start": "2025-12-15 19:55:23.743490", "stderr": "", "stderr_lines": [], "stdout": "13.6%", "stdout_lines": ["13.6%"]}
ok: [localhost] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.013314", "end": "2025-12-15 19:55:24.289744", "msg": "", "rc": 0, "start": "2025-12-15 19:55:24.276430", "stderr": "", "stderr_lines": [], "stdout": "12.4%", "stdout_lines": ["12.4%"]}
TASK [Get CPU temperature (ARM/SBC)] *******************************************
ok: [hp.nas.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.005105", "end": "2025-12-15 19:55:24.634024", "msg": "", "rc": 0, "start": "2025-12-15 19:55:24.628919", "stderr": "", "stderr_lines": [], "stdout": "30.0°C", "stdout_lines": ["30.0°C"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.004950", "end": "2025-12-15 19:55:24.681784", "msg": "", "rc": 0, "start": "2025-12-15 19:55:24.676834", "stderr": "", "stderr_lines": [], "stdout": "45.0°C", "stdout_lines": ["45.0°C"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.006039", "end": "2025-12-15 19:55:24.718436", "msg": "", "rc": 0, "start": "2025-12-15 19:55:24.712397", "stderr": "cat: /sys/class/thermal/thermal_zone0/temp: No data available", "stderr_lines": ["cat: /sys/class/thermal/thermal_zone0/temp: No data available"], "stdout": "0.0°C", "stdout_lines": ["0.0°C"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.006757", "end": "2025-12-15 19:55:24.761381", "msg": "", "rc": 0, "start": "2025-12-15 19:55:24.754624", "stderr": "", "stderr_lines": [], "stdout": "53.0°C", "stdout_lines": ["53.0°C"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003264", "end": "2025-12-15 19:55:24.772054", "msg": "", "rc": 0, "start": "2025-12-15 19:55:24.768790", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.002703", "end": "2025-12-15 19:55:00.711797", "msg": "", "rc": 0, "start": "2025-12-15 19:55:00.709094", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [media.labb.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003137", "end": "2025-12-15 19:54:54.854679", "msg": "", "rc": 0, "start": "2025-12-15 19:54:54.851542", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.011766", "end": "2025-12-15 19:55:25.628653", "msg": "", "rc": 0, "start": "2025-12-15 19:55:25.616887", "stderr": "", "stderr_lines": [], "stdout": "32.1°C", "stdout_lines": ["32.1°C"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.013020", "end": "2025-12-15 19:55:25.624598", "msg": "", "rc": 0, "start": "2025-12-15 19:55:25.611578", "stderr": "", "stderr_lines": [], "stdout": "34.6°C", "stdout_lines": ["34.6°C"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003247", "end": "2025-12-15 19:55:25.964589", "msg": "", "rc": 0, "start": "2025-12-15 19:55:25.961342", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003045", "end": "2025-12-15 19:54:58.190935", "msg": "", "rc": 0, "start": "2025-12-15 19:54:58.187890", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.004232", "end": "2025-12-15 16:55:26.232626", "msg": "", "rc": 0, "start": "2025-12-15 16:55:26.228394", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [dev.prod.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003513", "end": "2025-12-15 19:55:04.287974", "msg": "", "rc": 0, "start": "2025-12-15 19:55:04.284461", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.028526", "end": "2025-12-15 19:55:26.261350", "msg": "", "rc": 0, "start": "2025-12-15 19:55:26.232824", "stderr": "", "stderr_lines": [], "stdout": "35.4°C", "stdout_lines": ["35.4°C"]}
ok: [jump.point.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.002946", "end": "2025-12-15 19:55:26.526644", "msg": "", "rc": 0, "start": "2025-12-15 19:55:26.523698", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [localhost] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003971", "end": "2025-12-15 19:55:27.078057", "msg": "", "rc": 0, "start": "2025-12-15 19:55:27.074086", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
TASK [Get CPU load] ************************************************************
ok: [hp.nas.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004284", "end": "2025-12-15 19:55:27.421873", "msg": "", "rc": 0, "start": "2025-12-15 19:55:27.417589", "stderr": "", "stderr_lines": [], "stdout": "0.29", "stdout_lines": ["0.29"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004130", "end": "2025-12-15 19:55:27.439819", "msg": "", "rc": 0, "start": "2025-12-15 19:55:27.435689", "stderr": "", "stderr_lines": [], "stdout": "0.09", "stdout_lines": ["0.09"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004769", "end": "2025-12-15 19:55:27.456755", "msg": "", "rc": 0, "start": "2025-12-15 19:55:27.451986", "stderr": "", "stderr_lines": [], "stdout": "0.53", "stdout_lines": ["0.53"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005387", "end": "2025-12-15 19:55:27.518970", "msg": "", "rc": 0, "start": "2025-12-15 19:55:27.513583", "stderr": "", "stderr_lines": [], "stdout": "0.01", "stdout_lines": ["0.01"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005654", "end": "2025-12-15 19:55:27.537005", "msg": "", "rc": 0, "start": "2025-12-15 19:55:27.531351", "stderr": "", "stderr_lines": [], "stdout": "0.78", "stdout_lines": ["0.78"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004281", "end": "2025-12-15 19:55:03.515735", "msg": "", "rc": 0, "start": "2025-12-15 19:55:03.511454", "stderr": "", "stderr_lines": [], "stdout": "0.03", "stdout_lines": ["0.03"]}
ok: [media.labb.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005056", "end": "2025-12-15 19:54:57.649763", "msg": "", "rc": 0, "start": "2025-12-15 19:54:57.644707", "stderr": "", "stderr_lines": [], "stdout": "0.06", "stdout_lines": ["0.06"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.009988", "end": "2025-12-15 19:55:28.326880", "msg": "", "rc": 0, "start": "2025-12-15 19:55:28.316892", "stderr": "", "stderr_lines": [], "stdout": "0.03", "stdout_lines": ["0.03"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.011142", "end": "2025-12-15 19:55:28.333737", "msg": "", "rc": 0, "start": "2025-12-15 19:55:28.322595", "stderr": "", "stderr_lines": [], "stdout": "0.42", "stdout_lines": ["0.42"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005983", "end": "2025-12-15 19:55:28.762692", "msg": "", "rc": 0, "start": "2025-12-15 19:55:28.756709", "stderr": "", "stderr_lines": [], "stdout": "0.07", "stdout_lines": ["0.07"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005894", "end": "2025-12-15 19:55:00.970629", "msg": "", "rc": 0, "start": "2025-12-15 19:55:00.964735", "stderr": "", "stderr_lines": [], "stdout": "0.33", "stdout_lines": ["0.33"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.006416", "end": "2025-12-15 16:55:28.975385", "msg": "", "rc": 0, "start": "2025-12-15 16:55:28.968969", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}
ok: [dev.prod.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004657", "end": "2025-12-15 19:55:06.959512", "msg": "", "rc": 0, "start": "2025-12-15 19:55:06.954855", "stderr": "", "stderr_lines": [], "stdout": "0.22", "stdout_lines": ["0.22"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.024316", "end": "2025-12-15 19:55:28.958270", "msg": "", "rc": 0, "start": "2025-12-15 19:55:28.933954", "stderr": "", "stderr_lines": [], "stdout": "0.32", "stdout_lines": ["0.32"]}
ok: [jump.point.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005335", "end": "2025-12-15 19:55:29.313294", "msg": "", "rc": 0, "start": "2025-12-15 19:55:29.307959", "stderr": "", "stderr_lines": [], "stdout": "0.03", "stdout_lines": ["0.03"]}
ok: [localhost] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.020866", "end": "2025-12-15 19:55:29.908132", "msg": "", "rc": 0, "start": "2025-12-15 19:55:29.887266", "stderr": "", "stderr_lines": [], "stdout": "1.73", "stdout_lines": ["1.73"]}
TASK [Display health status] ***************************************************
ok: [ali2v.xeon.home] => {
"msg": "═══════════════════════════════════════\nHost: ali2v.xeon.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:55:16 up 1 day, 9:27, 1 user, load average: 0.11, 0.18, 0.27\nDisk Usage: 22%\nMemory Usage: 21.8%\nCPU Load: 0.09\nCPU Temp: 45.0°C\n═══════════════════════════════════════\n"
}
ok: [hp.nas.home] => {
"msg": "═══════════════════════════════════════\nHost: hp.nas.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:55:16 up 20 days, 6:46, 1 user, load average: 0.27, 0.28, 0.21\nDisk Usage: 23%\nMemory Usage: 80.7%\nCPU Load: 0.29\nCPU Temp: 30.0°C\n═══════════════════════════════════════\n"
}
ok: [hp2.i7.home] => {
"msg": "═══════════════════════════════════════\nHost: hp2.i7.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:55:16 up 20 days, 7:06, 1 user, load average: 0.63, 0.78, 0.75\nDisk Usage: 14%\nMemory Usage: 48.8%\nCPU Load: 0.53\nCPU Temp: 0.0°C\n═══════════════════════════════════════\n"
}
ok: [hp3.i5.home] => {
"msg": "═══════════════════════════════════════\nHost: hp3.i5.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:55:16 up 20 days, 8:19, 1 user, load average: 0.74, 0.58, 0.61\nDisk Usage: 14%\nMemory Usage: 59.4%\nCPU Load: 0.78\nCPU Temp: 53.0°C\n═══════════════════════════════════════\n"
}
ok: [mimi.pc.home] => {
"msg": "═══════════════════════════════════════\nHost: mimi.pc.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:55:16 up 20 days, 9:05, 1 user, load average: 0.01, 0.01, 0.01\nDisk Usage: 9%\nMemory Usage: 8.9%\nCPU Load: 0.01\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [orangepi.pc.home] => {
"msg": "═══════════════════════════════════════\nHost: orangepi.pc.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:55:17 up 13 days, 9:21, 1 user, load average: 0.21, 0.11, 0.09\nDisk Usage: 21%\nMemory Usage: 19.3%\nCPU Load: 0.32\nCPU Temp: 35.4°C\n═══════════════════════════════════════\n"
}
ok: [raspi.4gb.home] => {
"msg": "═══════════════════════════════════════\nHost: raspi.4gb.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:55:16 up 192 days, 11:28, 1 user, load average: 0.23, 0.31, 0.28\nDisk Usage: 6%\nMemory Usage: 12.8%\nCPU Load: 0.42\nCPU Temp: 34.6°C\n═══════════════════════════════════════\n"
}
ok: [raspi.8gb.home] => {
"msg": "═══════════════════════════════════════\nHost: raspi.8gb.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:55:16 up 192 days, 11:28, 1 user, load average: 0.04, 0.08, 0.08\nDisk Usage: 3%\nMemory Usage: 6.9%\nCPU Load: 0.03\nCPU Temp: 32.1°C\n═══════════════════════════════════════\n"
}
ok: [dev.lab.home] => {
"msg": "═══════════════════════════════════════\nHost: dev.lab.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:54:52 up 9 days, 7:44, 0 user, load average: 0.04, 0.14, 0.15\nDisk Usage: 48%\nMemory Usage: 71.0%\nCPU Load: 0.03\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [media.labb.home] => {
"msg": "═══════════════════════════════════════\nHost: media.labb.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:54:46 up 16 days, 3:56, 0 user, load average: 0.08, 0.04, 0.00\nDisk Usage: 24%\nMemory Usage: 72.1%\nCPU Load: 0.06\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [ali2v.truenas.home] => {
"msg": "═══════════════════════════════════════\nHost: ali2v.truenas.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:55:17 up 1 day, 9:26, 1 user, load average: 0.08, 0.07, 0.02\nDisk Usage: 1%\nMemory Usage: 34.2%\nCPU Load: 0.07\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [automate.prod.home] => {
"msg": "═══════════════════════════════════════\nHost: automate.prod.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:54:49 up 18 days, 22:49, 0 user, load average: 0.39, 0.47, 0.45\nDisk Usage: 28%\nMemory Usage: 26.0%\nCPU Load: 0.33\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [dev.prod.home] => {
"msg": "═══════════════════════════════════════\nHost: dev.prod.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:54:55 up 15 days, 9:10, 0 user, load average: 0.16, 0.23, 0.19\nDisk Usage: 75%\nMemory Usage: 55.8%\nCPU Load: 0.22\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [hp.truenas.home] => {
"msg": "═══════════════════════════════════════\nHost: hp.truenas.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 4:55PM up 20 days, 6:45, 1 user, load averages: 0.39, 0.29, 0.24\nDisk Usage: 10%\nMemory Usage: \nCPU Load: \nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [jump.point.home] => {
"msg": "═══════════════════════════════════════\nHost: jump.point.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:55:18 up 1 day, 9:26, 1 user, load average: 0.04, 0.05, 0.01\nDisk Usage: 79%\nMemory Usage: 13.6%\nCPU Load: 0.03\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [localhost] => {
"msg": "═══════════════════════════════════════\nHost: localhost\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:55:18 up 6:30, 1 user, load average: 1.40, 1.27, 1.27\nDisk Usage: 1%\nMemory Usage: 12.4%\nCPU Load: 1.73\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
PLAY RECAP *********************************************************************
ali2v.truenas.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
ali2v.xeon.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
automate.prod.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
dev.lab.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
dev.prod.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
hp.nas.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
hp.truenas.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=1
hp2.i7.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
hp3.i5.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
jump.point.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
localhost : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
media.labb.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
mimi.pc.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
orangepi.pc.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
raspi.4gb.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
raspi.8gb.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
```
---
*Généré automatiquement par Homelab Automation Dashboard*
*Date: 2025-12-16T00:55:31.823374+00:00*

View File

@ -0,0 +1,224 @@
# ✅ [Planifié] Health-check-5min
## Informations
| Propriété | Valeur |
|-----------|--------|
| **ID** | `67f86e211bc54d2b91c889949e0d4846` |
| **Nom** | [Planifié] Health-check-5min |
| **Cible** | `all` |
| **Statut** | completed |
| **Type** | Planifié |
| **Progression** | 100% |
| **Début** | 2025-12-16T01:00:00.000539+00:00 |
| **Fin** | 2025-12-16T01:00:22.761178+00:00 |
| **Durée** | 22.8s |
## Sortie
```
Using /mnt/c/dev/git/python/homelab-automation-api-v2/ansible/ansible.cfg as config file
PLAY [Health check on target host] *********************************************
TASK [Check if host is reachable (ping)] ***************************************
ok: [hp.nas.home] => {"changed": false, "ping": "pong"}
ok: [mimi.pc.home] => {"changed": false, "ping": "pong"}
ok: [hp2.i7.home] => {"changed": false, "ping": "pong"}
ok: [hp3.i5.home] => {"changed": false, "ping": "pong"}
ok: [ali2v.xeon.home] => {"changed": false, "ping": "pong"}
ok: [dev.lab.home] => {"changed": false, "ping": "pong"}
ok: [media.labb.home] => {"changed": false, "ping": "pong"}
ok: [raspi.8gb.home] => {"changed": false, "ping": "pong"}
ok: [raspi.4gb.home] => {"changed": false, "ping": "pong"}
ok: [automate.prod.home] => {"changed": false, "ping": "pong"}
ok: [ali2v.truenas.home] => {"changed": false, "ping": "pong"}
ok: [hp.truenas.home] => {"changed": false, "ping": "pong"}
ok: [dev.prod.home] => {"changed": false, "ping": "pong"}
ok: [localhost] => {"changed": false, "ping": "pong"}
ok: [jump.point.home] => {"changed": false, "ping": "pong"}
ok: [orangepi.pc.home] => {"changed": false, "ping": "pong"}
TASK [Gather minimal facts] ****************************************************
ok: [hp.nas.home]
ok: [mimi.pc.home]
ok: [hp2.i7.home]
ok: [ali2v.xeon.home]
ok: [hp3.i5.home]
ok: [dev.lab.home]
ok: [media.labb.home]
ok: [raspi.8gb.home]
ok: [raspi.4gb.home]
ok: [ali2v.truenas.home]
ok: [automate.prod.home]
ok: [hp.truenas.home]
ok: [dev.prod.home]
ok: [jump.point.home]
ok: [localhost]
ok: [orangepi.pc.home]
TASK [Get system uptime] *******************************************************
ok: [hp.nas.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.002982", "end": "2025-12-15 20:00:11.800238", "msg": "", "rc": 0, "start": "2025-12-15 20:00:11.797256", "stderr": "", "stderr_lines": [], "stdout": " 20:00:11 up 20 days, 6:51, 1 user, load average: 0.31, 0.32, 0.25", "stdout_lines": [" 20:00:11 up 20 days, 6:51, 1 user, load average: 0.31, 0.32, 0.25"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003883", "end": "2025-12-15 20:00:11.819677", "msg": "", "rc": 0, "start": "2025-12-15 20:00:11.815794", "stderr": "", "stderr_lines": [], "stdout": " 20:00:11 up 20 days, 9:10, 1 user, load average: 0.00, 0.01, 0.00", "stdout_lines": [" 20:00:11 up 20 days, 9:10, 1 user, load average: 0.00, 0.01, 0.00"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003480", "end": "2025-12-15 20:00:11.834388", "msg": "", "rc": 0, "start": "2025-12-15 20:00:11.830908", "stderr": "", "stderr_lines": [], "stdout": " 20:00:11 up 20 days, 7:11, 1 user, load average: 0.58, 0.67, 0.71", "stdout_lines": [" 20:00:11 up 20 days, 7:11, 1 user, load average: 0.58, 0.67, 0.71"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.002944", "end": "2025-12-15 20:00:11.849861", "msg": "", "rc": 0, "start": "2025-12-15 20:00:11.846917", "stderr": "", "stderr_lines": [], "stdout": " 20:00:11 up 1 day, 9:32, 1 user, load average: 0.10, 0.17, 0.24", "stdout_lines": [" 20:00:11 up 1 day, 9:32, 1 user, load average: 0.10, 0.17, 0.24"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003997", "end": "2025-12-15 20:00:11.844496", "msg": "", "rc": 0, "start": "2025-12-15 20:00:11.840499", "stderr": "", "stderr_lines": [], "stdout": " 20:00:11 up 20 days, 8:24, 1 user, load average: 0.42, 0.59, 0.62", "stdout_lines": [" 20:00:11 up 20 days, 8:24, 1 user, load average: 0.42, 0.59, 0.62"]}
ok: [dev.lab.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.002997", "end": "2025-12-15 19:59:47.677383", "msg": "", "rc": 0, "start": "2025-12-15 19:59:47.674386", "stderr": "", "stderr_lines": [], "stdout": " 19:59:47 up 9 days, 7:49, 0 user, load average: 0.12, 0.11, 0.12", "stdout_lines": [" 19:59:47 up 9 days, 7:49, 0 user, load average: 0.12, 0.11, 0.12"]}
ok: [media.labb.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003516", "end": "2025-12-15 19:59:41.815679", "msg": "", "rc": 0, "start": "2025-12-15 19:59:41.812163", "stderr": "", "stderr_lines": [], "stdout": " 19:59:41 up 16 days, 4:01, 0 user, load average: 0.01, 0.02, 0.00", "stdout_lines": [" 19:59:41 up 16 days, 4:01, 0 user, load average: 0.01, 0.02, 0.00"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.008532", "end": "2025-12-15 20:00:12.511083", "msg": "", "rc": 0, "start": "2025-12-15 20:00:12.502551", "stderr": "", "stderr_lines": [], "stdout": " 20:00:12 up 192 days, 11:33, 1 user, load average: 0.04, 0.09, 0.08", "stdout_lines": [" 20:00:12 up 192 days, 11:33, 1 user, load average: 0.04, 0.09, 0.08"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.009391", "end": "2025-12-15 20:00:12.557064", "msg": "", "rc": 0, "start": "2025-12-15 20:00:12.547673", "stderr": "", "stderr_lines": [], "stdout": " 20:00:12 up 192 days, 11:33, 1 user, load average: 0.38, 0.35, 0.30", "stdout_lines": [" 20:00:12 up 192 days, 11:33, 1 user, load average: 0.38, 0.35, 0.30"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.004738", "end": "2025-12-15 20:00:12.782436", "msg": "", "rc": 0, "start": "2025-12-15 20:00:12.777698", "stderr": "", "stderr_lines": [], "stdout": " 20:00:12 up 1 day, 9:31, 1 user, load average: 0.20, 0.10, 0.03", "stdout_lines": [" 20:00:12 up 1 day, 9:31, 1 user, load average: 0.20, 0.10, 0.03"]}
ok: [automate.prod.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003551", "end": "2025-12-15 19:59:44.993449", "msg": "", "rc": 0, "start": "2025-12-15 19:59:44.989898", "stderr": "", "stderr_lines": [], "stdout": " 19:59:44 up 18 days, 22:54, 0 user, load average: 0.40, 0.43, 0.44", "stdout_lines": [" 19:59:44 up 18 days, 22:54, 0 user, load average: 0.40, 0.43, 0.44"]}
ok: [dev.prod.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.002827", "end": "2025-12-15 19:59:50.966006", "msg": "", "rc": 0, "start": "2025-12-15 19:59:50.963179", "stderr": "", "stderr_lines": [], "stdout": " 19:59:50 up 15 days, 9:15, 0 user, load average: 0.34, 0.35, 0.24", "stdout_lines": [" 19:59:50 up 15 days, 9:15, 0 user, load average: 0.34, 0.35, 0.24"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.004301", "end": "2025-12-15 17:00:13.038643", "msg": "", "rc": 0, "start": "2025-12-15 17:00:13.034342", "stderr": "", "stderr_lines": [], "stdout": " 5:00PM up 20 days, 6:50, 1 user, load averages: 0.11, 0.17, 0.20", "stdout_lines": [" 5:00PM up 20 days, 6:50, 1 user, load averages: 0.11, 0.17, 0.20"]}
ok: [jump.point.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003688", "end": "2025-12-15 20:00:13.208548", "msg": "", "rc": 0, "start": "2025-12-15 20:00:13.204860", "stderr": "", "stderr_lines": [], "stdout": " 20:00:13 up 1 day, 9:31, 1 user, load average: 0.00, 0.02, 0.00", "stdout_lines": [" 20:00:13 up 1 day, 9:31, 1 user, load average: 0.00, 0.02, 0.00"]}
ok: [localhost] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.004590", "end": "2025-12-15 20:00:13.496219", "msg": "", "rc": 0, "start": "2025-12-15 20:00:13.491629", "stderr": "", "stderr_lines": [], "stdout": " 20:00:13 up 6:35, 1 user, load average: 1.58, 1.29, 1.27", "stdout_lines": [" 20:00:13 up 6:35, 1 user, load average: 1.58, 1.29, 1.27"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.019287", "end": "2025-12-15 20:00:13.201465", "msg": "", "rc": 0, "start": "2025-12-15 20:00:13.182178", "stderr": "", "stderr_lines": [], "stdout": " 20:00:13 up 13 days, 9:26, 1 user, load average: 0.13, 0.13, 0.10", "stdout_lines": [" 20:00:13 up 13 days, 9:26, 1 user, load average: 0.13, 0.13, 0.10"]}
TASK [Get disk usage] **********************************************************
ok: [hp.nas.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004299", "end": "2025-12-15 20:00:13.744074", "msg": "", "rc": 0, "start": "2025-12-15 20:00:13.739775", "stderr": "", "stderr_lines": [], "stdout": "23%", "stdout_lines": ["23%"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004129", "end": "2025-12-15 20:00:13.767924", "msg": "", "rc": 0, "start": "2025-12-15 20:00:13.763795", "stderr": "", "stderr_lines": [], "stdout": "22%", "stdout_lines": ["22%"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004897", "end": "2025-12-15 20:00:13.783663", "msg": "", "rc": 0, "start": "2025-12-15 20:00:13.778766", "stderr": "", "stderr_lines": [], "stdout": "9%", "stdout_lines": ["9%"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004829", "end": "2025-12-15 20:00:13.794740", "msg": "", "rc": 0, "start": "2025-12-15 20:00:13.789911", "stderr": "", "stderr_lines": [], "stdout": "14%", "stdout_lines": ["14%"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.007295", "end": "2025-12-15 20:00:13.807286", "msg": "", "rc": 0, "start": "2025-12-15 20:00:13.799991", "stderr": "", "stderr_lines": [], "stdout": "14%", "stdout_lines": ["14%"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005019", "end": "2025-12-15 19:59:49.599590", "msg": "", "rc": 0, "start": "2025-12-15 19:59:49.594571", "stderr": "", "stderr_lines": [], "stdout": "48%", "stdout_lines": ["48%"]}
ok: [media.labb.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005510", "end": "2025-12-15 19:59:43.763278", "msg": "", "rc": 0, "start": "2025-12-15 19:59:43.757768", "stderr": "", "stderr_lines": [], "stdout": "24%", "stdout_lines": ["24%"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.010572", "end": "2025-12-15 20:00:14.500940", "msg": "", "rc": 0, "start": "2025-12-15 20:00:14.490368", "stderr": "", "stderr_lines": [], "stdout": "3%", "stdout_lines": ["3%"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.011621", "end": "2025-12-15 20:00:14.524745", "msg": "", "rc": 0, "start": "2025-12-15 20:00:14.513124", "stderr": "", "stderr_lines": [], "stdout": "6%", "stdout_lines": ["6%"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005956", "end": "2025-12-15 20:00:14.705721", "msg": "", "rc": 0, "start": "2025-12-15 20:00:14.699765", "stderr": "", "stderr_lines": [], "stdout": "1%", "stdout_lines": ["1%"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005365", "end": "2025-12-15 19:59:46.979442", "msg": "", "rc": 0, "start": "2025-12-15 19:59:46.974077", "stderr": "", "stderr_lines": [], "stdout": "28%", "stdout_lines": ["28%"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005583", "end": "2025-12-15 17:00:14.971152", "msg": "", "rc": 0, "start": "2025-12-15 17:00:14.965569", "stderr": "", "stderr_lines": [], "stdout": "10%", "stdout_lines": ["10%"]}
ok: [dev.prod.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005505", "end": "2025-12-15 19:59:52.986522", "msg": "", "rc": 0, "start": "2025-12-15 19:59:52.981017", "stderr": "", "stderr_lines": [], "stdout": "75%", "stdout_lines": ["75%"]}
ok: [jump.point.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005393", "end": "2025-12-15 20:00:15.125702", "msg": "", "rc": 0, "start": "2025-12-15 20:00:15.120309", "stderr": "", "stderr_lines": [], "stdout": "79%", "stdout_lines": ["79%"]}
ok: [localhost] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.007280", "end": "2025-12-15 20:00:15.496075", "msg": "", "rc": 0, "start": "2025-12-15 20:00:15.488795", "stderr": "", "stderr_lines": [], "stdout": "1%", "stdout_lines": ["1%"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.025369", "end": "2025-12-15 20:00:15.119869", "msg": "", "rc": 0, "start": "2025-12-15 20:00:15.094500", "stderr": "", "stderr_lines": [], "stdout": "21%", "stdout_lines": ["21%"]}
TASK [Get memory usage (Linux)] ************************************************
ok: [hp.nas.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004502", "end": "2025-12-15 20:00:15.661041", "msg": "", "rc": 0, "start": "2025-12-15 20:00:15.656539", "stderr": "", "stderr_lines": [], "stdout": "80.8%", "stdout_lines": ["80.8%"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004151", "end": "2025-12-15 20:00:15.665841", "msg": "", "rc": 0, "start": "2025-12-15 20:00:15.661690", "stderr": "", "stderr_lines": [], "stdout": "21.7%", "stdout_lines": ["21.7%"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005042", "end": "2025-12-15 20:00:15.713793", "msg": "", "rc": 0, "start": "2025-12-15 20:00:15.708751", "stderr": "", "stderr_lines": [], "stdout": "8.9%", "stdout_lines": ["8.9%"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005135", "end": "2025-12-15 20:00:15.706989", "msg": "", "rc": 0, "start": "2025-12-15 20:00:15.701854", "stderr": "", "stderr_lines": [], "stdout": "48.9%", "stdout_lines": ["48.9%"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.006888", "end": "2025-12-15 20:00:15.743633", "msg": "", "rc": 0, "start": "2025-12-15 20:00:15.736745", "stderr": "", "stderr_lines": [], "stdout": "59.5%", "stdout_lines": ["59.5%"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.003939", "end": "2025-12-15 19:59:51.534887", "msg": "", "rc": 0, "start": "2025-12-15 19:59:51.530948", "stderr": "", "stderr_lines": [], "stdout": "71.2%", "stdout_lines": ["71.2%"]}
ok: [media.labb.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004861", "end": "2025-12-15 19:59:45.711496", "msg": "", "rc": 0, "start": "2025-12-15 19:59:45.706635", "stderr": "", "stderr_lines": [], "stdout": "72.2%", "stdout_lines": ["72.2%"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.012067", "end": "2025-12-15 20:00:16.371119", "msg": "", "rc": 0, "start": "2025-12-15 20:00:16.359052", "stderr": "", "stderr_lines": [], "stdout": "12.3%", "stdout_lines": ["12.3%"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.011078", "end": "2025-12-15 20:00:16.378598", "msg": "", "rc": 0, "start": "2025-12-15 20:00:16.367520", "stderr": "", "stderr_lines": [], "stdout": "6.8%", "stdout_lines": ["6.8%"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005747", "end": "2025-12-15 20:00:16.609565", "msg": "", "rc": 0, "start": "2025-12-15 20:00:16.603818", "stderr": "", "stderr_lines": [], "stdout": "34.3%", "stdout_lines": ["34.3%"]}
fatal: [hp.truenas.home]: FAILED! => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005905", "end": "2025-12-15 17:00:16.852230", "msg": "non-zero return code", "rc": 2, "start": "2025-12-15 17:00:16.846325", "stderr": "cat: /proc/meminfo: No such file or directory\nawk: division by zero\n source line number 1", "stderr_lines": ["cat: /proc/meminfo: No such file or directory", "awk: division by zero", " source line number 1"], "stdout": "", "stdout_lines": []}
...ignoring
ok: [automate.prod.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004494", "end": "2025-12-15 19:59:48.912657", "msg": "", "rc": 0, "start": "2025-12-15 19:59:48.908163", "stderr": "", "stderr_lines": [], "stdout": "25.7%", "stdout_lines": ["25.7%"]}
ok: [dev.prod.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004256", "end": "2025-12-15 19:59:54.865286", "msg": "", "rc": 0, "start": "2025-12-15 19:59:54.861030", "stderr": "", "stderr_lines": [], "stdout": "57.0%", "stdout_lines": ["57.0%"]}
ok: [jump.point.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005383", "end": "2025-12-15 20:00:17.028312", "msg": "", "rc": 0, "start": "2025-12-15 20:00:17.022929", "stderr": "", "stderr_lines": [], "stdout": "13.4%", "stdout_lines": ["13.4%"]}
ok: [localhost] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.007357", "end": "2025-12-15 20:00:17.428915", "msg": "", "rc": 0, "start": "2025-12-15 20:00:17.421558", "stderr": "", "stderr_lines": [], "stdout": "12.6%", "stdout_lines": ["12.6%"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.025495", "end": "2025-12-15 20:00:17.042310", "msg": "", "rc": 0, "start": "2025-12-15 20:00:17.016815", "stderr": "", "stderr_lines": [], "stdout": "19.1%", "stdout_lines": ["19.1%"]}
TASK [Get CPU temperature (ARM/SBC)] *******************************************
ok: [hp.nas.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.005731", "end": "2025-12-15 20:00:17.555070", "msg": "", "rc": 0, "start": "2025-12-15 20:00:17.549339", "stderr": "", "stderr_lines": [], "stdout": "30.0°C", "stdout_lines": ["30.0°C"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.004818", "end": "2025-12-15 20:00:17.574000", "msg": "", "rc": 0, "start": "2025-12-15 20:00:17.569182", "stderr": "", "stderr_lines": [], "stdout": "45.0°C", "stdout_lines": ["45.0°C"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.005717", "end": "2025-12-15 20:00:17.583904", "msg": "", "rc": 0, "start": "2025-12-15 20:00:17.578187", "stderr": "cat: /sys/class/thermal/thermal_zone0/temp: No data available", "stderr_lines": ["cat: /sys/class/thermal/thermal_zone0/temp: No data available"], "stdout": "0.0°C", "stdout_lines": ["0.0°C"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003524", "end": "2025-12-15 20:00:17.612484", "msg": "", "rc": 0, "start": "2025-12-15 20:00:17.608960", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.006619", "end": "2025-12-15 20:00:17.638721", "msg": "", "rc": 0, "start": "2025-12-15 20:00:17.632102", "stderr": "", "stderr_lines": [], "stdout": "52.5°C", "stdout_lines": ["52.5°C"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.002697", "end": "2025-12-15 19:59:53.405550", "msg": "", "rc": 0, "start": "2025-12-15 19:59:53.402853", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [media.labb.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003352", "end": "2025-12-15 19:59:47.582115", "msg": "", "rc": 0, "start": "2025-12-15 19:59:47.578763", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.011861", "end": "2025-12-15 20:00:18.252687", "msg": "", "rc": 0, "start": "2025-12-15 20:00:18.240826", "stderr": "", "stderr_lines": [], "stdout": "32.6°C", "stdout_lines": ["32.6°C"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.013028", "end": "2025-12-15 20:00:18.280420", "msg": "", "rc": 0, "start": "2025-12-15 20:00:18.267392", "stderr": "", "stderr_lines": [], "stdout": "36.5°C", "stdout_lines": ["36.5°C"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003324", "end": "2025-12-15 20:00:18.524007", "msg": "", "rc": 0, "start": "2025-12-15 20:00:18.520683", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.002882", "end": "2025-12-15 19:59:50.764830", "msg": "", "rc": 0, "start": "2025-12-15 19:59:50.761948", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003895", "end": "2025-12-15 17:00:18.744525", "msg": "", "rc": 0, "start": "2025-12-15 17:00:18.740630", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [dev.prod.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.002642", "end": "2025-12-15 19:59:56.729095", "msg": "", "rc": 0, "start": "2025-12-15 19:59:56.726453", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [jump.point.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.002905", "end": "2025-12-15 20:00:18.936024", "msg": "", "rc": 0, "start": "2025-12-15 20:00:18.933119", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [localhost] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003759", "end": "2025-12-15 20:00:19.297031", "msg": "", "rc": 0, "start": "2025-12-15 20:00:19.293272", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.028837", "end": "2025-12-15 20:00:18.952637", "msg": "", "rc": 0, "start": "2025-12-15 20:00:18.923800", "stderr": "", "stderr_lines": [], "stdout": "35.6°C", "stdout_lines": ["35.6°C"]}
TASK [Get CPU load] ************************************************************
ok: [hp.nas.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004265", "end": "2025-12-15 20:00:19.488334", "msg": "", "rc": 0, "start": "2025-12-15 20:00:19.484069", "stderr": "", "stderr_lines": [], "stdout": "0.28", "stdout_lines": ["0.28"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.003986", "end": "2025-12-15 20:00:19.498969", "msg": "", "rc": 0, "start": "2025-12-15 20:00:19.494983", "stderr": "", "stderr_lines": [], "stdout": "0.16", "stdout_lines": ["0.16"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004710", "end": "2025-12-15 20:00:19.515233", "msg": "", "rc": 0, "start": "2025-12-15 20:00:19.510523", "stderr": "", "stderr_lines": [], "stdout": "0.70", "stdout_lines": ["0.70"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004466", "end": "2025-12-15 20:00:19.532480", "msg": "", "rc": 0, "start": "2025-12-15 20:00:19.528014", "stderr": "", "stderr_lines": [], "stdout": "0.00", "stdout_lines": ["0.00"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005345", "end": "2025-12-15 20:00:19.537735", "msg": "", "rc": 0, "start": "2025-12-15 20:00:19.532390", "stderr": "", "stderr_lines": [], "stdout": "0.58", "stdout_lines": ["0.58"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004813", "end": "2025-12-15 19:59:55.403548", "msg": "", "rc": 0, "start": "2025-12-15 19:59:55.398735", "stderr": "", "stderr_lines": [], "stdout": "0.11", "stdout_lines": ["0.11"]}
ok: [media.labb.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005248", "end": "2025-12-15 19:59:49.536596", "msg": "", "rc": 0, "start": "2025-12-15 19:59:49.531348", "stderr": "", "stderr_lines": [], "stdout": "0.09", "stdout_lines": ["0.09"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.010181", "end": "2025-12-15 20:00:20.287858", "msg": "", "rc": 0, "start": "2025-12-15 20:00:20.277677", "stderr": "", "stderr_lines": [], "stdout": "0.04", "stdout_lines": ["0.04"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.011060", "end": "2025-12-15 20:00:20.333480", "msg": "", "rc": 0, "start": "2025-12-15 20:00:20.322420", "stderr": "", "stderr_lines": [], "stdout": "0.48", "stdout_lines": ["0.48"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005750", "end": "2025-12-15 20:00:20.563628", "msg": "", "rc": 0, "start": "2025-12-15 20:00:20.557878", "stderr": "", "stderr_lines": [], "stdout": "0.32", "stdout_lines": ["0.32"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005035", "end": "2025-12-15 19:59:52.816238", "msg": "", "rc": 0, "start": "2025-12-15 19:59:52.811203", "stderr": "", "stderr_lines": [], "stdout": "0.45", "stdout_lines": ["0.45"]}
ok: [dev.prod.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.003954", "end": "2025-12-15 19:59:58.866382", "msg": "", "rc": 0, "start": "2025-12-15 19:59:58.862428", "stderr": "", "stderr_lines": [], "stdout": "0.31", "stdout_lines": ["0.31"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.006242", "end": "2025-12-15 17:00:20.928430", "msg": "", "rc": 0, "start": "2025-12-15 17:00:20.922188", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.024395", "end": "2025-12-15 20:00:20.906219", "msg": "", "rc": 0, "start": "2025-12-15 20:00:20.881824", "stderr": "", "stderr_lines": [], "stdout": "0.27", "stdout_lines": ["0.27"]}
ok: [jump.point.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005305", "end": "2025-12-15 20:00:21.170344", "msg": "", "rc": 0, "start": "2025-12-15 20:00:21.165039", "stderr": "", "stderr_lines": [], "stdout": "0.00", "stdout_lines": ["0.00"]}
ok: [localhost] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.006803", "end": "2025-12-15 20:00:21.820407", "msg": "", "rc": 0, "start": "2025-12-15 20:00:21.813604", "stderr": "", "stderr_lines": [], "stdout": "1.54", "stdout_lines": ["1.54"]}
TASK [Display health status] ***************************************************
ok: [ali2v.xeon.home] => {
"msg": "═══════════════════════════════════════\nHost: ali2v.xeon.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:00:11 up 1 day, 9:32, 1 user, load average: 0.10, 0.17, 0.24\nDisk Usage: 22%\nMemory Usage: 21.7%\nCPU Load: 0.16\nCPU Temp: 45.0°C\n═══════════════════════════════════════\n"
}
ok: [hp.nas.home] => {
"msg": "═══════════════════════════════════════\nHost: hp.nas.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:00:11 up 20 days, 6:51, 1 user, load average: 0.31, 0.32, 0.25\nDisk Usage: 23%\nMemory Usage: 80.8%\nCPU Load: 0.28\nCPU Temp: 30.0°C\n═══════════════════════════════════════\n"
}
ok: [hp2.i7.home] => {
"msg": "═══════════════════════════════════════\nHost: hp2.i7.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:00:11 up 20 days, 7:11, 1 user, load average: 0.58, 0.67, 0.71\nDisk Usage: 14%\nMemory Usage: 48.9%\nCPU Load: 0.70\nCPU Temp: 0.0°C\n═══════════════════════════════════════\n"
}
ok: [hp3.i5.home] => {
"msg": "═══════════════════════════════════════\nHost: hp3.i5.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:00:11 up 20 days, 8:24, 1 user, load average: 0.42, 0.59, 0.62\nDisk Usage: 14%\nMemory Usage: 59.5%\nCPU Load: 0.58\nCPU Temp: 52.5°C\n═══════════════════════════════════════\n"
}
ok: [mimi.pc.home] => {
"msg": "═══════════════════════════════════════\nHost: mimi.pc.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:00:11 up 20 days, 9:10, 1 user, load average: 0.00, 0.01, 0.00\nDisk Usage: 9%\nMemory Usage: 8.9%\nCPU Load: 0.00\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [orangepi.pc.home] => {
"msg": "═══════════════════════════════════════\nHost: orangepi.pc.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:00:13 up 13 days, 9:26, 1 user, load average: 0.13, 0.13, 0.10\nDisk Usage: 21%\nMemory Usage: 19.1%\nCPU Load: 0.27\nCPU Temp: 35.6°C\n═══════════════════════════════════════\n"
}
ok: [raspi.4gb.home] => {
"msg": "═══════════════════════════════════════\nHost: raspi.4gb.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:00:12 up 192 days, 11:33, 1 user, load average: 0.38, 0.35, 0.30\nDisk Usage: 6%\nMemory Usage: 12.3%\nCPU Load: 0.48\nCPU Temp: 36.5°C\n═══════════════════════════════════════\n"
}
ok: [raspi.8gb.home] => {
"msg": "═══════════════════════════════════════\nHost: raspi.8gb.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:00:12 up 192 days, 11:33, 1 user, load average: 0.04, 0.09, 0.08\nDisk Usage: 3%\nMemory Usage: 6.8%\nCPU Load: 0.04\nCPU Temp: 32.6°C\n═══════════════════════════════════════\n"
}
ok: [dev.lab.home] => {
"msg": "═══════════════════════════════════════\nHost: dev.lab.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:59:47 up 9 days, 7:49, 0 user, load average: 0.12, 0.11, 0.12\nDisk Usage: 48%\nMemory Usage: 71.2%\nCPU Load: 0.11\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [media.labb.home] => {
"msg": "═══════════════════════════════════════\nHost: media.labb.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:59:41 up 16 days, 4:01, 0 user, load average: 0.01, 0.02, 0.00\nDisk Usage: 24%\nMemory Usage: 72.2%\nCPU Load: 0.09\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [ali2v.truenas.home] => {
"msg": "═══════════════════════════════════════\nHost: ali2v.truenas.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:00:12 up 1 day, 9:31, 1 user, load average: 0.20, 0.10, 0.03\nDisk Usage: 1%\nMemory Usage: 34.3%\nCPU Load: 0.32\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [automate.prod.home] => {
"msg": "═══════════════════════════════════════\nHost: automate.prod.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:59:44 up 18 days, 22:54, 0 user, load average: 0.40, 0.43, 0.44\nDisk Usage: 28%\nMemory Usage: 25.7%\nCPU Load: 0.45\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [dev.prod.home] => {
"msg": "═══════════════════════════════════════\nHost: dev.prod.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 19:59:50 up 15 days, 9:15, 0 user, load average: 0.34, 0.35, 0.24\nDisk Usage: 75%\nMemory Usage: 57.0%\nCPU Load: 0.31\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [hp.truenas.home] => {
"msg": "═══════════════════════════════════════\nHost: hp.truenas.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 5:00PM up 20 days, 6:50, 1 user, load averages: 0.11, 0.17, 0.20\nDisk Usage: 10%\nMemory Usage: \nCPU Load: \nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [jump.point.home] => {
"msg": "═══════════════════════════════════════\nHost: jump.point.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:00:13 up 1 day, 9:31, 1 user, load average: 0.00, 0.02, 0.00\nDisk Usage: 79%\nMemory Usage: 13.4%\nCPU Load: 0.00\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [localhost] => {
"msg": "═══════════════════════════════════════\nHost: localhost\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:00:13 up 6:35, 1 user, load average: 1.58, 1.29, 1.27\nDisk Usage: 1%\nMemory Usage: 12.6%\nCPU Load: 1.54\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
PLAY RECAP *********************************************************************
ali2v.truenas.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
ali2v.xeon.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
automate.prod.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
dev.lab.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
dev.prod.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
hp.nas.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
hp.truenas.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=1
hp2.i7.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
hp3.i5.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
jump.point.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
localhost : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
media.labb.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
mimi.pc.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
orangepi.pc.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
raspi.4gb.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
raspi.8gb.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
```
---
*Généré automatiquement par Homelab Automation Dashboard*
*Date: 2025-12-16T01:00:22.792574+00:00*

View File

@ -0,0 +1,224 @@
# ✅ [Planifié] Health-check-5min
## Informations
| Propriété | Valeur |
|-----------|--------|
| **ID** | `7a812f98696743119795d31659050840` |
| **Nom** | [Planifié] Health-check-5min |
| **Cible** | `all` |
| **Statut** | completed |
| **Type** | Planifié |
| **Progression** | 100% |
| **Début** | 2025-12-16T01:05:00.001063+00:00 |
| **Fin** | 2025-12-16T01:05:22.917696+00:00 |
| **Durée** | 22.9s |
## Sortie
```
Using /mnt/c/dev/git/python/homelab-automation-api-v2/ansible/ansible.cfg as config file
PLAY [Health check on target host] *********************************************
TASK [Check if host is reachable (ping)] ***************************************
ok: [hp.nas.home] => {"changed": false, "ping": "pong"}
ok: [mimi.pc.home] => {"changed": false, "ping": "pong"}
ok: [hp2.i7.home] => {"changed": false, "ping": "pong"}
ok: [ali2v.xeon.home] => {"changed": false, "ping": "pong"}
ok: [hp3.i5.home] => {"changed": false, "ping": "pong"}
ok: [dev.lab.home] => {"changed": false, "ping": "pong"}
ok: [media.labb.home] => {"changed": false, "ping": "pong"}
ok: [raspi.8gb.home] => {"changed": false, "ping": "pong"}
ok: [raspi.4gb.home] => {"changed": false, "ping": "pong"}
ok: [automate.prod.home] => {"changed": false, "ping": "pong"}
ok: [ali2v.truenas.home] => {"changed": false, "ping": "pong"}
ok: [hp.truenas.home] => {"changed": false, "ping": "pong"}
ok: [localhost] => {"changed": false, "ping": "pong"}
ok: [dev.prod.home] => {"changed": false, "ping": "pong"}
ok: [jump.point.home] => {"changed": false, "ping": "pong"}
ok: [orangepi.pc.home] => {"changed": false, "ping": "pong"}
TASK [Gather minimal facts] ****************************************************
ok: [hp.nas.home]
ok: [hp2.i7.home]
ok: [mimi.pc.home]
ok: [ali2v.xeon.home]
ok: [hp3.i5.home]
ok: [dev.lab.home]
ok: [media.labb.home]
ok: [raspi.8gb.home]
ok: [raspi.4gb.home]
ok: [ali2v.truenas.home]
ok: [automate.prod.home]
ok: [hp.truenas.home]
ok: [dev.prod.home]
ok: [jump.point.home]
ok: [localhost]
ok: [orangepi.pc.home]
TASK [Get system uptime] *******************************************************
ok: [hp.nas.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003302", "end": "2025-12-15 20:05:11.782850", "msg": "", "rc": 0, "start": "2025-12-15 20:05:11.779548", "stderr": "", "stderr_lines": [], "stdout": " 20:05:11 up 20 days, 6:56, 1 user, load average: 0.31, 0.31, 0.26", "stdout_lines": [" 20:05:11 up 20 days, 6:56, 1 user, load average: 0.31, 0.31, 0.26"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003659", "end": "2025-12-15 20:05:11.800483", "msg": "", "rc": 0, "start": "2025-12-15 20:05:11.796824", "stderr": "", "stderr_lines": [], "stdout": " 20:05:11 up 20 days, 9:15, 1 user, load average: 0.02, 0.02, 0.00", "stdout_lines": [" 20:05:11 up 20 days, 9:15, 1 user, load average: 0.02, 0.02, 0.00"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003341", "end": "2025-12-15 20:05:11.817241", "msg": "", "rc": 0, "start": "2025-12-15 20:05:11.813900", "stderr": "", "stderr_lines": [], "stdout": " 20:05:11 up 20 days, 7:16, 1 user, load average: 0.76, 0.75, 0.73", "stdout_lines": [" 20:05:11 up 20 days, 7:16, 1 user, load average: 0.76, 0.75, 0.73"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.004167", "end": "2025-12-15 20:05:11.813457", "msg": "", "rc": 0, "start": "2025-12-15 20:05:11.809290", "stderr": "", "stderr_lines": [], "stdout": " 20:05:11 up 20 days, 8:29, 1 user, load average: 0.91, 0.60, 0.60", "stdout_lines": [" 20:05:11 up 20 days, 8:29, 1 user, load average: 0.91, 0.60, 0.60"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.002804", "end": "2025-12-15 20:05:11.821702", "msg": "", "rc": 0, "start": "2025-12-15 20:05:11.818898", "stderr": "", "stderr_lines": [], "stdout": " 20:05:11 up 1 day, 9:37, 1 user, load average: 0.38, 0.20, 0.22", "stdout_lines": [" 20:05:11 up 1 day, 9:37, 1 user, load average: 0.38, 0.20, 0.22"]}
ok: [dev.lab.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.002919", "end": "2025-12-15 20:04:47.633776", "msg": "", "rc": 0, "start": "2025-12-15 20:04:47.630857", "stderr": "", "stderr_lines": [], "stdout": " 20:04:47 up 9 days, 7:54, 0 user, load average: 0.01, 0.06, 0.09", "stdout_lines": [" 20:04:47 up 9 days, 7:54, 0 user, load average: 0.01, 0.06, 0.09"]}
ok: [media.labb.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003418", "end": "2025-12-15 20:04:41.767097", "msg": "", "rc": 0, "start": "2025-12-15 20:04:41.763679", "stderr": "", "stderr_lines": [], "stdout": " 20:04:41 up 16 days, 4:06, 0 user, load average: 0.37, 0.09, 0.02", "stdout_lines": [" 20:04:41 up 16 days, 4:06, 0 user, load average: 0.37, 0.09, 0.02"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.008562", "end": "2025-12-15 20:05:12.461863", "msg": "", "rc": 0, "start": "2025-12-15 20:05:12.453301", "stderr": "", "stderr_lines": [], "stdout": " 20:05:12 up 192 days, 11:38, 1 user, load average: 0.15, 0.13, 0.09", "stdout_lines": [" 20:05:12 up 192 days, 11:38, 1 user, load average: 0.15, 0.13, 0.09"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.009327", "end": "2025-12-15 20:05:12.518590", "msg": "", "rc": 0, "start": "2025-12-15 20:05:12.509263", "stderr": "", "stderr_lines": [], "stdout": " 20:05:12 up 192 days, 11:38, 1 user, load average: 0.31, 0.28, 0.27", "stdout_lines": [" 20:05:12 up 192 days, 11:38, 1 user, load average: 0.31, 0.28, 0.27"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.004662", "end": "2025-12-15 20:05:12.741166", "msg": "", "rc": 0, "start": "2025-12-15 20:05:12.736504", "stderr": "", "stderr_lines": [], "stdout": " 20:05:12 up 1 day, 9:36, 1 user, load average: 0.00, 0.04, 0.01", "stdout_lines": [" 20:05:12 up 1 day, 9:36, 1 user, load average: 0.00, 0.04, 0.01"]}
ok: [automate.prod.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003279", "end": "2025-12-15 20:04:44.954602", "msg": "", "rc": 0, "start": "2025-12-15 20:04:44.951323", "stderr": "", "stderr_lines": [], "stdout": " 20:04:44 up 18 days, 22:59, 0 user, load average: 0.34, 0.48, 0.47", "stdout_lines": [" 20:04:44 up 18 days, 22:59, 0 user, load average: 0.34, 0.48, 0.47"]}
ok: [dev.prod.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003070", "end": "2025-12-15 20:04:50.930804", "msg": "", "rc": 0, "start": "2025-12-15 20:04:50.927734", "stderr": "", "stderr_lines": [], "stdout": " 20:04:50 up 15 days, 9:20, 0 user, load average: 0.13, 0.26, 0.24", "stdout_lines": [" 20:04:50 up 15 days, 9:20, 0 user, load average: 0.13, 0.26, 0.24"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.004338", "end": "2025-12-15 17:05:12.984631", "msg": "", "rc": 0, "start": "2025-12-15 17:05:12.980293", "stderr": "", "stderr_lines": [], "stdout": " 5:05PM up 20 days, 6:55, 1 user, load averages: 0.19, 0.22, 0.21", "stdout_lines": [" 5:05PM up 20 days, 6:55, 1 user, load averages: 0.19, 0.22, 0.21"]}
ok: [jump.point.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003690", "end": "2025-12-15 20:05:13.193988", "msg": "", "rc": 0, "start": "2025-12-15 20:05:13.190298", "stderr": "", "stderr_lines": [], "stdout": " 20:05:13 up 1 day, 9:36, 1 user, load average: 0.08, 0.03, 0.01", "stdout_lines": [" 20:05:13 up 1 day, 9:36, 1 user, load average: 0.08, 0.03, 0.01"]}
ok: [localhost] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.005431", "end": "2025-12-15 20:05:13.468898", "msg": "", "rc": 0, "start": "2025-12-15 20:05:13.463467", "stderr": "", "stderr_lines": [], "stdout": " 20:05:13 up 6:40, 1 user, load average: 1.94, 1.45, 1.33", "stdout_lines": [" 20:05:13 up 6:40, 1 user, load average: 1.94, 1.45, 1.33"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.022364", "end": "2025-12-15 20:05:13.409042", "msg": "", "rc": 0, "start": "2025-12-15 20:05:13.386678", "stderr": "", "stderr_lines": [], "stdout": " 20:05:13 up 13 days, 9:31, 2 users, load average: 0.24, 0.12, 0.09", "stdout_lines": [" 20:05:13 up 13 days, 9:31, 2 users, load average: 0.24, 0.12, 0.09"]}
TASK [Get disk usage] **********************************************************
ok: [hp.nas.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004851", "end": "2025-12-15 20:05:13.955639", "msg": "", "rc": 0, "start": "2025-12-15 20:05:13.950788", "stderr": "", "stderr_lines": [], "stdout": "23%", "stdout_lines": ["23%"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004214", "end": "2025-12-15 20:05:13.989249", "msg": "", "rc": 0, "start": "2025-12-15 20:05:13.985035", "stderr": "", "stderr_lines": [], "stdout": "22%", "stdout_lines": ["22%"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004691", "end": "2025-12-15 20:05:13.991167", "msg": "", "rc": 0, "start": "2025-12-15 20:05:13.986476", "stderr": "", "stderr_lines": [], "stdout": "14%", "stdout_lines": ["14%"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004975", "end": "2025-12-15 20:05:14.025264", "msg": "", "rc": 0, "start": "2025-12-15 20:05:14.020289", "stderr": "", "stderr_lines": [], "stdout": "9%", "stdout_lines": ["9%"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.006879", "end": "2025-12-15 20:05:14.045383", "msg": "", "rc": 0, "start": "2025-12-15 20:05:14.038504", "stderr": "", "stderr_lines": [], "stdout": "14%", "stdout_lines": ["14%"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005474", "end": "2025-12-15 20:04:49.831974", "msg": "", "rc": 0, "start": "2025-12-15 20:04:49.826500", "stderr": "", "stderr_lines": [], "stdout": "48%", "stdout_lines": ["48%"]}
ok: [media.labb.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005365", "end": "2025-12-15 20:04:44.001221", "msg": "", "rc": 0, "start": "2025-12-15 20:04:43.995856", "stderr": "", "stderr_lines": [], "stdout": "24%", "stdout_lines": ["24%"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.010699", "end": "2025-12-15 20:05:14.757802", "msg": "", "rc": 0, "start": "2025-12-15 20:05:14.747103", "stderr": "", "stderr_lines": [], "stdout": "3%", "stdout_lines": ["3%"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.011527", "end": "2025-12-15 20:05:14.795200", "msg": "", "rc": 0, "start": "2025-12-15 20:05:14.783673", "stderr": "", "stderr_lines": [], "stdout": "6%", "stdout_lines": ["6%"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005714", "end": "2025-12-15 20:05:14.965372", "msg": "", "rc": 0, "start": "2025-12-15 20:05:14.959658", "stderr": "", "stderr_lines": [], "stdout": "1%", "stdout_lines": ["1%"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005110", "end": "2025-12-15 20:04:47.189260", "msg": "", "rc": 0, "start": "2025-12-15 20:04:47.184150", "stderr": "", "stderr_lines": [], "stdout": "28%", "stdout_lines": ["28%"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005529", "end": "2025-12-15 17:05:15.255559", "msg": "", "rc": 0, "start": "2025-12-15 17:05:15.250030", "stderr": "", "stderr_lines": [], "stdout": "10%", "stdout_lines": ["10%"]}
ok: [dev.prod.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004966", "end": "2025-12-15 20:04:53.256332", "msg": "", "rc": 0, "start": "2025-12-15 20:04:53.251366", "stderr": "", "stderr_lines": [], "stdout": "75%", "stdout_lines": ["75%"]}
ok: [jump.point.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005413", "end": "2025-12-15 20:05:15.391277", "msg": "", "rc": 0, "start": "2025-12-15 20:05:15.385864", "stderr": "", "stderr_lines": [], "stdout": "79%", "stdout_lines": ["79%"]}
ok: [localhost] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.008744", "end": "2025-12-15 20:05:15.666231", "msg": "", "rc": 0, "start": "2025-12-15 20:05:15.657487", "stderr": "", "stderr_lines": [], "stdout": "1%", "stdout_lines": ["1%"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.025445", "end": "2025-12-15 20:05:15.497810", "msg": "", "rc": 0, "start": "2025-12-15 20:05:15.472365", "stderr": "", "stderr_lines": [], "stdout": "21%", "stdout_lines": ["21%"]}
TASK [Get memory usage (Linux)] ************************************************
ok: [hp.nas.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004372", "end": "2025-12-15 20:05:16.059620", "msg": "", "rc": 0, "start": "2025-12-15 20:05:16.055248", "stderr": "", "stderr_lines": [], "stdout": "80.8%", "stdout_lines": ["80.8%"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004253", "end": "2025-12-15 20:05:16.071171", "msg": "", "rc": 0, "start": "2025-12-15 20:05:16.066918", "stderr": "", "stderr_lines": [], "stdout": "21.7%", "stdout_lines": ["21.7%"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004811", "end": "2025-12-15 20:05:16.103738", "msg": "", "rc": 0, "start": "2025-12-15 20:05:16.098927", "stderr": "", "stderr_lines": [], "stdout": "49.0%", "stdout_lines": ["49.0%"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005149", "end": "2025-12-15 20:05:16.110791", "msg": "", "rc": 0, "start": "2025-12-15 20:05:16.105642", "stderr": "", "stderr_lines": [], "stdout": "8.9%", "stdout_lines": ["8.9%"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005613", "end": "2025-12-15 20:05:16.109137", "msg": "", "rc": 0, "start": "2025-12-15 20:05:16.103524", "stderr": "", "stderr_lines": [], "stdout": "59.5%", "stdout_lines": ["59.5%"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005238", "end": "2025-12-15 20:04:51.964691", "msg": "", "rc": 0, "start": "2025-12-15 20:04:51.959453", "stderr": "", "stderr_lines": [], "stdout": "71.2%", "stdout_lines": ["71.2%"]}
ok: [media.labb.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004331", "end": "2025-12-15 20:04:46.061737", "msg": "", "rc": 0, "start": "2025-12-15 20:04:46.057406", "stderr": "", "stderr_lines": [], "stdout": "72.2%", "stdout_lines": ["72.2%"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.011019", "end": "2025-12-15 20:05:16.767306", "msg": "", "rc": 0, "start": "2025-12-15 20:05:16.756287", "stderr": "", "stderr_lines": [], "stdout": "6.7%", "stdout_lines": ["6.7%"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.012067", "end": "2025-12-15 20:05:16.794546", "msg": "", "rc": 0, "start": "2025-12-15 20:05:16.782479", "stderr": "", "stderr_lines": [], "stdout": "12.6%", "stdout_lines": ["12.6%"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.006990", "end": "2025-12-15 20:05:17.093181", "msg": "", "rc": 0, "start": "2025-12-15 20:05:17.086191", "stderr": "", "stderr_lines": [], "stdout": "34.0%", "stdout_lines": ["34.0%"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004272", "end": "2025-12-15 20:04:49.288521", "msg": "", "rc": 0, "start": "2025-12-15 20:04:49.284249", "stderr": "", "stderr_lines": [], "stdout": "24.6%", "stdout_lines": ["24.6%"]}
fatal: [hp.truenas.home]: FAILED! => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005365", "end": "2025-12-15 17:05:17.267072", "msg": "non-zero return code", "rc": 2, "start": "2025-12-15 17:05:17.261707", "stderr": "cat: /proc/meminfo: No such file or directory\nawk: division by zero\n source line number 1", "stderr_lines": ["cat: /proc/meminfo: No such file or directory", "awk: division by zero", " source line number 1"], "stdout": "", "stdout_lines": []}
...ignoring
ok: [dev.prod.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.003873", "end": "2025-12-15 20:04:55.249314", "msg": "", "rc": 0, "start": "2025-12-15 20:04:55.245441", "stderr": "", "stderr_lines": [], "stdout": "56.0%", "stdout_lines": ["56.0%"]}
ok: [jump.point.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005403", "end": "2025-12-15 20:05:17.543229", "msg": "", "rc": 0, "start": "2025-12-15 20:05:17.537826", "stderr": "", "stderr_lines": [], "stdout": "13.6%", "stdout_lines": ["13.6%"]}
ok: [localhost] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.007469", "end": "2025-12-15 20:05:17.772918", "msg": "", "rc": 0, "start": "2025-12-15 20:05:17.765449", "stderr": "", "stderr_lines": [], "stdout": "13.1%", "stdout_lines": ["13.1%"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.028807", "end": "2025-12-15 20:05:17.612184", "msg": "", "rc": 0, "start": "2025-12-15 20:05:17.583377", "stderr": "", "stderr_lines": [], "stdout": "19.5%", "stdout_lines": ["19.5%"]}
TASK [Get CPU temperature (ARM/SBC)] *******************************************
ok: [hp.nas.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.005072", "end": "2025-12-15 20:05:18.149567", "msg": "", "rc": 0, "start": "2025-12-15 20:05:18.144495", "stderr": "", "stderr_lines": [], "stdout": "30.0°C", "stdout_lines": ["30.0°C"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.005534", "end": "2025-12-15 20:05:18.182395", "msg": "", "rc": 0, "start": "2025-12-15 20:05:18.176861", "stderr": "cat: /sys/class/thermal/thermal_zone0/temp: No data available", "stderr_lines": ["cat: /sys/class/thermal/thermal_zone0/temp: No data available"], "stdout": "0.0°C", "stdout_lines": ["0.0°C"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.004913", "end": "2025-12-15 20:05:18.187947", "msg": "", "rc": 0, "start": "2025-12-15 20:05:18.183034", "stderr": "", "stderr_lines": [], "stdout": "46.0°C", "stdout_lines": ["46.0°C"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.002939", "end": "2025-12-15 20:05:18.207699", "msg": "", "rc": 0, "start": "2025-12-15 20:05:18.204760", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.007509", "end": "2025-12-15 20:05:18.250786", "msg": "", "rc": 0, "start": "2025-12-15 20:05:18.243277", "stderr": "", "stderr_lines": [], "stdout": "53.0°C", "stdout_lines": ["53.0°C"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003406", "end": "2025-12-15 20:04:54.038447", "msg": "", "rc": 0, "start": "2025-12-15 20:04:54.035041", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [media.labb.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003354", "end": "2025-12-15 20:04:48.227555", "msg": "", "rc": 0, "start": "2025-12-15 20:04:48.224201", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.011915", "end": "2025-12-15 20:05:18.867558", "msg": "", "rc": 0, "start": "2025-12-15 20:05:18.855643", "stderr": "", "stderr_lines": [], "stdout": "32.6°C", "stdout_lines": ["32.6°C"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.013044", "end": "2025-12-15 20:05:18.920635", "msg": "", "rc": 0, "start": "2025-12-15 20:05:18.907591", "stderr": "", "stderr_lines": [], "stdout": "36.0°C", "stdout_lines": ["36.0°C"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003162", "end": "2025-12-15 20:05:19.170759", "msg": "", "rc": 0, "start": "2025-12-15 20:05:19.167597", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003902", "end": "2025-12-15 17:05:19.387925", "msg": "", "rc": 0, "start": "2025-12-15 17:05:19.384023", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [dev.prod.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.002496", "end": "2025-12-15 20:04:57.363362", "msg": "", "rc": 0, "start": "2025-12-15 20:04:57.360866", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.007361", "end": "2025-12-15 20:04:51.437087", "msg": "", "rc": 0, "start": "2025-12-15 20:04:51.429726", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [jump.point.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003038", "end": "2025-12-15 20:05:19.610045", "msg": "", "rc": 0, "start": "2025-12-15 20:05:19.607007", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [localhost] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.004350", "end": "2025-12-15 20:05:19.879155", "msg": "", "rc": 0, "start": "2025-12-15 20:05:19.874805", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.031600", "end": "2025-12-15 20:05:19.716128", "msg": "", "rc": 0, "start": "2025-12-15 20:05:19.684528", "stderr": "", "stderr_lines": [], "stdout": "39.0°C", "stdout_lines": ["39.0°C"]}
TASK [Get CPU load] ************************************************************
ok: [hp.nas.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004255", "end": "2025-12-15 20:05:20.248909", "msg": "", "rc": 0, "start": "2025-12-15 20:05:20.244654", "stderr": "", "stderr_lines": [], "stdout": "0.37", "stdout_lines": ["0.37"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005106", "end": "2025-12-15 20:05:20.274169", "msg": "", "rc": 0, "start": "2025-12-15 20:05:20.269063", "stderr": "", "stderr_lines": [], "stdout": "0.79", "stdout_lines": ["0.79"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004018", "end": "2025-12-15 20:05:20.283404", "msg": "", "rc": 0, "start": "2025-12-15 20:05:20.279386", "stderr": "", "stderr_lines": [], "stdout": "0.40", "stdout_lines": ["0.40"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005153", "end": "2025-12-15 20:05:20.298679", "msg": "", "rc": 0, "start": "2025-12-15 20:05:20.293526", "stderr": "", "stderr_lines": [], "stdout": "0.02", "stdout_lines": ["0.02"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005536", "end": "2025-12-15 20:05:20.330939", "msg": "", "rc": 0, "start": "2025-12-15 20:05:20.325403", "stderr": "", "stderr_lines": [], "stdout": "0.93", "stdout_lines": ["0.93"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005663", "end": "2025-12-15 20:04:56.127645", "msg": "", "rc": 0, "start": "2025-12-15 20:04:56.121982", "stderr": "", "stderr_lines": [], "stdout": "0.08", "stdout_lines": ["0.08"]}
ok: [media.labb.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005099", "end": "2025-12-15 20:04:50.292420", "msg": "", "rc": 0, "start": "2025-12-15 20:04:50.287321", "stderr": "", "stderr_lines": [], "stdout": "0.34", "stdout_lines": ["0.34"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.010265", "end": "2025-12-15 20:05:21.038927", "msg": "", "rc": 0, "start": "2025-12-15 20:05:21.028662", "stderr": "", "stderr_lines": [], "stdout": "0.12", "stdout_lines": ["0.12"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.011202", "end": "2025-12-15 20:05:21.045694", "msg": "", "rc": 0, "start": "2025-12-15 20:05:21.034492", "stderr": "", "stderr_lines": [], "stdout": "0.26", "stdout_lines": ["0.26"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005547", "end": "2025-12-15 20:05:21.251415", "msg": "", "rc": 0, "start": "2025-12-15 20:05:21.245868", "stderr": "", "stderr_lines": [], "stdout": "0.00", "stdout_lines": ["0.00"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004798", "end": "2025-12-15 20:04:53.463085", "msg": "", "rc": 0, "start": "2025-12-15 20:04:53.458287", "stderr": "", "stderr_lines": [], "stdout": "0.37", "stdout_lines": ["0.37"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.006154", "end": "2025-12-15 17:05:21.512731", "msg": "", "rc": 0, "start": "2025-12-15 17:05:21.506577", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}
ok: [dev.prod.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004799", "end": "2025-12-15 20:04:59.546666", "msg": "", "rc": 0, "start": "2025-12-15 20:04:59.541867", "stderr": "", "stderr_lines": [], "stdout": "0.50", "stdout_lines": ["0.50"]}
ok: [jump.point.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005290", "end": "2025-12-15 20:05:21.681782", "msg": "", "rc": 0, "start": "2025-12-15 20:05:21.676492", "stderr": "", "stderr_lines": [], "stdout": "0.07", "stdout_lines": ["0.07"]}
ok: [localhost] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.007166", "end": "2025-12-15 20:05:21.912434", "msg": "", "rc": 0, "start": "2025-12-15 20:05:21.905268", "stderr": "", "stderr_lines": [], "stdout": "1.94", "stdout_lines": ["1.94"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.026459", "end": "2025-12-15 20:05:21.788393", "msg": "", "rc": 0, "start": "2025-12-15 20:05:21.761934", "stderr": "", "stderr_lines": [], "stdout": "0.59", "stdout_lines": ["0.59"]}
TASK [Display health status] ***************************************************
ok: [ali2v.xeon.home] => {
"msg": "═══════════════════════════════════════\nHost: ali2v.xeon.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:05:11 up 1 day, 9:37, 1 user, load average: 0.38, 0.20, 0.22\nDisk Usage: 22%\nMemory Usage: 21.7%\nCPU Load: 0.40\nCPU Temp: 46.0°C\n═══════════════════════════════════════\n"
}
ok: [hp.nas.home] => {
"msg": "═══════════════════════════════════════\nHost: hp.nas.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:05:11 up 20 days, 6:56, 1 user, load average: 0.31, 0.31, 0.26\nDisk Usage: 23%\nMemory Usage: 80.8%\nCPU Load: 0.37\nCPU Temp: 30.0°C\n═══════════════════════════════════════\n"
}
ok: [hp2.i7.home] => {
"msg": "═══════════════════════════════════════\nHost: hp2.i7.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:05:11 up 20 days, 7:16, 1 user, load average: 0.76, 0.75, 0.73\nDisk Usage: 14%\nMemory Usage: 49.0%\nCPU Load: 0.79\nCPU Temp: 0.0°C\n═══════════════════════════════════════\n"
}
ok: [hp3.i5.home] => {
"msg": "═══════════════════════════════════════\nHost: hp3.i5.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:05:11 up 20 days, 8:29, 1 user, load average: 0.91, 0.60, 0.60\nDisk Usage: 14%\nMemory Usage: 59.5%\nCPU Load: 0.93\nCPU Temp: 53.0°C\n═══════════════════════════════════════\n"
}
ok: [mimi.pc.home] => {
"msg": "═══════════════════════════════════════\nHost: mimi.pc.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:05:11 up 20 days, 9:15, 1 user, load average: 0.02, 0.02, 0.00\nDisk Usage: 9%\nMemory Usage: 8.9%\nCPU Load: 0.02\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [orangepi.pc.home] => {
"msg": "═══════════════════════════════════════\nHost: orangepi.pc.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:05:13 up 13 days, 9:31, 2 users, load average: 0.24, 0.12, 0.09\nDisk Usage: 21%\nMemory Usage: 19.5%\nCPU Load: 0.59\nCPU Temp: 39.0°C\n═══════════════════════════════════════\n"
}
ok: [raspi.4gb.home] => {
"msg": "═══════════════════════════════════════\nHost: raspi.4gb.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:05:12 up 192 days, 11:38, 1 user, load average: 0.31, 0.28, 0.27\nDisk Usage: 6%\nMemory Usage: 12.6%\nCPU Load: 0.26\nCPU Temp: 36.0°C\n═══════════════════════════════════════\n"
}
ok: [raspi.8gb.home] => {
"msg": "═══════════════════════════════════════\nHost: raspi.8gb.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:05:12 up 192 days, 11:38, 1 user, load average: 0.15, 0.13, 0.09\nDisk Usage: 3%\nMemory Usage: 6.7%\nCPU Load: 0.12\nCPU Temp: 32.6°C\n═══════════════════════════════════════\n"
}
ok: [dev.lab.home] => {
"msg": "═══════════════════════════════════════\nHost: dev.lab.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:04:47 up 9 days, 7:54, 0 user, load average: 0.01, 0.06, 0.09\nDisk Usage: 48%\nMemory Usage: 71.2%\nCPU Load: 0.08\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [media.labb.home] => {
"msg": "═══════════════════════════════════════\nHost: media.labb.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:04:41 up 16 days, 4:06, 0 user, load average: 0.37, 0.09, 0.02\nDisk Usage: 24%\nMemory Usage: 72.2%\nCPU Load: 0.34\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [ali2v.truenas.home] => {
"msg": "═══════════════════════════════════════\nHost: ali2v.truenas.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:05:12 up 1 day, 9:36, 1 user, load average: 0.00, 0.04, 0.01\nDisk Usage: 1%\nMemory Usage: 34.0%\nCPU Load: 0.00\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [automate.prod.home] => {
"msg": "═══════════════════════════════════════\nHost: automate.prod.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:04:44 up 18 days, 22:59, 0 user, load average: 0.34, 0.48, 0.47\nDisk Usage: 28%\nMemory Usage: 24.6%\nCPU Load: 0.37\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [dev.prod.home] => {
"msg": "═══════════════════════════════════════\nHost: dev.prod.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:04:50 up 15 days, 9:20, 0 user, load average: 0.13, 0.26, 0.24\nDisk Usage: 75%\nMemory Usage: 56.0%\nCPU Load: 0.50\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [hp.truenas.home] => {
"msg": "═══════════════════════════════════════\nHost: hp.truenas.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 5:05PM up 20 days, 6:55, 1 user, load averages: 0.19, 0.22, 0.21\nDisk Usage: 10%\nMemory Usage: \nCPU Load: \nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [jump.point.home] => {
"msg": "═══════════════════════════════════════\nHost: jump.point.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:05:13 up 1 day, 9:36, 1 user, load average: 0.08, 0.03, 0.01\nDisk Usage: 79%\nMemory Usage: 13.6%\nCPU Load: 0.07\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [localhost] => {
"msg": "═══════════════════════════════════════\nHost: localhost\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:05:13 up 6:40, 1 user, load average: 1.94, 1.45, 1.33\nDisk Usage: 1%\nMemory Usage: 13.1%\nCPU Load: 1.94\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
PLAY RECAP *********************************************************************
ali2v.truenas.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
ali2v.xeon.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
automate.prod.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
dev.lab.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
dev.prod.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
hp.nas.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
hp.truenas.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=1
hp2.i7.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
hp3.i5.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
jump.point.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
localhost : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
media.labb.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
mimi.pc.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
orangepi.pc.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
raspi.4gb.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
raspi.8gb.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
```
---
*Généré automatiquement par Homelab Automation Dashboard*
*Date: 2025-12-16T01:05:22.959566+00:00*

View File

@ -0,0 +1,224 @@
# ✅ [Planifié] Health-check-5min
## Informations
| Propriété | Valeur |
|-----------|--------|
| **ID** | `65143541bd64425e91aa80f729823fa0` |
| **Nom** | [Planifié] Health-check-5min |
| **Cible** | `all` |
| **Statut** | completed |
| **Type** | Planifié |
| **Progression** | 100% |
| **Début** | 2025-12-16T01:10:00.001100+00:00 |
| **Fin** | 2025-12-16T01:10:21.154299+00:00 |
| **Durée** | 21.2s |
## Sortie
```
Using /mnt/c/dev/git/python/homelab-automation-api-v2/ansible/ansible.cfg as config file
PLAY [Health check on target host] *********************************************
TASK [Check if host is reachable (ping)] ***************************************
ok: [hp.nas.home] => {"changed": false, "ping": "pong"}
ok: [hp2.i7.home] => {"changed": false, "ping": "pong"}
ok: [mimi.pc.home] => {"changed": false, "ping": "pong"}
ok: [ali2v.xeon.home] => {"changed": false, "ping": "pong"}
ok: [hp3.i5.home] => {"changed": false, "ping": "pong"}
ok: [dev.lab.home] => {"changed": false, "ping": "pong"}
ok: [media.labb.home] => {"changed": false, "ping": "pong"}
ok: [raspi.8gb.home] => {"changed": false, "ping": "pong"}
ok: [raspi.4gb.home] => {"changed": false, "ping": "pong"}
ok: [automate.prod.home] => {"changed": false, "ping": "pong"}
ok: [ali2v.truenas.home] => {"changed": false, "ping": "pong"}
ok: [hp.truenas.home] => {"changed": false, "ping": "pong"}
ok: [localhost] => {"changed": false, "ping": "pong"}
ok: [dev.prod.home] => {"changed": false, "ping": "pong"}
ok: [jump.point.home] => {"changed": false, "ping": "pong"}
ok: [orangepi.pc.home] => {"changed": false, "ping": "pong"}
TASK [Gather minimal facts] ****************************************************
ok: [hp.nas.home]
ok: [mimi.pc.home]
ok: [ali2v.xeon.home]
ok: [hp2.i7.home]
ok: [hp3.i5.home]
ok: [dev.lab.home]
ok: [media.labb.home]
ok: [raspi.8gb.home]
ok: [raspi.4gb.home]
ok: [ali2v.truenas.home]
ok: [automate.prod.home]
ok: [hp.truenas.home]
ok: [dev.prod.home]
ok: [jump.point.home]
ok: [localhost]
ok: [orangepi.pc.home]
TASK [Get system uptime] *******************************************************
ok: [hp.nas.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003162", "end": "2025-12-15 20:10:11.034181", "msg": "", "rc": 0, "start": "2025-12-15 20:10:11.031019", "stderr": "", "stderr_lines": [], "stdout": " 20:10:11 up 20 days, 7:01, 1 user, load average: 0.74, 0.48, 0.34", "stdout_lines": [" 20:10:11 up 20 days, 7:01, 1 user, load average: 0.74, 0.48, 0.34"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003975", "end": "2025-12-15 20:10:11.051859", "msg": "", "rc": 0, "start": "2025-12-15 20:10:11.047884", "stderr": "", "stderr_lines": [], "stdout": " 20:10:11 up 20 days, 9:20, 1 user, load average: 0.04, 0.03, 0.00", "stdout_lines": [" 20:10:11 up 20 days, 9:20, 1 user, load average: 0.04, 0.03, 0.00"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003146", "end": "2025-12-15 20:10:11.069851", "msg": "", "rc": 0, "start": "2025-12-15 20:10:11.066705", "stderr": "", "stderr_lines": [], "stdout": " 20:10:11 up 20 days, 7:21, 1 user, load average: 0.68, 0.83, 0.79", "stdout_lines": [" 20:10:11 up 20 days, 7:21, 1 user, load average: 0.68, 0.83, 0.79"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003993", "end": "2025-12-15 20:10:11.070890", "msg": "", "rc": 0, "start": "2025-12-15 20:10:11.066897", "stderr": "", "stderr_lines": [], "stdout": " 20:10:11 up 20 days, 8:34, 1 user, load average: 0.69, 0.68, 0.64", "stdout_lines": [" 20:10:11 up 20 days, 8:34, 1 user, load average: 0.69, 0.68, 0.64"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003036", "end": "2025-12-15 20:10:11.077473", "msg": "", "rc": 0, "start": "2025-12-15 20:10:11.074437", "stderr": "", "stderr_lines": [], "stdout": " 20:10:11 up 1 day, 9:42, 1 user, load average: 0.51, 0.34, 0.26", "stdout_lines": [" 20:10:11 up 1 day, 9:42, 1 user, load average: 0.51, 0.34, 0.26"]}
ok: [dev.lab.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003185", "end": "2025-12-15 20:09:46.885229", "msg": "", "rc": 0, "start": "2025-12-15 20:09:46.882044", "stderr": "", "stderr_lines": [], "stdout": " 20:09:46 up 9 days, 7:59, 0 user, load average: 0.05, 0.07, 0.09", "stdout_lines": [" 20:09:46 up 9 days, 7:59, 0 user, load average: 0.05, 0.07, 0.09"]}
ok: [media.labb.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003385", "end": "2025-12-15 20:09:41.006649", "msg": "", "rc": 0, "start": "2025-12-15 20:09:41.003264", "stderr": "", "stderr_lines": [], "stdout": " 20:09:41 up 16 days, 4:11, 0 user, load average: 0.11, 0.11, 0.05", "stdout_lines": [" 20:09:41 up 16 days, 4:11, 0 user, load average: 0.11, 0.11, 0.05"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.008499", "end": "2025-12-15 20:10:11.732159", "msg": "", "rc": 0, "start": "2025-12-15 20:10:11.723660", "stderr": "", "stderr_lines": [], "stdout": " 20:10:11 up 192 days, 11:43, 1 user, load average: 0.23, 0.19, 0.12", "stdout_lines": [" 20:10:11 up 192 days, 11:43, 1 user, load average: 0.23, 0.19, 0.12"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.009364", "end": "2025-12-15 20:10:11.786024", "msg": "", "rc": 0, "start": "2025-12-15 20:10:11.776660", "stderr": "", "stderr_lines": [], "stdout": " 20:10:11 up 192 days, 11:43, 1 user, load average: 0.37, 0.31, 0.28", "stdout_lines": [" 20:10:11 up 192 days, 11:43, 1 user, load average: 0.37, 0.31, 0.28"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.004732", "end": "2025-12-15 20:10:11.987798", "msg": "", "rc": 0, "start": "2025-12-15 20:10:11.983066", "stderr": "", "stderr_lines": [], "stdout": " 20:10:11 up 1 day, 9:41, 1 user, load average: 0.14, 0.12, 0.04", "stdout_lines": [" 20:10:11 up 1 day, 9:41, 1 user, load average: 0.14, 0.12, 0.04"]}
ok: [automate.prod.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003145", "end": "2025-12-15 20:09:44.167841", "msg": "", "rc": 0, "start": "2025-12-15 20:09:44.164696", "stderr": "", "stderr_lines": [], "stdout": " 20:09:44 up 18 days, 23:04, 0 user, load average: 0.22, 0.39, 0.44", "stdout_lines": [" 20:09:44 up 18 days, 23:04, 0 user, load average: 0.22, 0.39, 0.44"]}
ok: [dev.prod.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.002859", "end": "2025-12-15 20:09:50.193406", "msg": "", "rc": 0, "start": "2025-12-15 20:09:50.190547", "stderr": "", "stderr_lines": [], "stdout": " 20:09:50 up 15 days, 9:25, 0 user, load average: 0.20, 0.22, 0.23", "stdout_lines": [" 20:09:50 up 15 days, 9:25, 0 user, load average: 0.20, 0.22, 0.23"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.004292", "end": "2025-12-15 17:10:12.237828", "msg": "", "rc": 0, "start": "2025-12-15 17:10:12.233536", "stderr": "", "stderr_lines": [], "stdout": " 5:10PM up 20 days, 6:59, 1 user, load averages: 0.22, 0.26, 0.24", "stdout_lines": [" 5:10PM up 20 days, 6:59, 1 user, load averages: 0.22, 0.26, 0.24"]}
ok: [jump.point.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003768", "end": "2025-12-15 20:10:12.394777", "msg": "", "rc": 0, "start": "2025-12-15 20:10:12.391009", "stderr": "", "stderr_lines": [], "stdout": " 20:10:12 up 1 day, 9:41, 1 user, load average: 0.24, 0.13, 0.06", "stdout_lines": [" 20:10:12 up 1 day, 9:41, 1 user, load average: 0.24, 0.13, 0.06"]}
ok: [localhost] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.005361", "end": "2025-12-15 20:10:12.649619", "msg": "", "rc": 0, "start": "2025-12-15 20:10:12.644258", "stderr": "", "stderr_lines": [], "stdout": " 20:10:12 up 6:45, 1 user, load average: 1.36, 1.41, 1.35", "stdout_lines": [" 20:10:12 up 6:45, 1 user, load average: 1.36, 1.41, 1.35"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.019411", "end": "2025-12-15 20:10:12.426509", "msg": "", "rc": 0, "start": "2025-12-15 20:10:12.407098", "stderr": "", "stderr_lines": [], "stdout": " 20:10:12 up 13 days, 9:36, 1 user, load average: 0.16, 0.13, 0.10", "stdout_lines": [" 20:10:12 up 13 days, 9:36, 1 user, load average: 0.16, 0.13, 0.10"]}
TASK [Get disk usage] **********************************************************
ok: [hp.nas.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004473", "end": "2025-12-15 20:10:12.963423", "msg": "", "rc": 0, "start": "2025-12-15 20:10:12.958950", "stderr": "", "stderr_lines": [], "stdout": "23%", "stdout_lines": ["23%"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005470", "end": "2025-12-15 20:10:12.987450", "msg": "", "rc": 0, "start": "2025-12-15 20:10:12.981980", "stderr": "", "stderr_lines": [], "stdout": "14%", "stdout_lines": ["14%"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004097", "end": "2025-12-15 20:10:12.991422", "msg": "", "rc": 0, "start": "2025-12-15 20:10:12.987325", "stderr": "", "stderr_lines": [], "stdout": "22%", "stdout_lines": ["22%"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004938", "end": "2025-12-15 20:10:13.007189", "msg": "", "rc": 0, "start": "2025-12-15 20:10:13.002251", "stderr": "", "stderr_lines": [], "stdout": "9%", "stdout_lines": ["9%"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005668", "end": "2025-12-15 20:10:13.047038", "msg": "", "rc": 0, "start": "2025-12-15 20:10:13.041370", "stderr": "", "stderr_lines": [], "stdout": "14%", "stdout_lines": ["14%"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005325", "end": "2025-12-15 20:09:48.833856", "msg": "", "rc": 0, "start": "2025-12-15 20:09:48.828531", "stderr": "", "stderr_lines": [], "stdout": "48%", "stdout_lines": ["48%"]}
ok: [media.labb.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005755", "end": "2025-12-15 20:09:42.980949", "msg": "", "rc": 0, "start": "2025-12-15 20:09:42.975194", "stderr": "", "stderr_lines": [], "stdout": "24%", "stdout_lines": ["24%"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.010666", "end": "2025-12-15 20:10:13.712395", "msg": "", "rc": 0, "start": "2025-12-15 20:10:13.701729", "stderr": "", "stderr_lines": [], "stdout": "3%", "stdout_lines": ["3%"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.011813", "end": "2025-12-15 20:10:13.752229", "msg": "", "rc": 0, "start": "2025-12-15 20:10:13.740416", "stderr": "", "stderr_lines": [], "stdout": "6%", "stdout_lines": ["6%"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005721", "end": "2025-12-15 20:10:13.937169", "msg": "", "rc": 0, "start": "2025-12-15 20:10:13.931448", "stderr": "", "stderr_lines": [], "stdout": "1%", "stdout_lines": ["1%"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005106", "end": "2025-12-15 20:09:46.157332", "msg": "", "rc": 0, "start": "2025-12-15 20:09:46.152226", "stderr": "", "stderr_lines": [], "stdout": "28%", "stdout_lines": ["28%"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005392", "end": "2025-12-15 17:10:14.217363", "msg": "", "rc": 0, "start": "2025-12-15 17:10:14.211971", "stderr": "", "stderr_lines": [], "stdout": "10%", "stdout_lines": ["10%"]}
ok: [dev.prod.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005075", "end": "2025-12-15 20:09:52.188584", "msg": "", "rc": 0, "start": "2025-12-15 20:09:52.183509", "stderr": "", "stderr_lines": [], "stdout": "75%", "stdout_lines": ["75%"]}
ok: [jump.point.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005632", "end": "2025-12-15 20:10:14.358095", "msg": "", "rc": 0, "start": "2025-12-15 20:10:14.352463", "stderr": "", "stderr_lines": [], "stdout": "79%", "stdout_lines": ["79%"]}
ok: [localhost] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.007044", "end": "2025-12-15 20:10:14.584727", "msg": "", "rc": 0, "start": "2025-12-15 20:10:14.577683", "stderr": "", "stderr_lines": [], "stdout": "1%", "stdout_lines": ["1%"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.025591", "end": "2025-12-15 20:10:14.346207", "msg": "", "rc": 0, "start": "2025-12-15 20:10:14.320616", "stderr": "", "stderr_lines": [], "stdout": "21%", "stdout_lines": ["21%"]}
TASK [Get memory usage (Linux)] ************************************************
ok: [hp.nas.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004444", "end": "2025-12-15 20:10:14.871347", "msg": "", "rc": 0, "start": "2025-12-15 20:10:14.866903", "stderr": "", "stderr_lines": [], "stdout": "80.9%", "stdout_lines": ["80.9%"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004102", "end": "2025-12-15 20:10:14.881391", "msg": "", "rc": 0, "start": "2025-12-15 20:10:14.877289", "stderr": "", "stderr_lines": [], "stdout": "21.8%", "stdout_lines": ["21.8%"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004794", "end": "2025-12-15 20:10:14.898384", "msg": "", "rc": 0, "start": "2025-12-15 20:10:14.893590", "stderr": "", "stderr_lines": [], "stdout": "48.9%", "stdout_lines": ["48.9%"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004843", "end": "2025-12-15 20:10:14.919994", "msg": "", "rc": 0, "start": "2025-12-15 20:10:14.915151", "stderr": "", "stderr_lines": [], "stdout": "8.9%", "stdout_lines": ["8.9%"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005518", "end": "2025-12-15 20:10:14.938198", "msg": "", "rc": 0, "start": "2025-12-15 20:10:14.932680", "stderr": "", "stderr_lines": [], "stdout": "59.5%", "stdout_lines": ["59.5%"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004397", "end": "2025-12-15 20:09:50.769494", "msg": "", "rc": 0, "start": "2025-12-15 20:09:50.765097", "stderr": "", "stderr_lines": [], "stdout": "71.3%", "stdout_lines": ["71.3%"]}
ok: [media.labb.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004658", "end": "2025-12-15 20:09:44.880851", "msg": "", "rc": 0, "start": "2025-12-15 20:09:44.876193", "stderr": "", "stderr_lines": [], "stdout": "72.2%", "stdout_lines": ["72.2%"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.012357", "end": "2025-12-15 20:10:15.561625", "msg": "", "rc": 0, "start": "2025-12-15 20:10:15.549268", "stderr": "", "stderr_lines": [], "stdout": "6.8%", "stdout_lines": ["6.8%"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.012057", "end": "2025-12-15 20:10:15.590231", "msg": "", "rc": 0, "start": "2025-12-15 20:10:15.578174", "stderr": "", "stderr_lines": [], "stdout": "12.3%", "stdout_lines": ["12.3%"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005988", "end": "2025-12-15 20:10:15.884859", "msg": "", "rc": 0, "start": "2025-12-15 20:10:15.878871", "stderr": "", "stderr_lines": [], "stdout": "34.1%", "stdout_lines": ["34.1%"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004064", "end": "2025-12-15 20:09:48.045575", "msg": "", "rc": 0, "start": "2025-12-15 20:09:48.041511", "stderr": "", "stderr_lines": [], "stdout": "26.1%", "stdout_lines": ["26.1%"]}
fatal: [hp.truenas.home]: FAILED! => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005531", "end": "2025-12-15 17:10:16.041122", "msg": "non-zero return code", "rc": 2, "start": "2025-12-15 17:10:16.035591", "stderr": "cat: /proc/meminfo: No such file or directory\nawk: division by zero\n source line number 1", "stderr_lines": ["cat: /proc/meminfo: No such file or directory", "awk: division by zero", " source line number 1"], "stdout": "", "stdout_lines": []}
...ignoring
ok: [dev.prod.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.003896", "end": "2025-12-15 20:09:54.031658", "msg": "", "rc": 0, "start": "2025-12-15 20:09:54.027762", "stderr": "", "stderr_lines": [], "stdout": "56.2%", "stdout_lines": ["56.2%"]}
ok: [localhost] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.007780", "end": "2025-12-15 20:10:16.470473", "msg": "", "rc": 0, "start": "2025-12-15 20:10:16.462693", "stderr": "", "stderr_lines": [], "stdout": "12.7%", "stdout_lines": ["12.7%"]}
ok: [jump.point.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.006055", "end": "2025-12-15 20:10:16.300857", "msg": "", "rc": 0, "start": "2025-12-15 20:10:16.294802", "stderr": "", "stderr_lines": [], "stdout": "13.7%", "stdout_lines": ["13.7%"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.025776", "end": "2025-12-15 20:10:16.245219", "msg": "", "rc": 0, "start": "2025-12-15 20:10:16.219443", "stderr": "", "stderr_lines": [], "stdout": "19.4%", "stdout_lines": ["19.4%"]}
TASK [Get CPU temperature (ARM/SBC)] *******************************************
ok: [hp.nas.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.005317", "end": "2025-12-15 20:10:16.783991", "msg": "", "rc": 0, "start": "2025-12-15 20:10:16.778674", "stderr": "", "stderr_lines": [], "stdout": "30.0°C", "stdout_lines": ["30.0°C"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.005293", "end": "2025-12-15 20:10:16.792300", "msg": "", "rc": 0, "start": "2025-12-15 20:10:16.787007", "stderr": "cat: /sys/class/thermal/thermal_zone0/temp: No data available", "stderr_lines": ["cat: /sys/class/thermal/thermal_zone0/temp: No data available"], "stdout": "0.0°C", "stdout_lines": ["0.0°C"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.004867", "end": "2025-12-15 20:10:16.795925", "msg": "", "rc": 0, "start": "2025-12-15 20:10:16.791058", "stderr": "", "stderr_lines": [], "stdout": "47.0°C", "stdout_lines": ["47.0°C"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003377", "end": "2025-12-15 20:10:16.811042", "msg": "", "rc": 0, "start": "2025-12-15 20:10:16.807665", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.006600", "end": "2025-12-15 20:10:16.830951", "msg": "", "rc": 0, "start": "2025-12-15 20:10:16.824351", "stderr": "", "stderr_lines": [], "stdout": "52.5°C", "stdout_lines": ["52.5°C"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.002683", "end": "2025-12-15 20:09:52.632415", "msg": "", "rc": 0, "start": "2025-12-15 20:09:52.629732", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [media.labb.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003271", "end": "2025-12-15 20:09:46.773739", "msg": "", "rc": 0, "start": "2025-12-15 20:09:46.770468", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.011707", "end": "2025-12-15 20:10:17.466281", "msg": "", "rc": 0, "start": "2025-12-15 20:10:17.454574", "stderr": "", "stderr_lines": [], "stdout": "32.6°C", "stdout_lines": ["32.6°C"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.013250", "end": "2025-12-15 20:10:17.518123", "msg": "", "rc": 0, "start": "2025-12-15 20:10:17.504873", "stderr": "", "stderr_lines": [], "stdout": "35.5°C", "stdout_lines": ["35.5°C"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003102", "end": "2025-12-15 20:10:17.740654", "msg": "", "rc": 0, "start": "2025-12-15 20:10:17.737552", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.002895", "end": "2025-12-15 20:09:49.920462", "msg": "", "rc": 0, "start": "2025-12-15 20:09:49.917567", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [dev.prod.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.002883", "end": "2025-12-15 20:09:55.918060", "msg": "", "rc": 0, "start": "2025-12-15 20:09:55.915177", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.004037", "end": "2025-12-15 17:10:17.972533", "msg": "", "rc": 0, "start": "2025-12-15 17:10:17.968496", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [jump.point.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.002981", "end": "2025-12-15 20:10:18.151950", "msg": "", "rc": 0, "start": "2025-12-15 20:10:18.148969", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [localhost] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.004447", "end": "2025-12-15 20:10:18.368585", "msg": "", "rc": 0, "start": "2025-12-15 20:10:18.364138", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.028446", "end": "2025-12-15 20:10:18.169043", "msg": "", "rc": 0, "start": "2025-12-15 20:10:18.140597", "stderr": "", "stderr_lines": [], "stdout": "36.4°C", "stdout_lines": ["36.4°C"]}
TASK [Get CPU load] ************************************************************
ok: [hp.nas.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004183", "end": "2025-12-15 20:10:18.681514", "msg": "", "rc": 0, "start": "2025-12-15 20:10:18.677331", "stderr": "", "stderr_lines": [], "stdout": "0.63", "stdout_lines": ["0.63"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004001", "end": "2025-12-15 20:10:18.712970", "msg": "", "rc": 0, "start": "2025-12-15 20:10:18.708969", "stderr": "", "stderr_lines": [], "stdout": "0.55", "stdout_lines": ["0.55"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004764", "end": "2025-12-15 20:10:18.723810", "msg": "", "rc": 0, "start": "2025-12-15 20:10:18.719046", "stderr": "", "stderr_lines": [], "stdout": "0.70", "stdout_lines": ["0.70"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005199", "end": "2025-12-15 20:10:18.739890", "msg": "", "rc": 0, "start": "2025-12-15 20:10:18.734691", "stderr": "", "stderr_lines": [], "stdout": "0.04", "stdout_lines": ["0.04"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.007140", "end": "2025-12-15 20:10:18.756236", "msg": "", "rc": 0, "start": "2025-12-15 20:10:18.749096", "stderr": "", "stderr_lines": [], "stdout": "0.71", "stdout_lines": ["0.71"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004142", "end": "2025-12-15 20:09:54.548974", "msg": "", "rc": 0, "start": "2025-12-15 20:09:54.544832", "stderr": "", "stderr_lines": [], "stdout": "0.04", "stdout_lines": ["0.04"]}
ok: [media.labb.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005609", "end": "2025-12-15 20:09:48.711637", "msg": "", "rc": 0, "start": "2025-12-15 20:09:48.706028", "stderr": "", "stderr_lines": [], "stdout": "0.10", "stdout_lines": ["0.10"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.010219", "end": "2025-12-15 20:10:19.449078", "msg": "", "rc": 0, "start": "2025-12-15 20:10:19.438859", "stderr": "", "stderr_lines": [], "stdout": "0.28", "stdout_lines": ["0.28"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.011353", "end": "2025-12-15 20:10:19.505442", "msg": "", "rc": 0, "start": "2025-12-15 20:10:19.494089", "stderr": "", "stderr_lines": [], "stdout": "0.39", "stdout_lines": ["0.39"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005603", "end": "2025-12-15 20:10:19.670739", "msg": "", "rc": 0, "start": "2025-12-15 20:10:19.665136", "stderr": "", "stderr_lines": [], "stdout": "0.13", "stdout_lines": ["0.13"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005330", "end": "2025-12-15 20:09:51.898081", "msg": "", "rc": 0, "start": "2025-12-15 20:09:51.892751", "stderr": "", "stderr_lines": [], "stdout": "0.36", "stdout_lines": ["0.36"]}
ok: [dev.prod.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004265", "end": "2025-12-15 20:09:57.897877", "msg": "", "rc": 0, "start": "2025-12-15 20:09:57.893612", "stderr": "", "stderr_lines": [], "stdout": "0.19", "stdout_lines": ["0.19"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005890", "end": "2025-12-15 17:10:19.958576", "msg": "", "rc": 0, "start": "2025-12-15 17:10:19.952686", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}
ok: [jump.point.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005294", "end": "2025-12-15 20:10:20.087409", "msg": "", "rc": 0, "start": "2025-12-15 20:10:20.082115", "stderr": "", "stderr_lines": [], "stdout": "0.35", "stdout_lines": ["0.35"]}
ok: [localhost] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.006431", "end": "2025-12-15 20:10:20.365105", "msg": "", "rc": 0, "start": "2025-12-15 20:10:20.358674", "stderr": "", "stderr_lines": [], "stdout": "1.38", "stdout_lines": ["1.38"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.024238", "end": "2025-12-15 20:10:20.080236", "msg": "", "rc": 0, "start": "2025-12-15 20:10:20.055998", "stderr": "", "stderr_lines": [], "stdout": "0.21", "stdout_lines": ["0.21"]}
TASK [Display health status] ***************************************************
ok: [ali2v.xeon.home] => {
"msg": "═══════════════════════════════════════\nHost: ali2v.xeon.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:10:11 up 1 day, 9:42, 1 user, load average: 0.51, 0.34, 0.26\nDisk Usage: 22%\nMemory Usage: 21.8%\nCPU Load: 0.55\nCPU Temp: 47.0°C\n═══════════════════════════════════════\n"
}
ok: [hp.nas.home] => {
"msg": "═══════════════════════════════════════\nHost: hp.nas.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:10:11 up 20 days, 7:01, 1 user, load average: 0.74, 0.48, 0.34\nDisk Usage: 23%\nMemory Usage: 80.9%\nCPU Load: 0.63\nCPU Temp: 30.0°C\n═══════════════════════════════════════\n"
}
ok: [hp2.i7.home] => {
"msg": "═══════════════════════════════════════\nHost: hp2.i7.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:10:11 up 20 days, 7:21, 1 user, load average: 0.68, 0.83, 0.79\nDisk Usage: 14%\nMemory Usage: 48.9%\nCPU Load: 0.70\nCPU Temp: 0.0°C\n═══════════════════════════════════════\n"
}
ok: [hp3.i5.home] => {
"msg": "═══════════════════════════════════════\nHost: hp3.i5.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:10:11 up 20 days, 8:34, 1 user, load average: 0.69, 0.68, 0.64\nDisk Usage: 14%\nMemory Usage: 59.5%\nCPU Load: 0.71\nCPU Temp: 52.5°C\n═══════════════════════════════════════\n"
}
ok: [mimi.pc.home] => {
"msg": "═══════════════════════════════════════\nHost: mimi.pc.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:10:11 up 20 days, 9:20, 1 user, load average: 0.04, 0.03, 0.00\nDisk Usage: 9%\nMemory Usage: 8.9%\nCPU Load: 0.04\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [orangepi.pc.home] => {
"msg": "═══════════════════════════════════════\nHost: orangepi.pc.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:10:12 up 13 days, 9:36, 1 user, load average: 0.16, 0.13, 0.10\nDisk Usage: 21%\nMemory Usage: 19.4%\nCPU Load: 0.21\nCPU Temp: 36.4°C\n═══════════════════════════════════════\n"
}
ok: [raspi.4gb.home] => {
"msg": "═══════════════════════════════════════\nHost: raspi.4gb.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:10:11 up 192 days, 11:43, 1 user, load average: 0.37, 0.31, 0.28\nDisk Usage: 6%\nMemory Usage: 12.3%\nCPU Load: 0.39\nCPU Temp: 35.5°C\n═══════════════════════════════════════\n"
}
ok: [raspi.8gb.home] => {
"msg": "═══════════════════════════════════════\nHost: raspi.8gb.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:10:11 up 192 days, 11:43, 1 user, load average: 0.23, 0.19, 0.12\nDisk Usage: 3%\nMemory Usage: 6.8%\nCPU Load: 0.28\nCPU Temp: 32.6°C\n═══════════════════════════════════════\n"
}
ok: [dev.lab.home] => {
"msg": "═══════════════════════════════════════\nHost: dev.lab.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:09:46 up 9 days, 7:59, 0 user, load average: 0.05, 0.07, 0.09\nDisk Usage: 48%\nMemory Usage: 71.3%\nCPU Load: 0.04\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [media.labb.home] => {
"msg": "═══════════════════════════════════════\nHost: media.labb.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:09:41 up 16 days, 4:11, 0 user, load average: 0.11, 0.11, 0.05\nDisk Usage: 24%\nMemory Usage: 72.2%\nCPU Load: 0.10\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [ali2v.truenas.home] => {
"msg": "═══════════════════════════════════════\nHost: ali2v.truenas.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:10:11 up 1 day, 9:41, 1 user, load average: 0.14, 0.12, 0.04\nDisk Usage: 1%\nMemory Usage: 34.1%\nCPU Load: 0.13\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [automate.prod.home] => {
"msg": "═══════════════════════════════════════\nHost: automate.prod.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:09:44 up 18 days, 23:04, 0 user, load average: 0.22, 0.39, 0.44\nDisk Usage: 28%\nMemory Usage: 26.1%\nCPU Load: 0.36\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [dev.prod.home] => {
"msg": "═══════════════════════════════════════\nHost: dev.prod.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:09:50 up 15 days, 9:25, 0 user, load average: 0.20, 0.22, 0.23\nDisk Usage: 75%\nMemory Usage: 56.2%\nCPU Load: 0.19\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [hp.truenas.home] => {
"msg": "═══════════════════════════════════════\nHost: hp.truenas.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 5:10PM up 20 days, 6:59, 1 user, load averages: 0.22, 0.26, 0.24\nDisk Usage: 10%\nMemory Usage: \nCPU Load: \nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [jump.point.home] => {
"msg": "═══════════════════════════════════════\nHost: jump.point.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:10:12 up 1 day, 9:41, 1 user, load average: 0.24, 0.13, 0.06\nDisk Usage: 79%\nMemory Usage: 13.7%\nCPU Load: 0.35\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [localhost] => {
"msg": "═══════════════════════════════════════\nHost: localhost\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:10:12 up 6:45, 1 user, load average: 1.36, 1.41, 1.35\nDisk Usage: 1%\nMemory Usage: 12.7%\nCPU Load: 1.38\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
PLAY RECAP *********************************************************************
ali2v.truenas.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
ali2v.xeon.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
automate.prod.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
dev.lab.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
dev.prod.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
hp.nas.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
hp.truenas.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=1
hp2.i7.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
hp3.i5.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
jump.point.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
localhost : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
media.labb.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
mimi.pc.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
orangepi.pc.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
raspi.4gb.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
raspi.8gb.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
```
---
*Généré automatiquement par Homelab Automation Dashboard*
*Date: 2025-12-16T01:10:21.187670+00:00*

View File

@ -0,0 +1,224 @@
# ✅ [Planifié] Health-check-5min
## Informations
| Propriété | Valeur |
|-----------|--------|
| **ID** | `b3b86b51f655407f92a12ccf7bb847eb` |
| **Nom** | [Planifié] Health-check-5min |
| **Cible** | `all` |
| **Statut** | completed |
| **Type** | Planifié |
| **Progression** | 100% |
| **Début** | 2025-12-16T01:15:00.000904+00:00 |
| **Fin** | 2025-12-16T01:15:21.722933+00:00 |
| **Durée** | 21.7s |
## Sortie
```
Using /mnt/c/dev/git/python/homelab-automation-api-v2/ansible/ansible.cfg as config file
PLAY [Health check on target host] *********************************************
TASK [Check if host is reachable (ping)] ***************************************
ok: [hp.nas.home] => {"changed": false, "ping": "pong"}
ok: [hp2.i7.home] => {"changed": false, "ping": "pong"}
ok: [mimi.pc.home] => {"changed": false, "ping": "pong"}
ok: [hp3.i5.home] => {"changed": false, "ping": "pong"}
ok: [ali2v.xeon.home] => {"changed": false, "ping": "pong"}
ok: [dev.lab.home] => {"changed": false, "ping": "pong"}
ok: [media.labb.home] => {"changed": false, "ping": "pong"}
ok: [raspi.8gb.home] => {"changed": false, "ping": "pong"}
ok: [raspi.4gb.home] => {"changed": false, "ping": "pong"}
ok: [automate.prod.home] => {"changed": false, "ping": "pong"}
ok: [ali2v.truenas.home] => {"changed": false, "ping": "pong"}
ok: [hp.truenas.home] => {"changed": false, "ping": "pong"}
ok: [localhost] => {"changed": false, "ping": "pong"}
ok: [dev.prod.home] => {"changed": false, "ping": "pong"}
ok: [jump.point.home] => {"changed": false, "ping": "pong"}
ok: [orangepi.pc.home] => {"changed": false, "ping": "pong"}
TASK [Gather minimal facts] ****************************************************
ok: [hp.nas.home]
ok: [hp2.i7.home]
ok: [mimi.pc.home]
ok: [hp3.i5.home]
ok: [ali2v.xeon.home]
ok: [dev.lab.home]
ok: [media.labb.home]
ok: [raspi.8gb.home]
ok: [raspi.4gb.home]
ok: [ali2v.truenas.home]
ok: [automate.prod.home]
ok: [hp.truenas.home]
ok: [dev.prod.home]
ok: [jump.point.home]
ok: [localhost]
ok: [orangepi.pc.home]
TASK [Get system uptime] *******************************************************
ok: [hp.nas.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003054", "end": "2025-12-15 20:15:11.393040", "msg": "", "rc": 0, "start": "2025-12-15 20:15:11.389986", "stderr": "", "stderr_lines": [], "stdout": " 20:15:11 up 20 days, 7:06, 1 user, load average: 0.52, 0.45, 0.36", "stdout_lines": [" 20:15:11 up 20 days, 7:06, 1 user, load average: 0.52, 0.45, 0.36"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003947", "end": "2025-12-15 20:15:11.411279", "msg": "", "rc": 0, "start": "2025-12-15 20:15:11.407332", "stderr": "", "stderr_lines": [], "stdout": " 20:15:11 up 20 days, 9:25, 1 user, load average: 0.01, 0.02, 0.00", "stdout_lines": [" 20:15:11 up 20 days, 9:25, 1 user, load average: 0.01, 0.02, 0.00"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003848", "end": "2025-12-15 20:15:11.417576", "msg": "", "rc": 0, "start": "2025-12-15 20:15:11.413728", "stderr": "", "stderr_lines": [], "stdout": " 20:15:11 up 20 days, 7:26, 1 user, load average: 0.96, 0.85, 0.80", "stdout_lines": [" 20:15:11 up 20 days, 7:26, 1 user, load average: 0.96, 0.85, 0.80"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.002986", "end": "2025-12-15 20:15:11.437212", "msg": "", "rc": 0, "start": "2025-12-15 20:15:11.434226", "stderr": "", "stderr_lines": [], "stdout": " 20:15:11 up 1 day, 9:47, 1 user, load average: 0.52, 0.48, 0.35", "stdout_lines": [" 20:15:11 up 1 day, 9:47, 1 user, load average: 0.52, 0.48, 0.35"]}
ok: [dev.lab.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003442", "end": "2025-12-15 20:14:47.254633", "msg": "", "rc": 0, "start": "2025-12-15 20:14:47.251191", "stderr": "", "stderr_lines": [], "stdout": " 20:14:47 up 9 days, 8:04, 0 user, load average: 0.04, 0.10, 0.09", "stdout_lines": [" 20:14:47 up 9 days, 8:04, 0 user, load average: 0.04, 0.10, 0.09"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.008613", "end": "2025-12-15 20:15:12.081145", "msg": "", "rc": 0, "start": "2025-12-15 20:15:12.072532", "stderr": "", "stderr_lines": [], "stdout": " 20:15:12 up 192 days, 11:48, 1 user, load average: 0.37, 0.25, 0.15", "stdout_lines": [" 20:15:12 up 192 days, 11:48, 1 user, load average: 0.37, 0.25, 0.15"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.009374", "end": "2025-12-15 20:15:12.124656", "msg": "", "rc": 0, "start": "2025-12-15 20:15:12.115282", "stderr": "", "stderr_lines": [], "stdout": " 20:15:12 up 192 days, 11:48, 1 user, load average: 0.40, 0.26, 0.26", "stdout_lines": [" 20:15:12 up 192 days, 11:48, 1 user, load average: 0.40, 0.26, 0.26"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:01.005080", "end": "2025-12-15 20:15:12.426376", "msg": "", "rc": 0, "start": "2025-12-15 20:15:11.421296", "stderr": "", "stderr_lines": [], "stdout": " 20:15:11 up 20 days, 8:39, 1 user, load average: 1.05, 0.70, 0.64", "stdout_lines": [" 20:15:11 up 20 days, 8:39, 1 user, load average: 1.05, 0.70, 0.64"]}
ok: [media.labb.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003757", "end": "2025-12-15 20:14:41.837745", "msg": "", "rc": 0, "start": "2025-12-15 20:14:41.833988", "stderr": "", "stderr_lines": [], "stdout": " 20:14:41 up 16 days, 4:16, 0 user, load average: 0.01, 0.04, 0.02", "stdout_lines": [" 20:14:41 up 16 days, 4:16, 0 user, load average: 0.01, 0.04, 0.02"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.004569", "end": "2025-12-15 20:15:12.584967", "msg": "", "rc": 0, "start": "2025-12-15 20:15:12.580398", "stderr": "", "stderr_lines": [], "stdout": " 20:15:12 up 1 day, 9:46, 1 user, load average: 0.00, 0.04, 0.02", "stdout_lines": [" 20:15:12 up 1 day, 9:46, 1 user, load average: 0.00, 0.04, 0.02"]}
ok: [automate.prod.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003264", "end": "2025-12-15 20:14:44.723695", "msg": "", "rc": 0, "start": "2025-12-15 20:14:44.720431", "stderr": "", "stderr_lines": [], "stdout": " 20:14:44 up 18 days, 23:09, 0 user, load average: 0.28, 0.37, 0.42", "stdout_lines": [" 20:14:44 up 18 days, 23:09, 0 user, load average: 0.28, 0.37, 0.42"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.004290", "end": "2025-12-15 17:15:12.865577", "msg": "", "rc": 0, "start": "2025-12-15 17:15:12.861287", "stderr": "", "stderr_lines": [], "stdout": " 5:15PM up 20 days, 7:05, 1 user, load averages: 0.37, 0.25, 0.24", "stdout_lines": [" 5:15PM up 20 days, 7:05, 1 user, load averages: 0.37, 0.25, 0.24"]}
ok: [dev.prod.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.002918", "end": "2025-12-15 20:14:50.876361", "msg": "", "rc": 0, "start": "2025-12-15 20:14:50.873443", "stderr": "", "stderr_lines": [], "stdout": " 20:14:50 up 15 days, 9:30, 0 user, load average: 0.13, 0.22, 0.23", "stdout_lines": [" 20:14:50 up 15 days, 9:30, 0 user, load average: 0.13, 0.22, 0.23"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.019744", "end": "2025-12-15 20:15:12.792405", "msg": "", "rc": 0, "start": "2025-12-15 20:15:12.772661", "stderr": "", "stderr_lines": [], "stdout": " 20:15:12 up 13 days, 9:41, 1 user, load average: 0.20, 0.10, 0.09", "stdout_lines": [" 20:15:12 up 13 days, 9:41, 1 user, load average: 0.20, 0.10, 0.09"]}
ok: [jump.point.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003853", "end": "2025-12-15 20:15:13.001730", "msg": "", "rc": 0, "start": "2025-12-15 20:15:12.997877", "stderr": "", "stderr_lines": [], "stdout": " 20:15:12 up 1 day, 9:46, 1 user, load average: 0.12, 0.29, 0.16", "stdout_lines": [" 20:15:12 up 1 day, 9:46, 1 user, load average: 0.12, 0.29, 0.16"]}
ok: [localhost] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.004771", "end": "2025-12-15 20:15:13.219449", "msg": "", "rc": 0, "start": "2025-12-15 20:15:13.214678", "stderr": "", "stderr_lines": [], "stdout": " 20:15:13 up 6:50, 1 user, load average: 1.29, 1.27, 1.29", "stdout_lines": [" 20:15:13 up 6:50, 1 user, load average: 1.29, 1.27, 1.29"]}
TASK [Get disk usage] **********************************************************
ok: [hp.nas.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004342", "end": "2025-12-15 20:15:13.396696", "msg": "", "rc": 0, "start": "2025-12-15 20:15:13.392354", "stderr": "", "stderr_lines": [], "stdout": "23%", "stdout_lines": ["23%"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004297", "end": "2025-12-15 20:15:13.409015", "msg": "", "rc": 0, "start": "2025-12-15 20:15:13.404718", "stderr": "", "stderr_lines": [], "stdout": "22%", "stdout_lines": ["22%"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004962", "end": "2025-12-15 20:15:13.415975", "msg": "", "rc": 0, "start": "2025-12-15 20:15:13.411013", "stderr": "", "stderr_lines": [], "stdout": "14%", "stdout_lines": ["14%"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005097", "end": "2025-12-15 20:15:13.442020", "msg": "", "rc": 0, "start": "2025-12-15 20:15:13.436923", "stderr": "", "stderr_lines": [], "stdout": "9%", "stdout_lines": ["9%"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005779", "end": "2025-12-15 20:15:13.457736", "msg": "", "rc": 0, "start": "2025-12-15 20:15:13.451957", "stderr": "", "stderr_lines": [], "stdout": "14%", "stdout_lines": ["14%"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004988", "end": "2025-12-15 20:14:49.242958", "msg": "", "rc": 0, "start": "2025-12-15 20:14:49.237970", "stderr": "", "stderr_lines": [], "stdout": "48%", "stdout_lines": ["48%"]}
ok: [media.labb.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005519", "end": "2025-12-15 20:14:43.374919", "msg": "", "rc": 0, "start": "2025-12-15 20:14:43.369400", "stderr": "", "stderr_lines": [], "stdout": "24%", "stdout_lines": ["24%"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.010673", "end": "2025-12-15 20:15:14.136941", "msg": "", "rc": 0, "start": "2025-12-15 20:15:14.126268", "stderr": "", "stderr_lines": [], "stdout": "3%", "stdout_lines": ["3%"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.011730", "end": "2025-12-15 20:15:14.154614", "msg": "", "rc": 0, "start": "2025-12-15 20:15:14.142884", "stderr": "", "stderr_lines": [], "stdout": "6%", "stdout_lines": ["6%"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.006373", "end": "2025-12-15 20:15:14.347320", "msg": "", "rc": 0, "start": "2025-12-15 20:15:14.340947", "stderr": "", "stderr_lines": [], "stdout": "1%", "stdout_lines": ["1%"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005270", "end": "2025-12-15 20:14:46.529243", "msg": "", "rc": 0, "start": "2025-12-15 20:14:46.523973", "stderr": "", "stderr_lines": [], "stdout": "28%", "stdout_lines": ["28%"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005522", "end": "2025-12-15 17:15:14.608171", "msg": "", "rc": 0, "start": "2025-12-15 17:15:14.602649", "stderr": "", "stderr_lines": [], "stdout": "10%", "stdout_lines": ["10%"]}
ok: [dev.prod.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005115", "end": "2025-12-15 20:14:52.595907", "msg": "", "rc": 0, "start": "2025-12-15 20:14:52.590792", "stderr": "", "stderr_lines": [], "stdout": "75%", "stdout_lines": ["75%"]}
ok: [jump.point.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005398", "end": "2025-12-15 20:15:14.773899", "msg": "", "rc": 0, "start": "2025-12-15 20:15:14.768501", "stderr": "", "stderr_lines": [], "stdout": "79%", "stdout_lines": ["79%"]}
ok: [localhost] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.007104", "end": "2025-12-15 20:15:15.041752", "msg": "", "rc": 0, "start": "2025-12-15 20:15:15.034648", "stderr": "", "stderr_lines": [], "stdout": "1%", "stdout_lines": ["1%"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.025141", "end": "2025-12-15 20:15:14.790005", "msg": "", "rc": 0, "start": "2025-12-15 20:15:14.764864", "stderr": "", "stderr_lines": [], "stdout": "21%", "stdout_lines": ["21%"]}
TASK [Get memory usage (Linux)] ************************************************
ok: [hp.nas.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004558", "end": "2025-12-15 20:15:15.311025", "msg": "", "rc": 0, "start": "2025-12-15 20:15:15.306467", "stderr": "", "stderr_lines": [], "stdout": "81.0%", "stdout_lines": ["81.0%"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004326", "end": "2025-12-15 20:15:15.318541", "msg": "", "rc": 0, "start": "2025-12-15 20:15:15.314215", "stderr": "", "stderr_lines": [], "stdout": "21.8%", "stdout_lines": ["21.8%"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004740", "end": "2025-12-15 20:15:15.345413", "msg": "", "rc": 0, "start": "2025-12-15 20:15:15.340673", "stderr": "", "stderr_lines": [], "stdout": "48.9%", "stdout_lines": ["48.9%"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004689", "end": "2025-12-15 20:15:15.346050", "msg": "", "rc": 0, "start": "2025-12-15 20:15:15.341361", "stderr": "", "stderr_lines": [], "stdout": "8.9%", "stdout_lines": ["8.9%"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005419", "end": "2025-12-15 20:15:15.362352", "msg": "", "rc": 0, "start": "2025-12-15 20:15:15.356933", "stderr": "", "stderr_lines": [], "stdout": "59.5%", "stdout_lines": ["59.5%"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004354", "end": "2025-12-15 20:14:51.149254", "msg": "", "rc": 0, "start": "2025-12-15 20:14:51.144900", "stderr": "", "stderr_lines": [], "stdout": "71.5%", "stdout_lines": ["71.5%"]}
ok: [media.labb.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004350", "end": "2025-12-15 20:14:45.290693", "msg": "", "rc": 0, "start": "2025-12-15 20:14:45.286343", "stderr": "", "stderr_lines": [], "stdout": "72.2%", "stdout_lines": ["72.2%"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.011026", "end": "2025-12-15 20:15:15.999614", "msg": "", "rc": 0, "start": "2025-12-15 20:15:15.988588", "stderr": "", "stderr_lines": [], "stdout": "6.8%", "stdout_lines": ["6.8%"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.012148", "end": "2025-12-15 20:15:16.017990", "msg": "", "rc": 0, "start": "2025-12-15 20:15:16.005842", "stderr": "", "stderr_lines": [], "stdout": "12.2%", "stdout_lines": ["12.2%"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005814", "end": "2025-12-15 20:15:16.272315", "msg": "", "rc": 0, "start": "2025-12-15 20:15:16.266501", "stderr": "", "stderr_lines": [], "stdout": "34.0%", "stdout_lines": ["34.0%"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004174", "end": "2025-12-15 20:14:48.458016", "msg": "", "rc": 0, "start": "2025-12-15 20:14:48.453842", "stderr": "", "stderr_lines": [], "stdout": "26.2%", "stdout_lines": ["26.2%"]}
fatal: [hp.truenas.home]: FAILED! => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005472", "end": "2025-12-15 17:15:16.485904", "msg": "non-zero return code", "rc": 2, "start": "2025-12-15 17:15:16.480432", "stderr": "cat: /proc/meminfo: No such file or directory\nawk: division by zero\n source line number 1", "stderr_lines": ["cat: /proc/meminfo: No such file or directory", "awk: division by zero", " source line number 1"], "stdout": "", "stdout_lines": []}
...ignoring
ok: [dev.prod.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.003574", "end": "2025-12-15 20:14:54.467376", "msg": "", "rc": 0, "start": "2025-12-15 20:14:54.463802", "stderr": "", "stderr_lines": [], "stdout": "56.0%", "stdout_lines": ["56.0%"]}
ok: [jump.point.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005486", "end": "2025-12-15 20:15:16.703291", "msg": "", "rc": 0, "start": "2025-12-15 20:15:16.697805", "stderr": "", "stderr_lines": [], "stdout": "13.4%", "stdout_lines": ["13.4%"]}
ok: [localhost] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.008202", "end": "2025-12-15 20:15:16.972619", "msg": "", "rc": 0, "start": "2025-12-15 20:15:16.964417", "stderr": "", "stderr_lines": [], "stdout": "12.7%", "stdout_lines": ["12.7%"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.026047", "end": "2025-12-15 20:15:16.699645", "msg": "", "rc": 0, "start": "2025-12-15 20:15:16.673598", "stderr": "", "stderr_lines": [], "stdout": "19.6%", "stdout_lines": ["19.6%"]}
TASK [Get CPU temperature (ARM/SBC)] *******************************************
ok: [hp.nas.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.005090", "end": "2025-12-15 20:15:17.211314", "msg": "", "rc": 0, "start": "2025-12-15 20:15:17.206224", "stderr": "", "stderr_lines": [], "stdout": "30.0°C", "stdout_lines": ["30.0°C"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.004834", "end": "2025-12-15 20:15:17.240616", "msg": "", "rc": 0, "start": "2025-12-15 20:15:17.235782", "stderr": "", "stderr_lines": [], "stdout": "46.0°C", "stdout_lines": ["46.0°C"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.005689", "end": "2025-12-15 20:15:17.243054", "msg": "", "rc": 0, "start": "2025-12-15 20:15:17.237365", "stderr": "cat: /sys/class/thermal/thermal_zone0/temp: No data available", "stderr_lines": ["cat: /sys/class/thermal/thermal_zone0/temp: No data available"], "stdout": "0.0°C", "stdout_lines": ["0.0°C"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003098", "end": "2025-12-15 20:15:17.270316", "msg": "", "rc": 0, "start": "2025-12-15 20:15:17.267218", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.007075", "end": "2025-12-15 20:15:17.288537", "msg": "", "rc": 0, "start": "2025-12-15 20:15:17.281462", "stderr": "", "stderr_lines": [], "stdout": "52.5°C", "stdout_lines": ["52.5°C"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.002818", "end": "2025-12-15 20:14:53.081596", "msg": "", "rc": 0, "start": "2025-12-15 20:14:53.078778", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [media.labb.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.002922", "end": "2025-12-15 20:14:47.244579", "msg": "", "rc": 0, "start": "2025-12-15 20:14:47.241657", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.011958", "end": "2025-12-15 20:15:17.916040", "msg": "", "rc": 0, "start": "2025-12-15 20:15:17.904082", "stderr": "", "stderr_lines": [], "stdout": "31.2°C", "stdout_lines": ["31.2°C"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.013001", "end": "2025-12-15 20:15:17.956275", "msg": "", "rc": 0, "start": "2025-12-15 20:15:17.943274", "stderr": "", "stderr_lines": [], "stdout": "37.0°C", "stdout_lines": ["37.0°C"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003160", "end": "2025-12-15 20:15:18.191862", "msg": "", "rc": 0, "start": "2025-12-15 20:15:18.188702", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.002974", "end": "2025-12-15 20:14:50.403618", "msg": "", "rc": 0, "start": "2025-12-15 20:14:50.400644", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003906", "end": "2025-12-15 17:15:18.425103", "msg": "", "rc": 0, "start": "2025-12-15 17:15:18.421197", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [dev.prod.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003802", "end": "2025-12-15 20:14:56.406635", "msg": "", "rc": 0, "start": "2025-12-15 20:14:56.402833", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [jump.point.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003231", "end": "2025-12-15 20:15:18.612014", "msg": "", "rc": 0, "start": "2025-12-15 20:15:18.608783", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [localhost] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.006217", "end": "2025-12-15 20:15:18.924880", "msg": "", "rc": 0, "start": "2025-12-15 20:15:18.918663", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.028512", "end": "2025-12-15 20:15:18.615469", "msg": "", "rc": 0, "start": "2025-12-15 20:15:18.586957", "stderr": "", "stderr_lines": [], "stdout": "35.8°C", "stdout_lines": ["35.8°C"]}
TASK [Get CPU load] ************************************************************
ok: [hp.nas.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004318", "end": "2025-12-15 20:15:19.136506", "msg": "", "rc": 0, "start": "2025-12-15 20:15:19.132188", "stderr": "", "stderr_lines": [], "stdout": "0.44", "stdout_lines": ["0.44"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004009", "end": "2025-12-15 20:15:19.147573", "msg": "", "rc": 0, "start": "2025-12-15 20:15:19.143564", "stderr": "", "stderr_lines": [], "stdout": "0.48", "stdout_lines": ["0.48"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004873", "end": "2025-12-15 20:15:19.181874", "msg": "", "rc": 0, "start": "2025-12-15 20:15:19.177001", "stderr": "", "stderr_lines": [], "stdout": "0.89", "stdout_lines": ["0.89"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005976", "end": "2025-12-15 20:15:19.196226", "msg": "", "rc": 0, "start": "2025-12-15 20:15:19.190250", "stderr": "", "stderr_lines": [], "stdout": "0.01", "stdout_lines": ["0.01"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005592", "end": "2025-12-15 20:15:19.198844", "msg": "", "rc": 0, "start": "2025-12-15 20:15:19.193252", "stderr": "", "stderr_lines": [], "stdout": "1.04", "stdout_lines": ["1.04"]}
ok: [media.labb.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004930", "end": "2025-12-15 20:14:49.137939", "msg": "", "rc": 0, "start": "2025-12-15 20:14:49.133009", "stderr": "", "stderr_lines": [], "stdout": "0.01", "stdout_lines": ["0.01"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005666", "end": "2025-12-15 20:14:55.111639", "msg": "", "rc": 0, "start": "2025-12-15 20:14:55.105973", "stderr": "", "stderr_lines": [], "stdout": "0.19", "stdout_lines": ["0.19"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.010149", "end": "2025-12-15 20:15:19.947422", "msg": "", "rc": 0, "start": "2025-12-15 20:15:19.937273", "stderr": "", "stderr_lines": [], "stdout": "0.31", "stdout_lines": ["0.31"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.011264", "end": "2025-12-15 20:15:19.957592", "msg": "", "rc": 0, "start": "2025-12-15 20:15:19.946328", "stderr": "", "stderr_lines": [], "stdout": "0.41", "stdout_lines": ["0.41"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005521", "end": "2025-12-15 20:15:20.218762", "msg": "", "rc": 0, "start": "2025-12-15 20:15:20.213241", "stderr": "", "stderr_lines": [], "stdout": "0.00", "stdout_lines": ["0.00"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005015", "end": "2025-12-15 20:14:52.370166", "msg": "", "rc": 0, "start": "2025-12-15 20:14:52.365151", "stderr": "", "stderr_lines": [], "stdout": "0.26", "stdout_lines": ["0.26"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005852", "end": "2025-12-15 17:15:20.436505", "msg": "", "rc": 0, "start": "2025-12-15 17:15:20.430653", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}
ok: [dev.prod.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.009100", "end": "2025-12-15 20:14:58.462624", "msg": "", "rc": 0, "start": "2025-12-15 20:14:58.453524", "stderr": "", "stderr_lines": [], "stdout": "0.12", "stdout_lines": ["0.12"]}
ok: [localhost] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.006489", "end": "2025-12-15 20:15:20.901981", "msg": "", "rc": 0, "start": "2025-12-15 20:15:20.895492", "stderr": "", "stderr_lines": [], "stdout": "1.33", "stdout_lines": ["1.33"]}
ok: [jump.point.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005264", "end": "2025-12-15 20:15:20.649651", "msg": "", "rc": 0, "start": "2025-12-15 20:15:20.644387", "stderr": "", "stderr_lines": [], "stdout": "0.18", "stdout_lines": ["0.18"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.024254", "end": "2025-12-15 20:15:20.535176", "msg": "", "rc": 0, "start": "2025-12-15 20:15:20.510922", "stderr": "", "stderr_lines": [], "stdout": "0.24", "stdout_lines": ["0.24"]}
TASK [Display health status] ***************************************************
ok: [ali2v.xeon.home] => {
"msg": "═══════════════════════════════════════\nHost: ali2v.xeon.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:15:11 up 1 day, 9:47, 1 user, load average: 0.52, 0.48, 0.35\nDisk Usage: 22%\nMemory Usage: 21.8%\nCPU Load: 0.48\nCPU Temp: 46.0°C\n═══════════════════════════════════════\n"
}
ok: [hp.nas.home] => {
"msg": "═══════════════════════════════════════\nHost: hp.nas.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:15:11 up 20 days, 7:06, 1 user, load average: 0.52, 0.45, 0.36\nDisk Usage: 23%\nMemory Usage: 81.0%\nCPU Load: 0.44\nCPU Temp: 30.0°C\n═══════════════════════════════════════\n"
}
ok: [hp2.i7.home] => {
"msg": "═══════════════════════════════════════\nHost: hp2.i7.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:15:11 up 20 days, 7:26, 1 user, load average: 0.96, 0.85, 0.80\nDisk Usage: 14%\nMemory Usage: 48.9%\nCPU Load: 0.89\nCPU Temp: 0.0°C\n═══════════════════════════════════════\n"
}
ok: [hp3.i5.home] => {
"msg": "═══════════════════════════════════════\nHost: hp3.i5.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:15:11 up 20 days, 8:39, 1 user, load average: 1.05, 0.70, 0.64\nDisk Usage: 14%\nMemory Usage: 59.5%\nCPU Load: 1.04\nCPU Temp: 52.5°C\n═══════════════════════════════════════\n"
}
ok: [mimi.pc.home] => {
"msg": "═══════════════════════════════════════\nHost: mimi.pc.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:15:11 up 20 days, 9:25, 1 user, load average: 0.01, 0.02, 0.00\nDisk Usage: 9%\nMemory Usage: 8.9%\nCPU Load: 0.01\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [raspi.4gb.home] => {
"msg": "═══════════════════════════════════════\nHost: raspi.4gb.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:15:12 up 192 days, 11:48, 1 user, load average: 0.40, 0.26, 0.26\nDisk Usage: 6%\nMemory Usage: 12.2%\nCPU Load: 0.41\nCPU Temp: 37.0°C\n═══════════════════════════════════════\n"
}
ok: [orangepi.pc.home] => {
"msg": "═══════════════════════════════════════\nHost: orangepi.pc.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:15:12 up 13 days, 9:41, 1 user, load average: 0.20, 0.10, 0.09\nDisk Usage: 21%\nMemory Usage: 19.6%\nCPU Load: 0.24\nCPU Temp: 35.8°C\n═══════════════════════════════════════\n"
}
ok: [raspi.8gb.home] => {
"msg": "═══════════════════════════════════════\nHost: raspi.8gb.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:15:12 up 192 days, 11:48, 1 user, load average: 0.37, 0.25, 0.15\nDisk Usage: 3%\nMemory Usage: 6.8%\nCPU Load: 0.31\nCPU Temp: 31.2°C\n═══════════════════════════════════════\n"
}
ok: [dev.lab.home] => {
"msg": "═══════════════════════════════════════\nHost: dev.lab.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:14:47 up 9 days, 8:04, 0 user, load average: 0.04, 0.10, 0.09\nDisk Usage: 48%\nMemory Usage: 71.5%\nCPU Load: 0.19\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [media.labb.home] => {
"msg": "═══════════════════════════════════════\nHost: media.labb.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:14:41 up 16 days, 4:16, 0 user, load average: 0.01, 0.04, 0.02\nDisk Usage: 24%\nMemory Usage: 72.2%\nCPU Load: 0.01\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [ali2v.truenas.home] => {
"msg": "═══════════════════════════════════════\nHost: ali2v.truenas.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:15:12 up 1 day, 9:46, 1 user, load average: 0.00, 0.04, 0.02\nDisk Usage: 1%\nMemory Usage: 34.0%\nCPU Load: 0.00\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [automate.prod.home] => {
"msg": "═══════════════════════════════════════\nHost: automate.prod.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:14:44 up 18 days, 23:09, 0 user, load average: 0.28, 0.37, 0.42\nDisk Usage: 28%\nMemory Usage: 26.2%\nCPU Load: 0.26\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [dev.prod.home] => {
"msg": "═══════════════════════════════════════\nHost: dev.prod.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:14:50 up 15 days, 9:30, 0 user, load average: 0.13, 0.22, 0.23\nDisk Usage: 75%\nMemory Usage: 56.0%\nCPU Load: 0.12\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [hp.truenas.home] => {
"msg": "═══════════════════════════════════════\nHost: hp.truenas.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 5:15PM up 20 days, 7:05, 1 user, load averages: 0.37, 0.25, 0.24\nDisk Usage: 10%\nMemory Usage: \nCPU Load: \nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [jump.point.home] => {
"msg": "═══════════════════════════════════════\nHost: jump.point.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:15:12 up 1 day, 9:46, 1 user, load average: 0.12, 0.29, 0.16\nDisk Usage: 79%\nMemory Usage: 13.4%\nCPU Load: 0.18\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [localhost] => {
"msg": "═══════════════════════════════════════\nHost: localhost\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:15:13 up 6:50, 1 user, load average: 1.29, 1.27, 1.29\nDisk Usage: 1%\nMemory Usage: 12.7%\nCPU Load: 1.33\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
PLAY RECAP *********************************************************************
ali2v.truenas.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
ali2v.xeon.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
automate.prod.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
dev.lab.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
dev.prod.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
hp.nas.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
hp.truenas.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=1
hp2.i7.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
hp3.i5.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
jump.point.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
localhost : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
media.labb.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
mimi.pc.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
orangepi.pc.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
raspi.4gb.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
raspi.8gb.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
```
---
*Généré automatiquement par Homelab Automation Dashboard*
*Date: 2025-12-16T01:15:21.756603+00:00*

View File

@ -0,0 +1,224 @@
# ✅ [Planifié] Health-check-5min
## Informations
| Propriété | Valeur |
|-----------|--------|
| **ID** | `ed7e678ab9b7436bb66283d14ebc343b` |
| **Nom** | [Planifié] Health-check-5min |
| **Cible** | `all` |
| **Statut** | completed |
| **Type** | Planifié |
| **Progression** | 100% |
| **Début** | 2025-12-16T01:20:00.000967+00:00 |
| **Fin** | 2025-12-16T01:20:22.483971+00:00 |
| **Durée** | 22.5s |
## Sortie
```
Using /mnt/c/dev/git/python/homelab-automation-api-v2/ansible/ansible.cfg as config file
PLAY [Health check on target host] *********************************************
TASK [Check if host is reachable (ping)] ***************************************
ok: [hp.nas.home] => {"changed": false, "ping": "pong"}
ok: [hp2.i7.home] => {"changed": false, "ping": "pong"}
ok: [mimi.pc.home] => {"changed": false, "ping": "pong"}
ok: [ali2v.xeon.home] => {"changed": false, "ping": "pong"}
ok: [hp3.i5.home] => {"changed": false, "ping": "pong"}
ok: [dev.lab.home] => {"changed": false, "ping": "pong"}
ok: [media.labb.home] => {"changed": false, "ping": "pong"}
ok: [raspi.8gb.home] => {"changed": false, "ping": "pong"}
ok: [raspi.4gb.home] => {"changed": false, "ping": "pong"}
ok: [automate.prod.home] => {"changed": false, "ping": "pong"}
ok: [ali2v.truenas.home] => {"changed": false, "ping": "pong"}
ok: [hp.truenas.home] => {"changed": false, "ping": "pong"}
ok: [localhost] => {"changed": false, "ping": "pong"}
ok: [dev.prod.home] => {"changed": false, "ping": "pong"}
ok: [jump.point.home] => {"changed": false, "ping": "pong"}
ok: [orangepi.pc.home] => {"changed": false, "ping": "pong"}
TASK [Gather minimal facts] ****************************************************
ok: [hp.nas.home]
ok: [mimi.pc.home]
ok: [hp2.i7.home]
ok: [hp3.i5.home]
ok: [ali2v.xeon.home]
ok: [dev.lab.home]
ok: [media.labb.home]
ok: [raspi.8gb.home]
ok: [raspi.4gb.home]
ok: [ali2v.truenas.home]
ok: [automate.prod.home]
ok: [dev.prod.home]
ok: [hp.truenas.home]
ok: [jump.point.home]
ok: [localhost]
ok: [orangepi.pc.home]
TASK [Get system uptime] *******************************************************
ok: [hp.nas.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003094", "end": "2025-12-15 20:20:12.003700", "msg": "", "rc": 0, "start": "2025-12-15 20:20:12.000606", "stderr": "", "stderr_lines": [], "stdout": " 20:20:12 up 20 days, 7:11, 1 user, load average: 0.41, 0.41, 0.37", "stdout_lines": [" 20:20:12 up 20 days, 7:11, 1 user, load average: 0.41, 0.41, 0.37"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003831", "end": "2025-12-15 20:20:12.020900", "msg": "", "rc": 0, "start": "2025-12-15 20:20:12.017069", "stderr": "", "stderr_lines": [], "stdout": " 20:20:12 up 20 days, 9:30, 1 user, load average: 0.01, 0.01, 0.00", "stdout_lines": [" 20:20:12 up 20 days, 9:30, 1 user, load average: 0.01, 0.01, 0.00"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003045", "end": "2025-12-15 20:20:12.047938", "msg": "", "rc": 0, "start": "2025-12-15 20:20:12.044893", "stderr": "", "stderr_lines": [], "stdout": " 20:20:12 up 1 day, 9:52, 1 user, load average: 0.10, 0.23, 0.27", "stdout_lines": [" 20:20:12 up 1 day, 9:52, 1 user, load average: 0.10, 0.23, 0.27"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.008591", "end": "2025-12-15 20:20:12.671683", "msg": "", "rc": 0, "start": "2025-12-15 20:20:12.663092", "stderr": "", "stderr_lines": [], "stdout": " 20:20:12 up 192 days, 11:53, 1 user, load average: 0.44, 0.27, 0.19", "stdout_lines": [" 20:20:12 up 192 days, 11:53, 1 user, load average: 0.44, 0.27, 0.19"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.009353", "end": "2025-12-15 20:20:12.702416", "msg": "", "rc": 0, "start": "2025-12-15 20:20:12.693063", "stderr": "", "stderr_lines": [], "stdout": " 20:20:12 up 192 days, 11:53, 1 user, load average: 0.20, 0.21, 0.24", "stdout_lines": [" 20:20:12 up 192 days, 11:53, 1 user, load average: 0.20, 0.21, 0.24"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:01.004085", "end": "2025-12-15 20:20:13.020867", "msg": "", "rc": 0, "start": "2025-12-15 20:20:12.016782", "stderr": "", "stderr_lines": [], "stdout": " 20:20:12 up 20 days, 7:31, 1 user, load average: 1.40, 1.01, 0.87", "stdout_lines": [" 20:20:12 up 20 days, 7:31, 1 user, load average: 1.40, 1.01, 0.87"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:01.004907", "end": "2025-12-15 20:20:13.037478", "msg": "", "rc": 0, "start": "2025-12-15 20:20:12.032571", "stderr": "", "stderr_lines": [], "stdout": " 20:20:12 up 20 days, 8:44, 1 user, load average: 1.01, 0.74, 0.67", "stdout_lines": [" 20:20:12 up 20 days, 8:44, 1 user, load average: 1.01, 0.74, 0.67"]}
ok: [dev.lab.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003019", "end": "2025-12-15 20:19:48.508891", "msg": "", "rc": 0, "start": "2025-12-15 20:19:48.505872", "stderr": "", "stderr_lines": [], "stdout": " 20:19:48 up 9 days, 8:09, 0 user, load average: 0.00, 0.04, 0.07", "stdout_lines": [" 20:19:48 up 9 days, 8:09, 0 user, load average: 0.00, 0.04, 0.07"]}
ok: [media.labb.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003303", "end": "2025-12-15 20:19:42.671217", "msg": "", "rc": 0, "start": "2025-12-15 20:19:42.667914", "stderr": "", "stderr_lines": [], "stdout": " 20:19:42 up 16 days, 4:21, 0 user, load average: 0.00, 0.02, 0.00", "stdout_lines": [" 20:19:42 up 16 days, 4:21, 0 user, load average: 0.00, 0.02, 0.00"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.004680", "end": "2025-12-15 20:20:13.480154", "msg": "", "rc": 0, "start": "2025-12-15 20:20:13.475474", "stderr": "", "stderr_lines": [], "stdout": " 20:20:13 up 1 day, 9:51, 1 user, load average: 0.19, 0.10, 0.04", "stdout_lines": [" 20:20:13 up 1 day, 9:51, 1 user, load average: 0.19, 0.10, 0.04"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.019584", "end": "2025-12-15 20:20:13.374984", "msg": "", "rc": 0, "start": "2025-12-15 20:20:13.355400", "stderr": "", "stderr_lines": [], "stdout": " 20:20:13 up 13 days, 9:46, 1 user, load average: 0.14, 0.10, 0.09", "stdout_lines": [" 20:20:13 up 13 days, 9:46, 1 user, load average: 0.14, 0.10, 0.09"]}
ok: [automate.prod.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003336", "end": "2025-12-15 20:19:45.608614", "msg": "", "rc": 0, "start": "2025-12-15 20:19:45.605278", "stderr": "", "stderr_lines": [], "stdout": " 20:19:45 up 18 days, 23:14, 0 user, load average: 0.31, 0.34, 0.39", "stdout_lines": [" 20:19:45 up 18 days, 23:14, 0 user, load average: 0.31, 0.34, 0.39"]}
ok: [dev.prod.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.005220", "end": "2025-12-15 20:19:51.597076", "msg": "", "rc": 0, "start": "2025-12-15 20:19:51.591856", "stderr": "", "stderr_lines": [], "stdout": " 20:19:51 up 15 days, 9:35, 0 user, load average: 0.66, 0.46, 0.32", "stdout_lines": [" 20:19:51 up 15 days, 9:35, 0 user, load average: 0.66, 0.46, 0.32"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.004794", "end": "2025-12-15 17:20:13.720689", "msg": "", "rc": 0, "start": "2025-12-15 17:20:13.715895", "stderr": "", "stderr_lines": [], "stdout": " 5:20PM up 20 days, 7:10, 1 user, load averages: 0.25, 0.27, 0.25", "stdout_lines": [" 5:20PM up 20 days, 7:10, 1 user, load averages: 0.25, 0.27, 0.25"]}
ok: [localhost] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.007340", "end": "2025-12-15 20:20:14.037196", "msg": "", "rc": 0, "start": "2025-12-15 20:20:14.029856", "stderr": "", "stderr_lines": [], "stdout": " 20:20:14 up 6:55, 1 user, load average: 1.40, 1.23, 1.26", "stdout_lines": [" 20:20:14 up 6:55, 1 user, load average: 1.40, 1.23, 1.26"]}
ok: [jump.point.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003700", "end": "2025-12-15 20:20:13.904315", "msg": "", "rc": 0, "start": "2025-12-15 20:20:13.900615", "stderr": "", "stderr_lines": [], "stdout": " 20:20:13 up 1 day, 9:51, 1 user, load average: 0.09, 0.20, 0.16", "stdout_lines": [" 20:20:13 up 1 day, 9:51, 1 user, load average: 0.09, 0.20, 0.16"]}
TASK [Get disk usage] **********************************************************
ok: [hp.nas.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004547", "end": "2025-12-15 20:20:14.295519", "msg": "", "rc": 0, "start": "2025-12-15 20:20:14.290972", "stderr": "", "stderr_lines": [], "stdout": "23%", "stdout_lines": ["23%"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004232", "end": "2025-12-15 20:20:14.324380", "msg": "", "rc": 0, "start": "2025-12-15 20:20:14.320148", "stderr": "", "stderr_lines": [], "stdout": "22%", "stdout_lines": ["22%"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005206", "end": "2025-12-15 20:20:14.318481", "msg": "", "rc": 0, "start": "2025-12-15 20:20:14.313275", "stderr": "", "stderr_lines": [], "stdout": "14%", "stdout_lines": ["14%"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005032", "end": "2025-12-15 20:20:14.352494", "msg": "", "rc": 0, "start": "2025-12-15 20:20:14.347462", "stderr": "", "stderr_lines": [], "stdout": "9%", "stdout_lines": ["9%"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005620", "end": "2025-12-15 20:20:14.357986", "msg": "", "rc": 0, "start": "2025-12-15 20:20:14.352366", "stderr": "", "stderr_lines": [], "stdout": "14%", "stdout_lines": ["14%"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005476", "end": "2025-12-15 20:19:50.152262", "msg": "", "rc": 0, "start": "2025-12-15 20:19:50.146786", "stderr": "", "stderr_lines": [], "stdout": "48%", "stdout_lines": ["48%"]}
ok: [media.labb.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005652", "end": "2025-12-15 20:19:44.280117", "msg": "", "rc": 0, "start": "2025-12-15 20:19:44.274465", "stderr": "", "stderr_lines": [], "stdout": "24%", "stdout_lines": ["24%"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.010525", "end": "2025-12-15 20:20:15.078169", "msg": "", "rc": 0, "start": "2025-12-15 20:20:15.067644", "stderr": "", "stderr_lines": [], "stdout": "3%", "stdout_lines": ["3%"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.011651", "end": "2025-12-15 20:20:15.112273", "msg": "", "rc": 0, "start": "2025-12-15 20:20:15.100622", "stderr": "", "stderr_lines": [], "stdout": "6%", "stdout_lines": ["6%"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.006037", "end": "2025-12-15 20:20:15.268109", "msg": "", "rc": 0, "start": "2025-12-15 20:20:15.262072", "stderr": "", "stderr_lines": [], "stdout": "1%", "stdout_lines": ["1%"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005334", "end": "2025-12-15 20:19:47.450390", "msg": "", "rc": 0, "start": "2025-12-15 20:19:47.445056", "stderr": "", "stderr_lines": [], "stdout": "28%", "stdout_lines": ["28%"]}
ok: [dev.prod.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004795", "end": "2025-12-15 20:19:53.538592", "msg": "", "rc": 0, "start": "2025-12-15 20:19:53.533797", "stderr": "", "stderr_lines": [], "stdout": "75%", "stdout_lines": ["75%"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005547", "end": "2025-12-15 17:20:15.580003", "msg": "", "rc": 0, "start": "2025-12-15 17:20:15.574456", "stderr": "", "stderr_lines": [], "stdout": "10%", "stdout_lines": ["10%"]}
ok: [jump.point.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005337", "end": "2025-12-15 20:20:15.695022", "msg": "", "rc": 0, "start": "2025-12-15 20:20:15.689685", "stderr": "", "stderr_lines": [], "stdout": "79%", "stdout_lines": ["79%"]}
ok: [localhost] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.020848", "end": "2025-12-15 20:20:15.978998", "msg": "", "rc": 0, "start": "2025-12-15 20:20:15.958150", "stderr": "", "stderr_lines": [], "stdout": "1%", "stdout_lines": ["1%"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.024947", "end": "2025-12-15 20:20:15.685808", "msg": "", "rc": 0, "start": "2025-12-15 20:20:15.660861", "stderr": "", "stderr_lines": [], "stdout": "21%", "stdout_lines": ["21%"]}
TASK [Get memory usage (Linux)] ************************************************
ok: [hp.nas.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004409", "end": "2025-12-15 20:20:16.214486", "msg": "", "rc": 0, "start": "2025-12-15 20:20:16.210077", "stderr": "", "stderr_lines": [], "stdout": "81.1%", "stdout_lines": ["81.1%"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004091", "end": "2025-12-15 20:20:16.244183", "msg": "", "rc": 0, "start": "2025-12-15 20:20:16.240092", "stderr": "", "stderr_lines": [], "stdout": "21.8%", "stdout_lines": ["21.8%"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004735", "end": "2025-12-15 20:20:16.270642", "msg": "", "rc": 0, "start": "2025-12-15 20:20:16.265907", "stderr": "", "stderr_lines": [], "stdout": "9.0%", "stdout_lines": ["9.0%"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004584", "end": "2025-12-15 20:20:16.272378", "msg": "", "rc": 0, "start": "2025-12-15 20:20:16.267794", "stderr": "", "stderr_lines": [], "stdout": "49.3%", "stdout_lines": ["49.3%"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005358", "end": "2025-12-15 20:20:16.293074", "msg": "", "rc": 0, "start": "2025-12-15 20:20:16.287716", "stderr": "", "stderr_lines": [], "stdout": "59.5%", "stdout_lines": ["59.5%"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.003869", "end": "2025-12-15 20:19:52.117143", "msg": "", "rc": 0, "start": "2025-12-15 20:19:52.113274", "stderr": "", "stderr_lines": [], "stdout": "71.8%", "stdout_lines": ["71.8%"]}
ok: [media.labb.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004586", "end": "2025-12-15 20:19:46.239371", "msg": "", "rc": 0, "start": "2025-12-15 20:19:46.234785", "stderr": "", "stderr_lines": [], "stdout": "72.1%", "stdout_lines": ["72.1%"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.010835", "end": "2025-12-15 20:20:16.976782", "msg": "", "rc": 0, "start": "2025-12-15 20:20:16.965947", "stderr": "", "stderr_lines": [], "stdout": "6.9%", "stdout_lines": ["6.9%"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.011941", "end": "2025-12-15 20:20:16.988262", "msg": "", "rc": 0, "start": "2025-12-15 20:20:16.976321", "stderr": "", "stderr_lines": [], "stdout": "12.3%", "stdout_lines": ["12.3%"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005771", "end": "2025-12-15 20:20:17.248731", "msg": "", "rc": 0, "start": "2025-12-15 20:20:17.242960", "stderr": "", "stderr_lines": [], "stdout": "34.1%", "stdout_lines": ["34.1%"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004297", "end": "2025-12-15 20:19:49.408508", "msg": "", "rc": 0, "start": "2025-12-15 20:19:49.404211", "stderr": "", "stderr_lines": [], "stdout": "26.1%", "stdout_lines": ["26.1%"]}
fatal: [hp.truenas.home]: FAILED! => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005216", "end": "2025-12-15 17:20:17.442067", "msg": "non-zero return code", "rc": 2, "start": "2025-12-15 17:20:17.436851", "stderr": "cat: /proc/meminfo: No such file or directory\nawk: division by zero\n source line number 1", "stderr_lines": ["cat: /proc/meminfo: No such file or directory", "awk: division by zero", " source line number 1"], "stdout": "", "stdout_lines": []}
...ignoring
ok: [dev.prod.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004819", "end": "2025-12-15 20:19:55.426858", "msg": "", "rc": 0, "start": "2025-12-15 20:19:55.422039", "stderr": "", "stderr_lines": [], "stdout": "57.4%", "stdout_lines": ["57.4%"]}
ok: [jump.point.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005515", "end": "2025-12-15 20:20:17.678458", "msg": "", "rc": 0, "start": "2025-12-15 20:20:17.672943", "stderr": "", "stderr_lines": [], "stdout": "13.6%", "stdout_lines": ["13.6%"]}
ok: [localhost] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.008477", "end": "2025-12-15 20:20:17.872659", "msg": "", "rc": 0, "start": "2025-12-15 20:20:17.864182", "stderr": "", "stderr_lines": [], "stdout": "12.6%", "stdout_lines": ["12.6%"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.025475", "end": "2025-12-15 20:20:17.618038", "msg": "", "rc": 0, "start": "2025-12-15 20:20:17.592563", "stderr": "", "stderr_lines": [], "stdout": "19.6%", "stdout_lines": ["19.6%"]}
TASK [Get CPU temperature (ARM/SBC)] *******************************************
ok: [hp.nas.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.005050", "end": "2025-12-15 20:20:18.132742", "msg": "", "rc": 0, "start": "2025-12-15 20:20:18.127692", "stderr": "", "stderr_lines": [], "stdout": "30.0°C", "stdout_lines": ["30.0°C"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.004942", "end": "2025-12-15 20:20:18.155066", "msg": "", "rc": 0, "start": "2025-12-15 20:20:18.150124", "stderr": "", "stderr_lines": [], "stdout": "46.0°C", "stdout_lines": ["46.0°C"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.005995", "end": "2025-12-15 20:20:18.167018", "msg": "", "rc": 0, "start": "2025-12-15 20:20:18.161023", "stderr": "cat: /sys/class/thermal/thermal_zone0/temp: No data available", "stderr_lines": ["cat: /sys/class/thermal/thermal_zone0/temp: No data available"], "stdout": "0.0°C", "stdout_lines": ["0.0°C"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.004038", "end": "2025-12-15 20:20:18.197201", "msg": "", "rc": 0, "start": "2025-12-15 20:20:18.193163", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.007006", "end": "2025-12-15 20:20:18.201730", "msg": "", "rc": 0, "start": "2025-12-15 20:20:18.194724", "stderr": "", "stderr_lines": [], "stdout": "52.5°C", "stdout_lines": ["52.5°C"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.002864", "end": "2025-12-15 20:19:54.001020", "msg": "", "rc": 0, "start": "2025-12-15 20:19:53.998156", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [media.labb.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.002991", "end": "2025-12-15 20:19:48.130710", "msg": "", "rc": 0, "start": "2025-12-15 20:19:48.127719", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.011915", "end": "2025-12-15 20:20:18.840427", "msg": "", "rc": 0, "start": "2025-12-15 20:20:18.828512", "stderr": "", "stderr_lines": [], "stdout": "32.1°C", "stdout_lines": ["32.1°C"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.013124", "end": "2025-12-15 20:20:18.878959", "msg": "", "rc": 0, "start": "2025-12-15 20:20:18.865835", "stderr": "", "stderr_lines": [], "stdout": "35.0°C", "stdout_lines": ["35.0°C"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003296", "end": "2025-12-15 20:20:19.129927", "msg": "", "rc": 0, "start": "2025-12-15 20:20:19.126631", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003299", "end": "2025-12-15 20:19:51.350537", "msg": "", "rc": 0, "start": "2025-12-15 20:19:51.347238", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [dev.prod.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.002569", "end": "2025-12-15 20:19:57.310571", "msg": "", "rc": 0, "start": "2025-12-15 20:19:57.308002", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003892", "end": "2025-12-15 17:20:19.347868", "msg": "", "rc": 0, "start": "2025-12-15 17:20:19.343976", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [jump.point.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003436", "end": "2025-12-15 20:20:19.557205", "msg": "", "rc": 0, "start": "2025-12-15 20:20:19.553769", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [localhost] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.004052", "end": "2025-12-15 20:20:19.796572", "msg": "", "rc": 0, "start": "2025-12-15 20:20:19.792520", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.028748", "end": "2025-12-15 20:20:19.527741", "msg": "", "rc": 0, "start": "2025-12-15 20:20:19.498993", "stderr": "", "stderr_lines": [], "stdout": "35.5°C", "stdout_lines": ["35.5°C"]}
TASK [Get CPU load] ************************************************************
ok: [hp.nas.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004222", "end": "2025-12-15 20:20:20.043886", "msg": "", "rc": 0, "start": "2025-12-15 20:20:20.039664", "stderr": "", "stderr_lines": [], "stdout": "0.37", "stdout_lines": ["0.37"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004680", "end": "2025-12-15 20:20:20.068355", "msg": "", "rc": 0, "start": "2025-12-15 20:20:20.063675", "stderr": "", "stderr_lines": [], "stdout": "1.29", "stdout_lines": ["1.29"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004184", "end": "2025-12-15 20:20:20.079271", "msg": "", "rc": 0, "start": "2025-12-15 20:20:20.075087", "stderr": "", "stderr_lines": [], "stdout": "0.16", "stdout_lines": ["0.16"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005362", "end": "2025-12-15 20:20:20.098086", "msg": "", "rc": 0, "start": "2025-12-15 20:20:20.092724", "stderr": "", "stderr_lines": [], "stdout": "0.01", "stdout_lines": ["0.01"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005363", "end": "2025-12-15 20:20:20.109412", "msg": "", "rc": 0, "start": "2025-12-15 20:20:20.104049", "stderr": "", "stderr_lines": [], "stdout": "1.02", "stdout_lines": ["1.02"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004442", "end": "2025-12-15 20:19:55.917465", "msg": "", "rc": 0, "start": "2025-12-15 20:19:55.913023", "stderr": "", "stderr_lines": [], "stdout": "0.00", "stdout_lines": ["0.00"]}
ok: [media.labb.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005099", "end": "2025-12-15 20:19:50.043699", "msg": "", "rc": 0, "start": "2025-12-15 20:19:50.038600", "stderr": "", "stderr_lines": [], "stdout": "0.00", "stdout_lines": ["0.00"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.011185", "end": "2025-12-15 20:20:20.872479", "msg": "", "rc": 0, "start": "2025-12-15 20:20:20.861294", "stderr": "", "stderr_lines": [], "stdout": "0.33", "stdout_lines": ["0.33"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.010199", "end": "2025-12-15 20:20:20.893735", "msg": "", "rc": 0, "start": "2025-12-15 20:20:20.883536", "stderr": "", "stderr_lines": [], "stdout": "0.45", "stdout_lines": ["0.45"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005664", "end": "2025-12-15 20:20:21.049553", "msg": "", "rc": 0, "start": "2025-12-15 20:20:21.043889", "stderr": "", "stderr_lines": [], "stdout": "0.24", "stdout_lines": ["0.24"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004838", "end": "2025-12-15 20:19:53.216572", "msg": "", "rc": 0, "start": "2025-12-15 20:19:53.211734", "stderr": "", "stderr_lines": [], "stdout": "0.29", "stdout_lines": ["0.29"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005901", "end": "2025-12-15 17:20:21.354447", "msg": "", "rc": 0, "start": "2025-12-15 17:20:21.348546", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}
ok: [dev.prod.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004442", "end": "2025-12-15 20:19:59.342217", "msg": "", "rc": 0, "start": "2025-12-15 20:19:59.337775", "stderr": "", "stderr_lines": [], "stdout": "0.61", "stdout_lines": ["0.61"]}
ok: [jump.point.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005356", "end": "2025-12-15 20:20:21.483183", "msg": "", "rc": 0, "start": "2025-12-15 20:20:21.477827", "stderr": "", "stderr_lines": [], "stdout": "0.08", "stdout_lines": ["0.08"]}
ok: [localhost] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.006153", "end": "2025-12-15 20:20:21.667302", "msg": "", "rc": 0, "start": "2025-12-15 20:20:21.661149", "stderr": "", "stderr_lines": [], "stdout": "1.42", "stdout_lines": ["1.42"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.024539", "end": "2025-12-15 20:20:21.434562", "msg": "", "rc": 0, "start": "2025-12-15 20:20:21.410023", "stderr": "", "stderr_lines": [], "stdout": "0.20", "stdout_lines": ["0.20"]}
TASK [Display health status] ***************************************************
ok: [hp.nas.home] => {
"msg": "═══════════════════════════════════════\nHost: hp.nas.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:20:12 up 20 days, 7:11, 1 user, load average: 0.41, 0.41, 0.37\nDisk Usage: 23%\nMemory Usage: 81.1%\nCPU Load: 0.37\nCPU Temp: 30.0°C\n═══════════════════════════════════════\n"
}
ok: [ali2v.xeon.home] => {
"msg": "═══════════════════════════════════════\nHost: ali2v.xeon.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:20:12 up 1 day, 9:52, 1 user, load average: 0.10, 0.23, 0.27\nDisk Usage: 22%\nMemory Usage: 21.8%\nCPU Load: 0.16\nCPU Temp: 46.0°C\n═══════════════════════════════════════\n"
}
ok: [hp2.i7.home] => {
"msg": "═══════════════════════════════════════\nHost: hp2.i7.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:20:12 up 20 days, 7:31, 1 user, load average: 1.40, 1.01, 0.87\nDisk Usage: 14%\nMemory Usage: 49.3%\nCPU Load: 1.29\nCPU Temp: 0.0°C\n═══════════════════════════════════════\n"
}
ok: [hp3.i5.home] => {
"msg": "═══════════════════════════════════════\nHost: hp3.i5.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:20:12 up 20 days, 8:44, 1 user, load average: 1.01, 0.74, 0.67\nDisk Usage: 14%\nMemory Usage: 59.5%\nCPU Load: 1.02\nCPU Temp: 52.5°C\n═══════════════════════════════════════\n"
}
ok: [mimi.pc.home] => {
"msg": "═══════════════════════════════════════\nHost: mimi.pc.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:20:12 up 20 days, 9:30, 1 user, load average: 0.01, 0.01, 0.00\nDisk Usage: 9%\nMemory Usage: 9.0%\nCPU Load: 0.01\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [orangepi.pc.home] => {
"msg": "═══════════════════════════════════════\nHost: orangepi.pc.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:20:13 up 13 days, 9:46, 1 user, load average: 0.14, 0.10, 0.09\nDisk Usage: 21%\nMemory Usage: 19.6%\nCPU Load: 0.20\nCPU Temp: 35.5°C\n═══════════════════════════════════════\n"
}
ok: [raspi.4gb.home] => {
"msg": "═══════════════════════════════════════\nHost: raspi.4gb.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:20:12 up 192 days, 11:53, 1 user, load average: 0.20, 0.21, 0.24\nDisk Usage: 6%\nMemory Usage: 12.3%\nCPU Load: 0.33\nCPU Temp: 35.0°C\n═══════════════════════════════════════\n"
}
ok: [raspi.8gb.home] => {
"msg": "═══════════════════════════════════════\nHost: raspi.8gb.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:20:12 up 192 days, 11:53, 1 user, load average: 0.44, 0.27, 0.19\nDisk Usage: 3%\nMemory Usage: 6.9%\nCPU Load: 0.45\nCPU Temp: 32.1°C\n═══════════════════════════════════════\n"
}
ok: [dev.lab.home] => {
"msg": "═══════════════════════════════════════\nHost: dev.lab.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:19:48 up 9 days, 8:09, 0 user, load average: 0.00, 0.04, 0.07\nDisk Usage: 48%\nMemory Usage: 71.8%\nCPU Load: 0.00\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [media.labb.home] => {
"msg": "═══════════════════════════════════════\nHost: media.labb.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:19:42 up 16 days, 4:21, 0 user, load average: 0.00, 0.02, 0.00\nDisk Usage: 24%\nMemory Usage: 72.1%\nCPU Load: 0.00\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [ali2v.truenas.home] => {
"msg": "═══════════════════════════════════════\nHost: ali2v.truenas.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:20:13 up 1 day, 9:51, 1 user, load average: 0.19, 0.10, 0.04\nDisk Usage: 1%\nMemory Usage: 34.1%\nCPU Load: 0.24\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [automate.prod.home] => {
"msg": "═══════════════════════════════════════\nHost: automate.prod.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:19:45 up 18 days, 23:14, 0 user, load average: 0.31, 0.34, 0.39\nDisk Usage: 28%\nMemory Usage: 26.1%\nCPU Load: 0.29\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [dev.prod.home] => {
"msg": "═══════════════════════════════════════\nHost: dev.prod.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:19:51 up 15 days, 9:35, 0 user, load average: 0.66, 0.46, 0.32\nDisk Usage: 75%\nMemory Usage: 57.4%\nCPU Load: 0.61\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [hp.truenas.home] => {
"msg": "═══════════════════════════════════════\nHost: hp.truenas.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 5:20PM up 20 days, 7:10, 1 user, load averages: 0.25, 0.27, 0.25\nDisk Usage: 10%\nMemory Usage: \nCPU Load: \nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [jump.point.home] => {
"msg": "═══════════════════════════════════════\nHost: jump.point.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:20:13 up 1 day, 9:51, 1 user, load average: 0.09, 0.20, 0.16\nDisk Usage: 79%\nMemory Usage: 13.6%\nCPU Load: 0.08\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [localhost] => {
"msg": "═══════════════════════════════════════\nHost: localhost\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:20:14 up 6:55, 1 user, load average: 1.40, 1.23, 1.26\nDisk Usage: 1%\nMemory Usage: 12.6%\nCPU Load: 1.42\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
PLAY RECAP *********************************************************************
ali2v.truenas.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
ali2v.xeon.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
automate.prod.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
dev.lab.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
dev.prod.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
hp.nas.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
hp.truenas.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=1
hp2.i7.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
hp3.i5.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
jump.point.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
localhost : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
media.labb.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
mimi.pc.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
orangepi.pc.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
raspi.4gb.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
raspi.8gb.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
```
---
*Généré automatiquement par Homelab Automation Dashboard*
*Date: 2025-12-16T01:20:22.519655+00:00*

View File

@ -0,0 +1,224 @@
# ✅ [Planifié] Health-check-5min
## Informations
| Propriété | Valeur |
|-----------|--------|
| **ID** | `1d43a904e4bc4618986d7ba3288a7625` |
| **Nom** | [Planifié] Health-check-5min |
| **Cible** | `all` |
| **Statut** | completed |
| **Type** | Planifié |
| **Progression** | 100% |
| **Début** | 2025-12-16T01:25:00.001100+00:00 |
| **Fin** | 2025-12-16T01:25:22.121727+00:00 |
| **Durée** | 22.1s |
## Sortie
```
Using /mnt/c/dev/git/python/homelab-automation-api-v2/ansible/ansible.cfg as config file
PLAY [Health check on target host] *********************************************
TASK [Check if host is reachable (ping)] ***************************************
ok: [mimi.pc.home] => {"changed": false, "ping": "pong"}
ok: [hp2.i7.home] => {"changed": false, "ping": "pong"}
ok: [hp.nas.home] => {"changed": false, "ping": "pong"}
ok: [ali2v.xeon.home] => {"changed": false, "ping": "pong"}
ok: [hp3.i5.home] => {"changed": false, "ping": "pong"}
ok: [dev.lab.home] => {"changed": false, "ping": "pong"}
ok: [media.labb.home] => {"changed": false, "ping": "pong"}
ok: [raspi.8gb.home] => {"changed": false, "ping": "pong"}
ok: [raspi.4gb.home] => {"changed": false, "ping": "pong"}
ok: [automate.prod.home] => {"changed": false, "ping": "pong"}
ok: [ali2v.truenas.home] => {"changed": false, "ping": "pong"}
ok: [hp.truenas.home] => {"changed": false, "ping": "pong"}
ok: [localhost] => {"changed": false, "ping": "pong"}
ok: [dev.prod.home] => {"changed": false, "ping": "pong"}
ok: [jump.point.home] => {"changed": false, "ping": "pong"}
ok: [orangepi.pc.home] => {"changed": false, "ping": "pong"}
TASK [Gather minimal facts] ****************************************************
ok: [hp.nas.home]
ok: [mimi.pc.home]
ok: [hp2.i7.home]
ok: [ali2v.xeon.home]
ok: [hp3.i5.home]
ok: [dev.lab.home]
ok: [media.labb.home]
ok: [raspi.8gb.home]
ok: [raspi.4gb.home]
ok: [ali2v.truenas.home]
ok: [automate.prod.home]
ok: [hp.truenas.home]
ok: [dev.prod.home]
ok: [jump.point.home]
ok: [localhost]
ok: [orangepi.pc.home]
TASK [Get system uptime] *******************************************************
ok: [hp.nas.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.002990", "end": "2025-12-15 20:25:11.825235", "msg": "", "rc": 0, "start": "2025-12-15 20:25:11.822245", "stderr": "", "stderr_lines": [], "stdout": " 20:25:11 up 20 days, 7:16, 1 user, load average: 0.50, 0.43, 0.38", "stdout_lines": [" 20:25:11 up 20 days, 7:16, 1 user, load average: 0.50, 0.43, 0.38"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.004045", "end": "2025-12-15 20:25:11.839367", "msg": "", "rc": 0, "start": "2025-12-15 20:25:11.835322", "stderr": "", "stderr_lines": [], "stdout": " 20:25:11 up 20 days, 9:35, 1 user, load average: 0.12, 0.03, 0.01", "stdout_lines": [" 20:25:11 up 20 days, 9:35, 1 user, load average: 0.12, 0.03, 0.01"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003926", "end": "2025-12-15 20:25:11.853539", "msg": "", "rc": 0, "start": "2025-12-15 20:25:11.849613", "stderr": "", "stderr_lines": [], "stdout": " 20:25:11 up 20 days, 8:49, 1 user, load average: 0.71, 0.67, 0.65", "stdout_lines": [" 20:25:11 up 20 days, 8:49, 1 user, load average: 0.71, 0.67, 0.65"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.002813", "end": "2025-12-15 20:25:11.866061", "msg": "", "rc": 0, "start": "2025-12-15 20:25:11.863248", "stderr": "", "stderr_lines": [], "stdout": " 20:25:11 up 1 day, 9:57, 1 user, load average: 0.25, 0.18, 0.23", "stdout_lines": [" 20:25:11 up 1 day, 9:57, 1 user, load average: 0.25, 0.18, 0.23"]}
ok: [dev.lab.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.002765", "end": "2025-12-15 20:24:47.703256", "msg": "", "rc": 0, "start": "2025-12-15 20:24:47.700491", "stderr": "", "stderr_lines": [], "stdout": " 20:24:47 up 9 days, 8:14, 0 user, load average: 0.19, 0.36, 0.21", "stdout_lines": [" 20:24:47 up 9 days, 8:14, 0 user, load average: 0.19, 0.36, 0.21"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.008426", "end": "2025-12-15 20:25:12.521565", "msg": "", "rc": 0, "start": "2025-12-15 20:25:12.513139", "stderr": "", "stderr_lines": [], "stdout": " 20:25:12 up 192 days, 11:58, 1 user, load average: 0.50, 0.29, 0.20", "stdout_lines": [" 20:25:12 up 192 days, 11:58, 1 user, load average: 0.50, 0.29, 0.20"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.009314", "end": "2025-12-15 20:25:12.553361", "msg": "", "rc": 0, "start": "2025-12-15 20:25:12.544047", "stderr": "", "stderr_lines": [], "stdout": " 20:25:12 up 192 days, 11:58, 1 user, load average: 0.50, 0.32, 0.28", "stdout_lines": [" 20:25:12 up 192 days, 11:58, 1 user, load average: 0.50, 0.32, 0.28"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:01.004482", "end": "2025-12-15 20:25:12.839874", "msg": "", "rc": 0, "start": "2025-12-15 20:25:11.835392", "stderr": "", "stderr_lines": [], "stdout": " 20:25:11 up 20 days, 7:36, 1 user, load average: 0.75, 0.91, 0.88", "stdout_lines": [" 20:25:11 up 20 days, 7:36, 1 user, load average: 0.75, 0.91, 0.88"]}
ok: [media.labb.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003947", "end": "2025-12-15 20:24:42.277813", "msg": "", "rc": 0, "start": "2025-12-15 20:24:42.273866", "stderr": "", "stderr_lines": [], "stdout": " 20:24:42 up 16 days, 4:26, 0 user, load average: 0.08, 0.02, 0.00", "stdout_lines": [" 20:24:42 up 16 days, 4:26, 0 user, load average: 0.08, 0.02, 0.00"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.004777", "end": "2025-12-15 20:25:13.027188", "msg": "", "rc": 0, "start": "2025-12-15 20:25:13.022411", "stderr": "", "stderr_lines": [], "stdout": " 20:25:13 up 1 day, 9:56, 1 user, load average: 0.04, 0.06, 0.03", "stdout_lines": [" 20:25:13 up 1 day, 9:56, 1 user, load average: 0.04, 0.06, 0.03"]}
ok: [automate.prod.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003847", "end": "2025-12-15 20:24:45.162104", "msg": "", "rc": 0, "start": "2025-12-15 20:24:45.158257", "stderr": "", "stderr_lines": [], "stdout": " 20:24:45 up 18 days, 23:19, 0 user, load average: 0.40, 0.39, 0.39", "stdout_lines": [" 20:24:45 up 18 days, 23:19, 0 user, load average: 0.40, 0.39, 0.39"]}
ok: [dev.prod.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003878", "end": "2025-12-15 20:24:51.295563", "msg": "", "rc": 0, "start": "2025-12-15 20:24:51.291685", "stderr": "", "stderr_lines": [], "stdout": " 20:24:51 up 15 days, 9:40, 0 user, load average: 0.12, 0.31, 0.29", "stdout_lines": [" 20:24:51 up 15 days, 9:40, 0 user, load average: 0.12, 0.31, 0.29"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.004298", "end": "2025-12-15 17:25:13.340736", "msg": "", "rc": 0, "start": "2025-12-15 17:25:13.336438", "stderr": "", "stderr_lines": [], "stdout": " 5:25PM up 20 days, 7:15, 1 user, load averages: 0.16, 0.25, 0.24", "stdout_lines": [" 5:25PM up 20 days, 7:15, 1 user, load averages: 0.16, 0.25, 0.24"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.019458", "end": "2025-12-15 20:25:13.222959", "msg": "", "rc": 0, "start": "2025-12-15 20:25:13.203501", "stderr": "", "stderr_lines": [], "stdout": " 20:25:13 up 13 days, 9:51, 1 user, load average: 0.24, 0.16, 0.11", "stdout_lines": [" 20:25:13 up 13 days, 9:51, 1 user, load average: 0.24, 0.16, 0.11"]}
ok: [localhost] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.007755", "end": "2025-12-15 20:25:13.622058", "msg": "", "rc": 0, "start": "2025-12-15 20:25:13.614303", "stderr": "", "stderr_lines": [], "stdout": " 20:25:13 up 7:00, 1 user, load average: 1.41, 1.24, 1.25", "stdout_lines": [" 20:25:13 up 7:00, 1 user, load average: 1.41, 1.24, 1.25"]}
ok: [jump.point.home] => {"changed": false, "cmd": ["uptime"], "delta": "0:00:00.003797", "end": "2025-12-15 20:25:13.479179", "msg": "", "rc": 0, "start": "2025-12-15 20:25:13.475382", "stderr": "", "stderr_lines": [], "stdout": " 20:25:13 up 1 day, 9:56, 1 user, load average: 0.07, 0.13, 0.14", "stdout_lines": [" 20:25:13 up 1 day, 9:56, 1 user, load average: 0.07, 0.13, 0.14"]}
TASK [Get disk usage] **********************************************************
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004090", "end": "2025-12-15 20:25:13.880270", "msg": "", "rc": 0, "start": "2025-12-15 20:25:13.876180", "stderr": "", "stderr_lines": [], "stdout": "22%", "stdout_lines": ["22%"]}
ok: [hp.nas.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004413", "end": "2025-12-15 20:25:13.884074", "msg": "", "rc": 0, "start": "2025-12-15 20:25:13.879661", "stderr": "", "stderr_lines": [], "stdout": "23%", "stdout_lines": ["23%"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004676", "end": "2025-12-15 20:25:13.899787", "msg": "", "rc": 0, "start": "2025-12-15 20:25:13.895111", "stderr": "", "stderr_lines": [], "stdout": "14%", "stdout_lines": ["14%"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004584", "end": "2025-12-15 20:25:13.923963", "msg": "", "rc": 0, "start": "2025-12-15 20:25:13.919379", "stderr": "", "stderr_lines": [], "stdout": "9%", "stdout_lines": ["9%"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005701", "end": "2025-12-15 20:25:13.940021", "msg": "", "rc": 0, "start": "2025-12-15 20:25:13.934320", "stderr": "", "stderr_lines": [], "stdout": "14%", "stdout_lines": ["14%"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.004794", "end": "2025-12-15 20:24:49.736161", "msg": "", "rc": 0, "start": "2025-12-15 20:24:49.731367", "stderr": "", "stderr_lines": [], "stdout": "48%", "stdout_lines": ["48%"]}
ok: [media.labb.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005242", "end": "2025-12-15 20:24:43.844287", "msg": "", "rc": 0, "start": "2025-12-15 20:24:43.839045", "stderr": "", "stderr_lines": [], "stdout": "24%", "stdout_lines": ["24%"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.010534", "end": "2025-12-15 20:25:14.624044", "msg": "", "rc": 0, "start": "2025-12-15 20:25:14.613510", "stderr": "", "stderr_lines": [], "stdout": "3%", "stdout_lines": ["3%"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.011601", "end": "2025-12-15 20:25:14.659364", "msg": "", "rc": 0, "start": "2025-12-15 20:25:14.647763", "stderr": "", "stderr_lines": [], "stdout": "6%", "stdout_lines": ["6%"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005812", "end": "2025-12-15 20:25:14.850534", "msg": "", "rc": 0, "start": "2025-12-15 20:25:14.844722", "stderr": "", "stderr_lines": [], "stdout": "1%", "stdout_lines": ["1%"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005194", "end": "2025-12-15 20:24:47.021417", "msg": "", "rc": 0, "start": "2025-12-15 20:24:47.016223", "stderr": "", "stderr_lines": [], "stdout": "28%", "stdout_lines": ["28%"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005638", "end": "2025-12-15 17:25:15.118042", "msg": "", "rc": 0, "start": "2025-12-15 17:25:15.112404", "stderr": "", "stderr_lines": [], "stdout": "10%", "stdout_lines": ["10%"]}
ok: [dev.prod.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.006729", "end": "2025-12-15 20:24:53.087065", "msg": "", "rc": 0, "start": "2025-12-15 20:24:53.080336", "stderr": "", "stderr_lines": [], "stdout": "75%", "stdout_lines": ["75%"]}
ok: [jump.point.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.005462", "end": "2025-12-15 20:25:15.275755", "msg": "", "rc": 0, "start": "2025-12-15 20:25:15.270293", "stderr": "", "stderr_lines": [], "stdout": "79%", "stdout_lines": ["79%"]}
ok: [localhost] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.019118", "end": "2025-12-15 20:25:15.469376", "msg": "", "rc": 0, "start": "2025-12-15 20:25:15.450258", "stderr": "", "stderr_lines": [], "stdout": "1%", "stdout_lines": ["1%"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "df -h / | tail -1 | awk '{print $5}'", "delta": "0:00:00.025205", "end": "2025-12-15 20:25:15.265243", "msg": "", "rc": 0, "start": "2025-12-15 20:25:15.240038", "stderr": "", "stderr_lines": [], "stdout": "21%", "stdout_lines": ["21%"]}
TASK [Get memory usage (Linux)] ************************************************
ok: [hp.nas.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004459", "end": "2025-12-15 20:25:15.777927", "msg": "", "rc": 0, "start": "2025-12-15 20:25:15.773468", "stderr": "", "stderr_lines": [], "stdout": "81.2%", "stdout_lines": ["81.2%"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004137", "end": "2025-12-15 20:25:15.786146", "msg": "", "rc": 0, "start": "2025-12-15 20:25:15.782009", "stderr": "", "stderr_lines": [], "stdout": "21.8%", "stdout_lines": ["21.8%"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004809", "end": "2025-12-15 20:25:15.803559", "msg": "", "rc": 0, "start": "2025-12-15 20:25:15.798750", "stderr": "", "stderr_lines": [], "stdout": "49.2%", "stdout_lines": ["49.2%"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004528", "end": "2025-12-15 20:25:15.840828", "msg": "", "rc": 0, "start": "2025-12-15 20:25:15.836300", "stderr": "", "stderr_lines": [], "stdout": "9.0%", "stdout_lines": ["9.0%"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.006114", "end": "2025-12-15 20:25:15.855325", "msg": "", "rc": 0, "start": "2025-12-15 20:25:15.849211", "stderr": "", "stderr_lines": [], "stdout": "59.5%", "stdout_lines": ["59.5%"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.003565", "end": "2025-12-15 20:24:51.628287", "msg": "", "rc": 0, "start": "2025-12-15 20:24:51.624722", "stderr": "", "stderr_lines": [], "stdout": "71.6%", "stdout_lines": ["71.6%"]}
ok: [media.labb.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004697", "end": "2025-12-15 20:24:45.764360", "msg": "", "rc": 0, "start": "2025-12-15 20:24:45.759663", "stderr": "", "stderr_lines": [], "stdout": "72.2%", "stdout_lines": ["72.2%"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.010972", "end": "2025-12-15 20:25:16.452408", "msg": "", "rc": 0, "start": "2025-12-15 20:25:16.441436", "stderr": "", "stderr_lines": [], "stdout": "6.8%", "stdout_lines": ["6.8%"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.012328", "end": "2025-12-15 20:25:16.496648", "msg": "", "rc": 0, "start": "2025-12-15 20:25:16.484320", "stderr": "", "stderr_lines": [], "stdout": "12.3%", "stdout_lines": ["12.3%"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005791", "end": "2025-12-15 20:25:16.754738", "msg": "", "rc": 0, "start": "2025-12-15 20:25:16.748947", "stderr": "", "stderr_lines": [], "stdout": "34.0%", "stdout_lines": ["34.0%"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.004257", "end": "2025-12-15 20:24:48.928704", "msg": "", "rc": 0, "start": "2025-12-15 20:24:48.924447", "stderr": "", "stderr_lines": [], "stdout": "26.0%", "stdout_lines": ["26.0%"]}
ok: [dev.prod.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.006447", "end": "2025-12-15 20:24:54.908175", "msg": "", "rc": 0, "start": "2025-12-15 20:24:54.901728", "stderr": "", "stderr_lines": [], "stdout": "58.1%", "stdout_lines": ["58.1%"]}
fatal: [hp.truenas.home]: FAILED! => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005327", "end": "2025-12-15 17:25:16.966856", "msg": "non-zero return code", "rc": 2, "start": "2025-12-15 17:25:16.961529", "stderr": "cat: /proc/meminfo: No such file or directory\nawk: division by zero\n source line number 1", "stderr_lines": ["cat: /proc/meminfo: No such file or directory", "awk: division by zero", " source line number 1"], "stdout": "", "stdout_lines": []}
...ignoring
ok: [jump.point.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.005478", "end": "2025-12-15 20:25:17.186005", "msg": "", "rc": 0, "start": "2025-12-15 20:25:17.180527", "stderr": "", "stderr_lines": [], "stdout": "13.5%", "stdout_lines": ["13.5%"]}
ok: [localhost] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.008809", "end": "2025-12-15 20:25:17.423486", "msg": "", "rc": 0, "start": "2025-12-15 20:25:17.414677", "stderr": "", "stderr_lines": [], "stdout": "12.5%", "stdout_lines": ["12.5%"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "if command -v free >/dev/null 2>&1; then\n free -m | grep Mem | awk '{printf \"%.1f%%\", $3/$2 * 100}'\nelse\n # Fallback for systems without free command\n cat /proc/meminfo | awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf \"%.1f%%\", (total-avail)/total*100}'\nfi\n", "delta": "0:00:00.025764", "end": "2025-12-15 20:25:17.156710", "msg": "", "rc": 0, "start": "2025-12-15 20:25:17.130946", "stderr": "", "stderr_lines": [], "stdout": "20.6%", "stdout_lines": ["20.6%"]}
TASK [Get CPU temperature (ARM/SBC)] *******************************************
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.004974", "end": "2025-12-15 20:25:17.701317", "msg": "", "rc": 0, "start": "2025-12-15 20:25:17.696343", "stderr": "", "stderr_lines": [], "stdout": "46.0°C", "stdout_lines": ["46.0°C"]}
ok: [hp.nas.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.005187", "end": "2025-12-15 20:25:17.713616", "msg": "", "rc": 0, "start": "2025-12-15 20:25:17.708429", "stderr": "", "stderr_lines": [], "stdout": "30.0°C", "stdout_lines": ["30.0°C"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.006260", "end": "2025-12-15 20:25:17.721594", "msg": "", "rc": 0, "start": "2025-12-15 20:25:17.715334", "stderr": "cat: /sys/class/thermal/thermal_zone0/temp: No data available", "stderr_lines": ["cat: /sys/class/thermal/thermal_zone0/temp: No data available"], "stdout": "0.0°C", "stdout_lines": ["0.0°C"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003141", "end": "2025-12-15 20:25:17.756244", "msg": "", "rc": 0, "start": "2025-12-15 20:25:17.753103", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.006439", "end": "2025-12-15 20:25:17.754241", "msg": "", "rc": 0, "start": "2025-12-15 20:25:17.747802", "stderr": "", "stderr_lines": [], "stdout": "53.0°C", "stdout_lines": ["53.0°C"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.002753", "end": "2025-12-15 20:24:53.568495", "msg": "", "rc": 0, "start": "2025-12-15 20:24:53.565742", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [media.labb.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.002863", "end": "2025-12-15 20:24:47.668671", "msg": "", "rc": 0, "start": "2025-12-15 20:24:47.665808", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.011853", "end": "2025-12-15 20:25:18.377936", "msg": "", "rc": 0, "start": "2025-12-15 20:25:18.366083", "stderr": "", "stderr_lines": [], "stdout": "32.6°C", "stdout_lines": ["32.6°C"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.013121", "end": "2025-12-15 20:25:18.413794", "msg": "", "rc": 0, "start": "2025-12-15 20:25:18.400673", "stderr": "", "stderr_lines": [], "stdout": "35.0°C", "stdout_lines": ["35.0°C"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003221", "end": "2025-12-15 20:25:18.706494", "msg": "", "rc": 0, "start": "2025-12-15 20:25:18.703273", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.002819", "end": "2025-12-15 20:24:50.842757", "msg": "", "rc": 0, "start": "2025-12-15 20:24:50.839938", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [dev.prod.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.002834", "end": "2025-12-15 20:24:56.833499", "msg": "", "rc": 0, "start": "2025-12-15 20:24:56.830665", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003893", "end": "2025-12-15 17:25:18.873323", "msg": "", "rc": 0, "start": "2025-12-15 17:25:18.869430", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [localhost] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.005054", "end": "2025-12-15 20:25:19.309406", "msg": "", "rc": 0, "start": "2025-12-15 20:25:19.304352", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [jump.point.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.003244", "end": "2025-12-15 20:25:19.144815", "msg": "", "rc": 0, "start": "2025-12-15 20:25:19.141571", "stderr": "", "stderr_lines": [], "stdout": "N/A", "stdout_lines": ["N/A"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "if [ -f /sys/class/thermal/thermal_zone0/temp ]; then\n temp=$(cat /sys/class/thermal/thermal_zone0/temp)\n # Use awk instead of bc for better compatibility\n echo \"${temp}\" | awk '{printf \"%.1f°C\", $1/1000}'\nelse\n echo \"N/A\"\nfi\n", "delta": "0:00:00.028976", "end": "2025-12-15 20:25:19.079001", "msg": "", "rc": 0, "start": "2025-12-15 20:25:19.050025", "stderr": "", "stderr_lines": [], "stdout": "36.9°C", "stdout_lines": ["36.9°C"]}
TASK [Get CPU load] ************************************************************
ok: [hp.nas.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004229", "end": "2025-12-15 20:25:19.601354", "msg": "", "rc": 0, "start": "2025-12-15 20:25:19.597125", "stderr": "", "stderr_lines": [], "stdout": "0.54", "stdout_lines": ["0.54"]}
ok: [ali2v.xeon.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004159", "end": "2025-12-15 20:25:19.621358", "msg": "", "rc": 0, "start": "2025-12-15 20:25:19.617199", "stderr": "", "stderr_lines": [], "stdout": "0.45", "stdout_lines": ["0.45"]}
ok: [hp2.i7.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004678", "end": "2025-12-15 20:25:19.641740", "msg": "", "rc": 0, "start": "2025-12-15 20:25:19.637062", "stderr": "", "stderr_lines": [], "stdout": "0.69", "stdout_lines": ["0.69"]}
ok: [mimi.pc.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.006065", "end": "2025-12-15 20:25:19.653559", "msg": "", "rc": 0, "start": "2025-12-15 20:25:19.647494", "stderr": "", "stderr_lines": [], "stdout": "0.10", "stdout_lines": ["0.10"]}
ok: [hp3.i5.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005812", "end": "2025-12-15 20:25:19.664969", "msg": "", "rc": 0, "start": "2025-12-15 20:25:19.659157", "stderr": "", "stderr_lines": [], "stdout": "0.60", "stdout_lines": ["0.60"]}
ok: [dev.lab.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005039", "end": "2025-12-15 20:24:55.450020", "msg": "", "rc": 0, "start": "2025-12-15 20:24:55.444981", "stderr": "", "stderr_lines": [], "stdout": "0.24", "stdout_lines": ["0.24"]}
ok: [media.labb.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005582", "end": "2025-12-15 20:24:49.586736", "msg": "", "rc": 0, "start": "2025-12-15 20:24:49.581154", "stderr": "", "stderr_lines": [], "stdout": "0.07", "stdout_lines": ["0.07"]}
ok: [raspi.8gb.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.010047", "end": "2025-12-15 20:25:20.378901", "msg": "", "rc": 0, "start": "2025-12-15 20:25:20.368854", "stderr": "", "stderr_lines": [], "stdout": "0.50", "stdout_lines": ["0.50"]}
ok: [raspi.4gb.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.011119", "end": "2025-12-15 20:25:20.448156", "msg": "", "rc": 0, "start": "2025-12-15 20:25:20.437037", "stderr": "", "stderr_lines": [], "stdout": "0.58", "stdout_lines": ["0.58"]}
ok: [ali2v.truenas.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005557", "end": "2025-12-15 20:25:20.594154", "msg": "", "rc": 0, "start": "2025-12-15 20:25:20.588597", "stderr": "", "stderr_lines": [], "stdout": "0.04", "stdout_lines": ["0.04"]}
ok: [automate.prod.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005018", "end": "2025-12-15 20:24:52.814576", "msg": "", "rc": 0, "start": "2025-12-15 20:24:52.809558", "stderr": "", "stderr_lines": [], "stdout": "0.36", "stdout_lines": ["0.36"]}
ok: [dev.prod.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.004629", "end": "2025-12-15 20:24:58.868555", "msg": "", "rc": 0, "start": "2025-12-15 20:24:58.863926", "stderr": "", "stderr_lines": [], "stdout": "0.11", "stdout_lines": ["0.11"]}
ok: [hp.truenas.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005975", "end": "2025-12-15 17:25:20.921084", "msg": "", "rc": 0, "start": "2025-12-15 17:25:20.915109", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}
ok: [jump.point.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.005343", "end": "2025-12-15 20:25:21.029235", "msg": "", "rc": 0, "start": "2025-12-15 20:25:21.023892", "stderr": "", "stderr_lines": [], "stdout": "0.06", "stdout_lines": ["0.06"]}
ok: [orangepi.pc.home] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.024172", "end": "2025-12-15 20:25:20.991830", "msg": "", "rc": 0, "start": "2025-12-15 20:25:20.967658", "stderr": "", "stderr_lines": [], "stdout": "0.27", "stdout_lines": ["0.27"]}
ok: [localhost] => {"changed": false, "cmd": "if [ -f /proc/loadavg ]; then\n cat /proc/loadavg | awk '{print $1}'\nelse\n uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' '\nfi\n", "delta": "0:00:00.007328", "end": "2025-12-15 20:25:21.328721", "msg": "", "rc": 0, "start": "2025-12-15 20:25:21.321393", "stderr": "", "stderr_lines": [], "stdout": "1.35", "stdout_lines": ["1.35"]}
TASK [Display health status] ***************************************************
ok: [ali2v.xeon.home] => {
"msg": "═══════════════════════════════════════\nHost: ali2v.xeon.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:25:11 up 1 day, 9:57, 1 user, load average: 0.25, 0.18, 0.23\nDisk Usage: 22%\nMemory Usage: 21.8%\nCPU Load: 0.45\nCPU Temp: 46.0°C\n═══════════════════════════════════════\n"
}
ok: [hp.nas.home] => {
"msg": "═══════════════════════════════════════\nHost: hp.nas.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:25:11 up 20 days, 7:16, 1 user, load average: 0.50, 0.43, 0.38\nDisk Usage: 23%\nMemory Usage: 81.2%\nCPU Load: 0.54\nCPU Temp: 30.0°C\n═══════════════════════════════════════\n"
}
ok: [hp2.i7.home] => {
"msg": "═══════════════════════════════════════\nHost: hp2.i7.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:25:11 up 20 days, 7:36, 1 user, load average: 0.75, 0.91, 0.88\nDisk Usage: 14%\nMemory Usage: 49.2%\nCPU Load: 0.69\nCPU Temp: 0.0°C\n═══════════════════════════════════════\n"
}
ok: [hp3.i5.home] => {
"msg": "═══════════════════════════════════════\nHost: hp3.i5.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:25:11 up 20 days, 8:49, 1 user, load average: 0.71, 0.67, 0.65\nDisk Usage: 14%\nMemory Usage: 59.5%\nCPU Load: 0.60\nCPU Temp: 53.0°C\n═══════════════════════════════════════\n"
}
ok: [mimi.pc.home] => {
"msg": "═══════════════════════════════════════\nHost: mimi.pc.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:25:11 up 20 days, 9:35, 1 user, load average: 0.12, 0.03, 0.01\nDisk Usage: 9%\nMemory Usage: 9.0%\nCPU Load: 0.10\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [orangepi.pc.home] => {
"msg": "═══════════════════════════════════════\nHost: orangepi.pc.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:25:13 up 13 days, 9:51, 1 user, load average: 0.24, 0.16, 0.11\nDisk Usage: 21%\nMemory Usage: 20.6%\nCPU Load: 0.27\nCPU Temp: 36.9°C\n═══════════════════════════════════════\n"
}
ok: [raspi.4gb.home] => {
"msg": "═══════════════════════════════════════\nHost: raspi.4gb.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:25:12 up 192 days, 11:58, 1 user, load average: 0.50, 0.32, 0.28\nDisk Usage: 6%\nMemory Usage: 12.3%\nCPU Load: 0.58\nCPU Temp: 35.0°C\n═══════════════════════════════════════\n"
}
ok: [raspi.8gb.home] => {
"msg": "═══════════════════════════════════════\nHost: raspi.8gb.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:25:12 up 192 days, 11:58, 1 user, load average: 0.50, 0.29, 0.20\nDisk Usage: 3%\nMemory Usage: 6.8%\nCPU Load: 0.50\nCPU Temp: 32.6°C\n═══════════════════════════════════════\n"
}
ok: [dev.lab.home] => {
"msg": "═══════════════════════════════════════\nHost: dev.lab.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:24:47 up 9 days, 8:14, 0 user, load average: 0.19, 0.36, 0.21\nDisk Usage: 48%\nMemory Usage: 71.6%\nCPU Load: 0.24\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [media.labb.home] => {
"msg": "═══════════════════════════════════════\nHost: media.labb.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:24:42 up 16 days, 4:26, 0 user, load average: 0.08, 0.02, 0.00\nDisk Usage: 24%\nMemory Usage: 72.2%\nCPU Load: 0.07\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [ali2v.truenas.home] => {
"msg": "═══════════════════════════════════════\nHost: ali2v.truenas.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:25:13 up 1 day, 9:56, 1 user, load average: 0.04, 0.06, 0.03\nDisk Usage: 1%\nMemory Usage: 34.0%\nCPU Load: 0.04\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [automate.prod.home] => {
"msg": "═══════════════════════════════════════\nHost: automate.prod.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:24:45 up 18 days, 23:19, 0 user, load average: 0.40, 0.39, 0.39\nDisk Usage: 28%\nMemory Usage: 26.0%\nCPU Load: 0.36\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [dev.prod.home] => {
"msg": "═══════════════════════════════════════\nHost: dev.prod.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:24:51 up 15 days, 9:40, 0 user, load average: 0.12, 0.31, 0.29\nDisk Usage: 75%\nMemory Usage: 58.1%\nCPU Load: 0.11\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [hp.truenas.home] => {
"msg": "═══════════════════════════════════════\nHost: hp.truenas.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 5:25PM up 20 days, 7:15, 1 user, load averages: 0.16, 0.25, 0.24\nDisk Usage: 10%\nMemory Usage: \nCPU Load: \nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [jump.point.home] => {
"msg": "═══════════════════════════════════════\nHost: jump.point.home\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:25:13 up 1 day, 9:56, 1 user, load average: 0.07, 0.13, 0.14\nDisk Usage: 79%\nMemory Usage: 13.5%\nCPU Load: 0.06\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
ok: [localhost] => {
"msg": "═══════════════════════════════════════\nHost: localhost\nStatus: OK\n═══════════════════════════════════════\nUptime: 20:25:13 up 7:00, 1 user, load average: 1.41, 1.24, 1.25\nDisk Usage: 1%\nMemory Usage: 12.5%\nCPU Load: 1.35\nCPU Temp: N/A\n═══════════════════════════════════════\n"
}
PLAY RECAP *********************************************************************
ali2v.truenas.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
ali2v.xeon.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
automate.prod.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
dev.lab.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
dev.prod.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
hp.nas.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
hp.truenas.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=1
hp2.i7.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
hp3.i5.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
jump.point.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
localhost : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
media.labb.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
mimi.pc.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
orangepi.pc.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
raspi.4gb.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
raspi.8gb.home : ok=8 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
```
---
*Généré automatiquement par Homelab Automation Dashboard*
*Date: 2025-12-16T01:25:22.162099+00:00*

Some files were not shown because too many files have changed in this diff Show More