lmnr 0.5.0__py3-none-any.whl → 0.5.1a0__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.
@@ -4,8 +4,6 @@ import logging
4
4
  import uuid
5
5
 
6
6
  from contextvars import Context
7
- from lmnr.sdk.client.asynchronous.async_client import AsyncLaminarClient
8
- from lmnr.sdk.client.synchronous.sync_client import LaminarClient
9
7
  from lmnr.sdk.log import VerboseColorfulFormatter
10
8
  from lmnr.openllmetry_sdk.instruments import Instruments
11
9
  from lmnr.openllmetry_sdk.tracing.attributes import (
@@ -27,8 +25,8 @@ from opentelemetry.exporter.otlp.proto.http.trace_exporter import (
27
25
  from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import (
28
26
  OTLPSpanExporter as GRPCExporter,
29
27
  )
28
+ from opentelemetry.instrumentation.instrumentor import BaseInstrumentor
30
29
  from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import Compression
31
- from opentelemetry.instrumentation.threading import ThreadingInstrumentor
32
30
  from opentelemetry.context import get_value, attach, get_current, set_value
33
31
  from opentelemetry.propagate import set_global_textmap
34
32
  from opentelemetry.propagators.textmap import TextMapPropagator
@@ -39,7 +37,7 @@ from opentelemetry.sdk.trace.export import (
39
37
  SimpleSpanProcessor,
40
38
  BatchSpanProcessor,
41
39
  )
42
- from opentelemetry.trace import get_tracer_provider, ProxyTracerProvider
40
+ from opentelemetry.trace import ProxyTracerProvider
43
41
 
44
42
  from typing import Dict, Optional, Set
45
43
 
@@ -71,22 +69,14 @@ EXCLUDED_URLS = """
71
69
  openaipublic.blob.core.windows.net"""
72
70
 
73
71
  MAX_EVENTS_OR_ATTRIBUTES_PER_SPAN = 5000
72
+ instrumentors: dict[str, BaseInstrumentor] = {}
74
73
 
75
74
 
76
75
  class TracerWrapper(object):
77
- resource_attributes: dict = {}
78
- enable_content_tracing: bool = True
79
- endpoint: str = None
80
- headers: Dict[str, str] = {}
81
76
  __tracer_provider: TracerProvider = None
82
- __logger: logging.Logger = None
83
- __span_id_to_path: dict[int, list[str]] = {}
84
- __span_id_lists: dict[int, list[str]] = {}
85
- __client: LaminarClient = None
86
- __async_client: AsyncLaminarClient = None
87
-
88
- def __new__(
89
- cls,
77
+
78
+ def __init__(
79
+ self,
90
80
  disable_batch=False,
91
81
  processor: Optional[SpanProcessor] = None,
92
82
  propagator: Optional[TextMapPropagator] = None,
@@ -96,84 +86,73 @@ class TracerWrapper(object):
96
86
  base_http_url: Optional[str] = None,
97
87
  project_api_key: Optional[str] = None,
98
88
  max_export_batch_size: Optional[int] = None,
99
- ) -> "TracerWrapper":
100
- cls._initialize_logger(cls)
101
- if not hasattr(cls, "instance"):
102
- obj = cls.instance = super(TracerWrapper, cls).__new__(cls)
103
- if not TracerWrapper.endpoint:
104
- return obj
105
-
106
- obj.__client = LaminarClient(
107
- base_url=base_http_url,
108
- project_api_key=project_api_key,
109
- )
110
- obj.__async_client = AsyncLaminarClient(
111
- base_url=base_http_url,
112
- project_api_key=project_api_key,
113
- )
89
+ resource_attributes: dict = {},
90
+ enable_content_tracing: bool = True,
91
+ endpoint: str = None,
92
+ headers: Dict[str, str] = {},
93
+ ) -> None:
94
+ self.resource_attributes = resource_attributes
95
+ self.enable_content_tracing = enable_content_tracing
96
+ self.endpoint = endpoint
97
+ self.headers = headers
98
+ self.__logger = logging.getLogger(__name__)
99
+ console_log_handler = logging.StreamHandler()
100
+ console_log_handler.setFormatter(VerboseColorfulFormatter())
101
+ console_log_handler.setLevel(logging.INFO)
102
+ self.__logger.addHandler(console_log_handler)
103
+ self.__span_id_to_path = {}
104
+ self.__span_id_lists = {}
105
+
106
+ if not self.endpoint:
107
+ return
114
108
 
115
- obj.__resource = Resource(attributes=TracerWrapper.resource_attributes)
116
- obj.__tracer_provider = init_tracer_provider(resource=obj.__resource)
117
- if processor:
118
- obj.__spans_processor: SpanProcessor = processor
119
- obj.__spans_processor_original_on_start = processor.on_start
109
+ self.__resource = Resource(attributes=self.resource_attributes)
110
+ self.__tracer_provider = init_tracer_provider(resource=self.__resource)
111
+ if processor:
112
+ self.__spans_processor = processor
113
+ self.__spans_processor_original_on_start = processor.on_start
114
+ else:
115
+ self.__spans_exporter = (
116
+ exporter
117
+ if exporter
118
+ else init_spans_exporter(self.endpoint, self.headers)
119
+ )
120
+ if disable_batch or is_notebook():
121
+ self.__spans_processor = SimpleSpanProcessor(self.__spans_exporter)
120
122
  else:
121
- obj.__spans_exporter: SpanExporter = (
122
- exporter
123
- if exporter
124
- else init_spans_exporter(
125
- TracerWrapper.endpoint, TracerWrapper.headers
126
- )
123
+ self.__spans_processor = BatchSpanProcessor(
124
+ self.__spans_exporter,
125
+ max_export_batch_size=max_export_batch_size,
127
126
  )
128
- if disable_batch or is_notebook():
129
- obj.__spans_processor: SpanProcessor = SimpleSpanProcessor(
130
- obj.__spans_exporter
131
- )
132
- else:
133
- obj.__spans_processor: SpanProcessor = BatchSpanProcessor(
134
- obj.__spans_exporter,
135
- max_export_batch_size=max_export_batch_size,
136
- )
137
- obj.__spans_processor_original_on_start = None
138
-
139
- obj.__spans_processor.on_start = obj._span_processor_on_start
140
- obj.__tracer_provider.add_span_processor(obj.__spans_processor)
141
-
142
- if propagator:
143
- set_global_textmap(propagator)
144
-
145
- # this makes sure otel context is propagated so we always want it
146
- ThreadingInstrumentor().instrument()
147
-
148
- instrument_set = init_instrumentations(
149
- should_enrich_metrics,
150
- instruments,
151
- client=obj.__client,
152
- async_client=obj.__async_client,
153
- )
127
+ self.__spans_processor_original_on_start = None
154
128
 
155
- if not instrument_set:
156
- cls.__logger.info(
157
- "No instruments set through Laminar. "
158
- "Only enabling basic OpenTelemetry tracing."
159
- )
129
+ self.__spans_processor.on_start = self._span_processor_on_start
130
+ self.__tracer_provider.add_span_processor(self.__spans_processor)
160
131
 
161
- obj.__content_allow_list = ContentAllowList()
132
+ if propagator:
133
+ set_global_textmap(propagator)
162
134
 
163
- # Force flushes for debug environments (e.g. local development)
164
- atexit.register(obj.exit_handler)
135
+ instrument_set = init_instrumentations(
136
+ should_enrich_metrics,
137
+ instruments,
138
+ tracer_provider=self.__tracer_provider,
139
+ project_api_key=project_api_key,
140
+ base_http_url=base_http_url,
141
+ )
165
142
 
166
- return cls.instance
143
+ if not instrument_set:
144
+ self.__logger.info(
145
+ "No instruments set through Laminar. "
146
+ "Only enabling basic OpenTelemetry tracing."
147
+ )
167
148
 
168
- def exit_handler(self):
169
- self.__span_id_to_path = {}
170
- self.flush()
149
+ self.__content_allow_list = ContentAllowList()
171
150
 
172
- def _initialize_logger(self):
173
- self.__logger = logging.getLogger(__name__)
174
- console_log_handler = logging.StreamHandler()
175
- console_log_handler.setFormatter(VerboseColorfulFormatter())
176
- self.__logger.addHandler(console_log_handler)
151
+ # Force flushes for debug environments (e.g. local development)
152
+ atexit.register(self.exit_handler)
153
+
154
+ def exit_handler(self):
155
+ self.shutdown()
177
156
 
178
157
  def _span_processor_on_start(
179
158
  self, span: Span, parent_context: Optional[Context] = None
@@ -214,30 +193,27 @@ class TracerWrapper(object):
214
193
  if self.__spans_processor_original_on_start:
215
194
  self.__spans_processor_original_on_start(span, parent_context)
216
195
 
217
- @staticmethod
218
- def set_static_params(
219
- resource_attributes: dict,
220
- enable_content_tracing: bool,
221
- endpoint: str,
222
- headers: Dict[str, str],
223
- ) -> None:
224
- TracerWrapper.resource_attributes = resource_attributes
225
- TracerWrapper.enable_content_tracing = enable_content_tracing
226
- TracerWrapper.endpoint = endpoint
227
- TracerWrapper.headers = headers
228
-
229
- @classmethod
230
- def verify_initialized(cls) -> bool:
231
- return hasattr(cls, "instance")
232
-
233
- @classmethod
234
- def clear(cls):
196
+ def clear_state(self):
235
197
  # Any state cleanup. Now used in between tests
236
- cls.__span_id_to_path = {}
237
- cls.__span_id_lists = {}
198
+ self.__span_id_to_path = {}
199
+ self.__span_id_lists = {}
200
+
201
+ def shutdown(self):
202
+ global instrumentors
203
+ self.__spans_processor.force_flush(timeout_millis=30000)
204
+ for v in instrumentors.values():
205
+ try:
206
+ v.uninstrument()
207
+ except Exception:
208
+ self.__logger.debug("Error uninstrumenting instrumentor", exc_info=True)
209
+ instrumentors = {}
210
+ self.__spans_processor.shutdown()
211
+
212
+ # Clean up attributes
213
+ self.clear_state()
238
214
 
239
215
  def flush(self):
240
- self.__spans_processor.force_flush()
216
+ return self.__spans_processor.force_flush()
241
217
 
242
218
  def get_tracer(self):
243
219
  return self.__tracer_provider.get_tracer(TRACER_NAME)
@@ -309,11 +285,9 @@ def init_spans_exporter(api_endpoint: str, headers: Dict[str, str]) -> SpanExpor
309
285
  )
310
286
 
311
287
 
312
- # TODO: check if it's safer to use the default tracer provider obtained from
313
- # get_tracer_provider()
314
288
  def init_tracer_provider(resource: Resource) -> TracerProvider:
315
289
  provider: TracerProvider = None
316
- default_provider: TracerProvider = get_tracer_provider()
290
+ default_provider: TracerProvider = trace.get_tracer_provider()
317
291
 
318
292
  if isinstance(default_provider, ProxyTracerProvider):
319
293
  provider = TracerProvider(resource=resource)
@@ -333,8 +307,9 @@ def init_instrumentations(
333
307
  should_enrich_metrics: bool,
334
308
  instruments: Optional[Set[Instruments]] = None,
335
309
  block_instruments: Optional[Set[Instruments]] = None,
336
- client: Optional[LaminarClient] = None,
337
- async_client: Optional[AsyncLaminarClient] = None,
310
+ tracer_provider: Optional[TracerProvider] = None,
311
+ project_api_key: Optional[str] = None,
312
+ base_http_url: Optional[str] = None,
338
313
  ):
339
314
  block_instruments = block_instruments or set()
340
315
  # These libraries are not instrumented by default,
@@ -360,97 +335,109 @@ def init_instrumentations(
360
335
  instrument_set = False
361
336
  for instrument in instruments:
362
337
  if instrument == Instruments.ALEPHALPHA:
363
- if init_alephalpha_instrumentor():
338
+ if init_alephalpha_instrumentor(tracer_provider=tracer_provider):
364
339
  instrument_set = True
365
340
  elif instrument == Instruments.ANTHROPIC:
366
- if init_anthropic_instrumentor(should_enrich_metrics):
341
+ if init_anthropic_instrumentor(
342
+ should_enrich_metrics, tracer_provider=tracer_provider
343
+ ):
367
344
  instrument_set = True
368
345
  elif instrument == Instruments.BEDROCK:
369
- if init_bedrock_instrumentor(should_enrich_metrics):
346
+ if init_bedrock_instrumentor(
347
+ should_enrich_metrics, tracer_provider=tracer_provider
348
+ ):
370
349
  instrument_set = True
371
350
  elif instrument == Instruments.CHROMA:
372
- if init_chroma_instrumentor():
351
+ if init_chroma_instrumentor(tracer_provider=tracer_provider):
373
352
  instrument_set = True
374
353
  elif instrument == Instruments.COHERE:
375
- if init_cohere_instrumentor():
354
+ if init_cohere_instrumentor(tracer_provider=tracer_provider):
376
355
  instrument_set = True
377
356
  elif instrument == Instruments.GOOGLE_GENERATIVEAI:
378
- if init_google_generativeai_instrumentor():
357
+ if init_google_generativeai_instrumentor(tracer_provider=tracer_provider):
379
358
  instrument_set = True
380
359
  elif instrument == Instruments.GROQ:
381
- if init_groq_instrumentor():
360
+ if init_groq_instrumentor(tracer_provider=tracer_provider):
382
361
  instrument_set = True
383
362
  elif instrument == Instruments.HAYSTACK:
384
- if init_haystack_instrumentor():
363
+ if init_haystack_instrumentor(tracer_provider=tracer_provider):
385
364
  instrument_set = True
386
365
  elif instrument == Instruments.LANCEDB:
387
- if init_lancedb_instrumentor():
366
+ if init_lancedb_instrumentor(tracer_provider=tracer_provider):
388
367
  instrument_set = True
389
368
  elif instrument == Instruments.LANGCHAIN:
390
- if init_langchain_instrumentor():
369
+ if init_langchain_instrumentor(tracer_provider=tracer_provider):
391
370
  instrument_set = True
392
371
  elif instrument == Instruments.LLAMA_INDEX:
393
- if init_llama_index_instrumentor():
372
+ if init_llama_index_instrumentor(tracer_provider=tracer_provider):
394
373
  instrument_set = True
395
374
  elif instrument == Instruments.MARQO:
396
- if init_marqo_instrumentor():
375
+ if init_marqo_instrumentor(tracer_provider=tracer_provider):
397
376
  instrument_set = True
398
377
  elif instrument == Instruments.MILVUS:
399
- if init_milvus_instrumentor():
378
+ if init_milvus_instrumentor(tracer_provider=tracer_provider):
400
379
  instrument_set = True
401
380
  elif instrument == Instruments.MISTRAL:
402
- if init_mistralai_instrumentor():
381
+ if init_mistralai_instrumentor(tracer_provider=tracer_provider):
403
382
  instrument_set = True
404
383
  elif instrument == Instruments.OLLAMA:
405
- if init_ollama_instrumentor():
384
+ if init_ollama_instrumentor(tracer_provider=tracer_provider):
406
385
  instrument_set = True
407
386
  elif instrument == Instruments.OPENAI:
408
- if init_openai_instrumentor(should_enrich_metrics):
387
+ if init_openai_instrumentor(
388
+ should_enrich_metrics, tracer_provider=tracer_provider
389
+ ):
409
390
  instrument_set = True
410
391
  elif instrument == Instruments.PINECONE:
411
- if init_pinecone_instrumentor():
392
+ if init_pinecone_instrumentor(tracer_provider=tracer_provider):
412
393
  instrument_set = True
413
394
  elif instrument == Instruments.PYMYSQL:
414
- if init_pymysql_instrumentor():
395
+ if init_pymysql_instrumentor(tracer_provider=tracer_provider):
415
396
  instrument_set = True
416
397
  elif instrument == Instruments.QDRANT:
417
- if init_qdrant_instrumentor():
398
+ if init_qdrant_instrumentor(tracer_provider=tracer_provider):
418
399
  instrument_set = True
419
400
  elif instrument == Instruments.REDIS:
420
- if init_redis_instrumentor():
401
+ if init_redis_instrumentor(tracer_provider=tracer_provider):
421
402
  instrument_set = True
422
403
  elif instrument == Instruments.REPLICATE:
423
- if init_replicate_instrumentor():
404
+ if init_replicate_instrumentor(tracer_provider=tracer_provider):
424
405
  instrument_set = True
425
406
  elif instrument == Instruments.REQUESTS:
426
- if init_requests_instrumentor():
407
+ if init_requests_instrumentor(tracer_provider=tracer_provider):
427
408
  instrument_set = True
428
409
  elif instrument == Instruments.SAGEMAKER:
429
- if init_sagemaker_instrumentor(should_enrich_metrics):
410
+ if init_sagemaker_instrumentor(
411
+ should_enrich_metrics, tracer_provider=tracer_provider
412
+ ):
430
413
  instrument_set = True
431
414
  elif instrument == Instruments.TOGETHER:
432
- if init_together_instrumentor():
415
+ if init_together_instrumentor(tracer_provider=tracer_provider):
433
416
  instrument_set = True
434
417
  elif instrument == Instruments.TRANSFORMERS:
435
- if init_transformers_instrumentor():
418
+ if init_transformers_instrumentor(tracer_provider=tracer_provider):
436
419
  instrument_set = True
437
420
  elif instrument == Instruments.URLLIB3:
438
- if init_urllib3_instrumentor():
421
+ if init_urllib3_instrumentor(tracer_provider=tracer_provider):
439
422
  instrument_set = True
440
423
  elif instrument == Instruments.VERTEXAI:
441
- if init_vertexai_instrumentor():
424
+ if init_vertexai_instrumentor(tracer_provider=tracer_provider):
442
425
  instrument_set = True
443
426
  elif instrument == Instruments.WATSONX:
444
- if init_watsonx_instrumentor():
427
+ if init_watsonx_instrumentor(tracer_provider=tracer_provider):
445
428
  instrument_set = True
446
429
  elif instrument == Instruments.WEAVIATE:
447
- if init_weaviate_instrumentor():
430
+ if init_weaviate_instrumentor(tracer_provider=tracer_provider):
448
431
  instrument_set = True
449
432
  elif instrument == Instruments.PLAYWRIGHT:
450
- if init_playwright_instrumentor(client, async_client):
433
+ if init_playwright_instrumentor(
434
+ tracer_provider=tracer_provider,
435
+ project_api_key=project_api_key,
436
+ base_http_url=base_http_url,
437
+ ):
451
438
  instrument_set = True
452
439
  elif instrument == Instruments.BROWSER_USE:
453
- if init_browser_use_instrumentor():
440
+ if init_browser_use_instrumentor(tracer_provider=tracer_provider):
454
441
  instrument_set = True
455
442
  else:
456
443
  module_logger.warning(
@@ -465,35 +452,38 @@ def init_instrumentations(
465
452
  return instrument_set
466
453
 
467
454
 
468
- def init_browser_use_instrumentor():
455
+ def init_browser_use_instrumentor(**kwargs):
456
+ global instrumentors
469
457
  try:
470
458
  if is_package_installed("browser-use"):
471
459
  from lmnr.sdk.browser.browser_use_otel import BrowserUseInstrumentor
472
460
 
473
461
  instrumentor = BrowserUseInstrumentor()
474
- instrumentor.instrument()
462
+ instrumentor.instrument(**kwargs)
463
+ instrumentors["browser_use"] = instrumentor
475
464
  return True
476
465
  except Exception as e:
477
466
  module_logger.error(f"Error initializing BrowserUse instrumentor: {e}")
478
467
  return False
479
468
 
480
469
 
481
- def init_playwright_instrumentor(
482
- client: LaminarClient, async_client: AsyncLaminarClient
483
- ):
470
+ def init_playwright_instrumentor(**kwargs):
471
+ global instrumentors
484
472
  try:
485
473
  if is_package_installed("playwright"):
486
474
  from lmnr.sdk.browser.playwright_otel import PlaywrightInstrumentor
487
475
 
488
- instrumentor = PlaywrightInstrumentor(client, async_client)
489
- instrumentor.instrument()
476
+ instrumentor = PlaywrightInstrumentor()
477
+ instrumentor.instrument(**kwargs)
478
+ instrumentors["playwright"] = instrumentor
490
479
  return True
491
480
  except Exception as e:
492
481
  module_logger.error(f"Error initializing Playwright instrumentor: {e}")
493
482
  return False
494
483
 
495
484
 
496
- def init_openai_instrumentor(should_enrich_metrics: bool):
485
+ def init_openai_instrumentor(should_enrich_metrics: bool, **kwargs):
486
+ global instrumentors
497
487
  try:
498
488
  if is_package_installed("openai") and is_package_installed(
499
489
  "opentelemetry-instrumentation-openai"
@@ -509,7 +499,8 @@ def init_openai_instrumentor(should_enrich_metrics: bool):
509
499
  upload_base64_image=None,
510
500
  )
511
501
  if not instrumentor.is_instrumented_by_opentelemetry:
512
- instrumentor.instrument()
502
+ instrumentor.instrument(**kwargs)
503
+ instrumentors["openai"] = instrumentor
513
504
  return True
514
505
 
515
506
  except Exception as e:
@@ -517,7 +508,8 @@ def init_openai_instrumentor(should_enrich_metrics: bool):
517
508
  return False
518
509
 
519
510
 
520
- def init_anthropic_instrumentor(should_enrich_metrics: bool):
511
+ def init_anthropic_instrumentor(should_enrich_metrics: bool, **kwargs):
512
+ global instrumentors
521
513
  try:
522
514
  if is_package_installed("anthropic") and is_package_installed(
523
515
  "opentelemetry-instrumentation-anthropic"
@@ -529,14 +521,16 @@ def init_anthropic_instrumentor(should_enrich_metrics: bool):
529
521
  upload_base64_image=None,
530
522
  )
531
523
  if not instrumentor.is_instrumented_by_opentelemetry:
532
- instrumentor.instrument()
524
+ instrumentor.instrument(**kwargs)
525
+ instrumentors["anthropic"] = instrumentor
533
526
  return True
534
527
  except Exception as e:
535
528
  module_logger.error(f"Error initializing Anthropic instrumentor: {e}")
536
529
  return False
537
530
 
538
531
 
539
- def init_cohere_instrumentor():
532
+ def init_cohere_instrumentor(**kwargs):
533
+ global instrumentors
540
534
  try:
541
535
  if is_package_installed("cohere") and is_package_installed(
542
536
  "opentelemetry-instrumentation-cohere"
@@ -545,14 +539,16 @@ def init_cohere_instrumentor():
545
539
 
546
540
  instrumentor = CohereInstrumentor()
547
541
  if not instrumentor.is_instrumented_by_opentelemetry:
548
- instrumentor.instrument()
542
+ instrumentor.instrument(**kwargs)
543
+ instrumentors["cohere"] = instrumentor
549
544
  return True
550
545
  except Exception as e:
551
546
  module_logger.error(f"Error initializing Cohere instrumentor: {e}")
552
547
  return False
553
548
 
554
549
 
555
- def init_pinecone_instrumentor():
550
+ def init_pinecone_instrumentor(**kwargs):
551
+ global instrumentors
556
552
  try:
557
553
  if is_package_installed("pinecone") and is_package_installed(
558
554
  "opentelemetry-instrumentation-pinecone"
@@ -561,14 +557,16 @@ def init_pinecone_instrumentor():
561
557
 
562
558
  instrumentor = PineconeInstrumentor()
563
559
  if not instrumentor.is_instrumented_by_opentelemetry:
564
- instrumentor.instrument()
560
+ instrumentor.instrument(**kwargs)
561
+ instrumentors["pinecone"] = instrumentor
565
562
  return True
566
563
  except Exception as e:
567
564
  module_logger.error(f"Error initializing Pinecone instrumentor: {e}")
568
565
  return False
569
566
 
570
567
 
571
- def init_qdrant_instrumentor():
568
+ def init_qdrant_instrumentor(**kwargs):
569
+ global instrumentors
572
570
  try:
573
571
  if is_package_installed("qdrant_client") and is_package_installed(
574
572
  "opentelemetry-instrumentation-qdrant"
@@ -577,13 +575,16 @@ def init_qdrant_instrumentor():
577
575
 
578
576
  instrumentor = QdrantInstrumentor()
579
577
  if not instrumentor.is_instrumented_by_opentelemetry:
580
- instrumentor.instrument()
578
+ instrumentor.instrument(**kwargs)
579
+ instrumentors["qdrant"] = instrumentor
580
+ return True
581
581
  except Exception as e:
582
582
  module_logger.error(f"Error initializing Qdrant instrumentor: {e}")
583
583
  return False
584
584
 
585
585
 
586
- def init_chroma_instrumentor():
586
+ def init_chroma_instrumentor(**kwargs):
587
+ global instrumentors
587
588
  try:
588
589
  if is_package_installed("chromadb") and is_package_installed(
589
590
  "opentelemetry-instrumentation-chromadb"
@@ -592,14 +593,16 @@ def init_chroma_instrumentor():
592
593
 
593
594
  instrumentor = ChromaInstrumentor()
594
595
  if not instrumentor.is_instrumented_by_opentelemetry:
595
- instrumentor.instrument()
596
+ instrumentor.instrument(**kwargs)
597
+ instrumentors["chroma"] = instrumentor
596
598
  return True
597
599
  except Exception as e:
598
600
  module_logger.error(f"Error initializing Chroma instrumentor: {e}")
599
601
  return False
600
602
 
601
603
 
602
- def init_google_generativeai_instrumentor():
604
+ def init_google_generativeai_instrumentor(**kwargs):
605
+ global instrumentors
603
606
  try:
604
607
  if is_package_installed("google-generativeai") and is_package_installed(
605
608
  "opentelemetry-instrumentation-google-generativeai"
@@ -610,14 +613,16 @@ def init_google_generativeai_instrumentor():
610
613
 
611
614
  instrumentor = GoogleGenerativeAiInstrumentor()
612
615
  if not instrumentor.is_instrumented_by_opentelemetry:
613
- instrumentor.instrument()
616
+ instrumentor.instrument(**kwargs)
617
+ instrumentors["google_generativeai"] = instrumentor
614
618
  return True
615
619
  except Exception as e:
616
620
  module_logger.error(f"Error initializing Gemini instrumentor: {e}")
617
621
  return False
618
622
 
619
623
 
620
- def init_haystack_instrumentor():
624
+ def init_haystack_instrumentor(**kwargs):
625
+ global instrumentors
621
626
  try:
622
627
  if is_package_installed("haystack") and is_package_installed(
623
628
  "opentelemetry-instrumentation-haystack"
@@ -626,14 +631,16 @@ def init_haystack_instrumentor():
626
631
 
627
632
  instrumentor = HaystackInstrumentor()
628
633
  if not instrumentor.is_instrumented_by_opentelemetry:
629
- instrumentor.instrument()
634
+ instrumentor.instrument(**kwargs)
635
+ instrumentors["haystack"] = instrumentor
630
636
  return True
631
637
  except Exception as e:
632
638
  module_logger.error(f"Error initializing Haystack instrumentor: {e}")
633
639
  return False
634
640
 
635
641
 
636
- def init_langchain_instrumentor():
642
+ def init_langchain_instrumentor(**kwargs):
643
+ global instrumentors
637
644
  try:
638
645
  if is_package_installed("langchain") and is_package_installed(
639
646
  "opentelemetry-instrumentation-langchain"
@@ -643,6 +650,7 @@ def init_langchain_instrumentor():
643
650
  instrumentor = LangchainInstrumentor()
644
651
  if not instrumentor.is_instrumented_by_opentelemetry:
645
652
  instrumentor.instrument()
653
+ instrumentors["langchain"] = instrumentor
646
654
  return True
647
655
  except Exception as e:
648
656
  # FIXME: silencing this error temporarily, it appears to not be critical
@@ -651,7 +659,8 @@ def init_langchain_instrumentor():
651
659
  return False
652
660
 
653
661
 
654
- def init_mistralai_instrumentor():
662
+ def init_mistralai_instrumentor(**kwargs):
663
+ global instrumentors
655
664
  try:
656
665
  if is_package_installed("mistralai") and is_package_installed(
657
666
  "opentelemetry-instrumentation-mistralai"
@@ -660,14 +669,16 @@ def init_mistralai_instrumentor():
660
669
 
661
670
  instrumentor = MistralAiInstrumentor()
662
671
  if not instrumentor.is_instrumented_by_opentelemetry:
663
- instrumentor.instrument()
672
+ instrumentor.instrument(**kwargs)
673
+ instrumentors["mistralai"] = instrumentor
664
674
  return True
665
675
  except Exception as e:
666
676
  module_logger.error(f"Error initializing MistralAI instrumentor: {e}")
667
677
  return False
668
678
 
669
679
 
670
- def init_ollama_instrumentor():
680
+ def init_ollama_instrumentor(**kwargs):
681
+ global instrumentors
671
682
  try:
672
683
  if is_package_installed("ollama") and is_package_installed(
673
684
  "opentelemetry-instrumentation-ollama"
@@ -676,14 +687,16 @@ def init_ollama_instrumentor():
676
687
 
677
688
  instrumentor = OllamaInstrumentor()
678
689
  if not instrumentor.is_instrumented_by_opentelemetry:
679
- instrumentor.instrument()
690
+ instrumentor.instrument(**kwargs)
691
+ instrumentors["ollama"] = instrumentor
680
692
  return True
681
693
  except Exception as e:
682
694
  module_logger.error(f"Error initializing Ollama instrumentor: {e}")
683
695
  return False
684
696
 
685
697
 
686
- def init_transformers_instrumentor():
698
+ def init_transformers_instrumentor(**kwargs):
699
+ global instrumentors
687
700
  try:
688
701
  if is_package_installed("transformers") and is_package_installed(
689
702
  "opentelemetry-instrumentation-transformers"
@@ -694,14 +707,16 @@ def init_transformers_instrumentor():
694
707
 
695
708
  instrumentor = TransformersInstrumentor()
696
709
  if not instrumentor.is_instrumented_by_opentelemetry:
697
- instrumentor.instrument()
710
+ instrumentor.instrument(**kwargs)
711
+ instrumentors["transformers"] = instrumentor
698
712
  return True
699
713
  except Exception as e:
700
714
  module_logger.error(f"Error initializing Transformers instrumentor: {e}")
701
715
  return False
702
716
 
703
717
 
704
- def init_together_instrumentor():
718
+ def init_together_instrumentor(**kwargs):
719
+ global instrumentors
705
720
  try:
706
721
  if is_package_installed("together") and is_package_installed(
707
722
  "opentelemetry-instrumentation-together"
@@ -710,14 +725,16 @@ def init_together_instrumentor():
710
725
 
711
726
  instrumentor = TogetherAiInstrumentor()
712
727
  if not instrumentor.is_instrumented_by_opentelemetry:
713
- instrumentor.instrument()
728
+ instrumentor.instrument(**kwargs)
729
+ instrumentors["together"] = instrumentor
714
730
  return True
715
731
  except Exception as e:
716
732
  module_logger.error(f"Error initializing TogetherAI instrumentor: {e}")
717
733
  return False
718
734
 
719
735
 
720
- def init_llama_index_instrumentor():
736
+ def init_llama_index_instrumentor(**kwargs):
737
+ global instrumentors
721
738
  try:
722
739
  if (
723
740
  is_package_installed("llama-index") or is_package_installed("llama_index")
@@ -726,14 +743,16 @@ def init_llama_index_instrumentor():
726
743
 
727
744
  instrumentor = LlamaIndexInstrumentor()
728
745
  if not instrumentor.is_instrumented_by_opentelemetry:
729
- instrumentor.instrument()
746
+ instrumentor.instrument(**kwargs)
747
+ instrumentors["llama_index"] = instrumentor
730
748
  return True
731
749
  except Exception as e:
732
750
  module_logger.error(f"Error initializing LlamaIndex instrumentor: {e}")
733
751
  return False
734
752
 
735
753
 
736
- def init_milvus_instrumentor():
754
+ def init_milvus_instrumentor(**kwargs):
755
+ global instrumentors
737
756
  try:
738
757
  if is_package_installed("pymilvus") and is_package_installed(
739
758
  "opentelemetry-instrumentation-milvus"
@@ -742,56 +761,64 @@ def init_milvus_instrumentor():
742
761
 
743
762
  instrumentor = MilvusInstrumentor()
744
763
  if not instrumentor.is_instrumented_by_opentelemetry:
745
- instrumentor.instrument()
764
+ instrumentor.instrument(**kwargs)
765
+ instrumentors["milvus"] = instrumentor
746
766
  return True
747
767
  except Exception as e:
748
768
  module_logger.error(f"Error initializing Milvus instrumentor: {e}")
749
769
  return False
750
770
 
751
771
 
752
- def init_requests_instrumentor():
772
+ def init_requests_instrumentor(**kwargs):
773
+ global instrumentors
753
774
  try:
754
775
  if is_package_installed("requests"):
755
776
  from opentelemetry.instrumentation.requests import RequestsInstrumentor
756
777
 
757
778
  instrumentor = RequestsInstrumentor()
758
779
  if not instrumentor.is_instrumented_by_opentelemetry:
759
- instrumentor.instrument(excluded_urls=EXCLUDED_URLS)
780
+ instrumentor.instrument(excluded_urls=EXCLUDED_URLS, **kwargs)
781
+ instrumentors["requests"] = instrumentor
760
782
  return True
761
783
  except Exception as e:
762
784
  module_logger.error(f"Error initializing Requests instrumentor: {e}")
763
785
  return False
764
786
 
765
787
 
766
- def init_urllib3_instrumentor():
788
+ def init_urllib3_instrumentor(**kwargs):
789
+ global instrumentors
767
790
  try:
768
791
  if is_package_installed("urllib3"):
769
792
  from opentelemetry.instrumentation.urllib3 import URLLib3Instrumentor
770
793
 
771
794
  instrumentor = URLLib3Instrumentor()
772
795
  if not instrumentor.is_instrumented_by_opentelemetry:
773
- instrumentor.instrument(excluded_urls=EXCLUDED_URLS)
796
+ instrumentor.instrument(excluded_urls=EXCLUDED_URLS, **kwargs)
797
+ instrumentors["urllib3"] = instrumentor
774
798
  return True
775
799
  except Exception as e:
776
800
  module_logger.error(f"Error initializing urllib3 instrumentor: {e}")
777
801
  return False
778
802
 
779
803
 
780
- def init_pymysql_instrumentor():
804
+ def init_pymysql_instrumentor(**kwargs):
805
+ global instrumentors
781
806
  try:
782
807
  if is_package_installed("sqlalchemy"):
783
808
  from opentelemetry.instrumentation.sqlalchemy import SQLAlchemyInstrumentor
784
809
 
785
810
  instrumentor = SQLAlchemyInstrumentor()
786
811
  if not instrumentor.is_instrumented_by_opentelemetry:
787
- instrumentor.instrument()
812
+ instrumentor.instrument(**kwargs)
813
+ instrumentors["sqlalchemy"] = instrumentor
788
814
  return True
789
815
  except Exception as e:
790
816
  module_logger.error(f"Error initializing SQLAlchemy instrumentor: {e}")
791
817
  return False
792
818
 
793
819
 
794
- def init_bedrock_instrumentor(should_enrich_metrics: bool):
820
+ def init_bedrock_instrumentor(should_enrich_metrics: bool, **kwargs):
821
+ global instrumentors
795
822
  try:
796
823
  if is_package_installed("boto3") and is_package_installed(
797
824
  "opentelemetry-instrumentation-bedrock"
@@ -802,14 +829,16 @@ def init_bedrock_instrumentor(should_enrich_metrics: bool):
802
829
  enrich_token_usage=should_enrich_metrics,
803
830
  )
804
831
  if not instrumentor.is_instrumented_by_opentelemetry:
805
- instrumentor.instrument()
832
+ instrumentor.instrument(**kwargs)
833
+ instrumentors["bedrock"] = instrumentor
806
834
  return True
807
835
  except Exception as e:
808
836
  module_logger.error(f"Error initializing Bedrock instrumentor: {e}")
809
837
  return False
810
838
 
811
839
 
812
- def init_replicate_instrumentor():
840
+ def init_replicate_instrumentor(**kwargs):
841
+ global instrumentors
813
842
  try:
814
843
  if is_package_installed("replicate") and is_package_installed(
815
844
  "opentelemetry-instrumentation-replicate"
@@ -818,14 +847,16 @@ def init_replicate_instrumentor():
818
847
 
819
848
  instrumentor = ReplicateInstrumentor()
820
849
  if not instrumentor.is_instrumented_by_opentelemetry:
821
- instrumentor.instrument()
850
+ instrumentor.instrument(**kwargs)
851
+ instrumentors["replicate"] = instrumentor
822
852
  return True
823
853
  except Exception as e:
824
854
  module_logger.error(f"Error initializing Replicate instrumentor: {e}")
825
855
  return False
826
856
 
827
857
 
828
- def init_vertexai_instrumentor():
858
+ def init_vertexai_instrumentor(**kwargs):
859
+ global instrumentors
829
860
  try:
830
861
  if is_package_installed("vertexai") and is_package_installed(
831
862
  "opentelemetry-instrumentation-vertexai"
@@ -834,14 +865,16 @@ def init_vertexai_instrumentor():
834
865
 
835
866
  instrumentor = VertexAIInstrumentor()
836
867
  if not instrumentor.is_instrumented_by_opentelemetry:
837
- instrumentor.instrument()
868
+ instrumentor.instrument(**kwargs)
869
+ instrumentors["vertexai"] = instrumentor
838
870
  return True
839
871
  except Exception as e:
840
872
  module_logger.warning(f"Error initializing Vertex AI instrumentor: {e}")
841
873
  return False
842
874
 
843
875
 
844
- def init_watsonx_instrumentor():
876
+ def init_watsonx_instrumentor(**kwargs):
877
+ global instrumentors
845
878
  try:
846
879
  if (
847
880
  is_package_installed("ibm-watsonx-ai")
@@ -851,14 +884,16 @@ def init_watsonx_instrumentor():
851
884
 
852
885
  instrumentor = WatsonxInstrumentor()
853
886
  if not instrumentor.is_instrumented_by_opentelemetry:
854
- instrumentor.instrument()
887
+ instrumentor.instrument(**kwargs)
888
+ instrumentors["watsonx"] = instrumentor
855
889
  return True
856
890
  except Exception as e:
857
891
  module_logger.warning(f"Error initializing Watsonx instrumentor: {e}")
858
892
  return False
859
893
 
860
894
 
861
- def init_weaviate_instrumentor():
895
+ def init_weaviate_instrumentor(**kwargs):
896
+ global instrumentors
862
897
  try:
863
898
  if is_package_installed("weaviate") and is_package_installed(
864
899
  "opentelemetry-instrumentation-weaviate"
@@ -867,14 +902,16 @@ def init_weaviate_instrumentor():
867
902
 
868
903
  instrumentor = WeaviateInstrumentor()
869
904
  if not instrumentor.is_instrumented_by_opentelemetry:
870
- instrumentor.instrument()
905
+ instrumentor.instrument(**kwargs)
906
+ instrumentors["weaviate"] = instrumentor
871
907
  return True
872
908
  except Exception as e:
873
909
  module_logger.warning(f"Error initializing Weaviate instrumentor: {e}")
874
910
  return False
875
911
 
876
912
 
877
- def init_alephalpha_instrumentor():
913
+ def init_alephalpha_instrumentor(**kwargs):
914
+ global instrumentors
878
915
  try:
879
916
  if is_package_installed("aleph_alpha_client") and is_package_installed(
880
917
  "opentelemetry-instrumentation-alephalpha"
@@ -883,14 +920,16 @@ def init_alephalpha_instrumentor():
883
920
 
884
921
  instrumentor = AlephAlphaInstrumentor()
885
922
  if not instrumentor.is_instrumented_by_opentelemetry:
886
- instrumentor.instrument()
923
+ instrumentor.instrument(**kwargs)
924
+ instrumentors["alephalpha"] = instrumentor
887
925
  return True
888
926
  except Exception as e:
889
927
  module_logger.error(f"Error initializing Aleph Alpha instrumentor: {e}")
890
928
  return False
891
929
 
892
930
 
893
- def init_marqo_instrumentor():
931
+ def init_marqo_instrumentor(**kwargs):
932
+ global instrumentors
894
933
  try:
895
934
  if is_package_installed("marqo") and is_package_installed(
896
935
  "opentelemetry-instrumentation-marqo"
@@ -899,14 +938,16 @@ def init_marqo_instrumentor():
899
938
 
900
939
  instrumentor = MarqoInstrumentor()
901
940
  if not instrumentor.is_instrumented_by_opentelemetry:
902
- instrumentor.instrument()
941
+ instrumentor.instrument(**kwargs)
942
+ instrumentors["marqo"] = instrumentor
903
943
  return True
904
944
  except Exception as e:
905
945
  module_logger.error(f"Error initializing marqo instrumentor: {e}")
906
946
  return False
907
947
 
908
948
 
909
- def init_lancedb_instrumentor():
949
+ def init_lancedb_instrumentor(**kwargs):
950
+ global instrumentors
910
951
  try:
911
952
  if is_package_installed("lancedb") and is_package_installed(
912
953
  "opentelemetry-instrumentation-lancedb"
@@ -915,13 +956,16 @@ def init_lancedb_instrumentor():
915
956
 
916
957
  instrumentor = LanceInstrumentor()
917
958
  if not instrumentor.is_instrumented_by_opentelemetry:
918
- instrumentor.instrument()
959
+ instrumentor.instrument(**kwargs)
960
+ instrumentors["lancedb"] = instrumentor
919
961
  return True
920
962
  except Exception as e:
921
963
  module_logger.error(f"Error initializing LanceDB instrumentor: {e}")
964
+ return False
922
965
 
923
966
 
924
- def init_redis_instrumentor():
967
+ def init_redis_instrumentor(**kwargs):
968
+ global instrumentors
925
969
  try:
926
970
  if is_package_installed("redis") and is_package_installed(
927
971
  "opentelemetry-instrumentation-redis"
@@ -930,14 +974,16 @@ def init_redis_instrumentor():
930
974
 
931
975
  instrumentor = RedisInstrumentor()
932
976
  if not instrumentor.is_instrumented_by_opentelemetry:
933
- instrumentor.instrument(excluded_urls=EXCLUDED_URLS)
977
+ instrumentor.instrument(excluded_urls=EXCLUDED_URLS, **kwargs)
978
+ instrumentors["redis"] = instrumentor
934
979
  return True
935
980
  except Exception as e:
936
981
  module_logger.error(f"Error initializing redis instrumentor: {e}")
937
982
  return False
938
983
 
939
984
 
940
- def init_groq_instrumentor():
985
+ def init_groq_instrumentor(**kwargs):
986
+ global instrumentors
941
987
  try:
942
988
  if is_package_installed("groq") and is_package_installed(
943
989
  "opentelemetry-instrumentation-groq"
@@ -946,14 +992,16 @@ def init_groq_instrumentor():
946
992
 
947
993
  instrumentor = GroqInstrumentor()
948
994
  if not instrumentor.is_instrumented_by_opentelemetry:
949
- instrumentor.instrument()
995
+ instrumentor.instrument(**kwargs)
996
+ instrumentors["groq"] = instrumentor
950
997
  return True
951
998
  except Exception as e:
952
999
  module_logger.error(f"Error initializing Groq instrumentor: {e}")
953
1000
  return False
954
1001
 
955
1002
 
956
- def init_sagemaker_instrumentor(should_enrich_metrics: bool):
1003
+ def init_sagemaker_instrumentor(should_enrich_metrics: bool, **kwargs):
1004
+ global instrumentors
957
1005
  try:
958
1006
  if is_package_installed("boto3") and is_package_installed(
959
1007
  "opentelemetry-instrumentation-sagemaker"
@@ -964,7 +1012,8 @@ def init_sagemaker_instrumentor(should_enrich_metrics: bool):
964
1012
  enrich_token_usage=should_enrich_metrics,
965
1013
  )
966
1014
  if not instrumentor.is_instrumented_by_opentelemetry:
967
- instrumentor.instrument()
1015
+ instrumentor.instrument(**kwargs)
1016
+ instrumentors["sagemaker"] = instrumentor
968
1017
  return True
969
1018
  except Exception as e:
970
1019
  module_logger.error(f"Error initializing SageMaker instrumentor: {e}")