Spaces:
No application file
No application file
File size: 1,620 Bytes
f3305db |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# A JSON logger that sends data to remote endpoint.
# Architecturally, it hosts a background thread that sends logs to a remote endpoint.
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()
# process the data by keep only the top level fields, and turn any nested dict into a string
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")
|