57 lines
No EOL
2.1 KiB
Python
57 lines
No EOL
2.1 KiB
Python
import logging
|
|
import socketio
|
|
import time
|
|
|
|
class WebServerHandler(logging.Handler):
|
|
"""
|
|
A custom logging handler that sends log records to a web server via WebSockets.
|
|
"""
|
|
def __init__(self, url):
|
|
super().__init__()
|
|
self.url = url
|
|
self.sio = socketio.Client(reconnection_attempts=5, reconnection_delay=5)
|
|
self.is_connected = False
|
|
self.is_connecting = False # Re-entry guard
|
|
|
|
def connect(self):
|
|
"""Establish connection to the Socket.IO server, with re-entry protection."""
|
|
if self.is_connecting or self.is_connected:
|
|
return
|
|
|
|
self.is_connecting = True
|
|
try:
|
|
print(f"[LogHandler] Mencoba terhubung ke server log di {self.url}...")
|
|
self.sio.connect(self.url, transports=['websocket'])
|
|
self.is_connected = True
|
|
print("[LogHandler] Berhasil terhubung ke server log.")
|
|
except socketio.exceptions.ConnectionError as e:
|
|
self.is_connected = False
|
|
# Print directly to avoid re-triggering the handler
|
|
print(f"[LogHandler Error] Gagal terhubung ke server log. Error: {e}")
|
|
finally:
|
|
self.is_connecting = False
|
|
|
|
def emit(self, record):
|
|
"""
|
|
Emits a log record by sending it to the web server via Socket.IO.
|
|
"""
|
|
if not self.is_connected:
|
|
self.connect()
|
|
if not self.is_connected:
|
|
# If still not connected, print to console and drop the log.
|
|
print(f"[LogHandler Offline] {self.format(record)}")
|
|
return
|
|
|
|
try:
|
|
log_entry = self.format(record)
|
|
self.sio.emit('submit_log', {'message': log_entry})
|
|
except Exception as e:
|
|
print(f"[LogHandler Error] Gagal mengirim log via WebSocket. Error: {e}")
|
|
self.is_connected = False
|
|
|
|
def close(self):
|
|
"""Closes the Socket.IO connection."""
|
|
if self.is_connected:
|
|
self.sio.disconnect()
|
|
self.is_connected = False
|
|
super().close() |