pistarlog2ws/pistarlog2ws.py
2025-04-07 17:17:12 +02:00

78 lines
2.6 KiB
Python

"""Imports"""
import asyncio
import os
import traceback
from datetime import datetime
import websockets
import aiofiles
LOG_DIR = "/var/log/pi-star"
LOG_PREFIX = "MMDVM-"
LOG_EXT = ".log"
KEYWORDS = ["DMR"] # Add more keywords here
def get_logfile_path():
"""Return the correct logfile path based on UTC."""
date_str = datetime.utcnow().strftime("%Y-%m-%d")
return os.path.join(LOG_DIR, f"{LOG_PREFIX}{date_str}{LOG_EXT}")
async def tail_log(websocket, path):
"""Read the latest log file and stream lines with specified keywords."""
last_checked_file = get_logfile_path()
print(f"Client connected: {websocket.remote_address}")
# Wait for the file to exist
while not os.path.exists(last_checked_file):
print(f"Waiting for log file: {last_checked_file}")
await asyncio.sleep(2)
last_checked_file = get_logfile_path()
file = await aiofiles.open(last_checked_file, "r")
await file.seek(0, 2) # Move to the end of the file
try:
while True:
current_logfile = get_logfile_path()
if current_logfile != last_checked_file:
print(f"Switching to new log file: {current_logfile}")
await file.close() # Explicitly close previous file
last_checked_file = current_logfile
# Wait until the new log file is ready
while not os.path.exists(last_checked_file):
print(f"Waiting for new log file: {last_checked_file}")
await asyncio.sleep(2)
file = await aiofiles.open(last_checked_file, "r")
await file.seek(0, 2) # Go to end of new file
line = await file.readline()
if line:
print(f"READ LINE: {line.strip()}")
if any(keyword in line for keyword in KEYWORDS):
print(f"SENDING: {line.strip()}")
await websocket.send(line.strip())
else:
await asyncio.sleep(0.5) # Prevent busy-waiting
except websockets.exceptions.ConnectionClosed:
print(f"Client {websocket.remote_address} disconnected.")
except Exception as error:
print(f"Unexpected error: {error}")
traceback.print_exc()
finally:
await file.close() # Ensure file closure
async def main():
"""Start the WebSocket server."""
print("Starting WebSocket server on ws://0.0.0.0:8765")
async with websockets.serve(tail_log, "0.0.0.0", 8765):
await asyncio.Future() # Run forever
if __name__ == "__main__":
asyncio.run(main())