openlit 1.34.23__py3-none-any.whl → 1.34.25__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.
@@ -1,66 +1,174 @@
1
- # pylint: disable=useless-return, bad-staticmethod-argument, disable=duplicate-code
2
1
  """Initializer of Auto Instrumentation of Pinecone Functions"""
2
+
3
3
  from typing import Collection
4
4
  import importlib.metadata
5
5
  from opentelemetry.instrumentation.instrumentor import BaseInstrumentor
6
6
  from wrapt import wrap_function_wrapper
7
7
 
8
8
  from openlit.instrumentation.pinecone.pinecone import general_wrap
9
+ from openlit.instrumentation.pinecone.async_pinecone import async_general_wrap
9
10
 
10
- _instruments = ("pinecone-client >= 2.2.0",)
11
+ _instruments = ("pinecone >= 7.3.0",)
11
12
 
12
13
  class PineconeInstrumentor(BaseInstrumentor):
13
- """An instrumentor for Pinecone's client library."""
14
+ """
15
+ An instrumentor for Pinecone's client library.
16
+ """
14
17
 
15
18
  def instrumentation_dependencies(self) -> Collection[str]:
16
19
  return _instruments
17
20
 
18
21
  def _instrument(self, **kwargs):
19
- application_name = kwargs.get("application_name")
20
- environment = kwargs.get("environment")
22
+ version = importlib.metadata.version("pinecone")
23
+ environment = kwargs.get("environment", "default")
24
+ application_name = kwargs.get("application_name", "default")
21
25
  tracer = kwargs.get("tracer")
26
+ pricing_info = kwargs.get("pricing_info", {})
27
+ capture_message_content = kwargs.get("capture_message_content", False)
22
28
  metrics = kwargs.get("metrics_dict")
23
- pricing_info = kwargs.get("pricing_info")
24
- capture_message_content = kwargs.get("capture_message_content")
25
29
  disable_metrics = kwargs.get("disable_metrics")
26
- version = importlib.metadata.version("pinecone-client")
27
30
 
31
+ # Sync operations
28
32
  wrap_function_wrapper(
29
- "pinecone.control.pinecone",
33
+ "pinecone.pinecone",
30
34
  "Pinecone.create_index",
31
- general_wrap("pinecone.create_index", version, environment, application_name,
32
- tracer, pricing_info, capture_message_content, metrics, disable_metrics),
35
+ general_wrap("pinecone.create_collection", version, environment, application_name,
36
+ tracer, pricing_info, capture_message_content, metrics, disable_metrics),
37
+ )
38
+
39
+ wrap_function_wrapper(
40
+ "pinecone.pinecone",
41
+ "Pinecone.create_index_for_model",
42
+ general_wrap("pinecone.create_collection", version, environment, application_name,
43
+ tracer, pricing_info, capture_message_content, metrics, disable_metrics),
33
44
  )
34
45
 
35
46
  wrap_function_wrapper(
36
- "pinecone.data.index",
47
+ "pinecone.db_data.index",
37
48
  "Index.upsert",
38
49
  general_wrap("pinecone.upsert", version, environment, application_name,
39
- tracer, pricing_info, capture_message_content, metrics, disable_metrics),
50
+ tracer, pricing_info, capture_message_content, metrics, disable_metrics),
51
+ )
52
+
53
+ wrap_function_wrapper(
54
+ "pinecone.db_data.index",
55
+ "Index.upsert_records",
56
+ general_wrap("pinecone.upsert_records", version, environment, application_name,
57
+ tracer, pricing_info, capture_message_content, metrics, disable_metrics),
40
58
  )
41
59
 
42
60
  wrap_function_wrapper(
43
- "pinecone.data.index",
61
+ "pinecone.db_data.index",
44
62
  "Index.query",
45
63
  general_wrap("pinecone.query", version, environment, application_name,
46
- tracer, pricing_info, capture_message_content, metrics, disable_metrics),
64
+ tracer, pricing_info, capture_message_content, metrics, disable_metrics),
65
+ )
66
+
67
+ wrap_function_wrapper(
68
+ "pinecone.db_data.index",
69
+ "Index.search",
70
+ general_wrap("pinecone.search", version, environment, application_name,
71
+ tracer, pricing_info, capture_message_content, metrics, disable_metrics),
47
72
  )
