add system-logger
This commit is contained in:
parent
6d09b2d6f4
commit
53cc916be5
2 changed files with 196 additions and 0 deletions
60
modules/services/system-logger/default.nix
Normal file
60
modules/services/system-logger/default.nix
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
system-logger = pkgs.writeShellApplication {
|
||||
name = "system-logger";
|
||||
runtimeInputs = with pkgs; [curl jq zip gawk systemd];
|
||||
text = builtins.readFile ./system-logger.sh;
|
||||
};
|
||||
in {
|
||||
options.services.system-logger = {
|
||||
enable = lib.mkEnableOption {
|
||||
description = "Enable System Logger Service";
|
||||
default = false;
|
||||
};
|
||||
|
||||
logDirectory = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
default = "/var/lib/system-logger";
|
||||
description = "Directory to store log archives";
|
||||
};
|
||||
|
||||
maxSizeMB = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 1;
|
||||
description = "Maximum size of daily log archive in megabytes";
|
||||
};
|
||||
|
||||
retentionDays = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 30;
|
||||
description = "Number of days to retain log archives";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf config.services.system-logger.enable {
|
||||
systemd.timers.system-logger = {
|
||||
description = "System Logger Timer";
|
||||
wantedBy = ["timers.target"];
|
||||
timerConfig = {
|
||||
OnCalendar = "daily";
|
||||
Persistent = true;
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.system-logger = {
|
||||
description = "System Logger Service";
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
ExecStart = "${lib.getExe system-logger}";
|
||||
Restart = "on-failure";
|
||||
RestartSec = 60;
|
||||
User = "root";
|
||||
Group = "root";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
136
modules/services/system-logger/system-logger.sh
Executable file
136
modules/services/system-logger/system-logger.sh
Executable file
|
|
@ -0,0 +1,136 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Configuration
|
||||
LOG_DIR="/var/lib/system-logger"
|
||||
MAX_SIZE_MB=1
|
||||
RETENTION_DAYS=30
|
||||
DATE=$(date +%Y-%m-%d)
|
||||
HOSTNAME=$(hostname)
|
||||
TEMP_DIR=$(mktemp -d)
|
||||
|
||||
# Create log directory if it doesn't exist
|
||||
mkdir -p "$LOG_DIR"
|
||||
|
||||
# Check if today's log already exists
|
||||
if [ -f "$LOG_DIR/${DATE}-logs-${HOSTNAME}.zip" ]; then
|
||||
echo "Logs for today already exist. Exiting..."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "Starting system log collection for $DATE"
|
||||
|
||||
# Function to collect logs with size limit
|
||||
collect_logs() {
|
||||
local source="$1"
|
||||
local output="$2"
|
||||
local max_lines="$3"
|
||||
|
||||
if [ -f "$source" ]; then
|
||||
# Get the last N lines to stay within size limit
|
||||
tail -n "$max_lines" "$source" > "$output" 2>/dev/null || true
|
||||
echo "Collected from $source"
|
||||
else
|
||||
echo "Source $source not found, skipping..."
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to get journal logs with filtering
|
||||
get_journal_logs() {
|
||||
local output="$1"
|
||||
local filter="$2"
|
||||
local max_lines="$3"
|
||||
|
||||
journalctl --since "00:00:00" --until "23:59:59" \
|
||||
--no-pager --output=short \
|
||||
| grep -i "$filter" | tail -n "$max_lines" > "$output" 2>/dev/null || true
|
||||
echo "Collected journal logs for $filter"
|
||||
}
|
||||
|
||||
# Calculate approximate lines per log type to stay under 1MB
|
||||
# Assuming average line is ~100 bytes, we aim for ~10,000 total lines
|
||||
TOTAL_LINES=10000
|
||||
SSH_LINES=2000
|
||||
KERNEL_LINES=2000
|
||||
LOGIN_LINES=1000
|
||||
SYSTEM_LINES=2000
|
||||
AUTH_LINES=1000
|
||||
FAILED_LOGIN_LINES=500
|
||||
DISK_LINES=500
|
||||
NETWORK_LINES=500
|
||||
MEMORY_LINES=500
|
||||
|
||||
# Collect SSH connections
|
||||
get_journal_logs "$TEMP_DIR/ssh.log" "sshd" "$SSH_LINES"
|
||||
|
||||
# Collect kernel warnings and errors
|
||||
get_journal_logs "$TEMP_DIR/kernel.log" "kernel.*warning\|kernel.*error" "$KERNEL_LINES"
|
||||
|
||||
# Collect login/logout events
|
||||
get_journal_logs "$TEMP_DIR/login.log" "session.*opened\|session.*closed\|login\|logout" "$LOGIN_LINES"
|
||||
|
||||
# Collect system messages
|
||||
get_journal_logs "$TEMP_DIR/system.log" "systemd\|daemon" "$SYSTEM_LINES"
|
||||
|
||||
# Collect authentication events
|
||||
get_journal_logs "$TEMP_DIR/auth.log" "authentication\|auth" "$AUTH_LINES"
|
||||
|
||||
# Collect failed login attempts
|
||||
get_journal_logs "$TEMP_DIR/failed_login.log" "failed\|failure\|denied" "$FAILED_LOGIN_LINES"
|
||||
|
||||
# Collect disk usage and errors
|
||||
get_journal_logs "$TEMP_DIR/disk.log" "disk\|storage\|iostat" "$DISK_LINES"
|
||||
|
||||
# Collect network events
|
||||
get_journal_logs "$TEMP_DIR/network.log" "network\|connection\|interface" "$NETWORK_LINES"
|
||||
|
||||
# Collect memory usage
|
||||
get_journal_logs "$TEMP_DIR/memory.log" "memory\|oom\|swap" "$MEMORY_LINES"
|
||||
|
||||
# Collect traditional log files if they exist
|
||||
collect_logs "/var/log/auth.log" "$TEMP_DIR/auth_traditional.log" 1000
|
||||
collect_logs "/var/log/syslog" "$TEMP_DIR/syslog_traditional.log" 1000
|
||||
collect_logs "/var/log/messages" "$TEMP_DIR/messages_traditional.log" 1000
|
||||
|
||||
# Create a summary file
|
||||
{
|
||||
echo "=== System Log Summary for $DATE ==="
|
||||
echo "Hostname: $HOSTNAME"
|
||||
echo "Collection time: $(date)"
|
||||
echo "Total lines collected:"
|
||||
wc -l "$TEMP_DIR"/*.log 2>/dev/null || true
|
||||
echo ""
|
||||
echo "=== System Information ==="
|
||||
echo "Uptime: $(uptime)"
|
||||
echo "Load average: $(cat /proc/loadavg)"
|
||||
echo "Memory usage:"
|
||||
free -h
|
||||
echo ""
|
||||
echo "Disk usage:"
|
||||
df -h
|
||||
echo ""
|
||||
echo "Active users:"
|
||||
who
|
||||
} > "$TEMP_DIR/summary.txt"
|
||||
|
||||
# Create the zip file
|
||||
cd "$TEMP_DIR"
|
||||
zip -r "$LOG_DIR/${DATE}-logs-${HOSTNAME}.zip" ./* > /dev/null
|
||||
|
||||
# Check file size and warn if too large
|
||||
FILE_SIZE=$(stat -c%s "$LOG_DIR/${DATE}-logs-${HOSTNAME}.zip")
|
||||
FILE_SIZE_MB=$((FILE_SIZE / 1024 / 1024))
|
||||
|
||||
if [ "$FILE_SIZE_MB" -gt "$MAX_SIZE_MB" ]; then
|
||||
echo "WARNING: Log file size ($FILE_SIZE_MB MB) exceeds limit ($MAX_SIZE_MB MB)"
|
||||
fi
|
||||
|
||||
echo "Log collection completed: $LOG_DIR/${DATE}-logs-${HOSTNAME}.zip ($FILE_SIZE_MB MB)"
|
||||
|
||||
# Clean up old logs (older than RETENTION_DAYS)
|
||||
find "$LOG_DIR" -name "*-logs-*.zip" -type f -mtime +$RETENTION_DAYS -delete 2>/dev/null || true
|
||||
|
||||
# Clean up temporary directory
|
||||
rm -rf "$TEMP_DIR"
|
||||
|
||||
echo "System log collection finished successfully"
|
||||
Loading…
Add table
Add a link
Reference in a new issue