AdarshDRC commited on
Commit
829c74b
·
verified ·
1 Parent(s): 5598509

Create logging.py

Browse files
Files changed (1) hide show
  1. src/core/logging.py +80 -0
src/core/logging.py ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import asyncio
2
+ import json
3
+
4
+ from src.core.config import SUPABASE_URL, SUPABASE_SERVICE_KEY
5
+
6
+ _http_session = None
7
+
8
+ async def init_logging_session():
9
+ global _http_session
10
+ if SUPABASE_URL and SUPABASE_SERVICE_KEY:
11
+ import aiohttp
12
+ _http_session = aiohttp.ClientSession(
13
+ headers={
14
+ "Content-Type": "application/json",
15
+ "apikey": SUPABASE_SERVICE_KEY,
16
+ "Authorization": f"Bearer {SUPABASE_SERVICE_KEY}",
17
+ "Prefer": "return=minimal",
18
+ }
19
+ )
20
+
21
+ async def close_logging_session():
22
+ global _http_session
23
+ if _http_session:
24
+ await _http_session.close()
25
+
26
+ try:
27
+ from loguru import logger as _loguru
28
+ _loguru.remove()
29
+ _loguru.add(
30
+ lambda msg: print(msg, end=""),
31
+ format="<green>{time:HH:mm:ss}</green> | <level>{level:<8}</level> | {message}",
32
+ level="DEBUG",
33
+ colorize=True,
34
+ )
35
+ _log_fn = _loguru.log
36
+ except ImportError:
37
+ import logging as _logging
38
+ _logging.basicConfig(level=_logging.INFO)
39
+ _stdlib = _logging.getLogger("vsl")
40
+
41
+ def _log_fn(level: str, msg: str):
42
+ _stdlib.log(getattr(_logging, level, 20), msg)
43
+
44
+ async def _supabase_log(level: str, event: str, data: dict) -> None:
45
+ if not _http_session:
46
+ return
47
+ try:
48
+ import aiohttp
49
+ row = {
50
+ "level": level.upper(),
51
+ "event": event,
52
+ "user_id": str(data.get("user_id", "anonymous")),
53
+ "ip": str(data.get("ip", "")),
54
+ "mode": str(data.get("mode", "")),
55
+ "page": str(data.get("page", "")),
56
+ "duration_ms": int(data["duration_ms"]) if "duration_ms" in data else None,
57
+ "error": str(data["error"]) if "error" in data else None,
58
+ "data": data,
59
+ }
60
+ async with _http_session.post(
61
+ f"{SUPABASE_URL}/rest/v1/app_logs",
62
+ json=row,
63
+ timeout=aiohttp.ClientTimeout(total=5),
64
+ ) as r:
65
+ if r.status not in (200, 201):
66
+ body = await r.text()
67
+ _log_fn("WARNING", f"Supabase log failed {r.status}: {body[:200]}")
68
+ except Exception as exc:
69
+ _log_fn("DEBUG", f"Supabase log push skipped: {exc}")
70
+
71
+ def log(level: str, event: str, **data) -> None:
72
+ _log_fn(level.upper(), f"[{event}] {json.dumps(data, default=str)}")
73
+ try:
74
+ loop = asyncio.get_running_loop()
75
+ loop.create_task(_supabase_log(level, event, data))
76
+ except RuntimeError:
77
+ pass
78
+
79
+ def warn(msg: str) -> None:
80
+ _log_fn("WARNING", msg)