48
73
 
49
74
  wrap_function_wrapper(
50
- "pinecone.data.index",
75
+ "pinecone.db_data.index",
76
+ "Index.fetch",
77
+ general_wrap("pinecone.fetch", version, environment, application_name,
78
+ tracer, pricing_info, capture_message_content, metrics, disable_metrics),
79
+ )
80
+
81
+ wrap_function_wrapper(
82
+ "pinecone.db_data.index",
83
+ "Index.search_records",
84
+ general_wrap("pinecone.search_records", version, environment, application_name,
85
+ tracer, pricing_info, capture_message_content, metrics, disable_metrics),
86
+ )
87
+
88
+ wrap_function_wrapper(
89
+ "pinecone.db_data.index",
51
90
  "Index.update",
52
91
  general_wrap("pinecone.update", version, environment, application_name,
53
- tracer, pricing_info, capture_message_content, metrics, disable_metrics),
92
+ tracer, pricing_info, capture_message_content, metrics, disable_metrics),
54
93
  )
55
94
 
56
95
  wrap_function_wrapper(
57
- "pinecone.data.index",
96
+ "pinecone.db_data.index",
58
97
  "Index.delete",
59
98
  general_wrap("pinecone.delete", version, environment, application_name,
60
- tracer, pricing_info, capture_message_content, metrics, disable_metrics),
99
+ tracer, pricing_info, capture_message_content, metrics, disable_metrics),
61
100
  )
62
101
 
102
+ # Async operations
103
+ wrap_function_wrapper(
104
+ "pinecone.pinecone_asyncio",
105
+ "PineconeAsyncio.create_index",
106
+ async_general_wrap("pinecone.create_index", version, environment, application_name,
107
+ tracer, pricing_info, capture_message_content, metrics, disable_metrics),
108
+ )
109
+
110
+ wrap_function_wrapper(
111
+ "pinecone.pinecone_asyncio",
112
+ "PineconeAsyncio.create_index_for_model",
113
+ async_general_wrap("pinecone.create_index", version, environment, application_name,
114
+ tracer, pricing_info, capture_message_content, metrics, disable_metrics),
115
+ )
116
+
117
+ wrap_function_wrapper(
118
+ "pinecone.db_data.index_asyncio",
119
+ "_IndexAsyncio.upsert",
120
+ async_general_wrap("pinecone.upsert", version, environment, application_name,
121
+ tracer, pricing_info, capture_message_content, metrics, disable_metrics),
122
+ )
123
+
124
+ wrap_function_wrapper(
125
+ "pinecone.db_data.index_asyncio",
126
+ "_IndexAsyncio.upsert_records",
127
+ async_general_wrap("pinecone.upsert_records", version, environment, application_name,
128
+ tracer, pricing_info, capture_message_content, metrics, disable_metrics),
129
+ )
130
+
131
+ wrap_function_wrapper(
132
+ "pinecone.db_data.index_asyncio",
133
+ "_IndexAsyncio.query",
134
+ async_general_wrap("pinecone.query", version, environment, application_name,
135
+ tracer, pricing_info, capture_message_content, metrics, disable_metrics),
136
+ )
137
+
138
+ wrap_function_wrapper(
139
+ "pinecone.db_data.index_asyncio",
140
+ "_IndexAsyncio.search",
141
+ async_general_wrap("pinecone.search", version, environment, application_name,
142
+ tracer, pricing_info, capture_message_content, metrics, disable_metrics),
143
+ )
144
+
145
+ wrap_function_wrapper(
146
+ "pinecone.db_data.index_asyncio",
147
+ "_IndexAsyncio.fetch",
148
+ async_general_wrap("pinecone.fetch", version, environment, application_name,
149
+ tracer, pricing_info, capture_message_content, metrics, disable_metrics),
150
+ )
151
+
152
+ wrap_function_wrapper(
153
+ "pinecone.db_data.index_asyncio",
154
+ "_IndexAsyncio.search_records",
155
+ async_general_wrap("pinecone.search_records", version, environment, application_name,
156
+ tracer, pricing_info, capture_message_content, metrics, disable_metrics),
157
+ )
158
+
159
+ wrap_function_wrapper(
160
+ "pinecone.db_data.index_asyncio",
161
+ "_IndexAsyncio.update",
162
+ async_general_wrap("pinecone.update", version, environment, application_name,
163
+ tracer, pricing_info, capture_message_content, metrics, disable_metrics),
164
+ )
165
+
166
+ wrap_function_wrapper(
167
+ "pinecone.db_data.index_asyncio",
168
+ "_IndexAsyncio.delete",
169
+ async_general_wrap("pinecone.delete", version, environment, application_name,
170
+ tracer, pricing_info, capture_message_content, metrics, disable_metrics),
171
+ )
63
172
 
