sid.ovh/modules/nixos/journald-remote/server.py
sid de573124ce
All checks were successful
Build hosts / build-hosts (pull_request) Successful in 19s
Flake check / flake-check (pull_request) Successful in 19s
add mcp log server via journald
2026-05-19 12:56:26 +02:00

60 lines
1.6 KiB
Python

#!/usr/bin/env python3
import json
import subprocess
from fastmcp import FastMCP
mcp = FastMCP('ClusterLogQuery')
@mcp.tool()
async def search_cluster_logs(keyword: str, unit: str = '*', limit: int = 500):
"""
Search centralized systemd logs collected on this server.
Args:
keyword: The string to search for (e.g. 'oom-kill', 'failed').
unit: The systemd unit to filter (e.g. 'sshd'). If '*', matches all.
limit: The number of log lines to return (Max 1000).
"""
limit = min(max(limit, 10), 1000)
cmd = [
'journalctl',
'-n', str(limit),
'-o', 'json',
'--no-pager',
'--directory', '/var/log/journal/remote'
]
if unit != '*':
cmd.append(f'UNIT={unit}')
if keyword:
cmd.append(keyword)
try:
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, _ = proc.communicate()
logs = []
for line in stdout.decode('utf-8').strip().split('\n'):
if not line: continue
try:
log = json.loads(line)
logs.append({
'timestamp': log.get('TIME_ISO8601'),
'hostname': log.get('_HOSTNAME'),
'unit': log.get('_COMM'),
'message': log.get('MESSAGE')
})
except: pass
return json.dumps(logs)
except Exception as e:
return f'Error querying logs: {str(e)}'
def main():
mcp.run(transport='sse', host='0.0.0.0', port=9500)
if __name__ == '__main__':
main()