78 lines
2.6 KiB
Python
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())
|