64
- @staticmethod
65
173
  def _uninstrument(self, **kwargs):
66
174
  pass
@@ -0,0 +1,58 @@
1
+ """
2
+ Module for monitoring Pinecone async API calls.
3
+ """
4
+
5
+ import time
6
+ from opentelemetry.trace import SpanKind
7
+ from opentelemetry import context as context_api
8
+ from openlit.__helpers import (
9
+ handle_exception,
10
+ set_server_address_and_port,
11
+ )
12
+ from openlit.instrumentation.pinecone.utils import (
13
+ process_vectordb_response,
14
+ DB_OPERATION_MAP,
15
+ )
16
+
17
+ def async_general_wrap(gen_ai_endpoint, version, environment, application_name,
18
+ tracer, pricing_info, capture_message_content, metrics, disable_metrics):
19
+ """
20
+ Generates a telemetry wrapper for Pinecone async function calls.
21
+ """
22
+
23
+ async def wrapper(wrapped, instance, args, kwargs):
24
+ """
25
+ Wraps the Pinecone async function call.
26
+ """
27
+
28
+ if context_api.get_value(context_api._SUPPRESS_INSTRUMENTATION_KEY):
29
+ return await wrapped(*args, **kwargs)
30
+
31
+ # Get server address and port using the standard helper
32
+ server_address, server_port = set_server_address_and_port(instance, "pinecone.io", 443)
33
+
34
+ db_operation = DB_OPERATION_MAP.get(gen_ai_endpoint, "unknown")
35
+ if db_operation == "create_collection":
36
+ namespace = kwargs.get("name") or (args[0] if args else "unknown")
37
+ else:
38
+ namespace = kwargs.get("namespace") or (args[0] if args else "unknown")
39
+ span_name = f"{db_operation} {namespace}"
40
+
41
+ with tracer.start_as_current_span(span_name, kind=SpanKind.CLIENT) as span:
42
+ try:
43
+ start_time = time.time()
44
+ response = await wrapped(*args, **kwargs)
45
+
46
+ # Process response and generate telemetry
47
+ response = process_vectordb_response(
48
+ response, db_operation, server_address, server_port,
49
+ environment, application_name, metrics, start_time, span,
50
+ capture_message_content, disable_metrics, version, instance, args, **kwargs
51
+ )
52
+
53
+ except Exception as e:
54
+ handle_exception(span, e)
55
+
56
+ return response
57
+
58
+ return wrapper
@@ -1,173 +1,58 @@
1
- # pylint: disable=duplicate-code, broad-exception-caught, too-many-statements, unused-argument, possibly-used-before-assignment
2
1
  """
3
- Module for monitoring Pinecone.
2
+ Module for monitoring Pinecone API calls.
4
3
  """
5
4
 
6
- import logging
7
- from opentelemetry.trace import SpanKind, Status, StatusCode
8
- from opentelemetry.sdk.resources import SERVICE_NAME, TELEMETRY_SDK_NAME, DEPLOYMENT_ENVIRONMENT
9
- from openlit.__helpers import handle_exception
10
- from openlit.semcov import SemanticConvention
11
-
12
- # Initialize logger for logging potential issues and operations
13
- logger = logging.getLogger(__name__)
14
-
15
- def object_count(obj):
16
- """
17
- Counts Length of object if it exists, Else returns None
18
- """
19
-
20
- if obj:
21
- return len(obj)
22
-
23
- return None
5
+ import time
6
+ from opentelemetry.trace import SpanKind
7
+ from opentelemetry import context as context_api
8
+ from openlit.__helpers import (
9
+ handle_exception,
10
+ set_server_address_and_port,
11
+ )
12
+ from openlit.instrumentation.pinecone.utils import (
13
+ process_vectordb_response,
14
+ DB_OPERATION_MAP,
15
+ )
24
16
 
