Now Calling the correct package
This commit is contained in:
@@ -1,13 +1,23 @@
|
||||
import json
|
||||
import platform
|
||||
import subprocess
|
||||
import time
|
||||
from syslog_rfc5424_parser import parse
|
||||
import logging
|
||||
from syslog_rfc5424_parser import SyslogMessage
|
||||
import jc
|
||||
import ollama
|
||||
from discord_webhook import DiscordWebhook, DiscordEmbed
|
||||
import requests
|
||||
import config
|
||||
|
||||
# --- Logging Configuration ---
|
||||
logging.basicConfig(level=logging.INFO,
|
||||
format='%(asctime)s - %(levelname)s - %(message)s',
|
||||
handlers=[
|
||||
logging.FileHandler("monitor_agent.log"),
|
||||
logging.StreamHandler()
|
||||
])
|
||||
|
||||
# --- Data Ingestion & Parsing Functions ---
|
||||
|
||||
def get_system_logs():
|
||||
@@ -21,17 +31,17 @@ def get_system_logs():
|
||||
dict: A dictionary representing the parsed log entry.
|
||||
"""
|
||||
mock_log_entry = '<165>1 2025-08-15T12:00:00Z my-host app-name - - [meta sequenceId="1"] { "log": "Failed login attempt for user \'root\' from 10.0.0.1" }'
|
||||
parsed_log = parse(mock_log_entry)
|
||||
# The message part is a string, so we need to parse it as JSON
|
||||
# In a real scenario, you might need to handle non-json messages
|
||||
if parsed_log.message:
|
||||
try:
|
||||
log_content = json.loads(parsed_log.message)
|
||||
# We can merge the log content with the parsed log for a more complete picture
|
||||
# For now, we'll just return the content of the log message
|
||||
return log_content
|
||||
except json.JSONDecodeError:
|
||||
return {"log": parsed_log.message}
|
||||
try:
|
||||
parsed_log = SyslogMessage.parse(mock_log_entry)
|
||||
if parsed_log.msg:
|
||||
try:
|
||||
log_content = json.loads(parsed_log.msg)
|
||||
return log_content
|
||||
except json.JSONDecodeError:
|
||||
logging.warning(f"Could not parse log message as JSON: {parsed_log.msg}")
|
||||
return {"log": parsed_log.msg}
|
||||
except Exception as e:
|
||||
logging.error(f"Error parsing syslog message: {e}")
|
||||
return {}
|
||||
|
||||
def get_network_metrics():
|
||||
@@ -44,17 +54,17 @@ def get_network_metrics():
|
||||
Returns:
|
||||
dict: A dictionary containing the parsed network metrics.
|
||||
"""
|
||||
# We ping a reliable address, like Google's DNS, 3 times.
|
||||
# The '-c 3' argument is for Linux/macOS. For Windows, it would be '-n 3'.
|
||||
# Since the target is an Ubuntu server, we'll use '-c'.
|
||||
ping_param = '-n' if platform.system() == "Windows" else '-c'
|
||||
try:
|
||||
ping_output = subprocess.run(['ping', '-c', '3', '8.8.8.8'], capture_output=True, text=True, check=True).stdout
|
||||
ping_output = subprocess.run(['ping', ping_param, '3', '8.8.8.8'], capture_output=True, text=True, check=True).stdout
|
||||
parsed_metrics = jc.parse('ping', ping_output)
|
||||
# We're interested in the summary statistics
|
||||
if parsed_metrics:
|
||||
if parsed_metrics and isinstance(parsed_metrics, list):
|
||||
return parsed_metrics[0]
|
||||
else:
|
||||
logging.warning("Could not parse ping output with jc. Returning raw output.")
|
||||
return {"ping_output": ping_output}
|
||||
except (subprocess.CalledProcessError, FileNotFoundError) as e:
|
||||
# Handle cases where ping fails or is not installed
|
||||
logging.error(f"Error running ping command: {e}")
|
||||
return {"error": str(e)}
|
||||
return {}
|
||||
|
||||
@@ -79,12 +89,14 @@ Output Request: If you find an anomaly, provide a report as a single, coherent,
|
||||
Reasoning Hint: Think step by step to come to your conclusion. This is very important."""
|
||||
|
||||
try:
|
||||
response = ollama.generate(
|
||||
client = ollama.Client(host=config.OLLAMA_HOST)
|
||||
response = client.generate(
|
||||
model="llama3.1:8b",
|
||||
prompt=prompt
|
||||
)
|
||||
return response['response'].strip()
|
||||
except Exception as e:
|
||||
logging.error(f"Error communicating with Ollama: {e}")
|
||||
return f"Error communicating with Ollama: {e}"
|
||||
|
||||
# --- Alerting Functions ---
|
||||
@@ -97,7 +109,7 @@ def send_discord_alert(message):
|
||||
message (str): The message to send.
|
||||
"""
|
||||
if config.DISCORD_WEBHOOK_URL == "YOUR_DISCORD_WEBHOOK_URL_HERE":
|
||||
print("Skipping Discord alert: Webhook URL not configured.")
|
||||
logging.info("Skipping Discord alert: Webhook URL not configured.")
|
||||
return
|
||||
|
||||
webhook = DiscordWebhook(url=config.DISCORD_WEBHOOK_URL)
|
||||
@@ -105,9 +117,9 @@ def send_discord_alert(message):
|
||||
webhook.add_embed(embed)
|
||||
try:
|
||||
response = webhook.execute()
|
||||
print("Discord alert sent.")
|
||||
logging.info("Discord alert sent.")
|
||||
except Exception as e:
|
||||
print(f"Error sending Discord alert: {e}")
|
||||
logging.error(f"Error sending Discord alert: {e}")
|
||||
|
||||
def send_google_home_alert(message):
|
||||
"""
|
||||
@@ -116,9 +128,8 @@ def send_google_home_alert(message):
|
||||
Args:
|
||||
message (str): The message to be spoken.
|
||||
"""
|
||||
# Long or complex messages should be simplified for better Text-to-Speech delivery.
|
||||
if config.HOME_ASSISTANT_URL == "http://YOUR_HOME_ASSISTANT_IP:8123":
|
||||
print("Skipping Google Home alert: Home Assistant URL not configured.")
|
||||
logging.info("Skipping Google Home alert: Home Assistant URL not configured.")
|
||||
return
|
||||
|
||||
url = f"{config.HOME_ASSISTANT_URL}/api/services/tts/speak"
|
||||
@@ -134,10 +145,10 @@ def send_google_home_alert(message):
|
||||
|
||||
try:
|
||||
response = requests.post(url, headers=headers, json=payload)
|
||||
response.raise_for_status() # Raise an exception for bad status codes
|
||||
print("Google Home alert sent.")
|
||||
response.raise_for_status()
|
||||
logging.info("Google Home alert sent.")
|
||||
except requests.exceptions.RequestException as e:
|
||||
print(f"Error sending Google Home alert: {e}")
|
||||
logging.error(f"Error sending Google Home alert: {e}")
|
||||
|
||||
# --- Main Script Logic ---
|
||||
|
||||
@@ -146,26 +157,28 @@ def main():
|
||||
The main execution loop for the monitoring agent.
|
||||
"""
|
||||
while True:
|
||||
print("--- Running Monitoring Cycle ---")
|
||||
logging.info("--- Running Monitoring Cycle ---")
|
||||
system_logs = get_system_logs()
|
||||
logging.info(f"System Logs: {system_logs}")
|
||||
network_metrics = get_network_metrics()
|
||||
logging.info(f"Network Metrics: {network_metrics}")
|
||||
|
||||
combined_data = {
|
||||
"system_logs": system_logs,
|
||||
"network_metrics": network_metrics
|
||||
}
|
||||
logging.info(f"Combined Data: {json.dumps(combined_data, indent=2)}")
|
||||
|
||||
llm_response = analyze_data_with_llm(combined_data)
|
||||
print(f"LLM Response: {llm_response}")
|
||||
logging.info(f"LLM Response: {llm_response}")
|
||||
|
||||
if llm_response != "OK":
|
||||
print("Anomaly detected, sending alerts...")
|
||||
logging.info("Anomaly detected, sending alerts...")
|
||||
send_discord_alert(llm_response)
|
||||
send_google_home_alert(llm_response)
|
||||
|
||||
print("--- Cycle Complete, sleeping for 5 minutes ---")
|
||||
logging.info("--- Cycle Complete, sleeping for 5 minutes ---")
|
||||
time.sleep(300) # 300 seconds = 5 minutes
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
main()
|
||||
Reference in New Issue
Block a user