#!
/usr/bin/env lua
-- Network Sentinel Script
-- Monitors network connections and system resources
local socket = require("socket")
local os = require("os")
local io = require("io")
-- Configuration
local config = {
name = "Network Sentinel",
version = "2.1.0",
check_interval = 30,
alert_threshold = {
cpu_usage = 80,
memory_usage = 85,
connection_timeout = 5
},
monitored_hosts = {
"8.8.8.8",
"1.1.1.1",
"google.com",
"github.com"
},
log_file = "sentinel.log"
}
-- State tracking
local system_state = {
alerts = {},
last_check = 0,
uptime_start = os.time(),
check_count = 0,
failed_checks = 0
}
-- Utility functions
local function timestamp()
return os.date("%Y-%m-%d %H:%M:%S")
end
local function log_message(level, message)
local log_entry = string.format("[%s] %s: %s\n", timestamp(), level, message)
print(log_entry:sub(1, -2)) -- Remove trailing newline for console
-- Write to log file
local file = io.open(config.log_file, "a")
if file then
file:write(log_entry)
file:close()
end
end
-- System monitoring functions
local function get_system_stats()
local stats = {
timestamp = os.time(),
cpu_usage = math.random(15, 95), -- Simulated CPU usage
memory_usage = math.random(30, 90), -- Simulated memory usage
disk_usage = math.random(25, 85),
network_active = true
}
-- Add some realistic patterns
local hour = tonumber(os.date("%H"))
if hour >= 9 and hour <= 17 then
stats.cpu_usage = stats.cpu_usage + math.random(5, 15) -- Higher during
work hours
end
return stats
end
-- Network connectivity checker
local function check_host_connectivity(host, port)
port = port or 80
local start_time = socket.gettime()
log_message("DEBUG", string.format("Checking connectivity to %s:%d", host,
port))
local tcp = socket.tcp()
tcp:settimeout(config.alert_threshold.connection_timeout)
local result, err = tcp:connect(host, port)
local response_time = (socket.gettime() - start_time) * 1000 -- Convert to ms
tcp:close()
if result then
return {
host = host,
port = port,
status = "connected",
response_time = response_time,
error = nil
}
else
return {
host = host,
port = port,
status = "failed",
response_time = nil,
error = err or "Connection failed"
}
end
end
-- Alert system
local function trigger_alert(alert_type, message, severity)
local alert = {
type = alert_type,
message = message,
severity = severity or "WARNING",
timestamp = os.time(),
id = #system_state.alerts + 1
}
table.insert(system_state.alerts, alert)
log_message("ALERT", string.format("[%s] %s: %s", alert.severity, alert_type,
message))
-- Keep only last 50 alerts
if #system_state.alerts > 50 then
table.remove(system_state.alerts, 1)
end
end
-- Performance monitoring
local function monitor_system_performance()
local stats = get_system_stats()
-- Check CPU usage
if stats.cpu_usage > config.alert_threshold.cpu_usage then
trigger_alert("HIGH_CPU",
string.format("CPU usage at %d%% (threshold: %d%%)",
stats.cpu_usage, config.alert_threshold.cpu_usage),
"CRITICAL")
end
-- Check memory usage
if stats.memory_usage > config.alert_threshold.memory_usage then
trigger_alert("HIGH_MEMORY",
string.format("Memory usage at %d%% (threshold: %d%%)",
stats.memory_usage, config.alert_threshold.memory_usage),
"WARNING")
end
return stats
end
-- Network monitoring
local function monitor_network_connectivity()
local connectivity_results = {}
local failed_connections = 0
for _, host in ipairs(config.monitored_hosts) do
local result = check_host_connectivity(host)
table.insert(connectivity_results, result)
if result.status == "failed" then
failed_connections = failed_connections + 1
trigger_alert("CONNECTION_FAILED",
string.format("Failed to connect to %s: %s", host, result.error),
"ERROR")
else
log_message("INFO", string.format("Connected to %s in %.2fms", host,
result.response_time))
end
end
-- Check if majority of connections failed
if failed_connections > #config.monitored_hosts / 2 then
trigger_alert("NETWORK_OUTAGE",
string.format("Multiple connection failures (%d/%d hosts unreachable)",
failed_connections, #config.monitored_hosts),
"CRITICAL")
end
return connectivity_results
end
-- Report generation
local function generate_status_report()
local uptime = os.time() - system_state.uptime_start
local success_rate = ((system_state.check_count - system_state.failed_checks) /
system_state.check_count) * 100
local report = {
"=== NETWORK SENTINEL STATUS REPORT ===",
string.format("Generated: %s", timestamp()),
string.format("Uptime: %d seconds", uptime),
string.format("Total checks: %d", system_state.check_count),
string.format("Success rate: %.2f%%", success_rate),
string.format("Active alerts: %d", #system_state.alerts),
"",
"Recent Alerts:"
}
-- Add last 5 alerts
local recent_alerts = {}
for i = math.max(1, #system_state.alerts - 4), #system_state.alerts do
if system_state.alerts[i] then
local alert = system_state.alerts[i]
table.insert(recent_alerts, string.format(" [%s] %s: %s",
os.date("%H:%M:%S", alert.timestamp), alert.type, alert.message))
end
end
if #recent_alerts == 0 then
table.insert(report, " No recent alerts")
else
for _, alert_line in ipairs(recent_alerts) do
table.insert(report, alert_line)
end
end
return table.concat(report, "\n")
end
-- Main monitoring loop
local function monitoring_cycle()
log_message("INFO", "Starting monitoring cycle")
system_state.check_count = system_state.check_count + 1
local cycle_start = socket.gettime()
-- Monitor system performance
local sys_stats = monitor_system_performance()
-- Monitor network connectivity
local net_results = monitor_network_connectivity()
-- Calculate cycle time
local cycle_time = (socket.gettime() - cycle_start) * 1000
log_message("INFO", string.format("Monitoring cycle completed in %.2fms",
cycle_time))
-- Update state
system_state.last_check = os.time()
return {
system_stats = sys_stats,
network_results = net_results,
cycle_time = cycle_time
}
end
-- Main execution function
local function main(args)
log_message("INFO", string.format("Starting %s v%s", config.name,
config.version))
-- Parse command line arguments
local mode = args[1] or "monitor"
local cycles = tonumber(args[2]) or -1 -- -1 means infinite
if mode == "report" then
print(generate_status_report())
return 0
elseif mode == "test" then
log_message("INFO", "Running connectivity test")
monitor_network_connectivity()
return 0
elseif mode == "monitor" then
log_message("INFO", string.format("Starting monitoring mode (cycles: %s)",
cycles == -1 and "infinite" or tostring(cycles)))
local cycle_count = 0
while cycles == -1 or cycle_count < cycles do
local results = monitoring_cycle()
cycle_count = cycle_count + 1
-- Sleep between cycles
if cycles == -1 or cycle_count < cycles then
log_message("DEBUG", string.format("Sleeping for %d seconds",
config.check_interval))
socket.sleep(config.check_interval)
end
end
log_message("INFO", "Monitoring completed")
print(generate_status_report())
return 0
else
print("Usage: lua sentinel.lua [monitor|test|report] [cycles]")
print(" monitor [cycles] - Run monitoring (default: infinite)")
print(" test - Test connectivity once")
print(" report - Generate status report")
return 1
end
end
-- Script entry point
if arg then
local exit_code = main(arg)
os.exit(exit_code)
else
print("Network Sentinel Script loaded. Call main({mode, cycles}) to execute.")
print("Available modes: monitor, test, report")
end