25
17
  def general_wrap(gen_ai_endpoint, version, environment, application_name,
26
- tracer, pricing_info, capture_message_content, metrics, disable_metrics):
18
+ tracer, pricing_info, capture_message_content, metrics, disable_metrics):
27
19
  """
28
- Wraps a Pinecone operation to trace and log its execution metrics.
29
-
30
- This function is intended to wrap around Pinecone operations in order to
31
- measure their execution time, log relevant information, and trace the execution
32
- using OpenTelemetry. This helps in monitoring and debugging operations within
33
- the Pinecone space.
34
-
35
- Parameters:
36
- - pinecone_operation (str): The specific Pinecone operation being monitored.
37
- Examples include 'create_index', 'query', 'upsert', etc.
38
- - version (str): The version of the application interfacing with Pinecone.
39
- - environment (str): The deployment environment, such as 'production' or 'development'.
40
- - application_name (str): The name of the application performing the Pinecone operation.
41
- - tracer (opentelemetry.trace.Tracer): An object used for OpenTelemetry tracing.
42
- - pricing_info (dict): Information about pricing, not used in current implementation.
43
- - capture_message_content (bool): A flag indicating whether the content of responses should be traced.
44
-
45
- Returns:
46
- - function: A decorator function that, when applied, wraps the target function with
47
- additional functionality for tracing and logging Pinecone operations.
20
+ Generates a telemetry wrapper for Pinecone function calls.
48
21
  """
49
22
 
50
23
  def wrapper(wrapped, instance, args, kwargs):
51
24
  """
52
- Executes the wrapped Pinecone operation, adding tracing and logging.
53
-
54
- This inner wrapper function captures the execution of Pinecone operations,
55
- annotating the operation with relevant metrics and tracing information, and
56
- ensuring any exceptions are caught and logged appropriately.
57
-
58
- Parameters:
59
- - wrapped (Callable): The Pinecone operation to be wrapped and executed.
60
- - instance (object): The instance on which the operation is called (for class methods).
61
- - args (tuple): Positional arguments for the Pinecone operation.
62
- - kwargs (dict): Keyword arguments for the Pinecone operation.
63
-
64
- Returns:
65
- - Any: The result of executing the wrapped Pinecone operation.
25
+ Wraps the Pinecone function call.
66
26
  """
67
27
 
68
- with tracer.start_as_current_span(gen_ai_endpoint, kind= SpanKind.CLIENT) as span:
69
- response = wrapped(*args, **kwargs)
70
-
71
- try:
72
- span.set_attribute(TELEMETRY_SDK_NAME, "openlit")
73
- span.set_attribute(SemanticConvention.GEN_AI_ENDPOINT,
74
- gen_ai_endpoint)
75
- span.set_attribute(DEPLOYMENT_ENVIRONMENT,
76
- environment)
77
- span.set_attribute(SERVICE_NAME,
78
- application_name)
79
- span.set_attribute(SemanticConvention.GEN_AI_OPERATION,
80
- SemanticConvention.GEN_AI_OPERATION_TYPE_VECTORDB)
81
- span.set_attribute(SemanticConvention.DB_SYSTEM_NAME,
82
- SemanticConvention.DB_SYSTEM_PINECONE)
83
-
84
- if gen_ai_endpoint == "pinecone.create_index":
85
- db_operation = SemanticConvention.DB_OPERATION_CREATE_INDEX
86
- span.set_attribute(SemanticConvention.DB_OPERATION_NAME,
87
- SemanticConvention.DB_OPERATION_CREATE_INDEX)
88
- span.set_attribute(SemanticConvention.DB_INDEX_NAME,
89
- kwargs.get("name", ""))
90
- span.set_attribute(SemanticConvention.DB_INDEX_DIMENSION,
91
- kwargs.get("dimensions", ""))
92
- span.set_attribute(SemanticConvention.DB_INDEX_METRIC,
93
- kwargs.get("metric", ""))
94
- span.set_attribute(SemanticConvention.DB_INDEX_SPEC,
95
- str(kwargs.get("spec", "")))
28
+ if context_api.get_value(context_api._SUPPRESS_INSTRUMENTATION_KEY):
29
+ return wrapped(*args, **kwargs)
96
30
 
