MugdhaV commited on
Commit
00e34ab
·
1 Parent(s): df29455

feat: Add severity tags to all AppSignal error reports

Browse files

Use send_error_with_context() with set_params() to tag errors
with severity (critical/error/warning) and source location across
both app.py and ai_indexer.py.

Files changed (2) hide show
  1. ai_indexer.py +15 -8
  2. app.py +17 -9
ai_indexer.py CHANGED
@@ -17,7 +17,7 @@ from pathlib import Path
17
  from typing import List, Dict, Optional
18
  import logging
19
  from opentelemetry import trace
20
- from appsignal import send_error
21
 
22
  logging.basicConfig(level=logging.INFO)
23
  logger = logging.getLogger(__name__)
@@ -64,7 +64,8 @@ class LocalMediaIndexer:
64
  self.processor = AutoProcessor.from_pretrained(model_name)
65
  logger.info("[OK] Model loaded successfully")
66
  except Exception as e:
67
- send_error(e)
 
68
  logger.error(f"[ERROR] Error loading model: {e}")
69
  raise
70
 
@@ -109,7 +110,8 @@ class LocalMediaIndexer:
109
  return frames
110
 
111
  except Exception as e:
112
- send_error(e)
 
113
  logger.error(f"[ERROR] Error extracting frames from {video_path}: {e}")
114
  return []
115
 
@@ -135,7 +137,8 @@ class LocalMediaIndexer:
135
  image_features = image_features / image_features.norm(dim=-1, keepdim=True)
136
  return image_features.cpu().numpy().flatten()
137
  except Exception as e:
138
- send_error(e)
 
139
  logger.error(f"[ERROR] Error getting embedding: {e}")
140
  return None
141
 
@@ -232,7 +235,8 @@ class LocalMediaIndexer:
232
  logger.info(f" [OK] Indexed video: {file}")
233
 
234
  except Exception as e:
235
- send_error(e)
 
236
  logger.error(f"[ERROR] Error processing {file}: {e}")
237
 
238
  if not embeddings:
@@ -313,7 +317,8 @@ class LocalMediaIndexer:
313
  return results
314
 
315
  except Exception as e:
316
- send_error(e)
 
317
  logger.error(f"[ERROR] Search error: {e}")
318
  return []
319
 
@@ -335,7 +340,8 @@ class LocalMediaIndexer:
335
  logger.info(f"💾 Index saved to {self.index_dir}")
336
 
337
  except Exception as e:
338
- send_error(e)
 
339
  logger.error(f"[ERROR] Error saving index: {e}")
340
 
341
  def load_index(self) -> bool:
@@ -360,6 +366,7 @@ class LocalMediaIndexer:
360
  return False
361
 
362
  except Exception as e:
363
- send_error(e)
 
364
  logger.error(f"[ERROR] Error loading index: {e}")
365
  return False
 
17
  from typing import List, Dict, Optional
18
  import logging
19
  from opentelemetry import trace
20
+ from appsignal import send_error_with_context, set_params
21
 
22
  logging.basicConfig(level=logging.INFO)
23
  logger = logging.getLogger(__name__)
 
64
  self.processor = AutoProcessor.from_pretrained(model_name)
65
  logger.info("[OK] Model loaded successfully")
66
  except Exception as e:
67
+ with send_error_with_context(e):
68
+ set_params({"severity": "critical", "source": "model_loading"})
69
  logger.error(f"[ERROR] Error loading model: {e}")
70
  raise
71
 
 
110
  return frames
111
 
112
  except Exception as e:
113
+ with send_error_with_context(e):
114
+ set_params({"severity": "warning", "source": "video_frame_extraction", "video_path": video_path})
115
  logger.error(f"[ERROR] Error extracting frames from {video_path}: {e}")
116
  return []
117
 
 
137
  image_features = image_features / image_features.norm(dim=-1, keepdim=True)
138
  return image_features.cpu().numpy().flatten()
