|
|
|
|
|
import os |
|
import json |
|
import requests |
|
import threading |
|
import queue |
|
import logging |
|
|
|
_global_logger = None |
|
|
|
|
|
def get_remote_logger(): |
|
global _global_logger |
|
if _global_logger is None: |
|
if url := os.environ.get("REMOTE_LOGGER_URL"): |
|
logging.info(f"Remote logger enabled, sending data to {url}") |
|
_global_logger = RemoteLogger(url=url) |
|
else: |
|
_global_logger = EmptyLogger() |
|
return _global_logger |
|
|
|
|
|
class EmptyLogger: |
|
"""Dummy logger that does nothing.""" |
|
|
|
def __init__(self): |
|
pass |
|
|
|
def log(self, _data: dict): |
|
pass |
|
|
|
|
|
class RemoteLogger: |
|
"""A JSON logger that sends data to remote endpoint.""" |
|
|
|
def __init__(self, url: str): |
|
self.url = url |
|
|
|
self.logs = queue.Queue() |
|
self.thread = threading.Thread(target=self._send_logs, daemon=True) |
|
self.thread.start() |
|
|
|
def log(self, data: dict): |
|
self.logs.put_nowait(data) |
|
|
|
def _send_logs(self): |
|
while True: |
|
data = self.logs.get() |
|
|
|
|
|
for key, value in data.items(): |
|
if isinstance(value, (dict, list, tuple)): |
|
data[key] = json.dumps(value, ensure_ascii=False) |
|
|
|
try: |
|
requests.post(self.url, json=data) |
|
except Exception: |
|
logging.exception("Failed to send logs to remote endpoint") |
|
|