97
- elif gen_ai_endpoint == "pinecone.query":
98
- db_operation = SemanticConvention.DB_OPERATION_QUERY
99
- span.set_attribute(SemanticConvention.DB_OPERATION_NAME,
100
- SemanticConvention.DB_OPERATION_QUERY)
101
- span.set_attribute(SemanticConvention.DB_STATEMENT,
102
- str(kwargs.get("vector")))
103
- span.set_attribute(SemanticConvention.DB_N_RESULTS,
104
- kwargs.get("top_k", ""))
105
- span.set_attribute(SemanticConvention.DB_FILTER,
106
- str(kwargs.get("filter", "")))
107
- span.set_attribute(SemanticConvention.DB_NAMESPACE,
108
- str(kwargs.get("namespace", "")))
31
+ # Get server address and port using the standard helper
32
+ server_address, server_port = set_server_address_and_port(instance, "pinecone.io", 443)
109
33
 
110
- elif gen_ai_endpoint == "pinecone.update":
111
- db_operation = SemanticConvention.DB_OPERATION_UPDATE
112
- span.set_attribute(SemanticConvention.DB_OPERATION_NAME,
113
- SemanticConvention.DB_OPERATION_UPDATE)
114
- span.set_attribute(SemanticConvention.DB_UPDATE_ID,
115
- kwargs.get("id",""))
116
- span.set_attribute(SemanticConvention.DB_UPDATE_VALUES,
117
- str(kwargs.get("values",[])))
118
- span.set_attribute(SemanticConvention.DB_NAMESPACE,
119
- str(kwargs.get("namespace", "")))
120
- span.set_attribute(SemanticConvention.DB_UPDATE_METADATA,
121
- str(kwargs.get("set_metadata", "")))
34
+ db_operation = DB_OPERATION_MAP.get(gen_ai_endpoint, "unknown")
35
+ if db_operation == "create_collection":
36
+ namespace = kwargs.get("name") or (args[0] if args else "unknown")
37
+ else:
38
+ namespace = kwargs.get("namespace") or (args[0] if args else "unknown")
39
+ span_name = f"{db_operation} {namespace}"
122
40
 
123
- elif gen_ai_endpoint == "pinecone.upsert":
124
- db_operation = SemanticConvention.DB_OPERATION_UPSERT
125
- span.set_attribute(SemanticConvention.DB_OPERATION_NAME,
126
- SemanticConvention.DB_OPERATION_UPSERT)
127
- span.set_attribute(SemanticConvention.DB_VECTOR_COUNT,
128
- object_count(kwargs.get("vectors")))
129
-
130
- elif gen_ai_endpoint == "pinecone.delete":
131
- db_operation = SemanticConvention.DB_OPERATION_DELETE
132
- span.set_attribute(SemanticConvention.DB_OPERATION_NAME,
133
- SemanticConvention.DB_OPERATION_DELETE)
134
- span.set_attribute(SemanticConvention.DB_ID_COUNT,
135
- object_count(kwargs.get("ids")))
136
- span.set_attribute(SemanticConvention.DB_FILTER,
137
- str(kwargs.get("filter", "")))
138
- span.set_attribute(SemanticConvention.DB_DELETE_ALL,
139
- kwargs.get("delete_all", False))
140
- span.set_attribute(SemanticConvention.DB_NAMESPACE,
141
- kwargs.get("namespace", ""))
142
-
143
- span.set_status(Status(StatusCode.OK))
144
-
145
- if disable_metrics is False:
146
- attributes = {
147
- TELEMETRY_SDK_NAME:
148
- "openlit",
149
- SERVICE_NAME:
150
- application_name,
151
- SemanticConvention.DB_SYSTEM_NAME:
152
- SemanticConvention.DB_SYSTEM_PINECONE,
153
- DEPLOYMENT_ENVIRONMENT:
154
- environment,
155
- SemanticConvention.GEN_AI_OPERATION:
156
- SemanticConvention.GEN_AI_OPERATION_TYPE_VECTORDB,
157
- SemanticConvention.DB_OPERATION_NAME:
158
- db_operation
159
- }
160
-
161
- metrics["db_requests"].add(1, attributes)
41
+ with tracer.start_as_current_span(span_name, kind=SpanKind.CLIENT) as span:
42
+ try:
43
+ start_time = time.time()
44
+ response = wrapped(*args, **kwargs)
162
45
 
