AdarshDRC commited on
Commit
6bd9d26
·
verified ·
1 Parent(s): 11e0811

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +36 -30
main.py CHANGED
@@ -5,7 +5,6 @@ import uuid
5
  import re
6
  import time
7
  import json
8
- import base64
9
  import traceback
10
  import inflect
11
  from datetime import datetime, timezone
@@ -49,45 +48,52 @@ IDX_FACES = "enterprise-faces"
49
  IDX_OBJECTS = "enterprise-objects"
50
 
51
  # ════════════════════════════════════════════════════════════════
52
- # GRAFANA LOKI — async, fire-and-forget, never crashes the API
53
  # HF Space Secrets needed:
54
- # LOKI_URL → https://logs-prod-006.grafana.net (no trailing slash)
55
- # LOKI_USERNAME → your Grafana Cloud numeric user ID
56
- # LOKI_PASSWORD → your Grafana Cloud API token (Logs:Write scope)
57
  # ════════════════════════════════════════════════════════════════
58
- LOKI_URL = os.getenv("LOKI_URL", "")
59
- LOKI_USERNAME = os.getenv("LOKI_USERNAME", "")
60
- LOKI_PASSWORD = os.getenv("LOKI_PASSWORD", "")
61
 
62
- async def _loki_push(level: str, event: str, data: dict):
63
- """Fire-and-forget push to Grafana Loki. Silent on failure."""
64
- if not (LOKI_URL and LOKI_USERNAME and LOKI_PASSWORD):
65
  return
66
  try:
67
  import aiohttp
68
- ts_ns = str(int(time.time() * 1e9))
69
- line = json.dumps({"timestamp": datetime.now(timezone.utc).isoformat(),
70
- "level": level.upper(), "service": "enterprise-lens",
71
- "event": event, **data}, default=str)
72
- payload = {"streams": [{"stream": {"service": "enterprise-lens",
73
- "level": level.lower(),
74
- "event": event,
75
- "env": os.getenv("ENVIRONMENT", "production")},
76
- "values": [[ts_ns, line]]}]}
77
- creds = base64.b64encode(f"{LOKI_USERNAME}:{LOKI_PASSWORD}".encode()).decode()
78
- headers = {"Content-Type": "application/json", "Authorization": f"Basic {creds}"}
 
 
 
 
 
 
79
  async with aiohttp.ClientSession() as s:
80
- async with s.post(f"{LOKI_URL}/loki/api/v1/push",
81
- json=payload, headers=headers,
82
- timeout=aiohttp.ClientTimeout(total=5)) as r:
83
- if r.status not in (200, 204):
84
- _log_fn("WARNING", f"Loki returned {r.status}")
 
 
 
85
  except Exception as exc:
86
- _log_fn("DEBUG", f"Loki push skipped: {exc}")
87
 
88
  def log(level: str, event: str, **data):
89
  """
90
- Log to console + Grafana Loki (background task).
91
  Usage: log("INFO", "upload.complete", user_id="x", files=3, duration_ms=340)
92
  """
93
  clean = {k: v for k, v in data.items()}
@@ -95,7 +101,7 @@ def log(level: str, event: str, **data):
95
  try:
96
  loop = asyncio.get_event_loop()
97
  if loop.is_running():
98
- asyncio.create_task(_loki_push(level, event, data))
99
  except Exception:
100
  pass
101
 
 
5
  import re
6
  import time
7
  import json
 
8
  import traceback
9
  import inflect
10
  from datetime import datetime, timezone
 
48
  IDX_OBJECTS = "enterprise-objects"
49
 
50
  # ════════════════════════════════════════════════════════════════
51
+ # SUPABASE LOGGING — async, fire-and-forget, never crashes API
52
  # HF Space Secrets needed:
53
+ # SUPABASE_URL → https://xxxx.supabase.co
54
+ # SUPABASE_SERVICE_KEY → your Supabase service_role key (not anon!)
 
55
  # ════════════════════════════════════════════════════════════════
56
+ SUPABASE_URL = os.getenv("SUPABASE_URL", "")
57
+ SUPABASE_SERVICE_KEY = os.getenv("SUPABASE_SERVICE_KEY", "")
 
58
 
59
+ async def _supabase_log_push(level: str, event: str, data: dict):
60
+ """Fire-and-forget insert into Supabase app_logs table."""
61
+ if not (SUPABASE_URL and SUPABASE_SERVICE_KEY):
62
  return
63
  try:
64
  import aiohttp
65
+ row = {
66
+ "level": level.upper(),
67
+ "event": event,
68
+ "user_id": str(data.get("user_id", "anonymous")),
69
+ "ip": str(data.get("ip", "")),
70
+ "mode": str(data.get("mode", "")),
71
+ "page": str(data.get("page", "")),
72
+ "duration_ms": int(data["duration_ms"]) if "duration_ms" in data else None,
73
+ "error": str(data["error"]) if "error" in data else None,
74
+ "data": data,
75
+ }
76
+ headers = {
77
+ "Content-Type": "application/json",
78
+ "apikey": SUPABASE_SERVICE_KEY,
79
+ "Authorization": f"Bearer {SUPABASE_SERVICE_KEY}",
80
+ "Prefer": "return=minimal",
81
+ }
82
  async with aiohttp.ClientSession() as s:
83
+ async with s.post(
84
+ f"{SUPABASE_URL}/rest/v1/app_logs",
85
+ json=row, headers=headers,
86
+ timeout=aiohttp.ClientTimeout(total=5)
87
+ ) as r:
88
+ if r.status not in (200, 201):
89
+ body = await r.text()
90
+ _log_fn("WARNING", f"Supabase log insert failed {r.status}: {body[:200]}")
91
  except Exception as exc:
92
+ _log_fn("DEBUG", f"Supabase log push skipped: {exc}")
93
 
94
  def log(level: str, event: str, **data):
95
  """
96
+ Log to console + Supabase app_logs table (background task).
97
  Usage: log("INFO", "upload.complete", user_id="x", files=3, duration_ms=340)
98
  """
99
  clean = {k: v for k, v in data.items()}
 
101
  try:
102
  loop = asyncio.get_event_loop()
103
  if loop.is_running():
104
+ asyncio.create_task(_supabase_log_push(level, event, data))
105
  except Exception:
106
  pass
107