Telemetry
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
from datetime import datetime
|
||||
import asyncio
|
||||
import json
|
||||
|
||||
async def get_systemd_logs(lines: int = 200, service_name: str = "smartwave") -> list[dict]:
|
||||
"""
|
||||
Asynchronously fetches the last N log entries from a systemd service
|
||||
using native asyncio subprocess execution.
|
||||
"""
|
||||
cmd = (
|
||||
"journalctl",
|
||||
"-u", service_name,
|
||||
"-n", str(lines),
|
||||
"-o", "json",
|
||||
"--no-pager"
|
||||
)
|
||||
|
||||
try:
|
||||
# Create non-blocking child process
|
||||
proc = await asyncio.create_subprocess_exec(
|
||||
*cmd,
|
||||
stdout=asyncio.subprocess.PIPE,
|
||||
stderr=asyncio.subprocess.PIPE
|
||||
)
|
||||
|
||||
# Await completion and read output non-blockingly
|
||||
stdout_bytes, stderr_bytes = await proc.communicate()
|
||||
|
||||
if proc.returncode != 0:
|
||||
print(f"[Logs] journalctl error (code {proc.returncode}): {stderr_bytes.decode('utf-8', errors='replace')}")
|
||||
return []
|
||||
|
||||
structured_logs = []
|
||||
stdout_text = stdout_bytes.decode("utf-8", errors="replace")
|
||||
|
||||
for line in stdout_text.strip().split("\n"):
|
||||
if not line:
|
||||
continue
|
||||
try:
|
||||
entry = json.loads(line)
|
||||
|
||||
raw_ts = entry.get("__REALTIME_TIMESTAMP")
|
||||
timestamp_iso = None
|
||||
if raw_ts:
|
||||
timestamp_iso = datetime.fromtimestamp(int(raw_ts) / 1_000_000).isoformat()
|
||||
|
||||
structured_logs.append({
|
||||
"timestamp": timestamp_iso,
|
||||
"timestamp_us": int(raw_ts) if raw_ts else None,
|
||||
"message": entry.get("MESSAGE", ""),
|
||||
"priority": entry.get("PRIORITY"),
|
||||
"pid": entry.get("_PID"),
|
||||
})
|
||||
except (json.JSONDecodeError, ValueError):
|
||||
continue
|
||||
|
||||
return structured_logs
|
||||
|
||||
except Exception as e:
|
||||
print(f"[Logs] Failed to read systemd logs for '{service_name}': {e}")
|
||||
return []
|
||||
Reference in New Issue
Block a user