163
- # Return original response
164
- return response
46
+ # Process response and generate telemetry
47
+ response = process_vectordb_response(
48
+ response, db_operation, server_address, server_port,
49
+ environment, application_name, metrics, start_time, span,
50
+ capture_message_content, disable_metrics, version, instance, args, **kwargs
51
+ )
165
52
 
166
53
  except Exception as e:
167
54
  handle_exception(span, e)
168
- logger.error("Error in trace creation: %s", e)
169
55
 
170
- # Return original response
171
- return response
56
+ return response
172
57
 
173
58
  return wrapper
@@ -0,0 +1,186 @@
1
+ """
2
+ Pinecone OpenTelemetry instrumentation utility functions
3
+ """
4
+ import time
5
+
6
+ from opentelemetry.trace import Status, StatusCode
7
+
8
+ from openlit.__helpers import (
9
+ common_db_span_attributes,
10
+ record_db_metrics,
11
+ )
12
+ from openlit.semcov import SemanticConvention
13
+
14
+ # Operation mapping for simple span naming
15
+ DB_OPERATION_MAP = {
16
+ "pinecone.create_collection": SemanticConvention.DB_OPERATION_CREATE_COLLECTION,
17
+ "pinecone.upsert": SemanticConvention.DB_OPERATION_UPSERT,
18
+ "pinecone.query": SemanticConvention.DB_OPERATION_QUERY,
19
+ "pinecone.search": SemanticConvention.DB_OPERATION_SEARCH,
20
+ "pinecone.fetch": SemanticConvention.DB_OPERATION_FETCH,
21
+ "pinecone.update": SemanticConvention.DB_OPERATION_UPDATE,
22
+ "pinecone.delete": SemanticConvention.DB_OPERATION_DELETE,
23
+ "pinecone.upsert_records": SemanticConvention.DB_OPERATION_UPSERT,
24
+ "pinecone.search_records": SemanticConvention.DB_OPERATION_QUERY,
25
+ }
26
+
27
+ def object_count(obj):
28
+ """
29
+ Counts length of object if it exists, else returns 0.
30
+ """
31
+ return len(obj) if obj else 0
32
+
33
+ def common_vectordb_logic(scope, environment, application_name,
34
+ metrics, capture_message_content, disable_metrics, version, instance=None):
35
+ """
36
+ Process vector database request and generate telemetry.
37
+ """
38
+
39
+ scope._end_time = time.time()
40
+
41
+ # Set common database span attributes using helper
42
+ common_db_span_attributes(scope, SemanticConvention.DB_SYSTEM_PINECONE, scope._server_address, scope._server_port,
43
+ environment, application_name, version)
44
+
45
+ # Set DB operation specific attributes
46
+ scope._span.set_attribute(SemanticConvention.DB_OPERATION_NAME, scope._db_operation)
47
+ scope._span.set_attribute(SemanticConvention.DB_CLIENT_OPERATION_DURATION, scope._end_time - scope._start_time)
48
+
49
+ # Set Create Index operation specific attributes
50
+ if scope._db_operation == SemanticConvention.DB_OPERATION_CREATE_COLLECTION:
51
+ # Standard database attributes
52
+ scope._span.set_attribute(SemanticConvention.DB_COLLECTION_NAME, scope._kwargs.get("name", ""))
53
+
54
+ # Vector database specific attributes (extensions)
55
+ scope._span.set_attribute(SemanticConvention.DB_COLLECTION_DIMENSION, scope._kwargs.get("dimension", -1))
56
+ scope._span.set_attribute(SemanticConvention.DB_SEARCH_SIMILARITY_METRIC, scope._kwargs.get("metric", "cosine"))
57
+ scope._span.set_attribute(SemanticConvention.DB_COLLECTION_SPEC, str(scope._kwargs.get("spec", "")))
58
+
59
+ elif scope._db_operation == SemanticConvention.DB_OPERATION_SEARCH:
60
+ namespace = scope._kwargs.get("namespace", "default") or (scope._args[0] if scope._args else "unknown")
61
+ query = scope._kwargs.get("query", {})
62
+
63
+ # Extract query text or vector from different possible locations
64
+ query_text = query.get("inputs", {}).get("text", "")
65
+ query_vector = query.get("vector", {})
66
+ query_content = query_text or str(query_vector)
67
+
68
+ # Standard database attributes
69
+ scope._span.set_attribute(SemanticConvention.DB_QUERY_TEXT, query_content)
70
+ scope._span.set_attribute(SemanticConvention.DB_NAMESPACE, namespace)
71
+
72
+ # Vector database specific attributes (extensions)
73
+ scope._span.set_attribute(SemanticConvention.DB_VECTOR_QUERY_TOP_K, query.get("top_k", -1))
74
+ scope._span.set_attribute(SemanticConvention.DB_QUERY_SUMMARY,
75
+ f"{scope._db_operation} {namespace} "
76
+ f"top_k={query.get('top_k', -1)} "
77
+ f"text={query_text} "
78
+ f"vector={query_vector}")
79
+
80
+ elif scope._db_operation == SemanticConvention.DB_OPERATION_QUERY:
81
+ namespace = scope._kwargs.get("namespace", "default") or (scope._args[0] if scope._args else "unknown")
82
+ query = scope._kwargs.get("vector", [])
83
+
84
+ # Standard database attributes
85
+ scope._span.set_attribute(SemanticConvention.DB_QUERY_TEXT, str(query))
86
+ scope._span.set_attribute(SemanticConvention.DB_NAMESPACE, namespace)
87
+
88
+ # Vector database specific attributes (extensions)
89
+ scope._span.set_attribute(SemanticConvention.DB_VECTOR_QUERY_TOP_K, scope._kwargs.get("top_k", ""))
90
+ scope._span.set_attribute(SemanticConvention.DB_FILTER, str(scope._kwargs.get("filter", "")))
91
+ scope._span.set_attribute(SemanticConvention.DB_QUERY_SUMMARY,
92
+ f"{scope._db_operation} {namespace} "
93
+ f"top_k={scope._kwargs.get('top_k', -1)} "
94
+ f"filtered={scope._kwargs.get('filter', '')} "
95
+ f"vector={scope._kwargs.get('vector', '')}")
96
+
97
+ elif scope._db_operation == SemanticConvention.DB_OPERATION_FETCH:
98
+ namespace = scope._kwargs.get("namespace", "default") or (scope._args[0] if scope._args else "unknown")
99
+ query = scope._kwargs.get("ids", [])
100
+
101
+ # Standard database attributes
102
+ scope._span.set_attribute(SemanticConvention.DB_QUERY_TEXT, str(query))
103
+ scope._span.set_attribute(SemanticConvention.DB_NAMESPACE, namespace)
104
+
105
+ # Vector database specific attributes (extensions)
106
+ scope._span.set_attribute(SemanticConvention.DB_QUERY_SUMMARY,
107
+ f"{scope._db_operation} {namespace} "
108
+ f"ids={query}")
109
+ scope._span.set_attribute(SemanticConvention.DB_RESPONSE_RETURNED_ROWS, object_count(scope._response.vectors))
110
+
111
+ elif scope._db_operation == SemanticConvention.DB_OPERATION_UPDATE:
112
+ namespace = scope._kwargs.get("namespace") or (scope._args[0] if scope._args else "unknown")
113
+ query = scope._kwargs.get("id", "")
114
+
115
+ # Standard database attributes
116
+ scope._span.set_attribute(SemanticConvention.DB_QUERY_TEXT, query)
117
+ scope._span.set_attribute(SemanticConvention.DB_NAMESPACE, namespace)
118
+
119
+ # Vector database specific attributes (extensions)
120
+ scope._span.set_attribute(SemanticConvention.DB_QUERY_SUMMARY,
121
+ f"{scope._db_operation} {namespace} "
122
+ f"id={query} "
123
+ f"values={scope._kwargs.get('values', [])} "
124
+ f"set_metadata={scope._kwargs.get('set_metadata', '')}")
125
+
126
+ elif scope._db_operation == SemanticConvention.DB_OPERATION_UPSERT:
127
+ namespace = scope._kwargs.get("namespace") or (scope._args[0] if scope._args else "unknown")
128
+ query = scope._kwargs.get("vectors") or (scope._args[1] if len(scope._args) > 1 else None)
129
+
130
+ # Standard database attributes
131
+ scope._span.set_attribute(SemanticConvention.DB_QUERY_TEXT, str(query))
132
+ scope._span.set_attribute(SemanticConvention.DB_NAMESPACE, namespace)
133
+
134
+ # Vector database specific attributes (extensions)
135
+ scope._span.set_attribute(SemanticConvention.DB_VECTOR_COUNT, object_count(query))
136
+ scope._span.set_attribute(SemanticConvention.DB_QUERY_SUMMARY,
137
+ f"{scope._db_operation} {namespace} vectors_count={object_count(query)}")
138
+
139
+ elif scope._db_operation == SemanticConvention.DB_OPERATION_DELETE:
140
+ namespace = scope._kwargs.get("namespace") or (scope._args[0] if scope._args else "unknown")
141
+ query = scope._kwargs.get("ids") or (scope._args[1] if len(scope._args) > 1 else None)
142
+
143
+ # Standard database attributes
144
+ scope._span.set_attribute(SemanticConvention.DB_QUERY_TEXT, str(query))
145
+ scope._span.set_attribute(SemanticConvention.DB_NAMESPACE, namespace)
146
+
147
+ # Vector database specific attributes (extensions)
148
+ scope._span.set_attribute(SemanticConvention.DB_ID_COUNT, object_count(scope._kwargs.get("ids")))
149
+ scope._span.set_attribute(SemanticConvention.DB_FILTER, str(scope._kwargs.get("filter", "")))
150
+ scope._span.set_attribute(SemanticConvention.DB_DELETE_ALL, scope._kwargs.get("delete_all", False))
151
+ scope._span.set_attribute(SemanticConvention.DB_QUERY_SUMMARY,
152
+ f"{scope._db_operation} {namespace} "
153
+ f"ids={query} "
154
+ f"filter={scope._kwargs.get('filter', '')} "
155
+ f"delete_all={scope._kwargs.get('delete_all', False)}")
156
+
157
+ scope._span.set_status(Status(StatusCode.OK))
158
+
159
+ # Record metrics using helper
160
+ if not disable_metrics:
161
+ record_db_metrics(metrics, SemanticConvention.DB_SYSTEM_PINECONE, scope._server_address, scope._server_port,
162
+ environment, application_name, scope._start_time, scope._end_time)
163
+
164
+ def process_vectordb_response(response, db_operation, server_address, server_port,
165
+ environment, application_name, metrics, start_time, span,
166
+ capture_message_content=False, disable_metrics=False,
167
+ version="1.0.0", instance=None, args=None, **kwargs):
168
+ """
169
+ Process vector database response and generate telemetry following OpenTelemetry conventions.
170
+ """
171
+
172
+ scope = type("GenericScope", (), {})()
173
+
174
+ scope._start_time = start_time
175
+ scope._span = span
176
+ scope._kwargs = kwargs
177
+ scope._args = args or []
178
+ scope._db_operation = db_operation
179
+ scope._response = response
180
+ scope._server_address = server_address
181
+ scope._server_port = server_port
182
+
183
+ common_vectordb_logic(scope, environment, application_name,
184
+ metrics, capture_message_content, disable_metrics, version, instance)
185
+
186
+ return response