Watch over Temps
This commit is contained in:
5
.gitignore
vendored
5
.gitignore
vendored
@@ -1,2 +1,3 @@
|
|||||||
GEMINI.md
|
__pycache__/
|
||||||
PROGRESS.md
|
monitoring_data.json
|
||||||
|
__pycache__/config.cpython-313.pyc
|
||||||
|
|||||||
@@ -5,3 +5,4 @@
|
|||||||
- Focus on events indicating loss of connectivity or unreachable hosts.
|
- Focus on events indicating loss of connectivity or unreachable hosts.
|
||||||
- Highlight any unexpected network additions or unusual traffic patterns.
|
- Highlight any unexpected network additions or unusual traffic patterns.
|
||||||
- The DNS server 8.8.8.8 is Google's public DNS server and is a legitimate destination. Do not flag requests to 8.8.8.8 as anomalous.
|
- The DNS server 8.8.8.8 is Google's public DNS server and is a legitimate destination. Do not flag requests to 8.8.8.8 as anomalous.
|
||||||
|
- Action has been taken against IP addresses 45.88.8.215, 45.88.8.186, 120.48.49.12, and 23.137.255.140. These are completley banned and cannot access the system at all.
|
||||||
34
PROGRESS.md
Normal file
34
PROGRESS.md
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
# Project Progress
|
||||||
|
|
||||||
|
## Phase 1: Initial Setup
|
||||||
|
|
||||||
|
1. [x] Create `monitor_agent.py`
|
||||||
|
2. [x] Create `config.py`
|
||||||
|
3. [x] Create `requirements.txt`
|
||||||
|
4. [x] Create `README.md`
|
||||||
|
5. [x] Create `.gitignore`
|
||||||
|
6. [x] Create `SPEC.md`
|
||||||
|
7. [x] Create `PROMPT.md`
|
||||||
|
8. [x] Create `CONSTRAINTS.md`
|
||||||
|
|
||||||
|
## Phase 2: Data Storage
|
||||||
|
|
||||||
|
9. [x] Create `data_storage.py`
|
||||||
|
10. [x] Implement data storage functions in `data_storage.py`
|
||||||
|
11. [x] Update `monitor_agent.py` to use data storage
|
||||||
|
12. [x] Update `SPEC.md` to reflect data storage functionality
|
||||||
|
|
||||||
|
## Phase 3: Expanded Monitoring
|
||||||
|
|
||||||
|
13. [x] Implement CPU temperature monitoring
|
||||||
|
14. [x] Implement GPU temperature monitoring
|
||||||
|
15. [x] Implement system login attempt monitoring
|
||||||
|
16. [x] Update `monitor_agent.py` to include new metrics
|
||||||
|
17. [x] Update `SPEC.md` to reflect new metrics
|
||||||
|
18. [x] Extend `calculate_baselines` to include system temps
|
||||||
|
|
||||||
|
## Phase 4: Troubleshooting
|
||||||
|
|
||||||
|
19. [x] Investigated and resolved issue with `jc` library
|
||||||
|
20. [x] Removed `jc` library as a dependency
|
||||||
|
21. [x] Implemented manual parsing of `sensors` command output
|
||||||
Binary file not shown.
10
config.py
10
config.py
@@ -1,15 +1,15 @@
|
|||||||
# Configuration for the LLM-Powered Monitoring Agent
|
# Configuration for the LLM-Powered Monitoring Agent
|
||||||
|
|
||||||
# Discord Webhook URL
|
# Discord Webhook URL
|
||||||
DISCORD_WEBHOOK_URL = ""
|
DISCORD_WEBHOOK_URL = "https://discord.com/api/webhooks/1024892743987773471/3Oh1KOw9tevBd-XtUkj8Rz2K4SePCFsxKmRrHhQw5spDeZKNzoyYoq6zC2cnTKo8VjJn"
|
||||||
|
|
||||||
# Home Assistant Configuration
|
# Home Assistant Configuration
|
||||||
HOME_ASSISTANT_URL = "http://<HOME_ASSISTANT_IP>:8123"
|
HOME_ASSISTANT_URL = "http://192.168.2.112:8123"
|
||||||
HOME_ASSISTANT_TOKEN = ""
|
HOME_ASSISTANT_TOKEN = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJjOGRmZjI4NDY2MTQ0ZDFkODhiODVjNmQyZTA2MzFiNSIsImlhdCI6MTc1NTU0NDY4OSwiZXhwIjoyMDcwOTA0Njg5fQ.5ZeOkixbdme5SF1QVknZ0bjnPYj1Qrps5HDn-Loi-cQ"
|
||||||
GOOGLE_HOME_SPEAKER_ID = "media_player.your_speaker_entity_id"
|
GOOGLE_HOME_SPEAKER_ID = "media_player.spencer_room_speaker"
|
||||||
|
|
||||||
# Daily Recap Time (in 24-hour format, e.g., "20:00")
|
# Daily Recap Time (in 24-hour format, e.g., "20:00")
|
||||||
DAILY_RECAP_TIME = "20:00"
|
DAILY_RECAP_TIME = "20:00"
|
||||||
|
|
||||||
# Test Mode (True to run once and exit, False to run continuously)
|
# Test Mode (True to run once and exit, False to run continuously)
|
||||||
TEST_MODE = True
|
TEST_MODE = False
|
||||||
|
|||||||
@@ -31,6 +31,8 @@ def calculate_baselines():
|
|||||||
baseline_metrics = {
|
baseline_metrics = {
|
||||||
'avg_rtt': sum(d['network_metrics']['round_trip_ms_avg'] for d in recent_data) / len(recent_data),
|
'avg_rtt': sum(d['network_metrics']['round_trip_ms_avg'] for d in recent_data) / len(recent_data),
|
||||||
'packet_loss': sum(d['network_metrics']['packet_loss_percent'] for d in recent_data) / len(recent_data),
|
'packet_loss': sum(d['network_metrics']['packet_loss_percent'] for d in recent_data) / len(recent_data),
|
||||||
|
'avg_cpu_temp': sum(d['cpu_temperature']['cpu_temperature'] for d in recent_data) / len(recent_data),
|
||||||
|
'avg_gpu_temp': sum(d['gpu_temperature']['gpu_temperature'] for d in recent_data) / len(recent_data),
|
||||||
}
|
}
|
||||||
|
|
||||||
return baseline_metrics
|
return baseline_metrics
|
||||||
@@ -7,7 +7,6 @@ import ollama
|
|||||||
from discord_webhook import DiscordWebhook
|
from discord_webhook import DiscordWebhook
|
||||||
import requests
|
import requests
|
||||||
import data_storage
|
import data_storage
|
||||||
import jc
|
|
||||||
|
|
||||||
# Load configuration
|
# Load configuration
|
||||||
import config
|
import config
|
||||||
@@ -43,43 +42,40 @@ def get_network_metrics():
|
|||||||
print(f"Error parsing network metrics: {e}")
|
print(f"Error parsing network metrics: {e}")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
import re
|
||||||
|
|
||||||
def get_cpu_temperature():
|
def get_cpu_temperature():
|
||||||
"""Gets the CPU temperature using the sensors command."""
|
"""Gets the CPU temperature using the sensors command."""
|
||||||
try:
|
try:
|
||||||
subprocess.check_output(["sensors"], text=True)
|
sensors_output = subprocess.check_output(["sensors"], text=True)
|
||||||
|
# Use regex to find the CPU temperature
|
||||||
|
match = re.search(r"Package id 0:\s+\+([\d\.]+)", sensors_output)
|
||||||
|
if match:
|
||||||
|
return {"cpu_temperature": float(match.group(1))}
|
||||||
|
else:
|
||||||
|
return {"cpu_temperature": "N/A"}
|
||||||
except (subprocess.CalledProcessError, FileNotFoundError):
|
except (subprocess.CalledProcessError, FileNotFoundError):
|
||||||
print("Error: 'sensors' command not found. Please install lm-sensors.")
|
print("Error: 'sensors' command not found. Please install lm-sensors.")
|
||||||
return {"cpu_temperature": "N/A"}
|
return {"cpu_temperature": "N/A"}
|
||||||
try:
|
|
||||||
sensors_output = subprocess.check_output(["sensors"], text=True)
|
|
||||||
parsed_sensors = jc.parse('sensors', sensors_output)
|
|
||||||
# This is a simplified example, you may need to adjust the parsing logic based on your specific hardware
|
|
||||||
cpu_temp = parsed_sensors[0]['values'][0]['input']
|
|
||||||
return {"cpu_temperature": cpu_temp}
|
|
||||||
except (subprocess.CalledProcessError, FileNotFoundError, KeyError, IndexError, jc.exceptions.ParseError) as e:
|
|
||||||
print(f"Error getting CPU temperature: {e}")
|
|
||||||
return {"cpu_temperature": "N/A"}
|
|
||||||
|
|
||||||
def get_gpu_temperature():
|
def get_gpu_temperature():
|
||||||
"""Gets the GPU temperature using the sensors command."""
|
"""Gets the GPU temperature using the sensors command."""
|
||||||
try:
|
try:
|
||||||
subprocess.check_output(["sensors"], text=True)
|
sensors_output = subprocess.check_output(["sensors"], text=True)
|
||||||
|
# Use regex to find the GPU temperature for amdgpu
|
||||||
|
match = re.search(r"edge:\s+\+([\d\.]+)", sensors_output)
|
||||||
|
if match:
|
||||||
|
return {"gpu_temperature": float(match.group(1))}
|
||||||
|
else:
|
||||||
|
# if amdgpu not found, try radeon
|
||||||
|
match = re.search(r"temp1:\s+\+([\d\.]+)", sensors_output)
|
||||||
|
if match:
|
||||||
|
return {"gpu_temperature": float(match.group(1))}
|
||||||
|
else:
|
||||||
|
return {"gpu_temperature": "N/A"}
|
||||||
except (subprocess.CalledProcessError, FileNotFoundError):
|
except (subprocess.CalledProcessError, FileNotFoundError):
|
||||||
print("Error: 'sensors' command not found. Please install lm-sensors.")
|
print("Error: 'sensors' command not found. Please install lm-sensors.")
|
||||||
return {"gpu_temperature": "N/A"}
|
return {"gpu_temperature": "N/A"}
|
||||||
try:
|
|
||||||
sensors_output = subprocess.check_output(["sensors"], text=True)
|
|
||||||
parsed_sensors = jc.parse('sensors', sensors_output)
|
|
||||||
# This is a simplified example, you may need to adjust the parsing logic based on your specific hardware
|
|
||||||
# Look for the adapter that contains "amdgpu" or "radeon"
|
|
||||||
for adapter in parsed_sensors:
|
|
||||||
if 'amdgpu' in adapter.get('adapter', '').lower() or 'radeon' in adapter.get('adapter', '').lower():
|
|
||||||
gpu_temp = adapter['values'][0]['input']
|
|
||||||
return {"gpu_temperature": gpu_temp}
|
|
||||||
return {"gpu_temperature": "N/A"}
|
|
||||||
except (subprocess.CalledProcessError, FileNotFoundError, KeyError, IndexError, jc.exceptions.ParseError) as e:
|
|
||||||
print(f"Error getting GPU temperature: {e}")
|
|
||||||
return {"gpu_temperature": "N/A"}
|
|
||||||
|
|
||||||
def get_login_attempts():
|
def get_login_attempts():
|
||||||
"""Gets system login attempts from /var/log/auth.log."""
|
"""Gets system login attempts from /var/log/auth.log."""
|
||||||
@@ -98,7 +94,7 @@ def get_login_attempts():
|
|||||||
return {"failed_login_attempts": []}
|
return {"failed_login_attempts": []}
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Error reading login attempts: {e}")
|
print(f"Error reading login attempts: {e}")
|
||||||
return {"failed_login_attempts": []}
|
return {"failed_logins": []}
|
||||||
|
|
||||||
# --- LLM Interaction Function ---
|
# --- LLM Interaction Function ---
|
||||||
|
|
||||||
|
|||||||
@@ -3,4 +3,3 @@ discord-webhook
|
|||||||
requests
|
requests
|
||||||
syslog-rfc5424-parser
|
syslog-rfc5424-parser
|
||||||
apachelogs
|
apachelogs
|
||||||
jc
|
|
||||||
Reference in New Issue
Block a user