139
  except Exception as e:
140
+ with send_error_with_context(e):
141
+ set_params({"severity": "error", "source": "image_embedding"})
142
  logger.error(f"[ERROR] Error getting embedding: {e}")
143
  return None
144
 
 
235
  logger.info(f" [OK] Indexed video: {file}")
236
 
237
  except Exception as e:
238
+ with send_error_with_context(e):
239
+ set_params({"severity": "warning", "source": "file_indexing", "file": file})
240
  logger.error(f"[ERROR] Error processing {file}: {e}")
241
 
242
  if not embeddings:
 
317
  return results
318
 
319
  except Exception as e:
320
+ with send_error_with_context(e):
321
+ set_params({"severity": "error", "source": "indexer_search"})
322
  logger.error(f"[ERROR] Search error: {e}")
323
  return []
324
 
 
340
  logger.info(f"💾 Index saved to {self.index_dir}")
341
 
342
  except Exception as e:
343
+ with send_error_with_context(e):
344
+ set_params({"severity": "error", "source": "index_save"})
345
  logger.error(f"[ERROR] Error saving index: {e}")
346
 
347
  def load_index(self) -> bool:
 
366
  return False
367
 
368
  except Exception as e:
369
+ with send_error_with_context(e):
370
+ set_params({"severity": "error", "source": "index_load"})
371
  logger.error(f"[ERROR] Error loading index: {e}")
372
  return False
app.py CHANGED
@@ -25,7 +25,7 @@ from huggingface_hub import snapshot_download
25
  load_dotenv()
26
 
27
  # --- AppSignal APM ---
28
- from appsignal import Appsignal, set_category, send_error, set_gauge, increment_counter
29
  import time
30
  from opentelemetry.instrumentation.starlette import StarletteInstrumentor
31
  from opentelemetry import trace
@@ -78,7 +78,8 @@ if IS_HUGGINGFACE_SPACE or not os.path.exists(MEDIA_DIR) or not os.listdir(MEDIA
78
  )
79
  logger.info("Media files downloaded successfully")
80
  except Exception as e:
81
- send_error(e)
 
82
  logger.error(f"Failed to download media files: {e}")
83
  logger.warning("Continuing without demo media files")
84
 
@@ -95,7 +96,8 @@ try:
95
  indexer.index_local_directory(force_reindex=False)
96
 
97
  except Exception as e:
98
- send_error(e)
 
99
  logger.error(f"❌ Failed to initialize indexer: {e}")
100
  raise
101
 
@@ -125,7 +127,8 @@ def semantic_search(query: str, media_type: str = "all", top_k: int = 5) -> str:
125
  t_start = time.time()
126
  try:
127
  if not query or not query.strip():
128
- send_error(ValueError("Query cannot be empty"))
 
129
  increment_counter("semantic_search.errors", 1)
130
  return json.dumps({"error": "Query cannot be empty"}, indent=2)
131
 
@@ -164,7 +167,8 @@ def semantic_search(query: str, media_type: str = "all", top_k: int = 5) -> str:
164
 
165
  except Exception as e:
166
  increment_counter("semantic_search.errors", 1)
167
- send_error(e)
 
168
  logger.error(f"[ERROR] Search error: {e}")
169
  return json.dumps({"error": str(e)}, indent=2)
170
 
@@ -183,7 +187,8 @@ def get_media_details(file_path: str) -> str:
183
  span.set_attribute("media.file_path", file_path or "")
184
  try:
185
  if not os.path.exists(file_path):
186
- send_error(FileNotFoundError(f"File not found: {file_path}"))
 
187
  return json.dumps({"error": f"File not found: {file_path}"}, indent=2)
188
 
189
  stat = os.stat(file_path)
@@ -208,7 +213,8 @@ def get_media_details(file_path: str) -> str:
208
  return json.dumps(details, indent=2)
209
 
210
  except Exception as e:
211
- send_error(e)
 
