added start script
This commit is contained in:
21
README.md
21
README.md
@@ -12,6 +12,15 @@ source .venv/bin/activate
|
|||||||
pip install -e .
|
pip install -e .
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Or use the helper script, which creates/uses `.venv` automatically and runs `pip install -e .`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./start.sh
|
||||||
|
./start.sh status
|
||||||
|
./start.sh analyze
|
||||||
|
./start.sh stop
|
||||||
|
```
|
||||||
|
|
||||||
Analyze local logs:
|
Analyze local logs:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -24,6 +33,18 @@ Listen for FortiGate syslog locally:
|
|||||||
fgai listen-syslog --port 5514 --output logs/fg_syslog.jsonl
|
fgai listen-syslog --port 5514 --output logs/fg_syslog.jsonl
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Run the listener quietly in the background:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./start.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Stop the background listener:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./start.sh stop
|
||||||
|
```
|
||||||
|
|
||||||
UDP port `514` normally needs root privileges on Linux:
|
UDP port `514` normally needs root privileges on Linux:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
5
scripts/fgai-listener.sh
Executable file
5
scripts/fgai-listener.sh
Executable file
@@ -0,0 +1,5 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||||
|
exec "$ROOT_DIR/start.sh" "$@"
|
||||||
@@ -102,7 +102,7 @@ def fetch_policies(args: argparse.Namespace) -> int:
|
|||||||
|
|
||||||
|
|
||||||
def listen_syslog(args: argparse.Namespace) -> int:
|
def listen_syslog(args: argparse.Namespace) -> int:
|
||||||
listen_udp_syslog(args.host, args.port, args.output)
|
listen_udp_syslog(args.host, args.port, args.output, quiet=args.quiet)
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
@@ -145,6 +145,7 @@ def build_parser() -> argparse.ArgumentParser:
|
|||||||
listener.add_argument("--host", default="0.0.0.0", help="Bind address")
|
listener.add_argument("--host", default="0.0.0.0", help="Bind address")
|
||||||
listener.add_argument("--port", type=int, default=5514, help="UDP port. Use 514 only with sudo/capability.")
|
listener.add_argument("--port", type=int, default=5514, help="UDP port. Use 514 only with sudo/capability.")
|
||||||
listener.add_argument("--output", default="logs/fg_syslog.jsonl", help="File to append received logs to")
|
listener.add_argument("--output", default="logs/fg_syslog.jsonl", help="File to append received logs to")
|
||||||
|
listener.add_argument("--quiet", action="store_true", help="Do not print each received syslog message")
|
||||||
listener.set_defaults(func=listen_syslog)
|
listener.set_defaults(func=listen_syslog)
|
||||||
|
|
||||||
return parser
|
return parser
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import socket
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
def listen_udp_syslog(host: str, port: int, output: str, *, max_bytes: int = 65535) -> None:
|
def listen_udp_syslog(host: str, port: int, output: str, *, max_bytes: int = 65535, quiet: bool = False) -> None:
|
||||||
output_path = Path(output)
|
output_path = Path(output)
|
||||||
output_path.parent.mkdir(parents=True, exist_ok=True)
|
output_path.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
@@ -20,4 +20,5 @@ def listen_udp_syslog(host: str, port: int, output: str, *, max_bytes: int = 655
|
|||||||
if not message:
|
if not message:
|
||||||
continue
|
continue
|
||||||
handle.write(f"{message}\n")
|
handle.write(f"{message}\n")
|
||||||
print(f"{address[0]}:{address[1]} {message}")
|
if not quiet:
|
||||||
|
print(f"{address[0]}:{address[1]} {message}")
|
||||||
|
|||||||
118
start.sh
Executable file
118
start.sh
Executable file
@@ -0,0 +1,118 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
VENV_DIR="${FGAI_VENV_DIR:-$ROOT_DIR/.venv}"
|
||||||
|
PORT="${FGAI_SYSLOG_PORT:-5514}"
|
||||||
|
HOST="${FGAI_SYSLOG_HOST:-0.0.0.0}"
|
||||||
|
LOG_FILE="${FGAI_SYSLOG_FILE:-$ROOT_DIR/logs/fg_syslog.jsonl}"
|
||||||
|
LISTENER_LOG="${FGAI_LISTENER_LOG:-$ROOT_DIR/logs/fgai-listener.log}"
|
||||||
|
PID_FILE="${FGAI_PID_FILE:-$ROOT_DIR/run/fgai-listener.pid}"
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
printf 'Usage: %s [start|stop|restart|status|tail|analyze|install]\n' "$0"
|
||||||
|
printf '\nDefault action: start\n'
|
||||||
|
printf '\nEnvironment overrides:\n'
|
||||||
|
printf ' FGAI_SYSLOG_PORT=%s\n' "$PORT"
|
||||||
|
printf ' FGAI_SYSLOG_HOST=%s\n' "$HOST"
|
||||||
|
printf ' FGAI_SYSLOG_FILE=%s\n' "$LOG_FILE"
|
||||||
|
printf ' FGAI_LISTENER_LOG=%s\n' "$LISTENER_LOG"
|
||||||
|
}
|
||||||
|
|
||||||
|
install_deps() {
|
||||||
|
if [ ! -x "$VENV_DIR/bin/python" ]; then
|
||||||
|
printf 'Creating venv: %s\n' "$VENV_DIR"
|
||||||
|
python3 -m venv "$VENV_DIR"
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf 'Installing/updating fgAI dependencies...\n'
|
||||||
|
"$VENV_DIR/bin/python" -m pip install --upgrade pip
|
||||||
|
"$VENV_DIR/bin/python" -m pip install -e "$ROOT_DIR"
|
||||||
|
}
|
||||||
|
|
||||||
|
is_running() {
|
||||||
|
[ -f "$PID_FILE" ] && kill -0 "$(cat "$PID_FILE")" 2>/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
start_listener() {
|
||||||
|
install_deps
|
||||||
|
mkdir -p "$(dirname "$LOG_FILE")" "$(dirname "$LISTENER_LOG")" "$(dirname "$PID_FILE")"
|
||||||
|
touch "$LOG_FILE"
|
||||||
|
|
||||||
|
if is_running; then
|
||||||
|
printf 'fgAI syslog listener already running, pid %s\n' "$(cat "$PID_FILE")"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
nohup "$VENV_DIR/bin/fgai" listen-syslog \
|
||||||
|
--host "$HOST" \
|
||||||
|
--port "$PORT" \
|
||||||
|
--output "$LOG_FILE" \
|
||||||
|
--quiet > "$LISTENER_LOG" 2>&1 &
|
||||||
|
printf '%s\n' "$!" > "$PID_FILE"
|
||||||
|
|
||||||
|
printf 'Started fgAI syslog listener, pid %s\n' "$(cat "$PID_FILE")"
|
||||||
|
printf 'Input: udp://%s:%s\n' "$HOST" "$PORT"
|
||||||
|
printf 'Syslog file: %s\n' "$LOG_FILE"
|
||||||
|
printf 'Process log: %s\n' "$LISTENER_LOG"
|
||||||
|
}
|
||||||
|
|
||||||
|
stop_listener() {
|
||||||
|
if ! is_running; then
|
||||||
|
printf 'fgAI syslog listener is not running\n'
|
||||||
|
rm -f "$PID_FILE"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
kill "$(cat "$PID_FILE")"
|
||||||
|
rm -f "$PID_FILE"
|
||||||
|
printf 'Stopped fgAI syslog listener\n'
|
||||||
|
}
|
||||||
|
|
||||||
|
status_listener() {
|
||||||
|
if is_running; then
|
||||||
|
printf 'fgAI syslog listener running, pid %s\n' "$(cat "$PID_FILE")"
|
||||||
|
printf 'Input: udp://%s:%s\n' "$HOST" "$PORT"
|
||||||
|
printf 'Syslog file: %s\n' "$LOG_FILE"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf 'fgAI syslog listener is not running\n'
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
command="${1:-start}"
|
||||||
|
case "$command" in
|
||||||
|
start)
|
||||||
|
start_listener
|
||||||
|
;;
|
||||||
|
stop)
|
||||||
|
stop_listener
|
||||||
|
;;
|
||||||
|
restart)
|
||||||
|
stop_listener
|
||||||
|
start_listener
|
||||||
|
;;
|
||||||
|
status)
|
||||||
|
status_listener
|
||||||
|
;;
|
||||||
|
tail)
|
||||||
|
mkdir -p "$(dirname "$LOG_FILE")"
|
||||||
|
touch "$LOG_FILE"
|
||||||
|
tail -f "$LOG_FILE"
|
||||||
|
;;
|
||||||
|
analyze)
|
||||||
|
install_deps
|
||||||
|
"$VENV_DIR/bin/fgai" analyze-logs --logs "$LOG_FILE"
|
||||||
|
;;
|
||||||
|
install)
|
||||||
|
install_deps
|
||||||
|
;;
|
||||||
|
-h|--help|help)
|
||||||
|
usage
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
usage
|
||||||
|
exit 2
|
||||||
|
;;
|
||||||
|
esac
|
||||||
Reference in New Issue
Block a user