docent-python 0.1.11a0__py3-none-any.whl → 0.1.12a0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- docent/trace.py +33 -52
- {docent_python-0.1.11a0.dist-info → docent_python-0.1.12a0.dist-info}/METADATA +1 -1
- {docent_python-0.1.11a0.dist-info → docent_python-0.1.12a0.dist-info}/RECORD +5 -5
- {docent_python-0.1.11a0.dist-info → docent_python-0.1.12a0.dist-info}/WHEEL +0 -0
- {docent_python-0.1.11a0.dist-info → docent_python-0.1.12a0.dist-info}/licenses/LICENSE.md +0 -0
docent/trace.py
CHANGED
|
@@ -3,7 +3,6 @@ import contextvars
|
|
|
3
3
|
import itertools
|
|
4
4
|
import logging
|
|
5
5
|
import os
|
|
6
|
-
import signal
|
|
7
6
|
import sys
|
|
8
7
|
import threading
|
|
9
8
|
import uuid
|
|
@@ -158,6 +157,7 @@ class DocentTracer:
|
|
|
158
157
|
lambda: itertools.count(0)
|
|
159
158
|
)
|
|
160
159
|
self._transcript_counter_lock = threading.Lock()
|
|
160
|
+
self._flush_lock = threading.Lock()
|
|
161
161
|
|
|
162
162
|
def get_current_agent_run_id(self) -> Optional[str]:
|
|
163
163
|
"""
|
|
@@ -179,14 +179,6 @@ class DocentTracer:
|
|
|
179
179
|
# Register atexit handler
|
|
180
180
|
atexit.register(self.cleanup)
|
|
181
181
|
|
|
182
|
-
# Register signal handlers for graceful shutdown
|
|
183
|
-
try:
|
|
184
|
-
signal.signal(signal.SIGINT, self._signal_handler)
|
|
185
|
-
signal.signal(signal.SIGTERM, self._signal_handler)
|
|
186
|
-
except (ValueError, OSError):
|
|
187
|
-
# Signal handlers might not work in all environments
|
|
188
|
-
pass
|
|
189
|
-
|
|
190
182
|
self._cleanup_registered = True
|
|
191
183
|
|
|
192
184
|
def _next_span_order(self, transcript_id: str) -> int:
|
|
@@ -197,10 +189,6 @@ class DocentTracer:
|
|
|
197
189
|
with self._transcript_counter_lock:
|
|
198
190
|
return next(self._transcript_counters[transcript_id])
|
|
199
191
|
|
|
200
|
-
def _signal_handler(self, signum: int, frame: Optional[object]):
|
|
201
|
-
"""Handle shutdown signals."""
|
|
202
|
-
self.cleanup()
|
|
203
|
-
|
|
204
192
|
def _init_spans_exporter(self, endpoint: str) -> Optional[Union[HTTPExporter, GRPCExporter]]:
|
|
205
193
|
"""Initialize the appropriate span exporter based on endpoint."""
|
|
206
194
|
if not self.enable_otlp_export:
|
|
@@ -211,9 +199,11 @@ class DocentTracer:
|
|
|
211
199
|
http_exporter: HTTPExporter = HTTPExporter(
|
|
212
200
|
endpoint=f"{endpoint}/v1/traces", headers=self.headers
|
|
213
201
|
)
|
|
202
|
+
logger.debug(f"Initialized HTTP exporter for endpoint: {endpoint}/v1/traces")
|
|
214
203
|
return http_exporter
|
|
215
204
|
else:
|
|
216
205
|
grpc_exporter: GRPCExporter = GRPCExporter(endpoint=endpoint, headers=self.headers)
|
|
206
|
+
logger.debug(f"Initialized gRPC exporter for endpoint: {endpoint}")
|
|
217
207
|
return grpc_exporter
|
|
218
208
|
except Exception as e:
|
|
219
209
|
logger.error(f"Failed to initialize span exporter for {endpoint}: {e}")
|
|
@@ -239,9 +229,11 @@ class DocentTracer:
|
|
|
239
229
|
"""Create appropriate span processor based on configuration."""
|
|
240
230
|
if self.disable_batch or _is_notebook():
|
|
241
231
|
simple_processor: SimpleSpanProcessor = SimpleSpanProcessor(exporter)
|
|
232
|
+
logger.debug("Created SimpleSpanProcessor for immediate export")
|
|
242
233
|
return simple_processor
|
|
243
234
|
else:
|
|
244
235
|
batch_processor: BatchSpanProcessor = BatchSpanProcessor(exporter)
|
|
236
|
+
logger.debug("Created BatchSpanProcessor for batched export")
|
|
245
237
|
return batch_processor
|
|
246
238
|
|
|
247
239
|
def initialize(self):
|
|
@@ -310,8 +302,19 @@ class DocentTracer:
|
|
|
310
302
|
# attributes not available, skip them
|
|
311
303
|
pass
|
|
312
304
|
|
|
305
|
+
# Debug logging for span creation
|
|
306
|
+
span_name = getattr(span, "name", "unknown")
|
|
307
|
+
span_attrs = getattr(span, "attributes", {})
|
|
308
|
+
logger.debug(
|
|
309
|
+
f"Created span: name='{span_name}', collection_id={self.manager.collection_id}, agent_run_id={span_attrs.get('agent_run_id')}, transcript_id={span_attrs.get('transcript_id')}"
|
|
310
|
+
)
|
|
311
|
+
|
|
313
312
|
def on_end(self, span: ReadableSpan) -> None:
|
|
314
|
-
|
|
313
|
+
# Debug logging for span completion
|
|
314
|
+
span_attrs = span.attributes or {}
|
|
315
|
+
logger.debug(
|
|
316
|
+
f"Completed span: name='{span.name}', collection_id={span_attrs.get('collection_id')}, agent_run_id={span_attrs.get('agent_run_id')}, transcript_id={span_attrs.get('transcript_id')}, duration_ns={span.end_time - span.start_time if span.end_time and span.start_time else 'unknown'}"
|
|
317
|
+
)
|
|
315
318
|
|
|
316
319
|
def shutdown(self) -> None:
|
|
317
320
|
pass
|
|
@@ -422,15 +425,8 @@ class DocentTracer:
|
|
|
422
425
|
return
|
|
423
426
|
|
|
424
427
|
try:
|
|
425
|
-
|
|
426
|
-
try:
|
|
427
|
-
self._send_trace_done()
|
|
428
|
-
except Exception as e:
|
|
429
|
-
logger.warning(f"Failed to notify trace done: {e}")
|
|
430
|
-
|
|
431
|
-
self._root_context = None # type: ignore
|
|
428
|
+
self.flush()
|
|
432
429
|
|
|
433
|
-
# Shutdown our isolated tracer provider
|
|
434
430
|
if self._tracer_provider:
|
|
435
431
|
self._tracer_provider.shutdown()
|
|
436
432
|
self._tracer_provider = None
|
|
@@ -456,9 +452,12 @@ class DocentTracer:
|
|
|
456
452
|
return
|
|
457
453
|
|
|
458
454
|
try:
|
|
459
|
-
|
|
455
|
+
logger.debug(f"Flushing {len(self._spans_processors)} span processors")
|
|
456
|
+
for i, processor in enumerate(self._spans_processors):
|
|
460
457
|
if hasattr(processor, "force_flush"):
|
|
461
|
-
|
|
458
|
+
logger.debug(f"Flushing span processor {i}")
|
|
459
|
+
processor.force_flush(timeout_millis=50)
|
|
460
|
+
logger.debug("Span flush completed")
|
|
462
461
|
except Exception as e:
|
|
463
462
|
logger.error(f"Error during flush: {e}")
|
|
464
463
|
|
|
@@ -476,29 +475,6 @@ class DocentTracer:
|
|
|
476
475
|
"""Verify if the manager is properly initialized."""
|
|
477
476
|
return self._initialized
|
|
478
477
|
|
|
479
|
-
def __enter__(self) -> "DocentTracer":
|
|
480
|
-
"""Context manager entry."""
|
|
481
|
-
self.initialize()
|
|
482
|
-
return self
|
|
483
|
-
|
|
484
|
-
def __exit__(self, exc_type: type[BaseException], exc_val: Any, exc_tb: Any) -> None:
|
|
485
|
-
"""Context manager exit."""
|
|
486
|
-
self.close()
|
|
487
|
-
|
|
488
|
-
@property
|
|
489
|
-
def tracer(self) -> Optional[trace.Tracer]:
|
|
490
|
-
"""Get the tracer instance."""
|
|
491
|
-
if not self._initialized:
|
|
492
|
-
self.initialize()
|
|
493
|
-
return self._tracer
|
|
494
|
-
|
|
495
|
-
@property
|
|
496
|
-
def root_context(self) -> Optional[Context]:
|
|
497
|
-
"""Get the root context."""
|
|
498
|
-
if not self._initialized:
|
|
499
|
-
self.initialize()
|
|
500
|
-
return self._root_context
|
|
501
|
-
|
|
502
478
|
@contextmanager
|
|
503
479
|
def agent_run_context(
|
|
504
480
|
self,
|
|
@@ -617,13 +593,15 @@ class DocentTracer:
|
|
|
617
593
|
Get the API headers for HTTP requests.
|
|
618
594
|
|
|
619
595
|
Returns:
|
|
620
|
-
Dictionary of headers including Authorization
|
|
596
|
+
Dictionary of headers including Authorization if set
|
|
621
597
|
"""
|
|
598
|
+
headers = {"Content-Type": "application/json"}
|
|
622
599
|
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
600
|
+
authorization = self.headers.get("Authorization")
|
|
601
|
+
if authorization:
|
|
602
|
+
headers["Authorization"] = authorization
|
|
603
|
+
|
|
604
|
+
return headers
|
|
627
605
|
|
|
628
606
|
def _post_json(self, path: str, data: Dict[str, Any]) -> None:
|
|
629
607
|
if not self._api_endpoint_base:
|
|
@@ -1157,7 +1135,10 @@ def close_tracing() -> None:
|
|
|
1157
1135
|
def flush_tracing() -> None:
|
|
1158
1136
|
"""Force flush all spans to exporters."""
|
|
1159
1137
|
if _global_tracer:
|
|
1138
|
+
logger.debug("Flushing global tracer")
|
|
1160
1139
|
_global_tracer.flush()
|
|
1140
|
+
else:
|
|
1141
|
+
logger.debug("No global tracer available to flush")
|
|
1161
1142
|
|
|
1162
1143
|
|
|
1163
1144
|
def verify_initialized() -> bool:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
docent/__init__.py,sha256=J2BbO6rzilfw9WXRUeolr439EGFezqbMU_kCpCCryRA,59
|
|
2
2
|
docent/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
|
-
docent/trace.py,sha256
|
|
3
|
+
docent/trace.py,sha256=C8oO5NuChSgyHIB5OI6qOfXWaIld7jdvlEqImK56a1E,66761
|
|
4
4
|
docent/trace_temp.py,sha256=Z0lAPwVzXjFvxpiU-CuvfWIslq9Q4alNkZMoQ77Xudk,40711
|
|
5
5
|
docent/_log_util/__init__.py,sha256=3HXXrxrSm8PxwG4llotrCnSnp7GuroK1FNHsdg6f7aE,73
|
|
6
6
|
docent/_log_util/logger.py,sha256=kwM0yRW1IJd6-XTorjWn48B4l8qvD2ZM6VDjY5eskQI,4422
|
|
@@ -24,7 +24,7 @@ docent/samples/log.eval,sha256=orrW__9WBfANq7NwKsPSq9oTsQRcG6KohG5tMr_X_XY,39770
|
|
|
24
24
|
docent/samples/tb_airline.json,sha256=eR2jFFRtOw06xqbEglh6-dPewjifOk-cuxJq67Dtu5I,47028
|
|
25
25
|
docent/sdk/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
26
26
|
docent/sdk/client.py,sha256=rvOFXvyAr9QxCijN0_CWENbm8y3YQvR1msfFSBDZvOw,13309
|
|
27
|
-
docent_python-0.1.
|
|
28
|
-
docent_python-0.1.
|
|
29
|
-
docent_python-0.1.
|
|
30
|
-
docent_python-0.1.
|
|
27
|
+
docent_python-0.1.12a0.dist-info/METADATA,sha256=OnxdikeOy69TZy_HGoWUxi7VDu20k8nwrikLcIPLXho,1038
|
|
28
|
+
docent_python-0.1.12a0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
29
|
+
docent_python-0.1.12a0.dist-info/licenses/LICENSE.md,sha256=vOHzq3K4Ndu0UV9hPrtXvlD7pHOjyDQmGjHuLSIkRQY,1087
|
|
30
|
+
docent_python-0.1.12a0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|