212
  logger.error(f"[ERROR] Error getting details: {e}")
213
  return json.dumps({"error": str(e)}, indent=2)
214
 
@@ -248,7 +254,8 @@ def reindex_media(force: bool = False) -> str:
248
 
249
  except Exception as e:
250
  increment_counter("reindex.errors", 1)
251
- send_error(e)
 
252
  logger.error(f"[ERROR] Reindex error: {e}")
253
  return json.dumps({"error": str(e)}, indent=2)
254
 
@@ -293,7 +300,8 @@ def get_index_stats() -> str:
293
  return json.dumps(stats, indent=2)
294
 
295
  except Exception as e:
296
- send_error(e)
 
297
  logger.error(f"[ERROR] Error getting stats: {e}")
298
  return json.dumps({"error": str(e)}, indent=2)
299
 
 
25
  load_dotenv()
26
 
27
  # --- AppSignal APM ---
28
+ from appsignal import Appsignal, set_category, send_error, send_error_with_context, set_params, set_gauge, increment_counter
29
  import time
30
  from opentelemetry.instrumentation.starlette import StarletteInstrumentor
31
  from opentelemetry import trace
 
78
  )
79
  logger.info("Media files downloaded successfully")
80
  except Exception as e:
81
+ with send_error_with_context(e):
82
+ set_params({"severity": "warning", "source": "media_download"})
83
  logger.error(f"Failed to download media files: {e}")
84
  logger.warning("Continuing without demo media files")
85
 
 
96
  indexer.index_local_directory(force_reindex=False)
97
 
98
  except Exception as e:
99
+ with send_error_with_context(e):
100
+ set_params({"severity": "critical", "source": "indexer_init"})
101
  logger.error(f"❌ Failed to initialize indexer: {e}")
102
  raise
103
 
 
127
  t_start = time.time()
128
  try:
129
  if not query or not query.strip():
130
+ with send_error_with_context(ValueError("Query cannot be empty")):
131
+ set_params({"severity": "warning", "source": "semantic_search"})
132
  increment_counter("semantic_search.errors", 1)
133
  return json.dumps({"error": "Query cannot be empty"}, indent=2)
134
 
 
167
 
168
  except Exception as e:
169
  increment_counter("semantic_search.errors", 1)
170
+ with send_error_with_context(e):
171
+ set_params({"severity": "error", "source": "semantic_search"})
172
  logger.error(f"[ERROR] Search error: {e}")
173
  return json.dumps({"error": str(e)}, indent=2)
174
 
 
187
  span.set_attribute("media.file_path", file_path or "")
188
  try:
189
  if not os.path.exists(file_path):
190
+ with send_error_with_context(FileNotFoundError(f"File not found: {file_path}")):
191
+ set_params({"severity": "warning", "source": "get_media_details", "file_path": file_path})
192
  return json.dumps({"error": f"File not found: {file_path}"}, indent=2)
193
 
194
  stat = os.stat(file_path)
 
213
  return json.dumps(details, indent=2)
214
 
215
  except Exception as e:
216
+ with send_error_with_context(e):
217
+ set_params({"severity": "error", "source": "get_media_details"})
218
  logger.error(f"[ERROR] Error getting details: {e}")
219
  return json.dumps({"error": str(e)}, indent=2)
220
 
 
254
 
255
  except Exception as e:
256
  increment_counter("reindex.errors", 1)
257
+ with send_error_with_context(e):
258
+ set_params({"severity": "error", "source": "reindex_media"})
259
  logger.error(f"[ERROR] Reindex error: {e}")
260
  return json.dumps({"error": str(e)}, indent=2)
261
 
 
300
  return json.dumps(stats, indent=2)
301
 
302
  except Exception as e:
303
+ with send_error_with_context(e):
304
+ set_params({"severity": "error", "source": "get_index_stats"})
305
  logger.error(f"[ERROR] Error getting stats: {e}")
306
  return json.dumps({"error": str(e)}, indent=2)
307