monocle-apptrace 0.3.1__tar.gz → 0.4.0b1__tar.gz
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.
Potentially problematic release.
This version of monocle-apptrace might be problematic. Click here for more details.
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/.gitignore +2 -1
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/CHANGELOG.md +14 -1
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/PKG-INFO +1 -1
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/pyproject.toml +1 -1
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/src/monocle_apptrace/exporters/aws/s3_exporter.py +3 -1
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/src/monocle_apptrace/exporters/azure/blob_exporter.py +2 -2
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/src/monocle_apptrace/exporters/base_exporter.py +10 -4
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/src/monocle_apptrace/exporters/file_exporter.py +19 -4
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/src/monocle_apptrace/exporters/monocle_exporters.py +3 -3
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/src/monocle_apptrace/exporters/okahu/okahu_exporter.py +5 -2
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/src/monocle_apptrace/instrumentation/common/constants.py +5 -1
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/src/monocle_apptrace/instrumentation/common/instrumentor.py +24 -13
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/src/monocle_apptrace/instrumentation/common/span_handler.py +33 -18
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/src/monocle_apptrace/instrumentation/common/utils.py +62 -54
- monocle_apptrace-0.4.0b1/src/monocle_apptrace/instrumentation/common/wrapper.py +231 -0
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/src/monocle_apptrace/instrumentation/common/wrapper_method.py +10 -5
- monocle_apptrace-0.4.0b1/src/monocle_apptrace/instrumentation/metamodel/aiohttp/_helper.py +66 -0
- monocle_apptrace-0.4.0b1/src/monocle_apptrace/instrumentation/metamodel/aiohttp/entities/http.py +51 -0
- monocle_apptrace-0.4.0b1/src/monocle_apptrace/instrumentation/metamodel/aiohttp/methods.py +13 -0
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/src/monocle_apptrace/instrumentation/metamodel/flask/_helper.py +7 -2
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/src/monocle_apptrace/instrumentation/metamodel/flask/entities/http.py +0 -1
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/src/monocle_apptrace/instrumentation/metamodel/haystack/_helper.py +17 -4
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/src/monocle_apptrace/instrumentation/metamodel/haystack/methods.py +8 -1
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/src/monocle_apptrace/instrumentation/metamodel/llamaindex/_helper.py +13 -9
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/src/monocle_apptrace/instrumentation/metamodel/llamaindex/methods.py +14 -0
- monocle_apptrace-0.4.0b1/src/monocle_apptrace/instrumentation/metamodel/openai/entities/inference.py +219 -0
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/src/monocle_apptrace/instrumentation/metamodel/requests/_helper.py +1 -1
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/src/monocle_apptrace/instrumentation/metamodel/teamsai/_helper.py +19 -1
- monocle_apptrace-0.4.0b1/src/monocle_apptrace/instrumentation/metamodel/teamsai/entities/inference/__init__.py +0 -0
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/src/monocle_apptrace/instrumentation/metamodel/teamsai/entities/inference/actionplanner_output_processor.py +1 -1
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/src/monocle_apptrace/instrumentation/metamodel/teamsai/entities/inference/teamsai_output_processor.py +24 -18
- monocle_apptrace-0.4.0b1/src/monocle_apptrace/instrumentation/metamodel/teamsai/methods.py +60 -0
- monocle_apptrace-0.3.1/src/monocle_apptrace/instrumentation/common/wrapper.py +0 -94
- monocle_apptrace-0.3.1/src/monocle_apptrace/instrumentation/metamodel/openai/entities/inference.py +0 -71
- monocle_apptrace-0.3.1/src/monocle_apptrace/instrumentation/metamodel/teamsai/methods.py +0 -26
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/CODEOWNERS.md +0 -0
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/CODE_OF_CONDUCT.md +0 -0
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/CONTRIBUTING.md +0 -0
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/COPYRIGHT.template +0 -0
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/LICENSE +0 -0
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/MAINTAINER.md +0 -0
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/Monocle_User_Guide.md +0 -0
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/Monocle_committer_guide.md +0 -0
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/Monocle_contributor_guide.md +0 -0
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/NOTICE +0 -0
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/README.md +0 -0
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/SECURITY.md +0 -0
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/src/monocle_apptrace/README.md +0 -0
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/src/monocle_apptrace/__init__.py +0 -0
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/src/monocle_apptrace/__main__.py +0 -0
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/src/monocle_apptrace/exporters/aws/s3_exporter_opendal.py +0 -0
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/src/monocle_apptrace/exporters/azure/blob_exporter_opendal.py +0 -0
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/src/monocle_apptrace/exporters/exporter_processor.py +0 -0
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/src/monocle_apptrace/instrumentation/__init__.py +0 -0
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/src/monocle_apptrace/instrumentation/common/__init__.py +0 -0
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/src/monocle_apptrace/instrumentation/common/tracing.md +0 -0
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/src/monocle_apptrace/instrumentation/metamodel/__init__.py +0 -0
- {monocle_apptrace-0.3.1/src/monocle_apptrace/instrumentation/metamodel/anthropic → monocle_apptrace-0.4.0b1/src/monocle_apptrace/instrumentation/metamodel/aiohttp}/__init__.py +0 -0
- {monocle_apptrace-0.3.1/src/monocle_apptrace/instrumentation/metamodel/anthropic/entities → monocle_apptrace-0.4.0b1/src/monocle_apptrace/instrumentation/metamodel/anthropic}/__init__.py +0 -0
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/src/monocle_apptrace/instrumentation/metamodel/anthropic/_helper.py +0 -0
- {monocle_apptrace-0.3.1/src/monocle_apptrace/instrumentation/metamodel/botocore → monocle_apptrace-0.4.0b1/src/monocle_apptrace/instrumentation/metamodel/anthropic/entities}/__init__.py +0 -0
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/src/monocle_apptrace/instrumentation/metamodel/anthropic/entities/inference.py +0 -0
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/src/monocle_apptrace/instrumentation/metamodel/anthropic/methods.py +0 -0
- {monocle_apptrace-0.3.1/src/monocle_apptrace/instrumentation/metamodel/botocore/entities → monocle_apptrace-0.4.0b1/src/monocle_apptrace/instrumentation/metamodel/botocore}/__init__.py +0 -0
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/src/monocle_apptrace/instrumentation/metamodel/botocore/_helper.py +0 -0
- {monocle_apptrace-0.3.1/src/monocle_apptrace/instrumentation/metamodel/flask → monocle_apptrace-0.4.0b1/src/monocle_apptrace/instrumentation/metamodel/botocore/entities}/__init__.py +0 -0
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/src/monocle_apptrace/instrumentation/metamodel/botocore/entities/inference.py +0 -0
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/src/monocle_apptrace/instrumentation/metamodel/botocore/handlers/botocore_span_handler.py +0 -0
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/src/monocle_apptrace/instrumentation/metamodel/botocore/methods.py +0 -0
- {monocle_apptrace-0.3.1/src/monocle_apptrace/instrumentation/metamodel/haystack → monocle_apptrace-0.4.0b1/src/monocle_apptrace/instrumentation/metamodel/flask}/__init__.py +0 -0
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/src/monocle_apptrace/instrumentation/metamodel/flask/methods.py +0 -0
- {monocle_apptrace-0.3.1/src/monocle_apptrace/instrumentation/metamodel/haystack/entities → monocle_apptrace-0.4.0b1/src/monocle_apptrace/instrumentation/metamodel/haystack}/__init__.py +0 -0
- {monocle_apptrace-0.3.1/src/monocle_apptrace/instrumentation/metamodel/langchain → monocle_apptrace-0.4.0b1/src/monocle_apptrace/instrumentation/metamodel/haystack/entities}/__init__.py +0 -0
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/src/monocle_apptrace/instrumentation/metamodel/haystack/entities/inference.py +0 -0
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/src/monocle_apptrace/instrumentation/metamodel/haystack/entities/retrieval.py +0 -0
- {monocle_apptrace-0.3.1/src/monocle_apptrace/instrumentation/metamodel/langchain/entities → monocle_apptrace-0.4.0b1/src/monocle_apptrace/instrumentation/metamodel/langchain}/__init__.py +0 -0
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/src/monocle_apptrace/instrumentation/metamodel/langchain/_helper.py +0 -0
- {monocle_apptrace-0.3.1/src/monocle_apptrace/instrumentation/metamodel/langgraph → monocle_apptrace-0.4.0b1/src/monocle_apptrace/instrumentation/metamodel/langchain/entities}/__init__.py +0 -0
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/src/monocle_apptrace/instrumentation/metamodel/langchain/entities/inference.py +0 -0
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/src/monocle_apptrace/instrumentation/metamodel/langchain/entities/retrieval.py +0 -0
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/src/monocle_apptrace/instrumentation/metamodel/langchain/methods.py +0 -0
- {monocle_apptrace-0.3.1/src/monocle_apptrace/instrumentation/metamodel/langgraph/entities → monocle_apptrace-0.4.0b1/src/monocle_apptrace/instrumentation/metamodel/langgraph}/__init__.py +0 -0
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/src/monocle_apptrace/instrumentation/metamodel/langgraph/_helper.py +0 -0
- {monocle_apptrace-0.3.1/src/monocle_apptrace/instrumentation/metamodel/llamaindex → monocle_apptrace-0.4.0b1/src/monocle_apptrace/instrumentation/metamodel/langgraph/entities}/__init__.py +0 -0
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/src/monocle_apptrace/instrumentation/metamodel/langgraph/entities/inference.py +0 -0
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/src/monocle_apptrace/instrumentation/metamodel/langgraph/methods.py +0 -0
- {monocle_apptrace-0.3.1/src/monocle_apptrace/instrumentation/metamodel/llamaindex/entities → monocle_apptrace-0.4.0b1/src/monocle_apptrace/instrumentation/metamodel/llamaindex}/__init__.py +0 -0
- {monocle_apptrace-0.3.1/src/monocle_apptrace/instrumentation/metamodel/openai → monocle_apptrace-0.4.0b1/src/monocle_apptrace/instrumentation/metamodel/llamaindex/entities}/__init__.py +0 -0
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/src/monocle_apptrace/instrumentation/metamodel/llamaindex/entities/agent.py +0 -0
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/src/monocle_apptrace/instrumentation/metamodel/llamaindex/entities/inference.py +0 -0
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/src/monocle_apptrace/instrumentation/metamodel/llamaindex/entities/retrieval.py +0 -0
- {monocle_apptrace-0.3.1/src/monocle_apptrace/instrumentation/metamodel/openai/entities → monocle_apptrace-0.4.0b1/src/monocle_apptrace/instrumentation/metamodel/openai}/__init__.py +0 -0
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/src/monocle_apptrace/instrumentation/metamodel/openai/_helper.py +0 -0
- {monocle_apptrace-0.3.1/src/monocle_apptrace/instrumentation/metamodel/teamsai → monocle_apptrace-0.4.0b1/src/monocle_apptrace/instrumentation/metamodel/openai/entities}/__init__.py +0 -0
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/src/monocle_apptrace/instrumentation/metamodel/openai/entities/retrieval.py +0 -0
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/src/monocle_apptrace/instrumentation/metamodel/openai/methods.py +0 -0
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/src/monocle_apptrace/instrumentation/metamodel/requests/__init__.py +0 -0
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/src/monocle_apptrace/instrumentation/metamodel/requests/entities/http.py +0 -0
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/src/monocle_apptrace/instrumentation/metamodel/requests/methods.py +0 -0
- {monocle_apptrace-0.3.1/src/monocle_apptrace/instrumentation/metamodel/teamsai/entities → monocle_apptrace-0.4.0b1/src/monocle_apptrace/instrumentation/metamodel/teamsai}/__init__.py +0 -0
- {monocle_apptrace-0.3.1/src/monocle_apptrace/instrumentation/metamodel/teamsai/entities/inference → monocle_apptrace-0.4.0b1/src/monocle_apptrace/instrumentation/metamodel/teamsai/entities}/__init__.py +0 -0
- {monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/tox.ini +0 -0
|
@@ -1,3 +1,16 @@
|
|
|
1
|
+
## Version 0.4.0b1 (2025-05-14)
|
|
2
|
+
|
|
3
|
+
- Added conversation id in scope for teams ai bot ([#180](https://github.com/monocle2ai/monocle/pull/180))
|
|
4
|
+
- Update inference entity type of TeamsAI SDK ([#178](https://github.com/monocle2ai/monocle/pull/178))
|
|
5
|
+
- Added stream and async for openai ([#177](https://github.com/monocle2ai/monocle/pull/177))
|
|
6
|
+
- Update inference span of TeamsAI ([#176](https://github.com/monocle2ai/monocle/pull/176))
|
|
7
|
+
- Remove Preset span name and Bugfix for Event ([#175](https://github.com/monocle2ai/monocle/pull/175))
|
|
8
|
+
- Add haystack anthropic sample ([#174](https://github.com/monocle2ai/monocle/pull/174))
|
|
9
|
+
- aiohttp auto instrumentation ([#173](https://github.com/monocle2ai/monocle/pull/173))
|
|
10
|
+
- Add source path to spans and fix json syntax in file exporter ([#172](https://github.com/monocle2ai/monocle/pull/172))
|
|
11
|
+
- Added changes for openai streaming ([#171](https://github.com/monocle2ai/monocle/pull/171))
|
|
12
|
+
- Add llama index anthropic sample ([#170](https://github.com/monocle2ai/monocle/pull/170))
|
|
13
|
+
|
|
1
14
|
## Version 0.3.1 (2024-04-18)
|
|
2
15
|
|
|
3
16
|
- Add MetaModel for Anthropic SDK ([#159](https://github.com/monocle2ai/monocle/pull/159))
|
|
@@ -9,7 +22,7 @@
|
|
|
9
22
|
- Support monocle exporter list as parameter to `setup_monocle_telemetry()` ([#161](https://github.com/monocle2ai/monocle/pull/161))
|
|
10
23
|
- Add langchain anthropic sample ([#165](https://github.com/monocle2ai/monocle/pull/165))
|
|
11
24
|
|
|
12
|
-
## Version 0.3.0 (2024-
|
|
25
|
+
## Version 0.3.0 (2024-03-18)
|
|
13
26
|
|
|
14
27
|
- Fixed issue with passing context in async case ([#150](https://github.com/monocle2ai/monocle/pull/150))
|
|
15
28
|
- Added lambda processor ([#148](https://github.com/monocle2ai/monocle/pull/148))
|
|
@@ -129,6 +129,8 @@ class S3SpanExporter(SpanExporterBase):
|
|
|
129
129
|
# Serialize spans to JSON or any other format you prefer
|
|
130
130
|
valid_json_list = []
|
|
131
131
|
for span in spans:
|
|
132
|
+
if self.skip_export(span):
|
|
133
|
+
continue
|
|
132
134
|
try:
|
|
133
135
|
valid_json_list.append(span.to_json(indent=0).replace("\n", ""))
|
|
134
136
|
except json.JSONDecodeError as e:
|
|
@@ -169,7 +171,7 @@ class S3SpanExporter(SpanExporterBase):
|
|
|
169
171
|
Key=file_name,
|
|
170
172
|
Body=span_data_batch
|
|
171
173
|
)
|
|
172
|
-
logger.
|
|
174
|
+
logger.debug(f"Span batch uploaded to AWS S3 as {file_name}.")
|
|
173
175
|
|
|
174
176
|
async def force_flush(self, timeout_millis: int = 30000) -> bool:
|
|
175
177
|
await self.__export_spans() # Export any remaining spans in the queue
|
|
@@ -82,8 +82,8 @@ class AzureBlobSpanExporter(SpanExporterBase):
|
|
|
82
82
|
# With Monocle,OpenTelemetry is always loaded. If the Azure trace package is installed, then it triggers the blob trace generation on every blob operation.
|
|
83
83
|
# Thus, the Monocle span write ends up generating a blob span which again comes back to the exporter .. and would result in an infinite loop.
|
|
84
84
|
# To avoid this, we check if the span has the Monocle SDK version attribute and skip it if it doesn't. That way the blob span genearted by Azure library are not exported.
|
|
85
|
-
if
|
|
86
|
-
continue
|
|
85
|
+
if self.skip_export(span):
|
|
86
|
+
continue
|
|
87
87
|
self.export_queue.append(span)
|
|
88
88
|
if len(self.export_queue) >= self.max_batch_size:
|
|
89
89
|
await self.__export_spans()
|
{monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/src/monocle_apptrace/exporters/base_exporter.py
RENAMED
|
@@ -1,20 +1,21 @@
|
|
|
1
|
-
import time
|
|
1
|
+
import time, os
|
|
2
2
|
import random
|
|
3
3
|
import logging
|
|
4
4
|
from abc import ABC, abstractmethod
|
|
5
5
|
from opentelemetry.sdk.trace import ReadableSpan
|
|
6
|
-
from opentelemetry.sdk.trace.export import
|
|
6
|
+
from opentelemetry.sdk.trace.export import SpanExportResult
|
|
7
|
+
from monocle_apptrace.instrumentation.common.constants import MONOCLE_SDK_VERSION
|
|
7
8
|
from typing import Sequence
|
|
8
|
-
import asyncio
|
|
9
9
|
|
|
10
10
|
logger = logging.getLogger(__name__)
|
|
11
11
|
|
|
12
12
|
class SpanExporterBase(ABC):
|
|
13
|
-
def __init__(self):
|
|
13
|
+
def __init__(self, export_monocle_only: bool = True):
|
|
14
14
|
self.backoff_factor = 2
|
|
15
15
|
self.max_retries = 10
|
|
16
16
|
self.export_queue = []
|
|
17
17
|
self.last_export_time = time.time()
|
|
18
|
+
self.export_monocle_only = export_monocle_only or os.environ.get("MONOCLE_EXPORTS_ONLY", True)
|
|
18
19
|
|
|
19
20
|
@abstractmethod
|
|
20
21
|
async def export(self, spans: Sequence[ReadableSpan]) -> SpanExportResult:
|
|
@@ -27,6 +28,11 @@ class SpanExporterBase(ABC):
|
|
|
27
28
|
def shutdown(self) -> None:
|
|
28
29
|
pass
|
|
29
30
|
|
|
31
|
+
def skip_export(self, span:ReadableSpan) -> bool:
|
|
32
|
+
if self.export_monocle_only and (not span.attributes.get(MONOCLE_SDK_VERSION)):
|
|
33
|
+
return True
|
|
34
|
+
return False
|
|
35
|
+
|
|
30
36
|
@staticmethod
|
|
31
37
|
def retry_with_backoff(retries=3, backoff_in_seconds=1, max_backoff_in_seconds=32, exceptions=(Exception,)):
|
|
32
38
|
def decorator(func):
|
{monocle_apptrace-0.3.1 → monocle_apptrace-0.4.0b1}/src/monocle_apptrace/exporters/file_exporter.py
RENAMED
|
@@ -7,12 +7,13 @@ from typing import Optional, Callable, Sequence
|
|
|
7
7
|
from opentelemetry.sdk.trace import ReadableSpan
|
|
8
8
|
from opentelemetry.sdk.trace.export import SpanExporter, SpanExportResult
|
|
9
9
|
from opentelemetry.sdk.resources import SERVICE_NAME
|
|
10
|
+
from monocle_apptrace.exporters.base_exporter import SpanExporterBase
|
|
10
11
|
from monocle_apptrace.exporters.exporter_processor import ExportTaskProcessor
|
|
11
12
|
|
|
12
13
|
DEFAULT_FILE_PREFIX:str = "monocle_trace_"
|
|
13
14
|
DEFAULT_TIME_FORMAT:str = "%Y-%m-%d_%H.%M.%S"
|
|
14
15
|
|
|
15
|
-
class FileSpanExporter(
|
|
16
|
+
class FileSpanExporter(SpanExporterBase):
|
|
16
17
|
current_trace_id: int = None
|
|
17
18
|
current_file_path: str = None
|
|
18
19
|
|
|
@@ -28,6 +29,7 @@ class FileSpanExporter(SpanExporter):
|
|
|
28
29
|
+ linesep,
|
|
29
30
|
task_processor: Optional[ExportTaskProcessor] = None
|
|
30
31
|
):
|
|
32
|
+
super().__init__()
|
|
31
33
|
self.out_handle:TextIOWrapper = None
|
|
32
34
|
self.formatter = formatter
|
|
33
35
|
self.service_name = service_name
|
|
@@ -39,21 +41,32 @@ class FileSpanExporter(SpanExporter):
|
|
|
39
41
|
self.task_processor.start()
|
|
40
42
|
|
|
41
43
|
def export(self, spans: Sequence[ReadableSpan]) -> SpanExportResult:
|
|
44
|
+
is_root_span = any(not span.parent for span in spans)
|
|
42
45
|
if self.task_processor is not None and callable(getattr(self.task_processor, 'queue_task', None)):
|
|
43
46
|
# Check if any span is a root span (no parent)
|
|
44
|
-
is_root_span = any(not span.parent for span in spans)
|
|
45
47
|
self.task_processor.queue_task(self._process_spans, spans, is_root_span)
|
|
46
48
|
return SpanExportResult.SUCCESS
|
|
47
49
|
else:
|
|
48
|
-
return self._process_spans(spans)
|
|
50
|
+
return self._process_spans(spans, is_root_span=is_root_span)
|
|
49
51
|
|
|
50
52
|
def _process_spans(self, spans: Sequence[ReadableSpan], is_root_span: bool = False) -> SpanExportResult:
|
|
53
|
+
first_span:bool = True
|
|
51
54
|
for span in spans:
|
|
55
|
+
if self.skip_export(span):
|
|
56
|
+
continue
|
|
52
57
|
if span.context.trace_id != self.current_trace_id:
|
|
53
58
|
self.rotate_file(span.resource.attributes[SERVICE_NAME],
|
|
54
59
|
span.context.trace_id)
|
|
60
|
+
first_span = True
|
|
61
|
+
if first_span:
|
|
62
|
+
first_span = False
|
|
63
|
+
else:
|
|
64
|
+
self.out_handle.write(",")
|
|
55
65
|
self.out_handle.write(self.formatter(span))
|
|
56
|
-
|
|
66
|
+
if is_root_span:
|
|
67
|
+
self.reset_handle()
|
|
68
|
+
else:
|
|
69
|
+
self.out_handle.flush()
|
|
57
70
|
return SpanExportResult.SUCCESS
|
|
58
71
|
|
|
59
72
|
def rotate_file(self, trace_name:str, trace_id:int) -> None:
|
|
@@ -62,6 +75,7 @@ class FileSpanExporter(SpanExporter):
|
|
|
62
75
|
self.file_prefix + trace_name + "_" + hex(trace_id) + "_"
|
|
63
76
|
+ datetime.now().strftime(self.time_format) + ".json")
|
|
64
77
|
self.out_handle = open(self.current_file_path, "w", encoding='UTF-8')
|
|
78
|
+
self.out_handle.write("[")
|
|
65
79
|
self.current_trace_id = trace_id
|
|
66
80
|
|
|
67
81
|
def force_flush(self, timeout_millis: int = 30000) -> bool:
|
|
@@ -70,6 +84,7 @@ class FileSpanExporter(SpanExporter):
|
|
|
70
84
|
|
|
71
85
|
def reset_handle(self) -> None:
|
|
72
86
|
if self.out_handle is not None:
|
|
87
|
+
self.out_handle.write("]")
|
|
73
88
|
self.out_handle.close()
|
|
74
89
|
self.out_handle = None
|
|
75
90
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from typing import Dict, Any, List
|
|
2
2
|
import os
|
|
3
|
-
import logging
|
|
3
|
+
import logging, warnings
|
|
4
4
|
from importlib import import_module
|
|
5
5
|
from opentelemetry.sdk.trace.export import SpanExporter, ConsoleSpanExporter
|
|
6
6
|
from monocle_apptrace.exporters.exporter_processor import LambdaExportTaskProcessor, is_aws_lambda_environment
|
|
@@ -34,7 +34,7 @@ def get_monocle_exporter(exporters_list:str=None) -> List[SpanExporter]:
|
|
|
34
34
|
try:
|
|
35
35
|
exporter_class_path = monocle_exporters[exporter_name]
|
|
36
36
|
except KeyError:
|
|
37
|
-
|
|
37
|
+
warnings.warn(f"Unsupported Monocle span exporter '{exporter_name}', skipping.")
|
|
38
38
|
continue
|
|
39
39
|
try:
|
|
40
40
|
exporter_module = import_module(exporter_class_path["module"])
|
|
@@ -45,7 +45,7 @@ def get_monocle_exporter(exporters_list:str=None) -> List[SpanExporter]:
|
|
|
45
45
|
else:
|
|
46
46
|
exporters.append(exporter_class())
|
|
47
47
|
except Exception as ex:
|
|
48
|
-
|
|
48
|
+
warnings.warn(
|
|
49
49
|
f"Unable to initialize Monocle span exporter '{exporter_name}', error: {ex}. Using ConsoleSpanExporter as a fallback.")
|
|
50
50
|
exporters.append(ConsoleSpanExporter())
|
|
51
51
|
continue
|
|
@@ -6,7 +6,7 @@ import requests
|
|
|
6
6
|
from opentelemetry.sdk.trace import ReadableSpan
|
|
7
7
|
from opentelemetry.sdk.trace.export import SpanExporter, SpanExportResult, ConsoleSpanExporter
|
|
8
8
|
from requests.exceptions import ReadTimeout
|
|
9
|
-
|
|
9
|
+
from monocle_apptrace.exporters.base_exporter import SpanExporterBase
|
|
10
10
|
from monocle_apptrace.exporters.exporter_processor import ExportTaskProcessor
|
|
11
11
|
|
|
12
12
|
REQUESTS_SUCCESS_STATUS_CODES = (200, 202)
|
|
@@ -15,7 +15,7 @@ OKAHU_PROD_INGEST_ENDPOINT = "https://ingest.okahu.co/api/v1/trace/ingest"
|
|
|
15
15
|
logger = logging.getLogger(__name__)
|
|
16
16
|
|
|
17
17
|
|
|
18
|
-
class OkahuSpanExporter(
|
|
18
|
+
class OkahuSpanExporter(SpanExporterBase):
|
|
19
19
|
def __init__(
|
|
20
20
|
self,
|
|
21
21
|
endpoint: Optional[str] = None,
|
|
@@ -24,6 +24,7 @@ class OkahuSpanExporter(SpanExporter):
|
|
|
24
24
|
task_processor: ExportTaskProcessor = None
|
|
25
25
|
):
|
|
26
26
|
"""Okahu exporter."""
|
|
27
|
+
super().__init__()
|
|
27
28
|
okahu_endpoint: str = os.environ.get("OKAHU_INGESTION_ENDPOINT", OKAHU_PROD_INGEST_ENDPOINT)
|
|
28
29
|
self.endpoint = endpoint or okahu_endpoint
|
|
29
30
|
api_key: str = os.environ.get("OKAHU_API_KEY")
|
|
@@ -58,6 +59,8 @@ class OkahuSpanExporter(SpanExporter):
|
|
|
58
59
|
|
|
59
60
|
# append the batch object with all the spans object
|
|
60
61
|
for span in spans:
|
|
62
|
+
if self.skip_export(span):
|
|
63
|
+
continue
|
|
61
64
|
# create a object from serialized span
|
|
62
65
|
obj = json.loads(span.to_json())
|
|
63
66
|
if obj["parent_id"] is None:
|
|
@@ -51,7 +51,9 @@ llm_type_map = {
|
|
|
51
51
|
"openaigenerator": "openai",
|
|
52
52
|
"bedrockruntime":"aws_bedrock",
|
|
53
53
|
"sagemakerruntime":"aws_sagemaker",
|
|
54
|
+
"anthropic": "anthropic",
|
|
54
55
|
"chatanthropic":"anthropic",
|
|
56
|
+
"anthropicchatgenerator":"anthropic",
|
|
55
57
|
}
|
|
56
58
|
|
|
57
59
|
MONOCLE_INSTRUMENTOR = "monocle_apptrace"
|
|
@@ -74,4 +76,6 @@ WORKFLOW_TYPE_KEY = "monocle.workflow_type"
|
|
|
74
76
|
ADD_NEW_WORKFLOW = "monocle.add_new_workflow"
|
|
75
77
|
WORKFLOW_TYPE_GENERIC = "workflow.generic"
|
|
76
78
|
MONOCLE_SDK_VERSION = "monocle_apptrace.version"
|
|
77
|
-
MONOCLE_SDK_LANGUAGE = "monocle_apptrace.language"
|
|
79
|
+
MONOCLE_SDK_LANGUAGE = "monocle_apptrace.language"
|
|
80
|
+
MONOCLE_DETECTED_SPAN_ERROR = "monocle_apptrace.detected_span_error"
|
|
81
|
+
HTTP_SUCCESS_CODES = ('200', '201', '202', '204', '205', '206')
|
|
@@ -25,9 +25,9 @@ from monocle_apptrace.instrumentation.common.wrapper_method import (
|
|
|
25
25
|
WrapperMethod,
|
|
26
26
|
MONOCLE_SPAN_HANDLERS
|
|
27
27
|
)
|
|
28
|
-
from monocle_apptrace.instrumentation.common.wrapper import scope_wrapper, ascope_wrapper,
|
|
28
|
+
from monocle_apptrace.instrumentation.common.wrapper import scope_wrapper, ascope_wrapper, monocle_wrapper, amonocle_wrapper
|
|
29
29
|
from monocle_apptrace.instrumentation.common.utils import (
|
|
30
|
-
set_scope, remove_scope, http_route_handler, load_scopes,
|
|
30
|
+
set_scope, remove_scope, http_route_handler, load_scopes, http_async_route_handler
|
|
31
31
|
)
|
|
32
32
|
from monocle_apptrace.instrumentation.common.constants import MONOCLE_INSTRUMENTOR, WORKFLOW_TYPE_GENERIC
|
|
33
33
|
from functools import wraps
|
|
@@ -68,13 +68,20 @@ class MonocleInstrumentor(BaseInstrumentor):
|
|
|
68
68
|
|
|
69
69
|
def get_instrumentor(self, tracer):
|
|
70
70
|
def instrumented_endpoint_invoke(to_wrap,wrapped, span_name, instance,fn):
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
boto_method_to_wrap, fn, instance, args, kwargs)
|
|
71
|
+
if inspect.iscoroutinefunction(fn):
|
|
72
|
+
@wraps(fn)
|
|
73
|
+
async def with_instrumentation(*args, **kwargs):
|
|
74
|
+
boto_method_to_wrap = to_wrap.copy()
|
|
75
|
+
boto_method_to_wrap['skip_span'] = False
|
|
76
|
+
return await amonocle_wrapper(tracer, NonFrameworkSpanHandler(),
|
|
77
|
+
boto_method_to_wrap, fn, instance, "", args, kwargs)
|
|
78
|
+
else:
|
|
79
|
+
@wraps(fn)
|
|
80
|
+
def with_instrumentation(*args, **kwargs):
|
|
81
|
+
boto_method_to_wrap = to_wrap.copy()
|
|
82
|
+
boto_method_to_wrap['skip_span'] = False
|
|
83
|
+
return monocle_wrapper(tracer, NonFrameworkSpanHandler(),
|
|
84
|
+
boto_method_to_wrap, fn, instance, "", args, kwargs)
|
|
78
85
|
return with_instrumentation
|
|
79
86
|
return instrumented_endpoint_invoke
|
|
80
87
|
|
|
@@ -241,8 +248,8 @@ def start_trace():
|
|
|
241
248
|
SpanHandler.set_workflow_properties(span)
|
|
242
249
|
token = attach(updated_span_context)
|
|
243
250
|
return token
|
|
244
|
-
except:
|
|
245
|
-
logger.warning("Failed to start trace")
|
|
251
|
+
except Exception as e:
|
|
252
|
+
logger.warning("Failed to start trace {e}")
|
|
246
253
|
return None
|
|
247
254
|
|
|
248
255
|
def stop_trace(token) -> None:
|
|
@@ -328,8 +335,12 @@ def monocle_trace_scope_method(scope_name: str, scope_value:str=None):
|
|
|
328
335
|
if inspect.iscoroutinefunction(func):
|
|
329
336
|
@wraps(func)
|
|
330
337
|
async def wrapper(*args, **kwargs):
|
|
331
|
-
|
|
332
|
-
|
|
338
|
+
token = start_scope(scope_name, scope_value)
|
|
339
|
+
try:
|
|
340
|
+
result = await func(*args, **kwargs)
|
|
341
|
+
return result
|
|
342
|
+
finally:
|
|
343
|
+
stop_scope(token)
|
|
333
344
|
return wrapper
|
|
334
345
|
else:
|
|
335
346
|
@wraps(func)
|
|
@@ -8,7 +8,7 @@ from monocle_apptrace.instrumentation.common.constants import (
|
|
|
8
8
|
QUERY,
|
|
9
9
|
service_name_map,
|
|
10
10
|
service_type_map,
|
|
11
|
-
MONOCLE_SDK_VERSION, MONOCLE_SDK_LANGUAGE
|
|
11
|
+
MONOCLE_SDK_VERSION, MONOCLE_SDK_LANGUAGE, MONOCLE_DETECTED_SPAN_ERROR
|
|
12
12
|
)
|
|
13
13
|
from monocle_apptrace.instrumentation.common.utils import set_attribute, get_scopes, MonocleSpanException, get_monocle_version
|
|
14
14
|
from monocle_apptrace.instrumentation.common.constants import WORKFLOW_TYPE_KEY, WORKFLOW_TYPE_GENERIC
|
|
@@ -18,7 +18,8 @@ logger = logging.getLogger(__name__)
|
|
|
18
18
|
WORKFLOW_TYPE_MAP = {
|
|
19
19
|
"llama_index": "workflow.llamaindex",
|
|
20
20
|
"langchain": "workflow.langchain",
|
|
21
|
-
"haystack": "workflow.haystack"
|
|
21
|
+
"haystack": "workflow.haystack",
|
|
22
|
+
"teams.ai": "workflow.teams_ai",
|
|
22
23
|
}
|
|
23
24
|
|
|
24
25
|
class SpanHandler:
|
|
@@ -49,10 +50,11 @@ class SpanHandler:
|
|
|
49
50
|
set_attribute(QUERY, args[0]['prompt_builder']['question'])
|
|
50
51
|
|
|
51
52
|
@staticmethod
|
|
52
|
-
def set_default_monocle_attributes(span: Span):
|
|
53
|
+
def set_default_monocle_attributes(span: Span, source_path = "" ):
|
|
53
54
|
""" Set default monocle attributes for all spans """
|
|
54
55
|
span.set_attribute(MONOCLE_SDK_VERSION, get_monocle_version())
|
|
55
56
|
span.set_attribute(MONOCLE_SDK_LANGUAGE, "python")
|
|
57
|
+
span.set_attribute("span_source", source_path)
|
|
56
58
|
for scope_key, scope_value in get_scopes().items():
|
|
57
59
|
span.set_attribute(f"scope.{scope_key}", scope_value)
|
|
58
60
|
|
|
@@ -62,8 +64,6 @@ class SpanHandler:
|
|
|
62
64
|
SpanHandler.set_workflow_attributes(to_wrap, span)
|
|
63
65
|
SpanHandler.set_app_hosting_identifier_attribute(span)
|
|
64
66
|
|
|
65
|
-
span.set_status(StatusCode.OK)
|
|
66
|
-
|
|
67
67
|
@staticmethod
|
|
68
68
|
def set_non_workflow_properties(span: Span, to_wrap = None):
|
|
69
69
|
workflow_name = SpanHandler.get_workflow_name(span=span)
|
|
@@ -74,11 +74,14 @@ class SpanHandler:
|
|
|
74
74
|
if span.status.status_code == StatusCode.UNSET:
|
|
75
75
|
span.set_status(StatusCode.OK)
|
|
76
76
|
|
|
77
|
-
def hydrate_span(self, to_wrap, wrapped, instance, args, kwargs, result, span):
|
|
78
|
-
self.hydrate_attributes(to_wrap, wrapped, instance, args, kwargs, result, span)
|
|
79
|
-
self.hydrate_events(to_wrap, wrapped, instance, args, kwargs, result, span)
|
|
77
|
+
def hydrate_span(self, to_wrap, wrapped, instance, args, kwargs, result, span) -> bool:
|
|
78
|
+
detected_error_in_attribute = self.hydrate_attributes(to_wrap, wrapped, instance, args, kwargs, result, span)
|
|
79
|
+
detected_error_in_event = self.hydrate_events(to_wrap, wrapped, instance, args, kwargs, result, span)
|
|
80
|
+
if detected_error_in_attribute or detected_error_in_event:
|
|
81
|
+
span.set_attribute(MONOCLE_DETECTED_SPAN_ERROR, True)
|
|
80
82
|
|
|
81
|
-
def hydrate_attributes(self, to_wrap, wrapped, instance, args, kwargs, result, span):
|
|
83
|
+
def hydrate_attributes(self, to_wrap, wrapped, instance, args, kwargs, result, span:Span) -> bool:
|
|
84
|
+
detected_error:bool = False
|
|
82
85
|
span_index = 0
|
|
83
86
|
if SpanHandler.is_root_span(span):
|
|
84
87
|
span_index = 2 # root span will have workflow and hosting entities pre-populated
|
|
@@ -86,7 +89,7 @@ class SpanHandler:
|
|
|
86
89
|
'output_processor' in to_wrap and to_wrap["output_processor"] is not None):
|
|
87
90
|
output_processor=to_wrap['output_processor']
|
|
88
91
|
if 'type' in output_processor:
|
|
89
|
-
|
|
92
|
+
span.set_attribute("span.type", output_processor['type'])
|
|
90
93
|
else:
|
|
91
94
|
logger.warning("type of span not found or incorrect written in entity json")
|
|
92
95
|
if 'attributes' in output_processor:
|
|
@@ -104,6 +107,7 @@ class SpanHandler:
|
|
|
104
107
|
span.set_attribute(attribute_name, result)
|
|
105
108
|
except MonocleSpanException as e:
|
|
106
109
|
span.set_status(StatusCode.ERROR, e.message)
|
|
110
|
+
detected_error = True
|
|
107
111
|
except Exception as e:
|
|
108
112
|
logger.debug(f"Error processing accessor: {e}")
|
|
109
113
|
else:
|
|
@@ -121,13 +125,14 @@ class SpanHandler:
|
|
|
121
125
|
|
|
122
126
|
if span_index > 0:
|
|
123
127
|
span.set_attribute("entity.count", span_index)
|
|
128
|
+
return detected_error
|
|
124
129
|
|
|
125
|
-
|
|
126
|
-
|
|
130
|
+
def hydrate_events(self, to_wrap, wrapped, instance, args, kwargs, ret_result, span) -> bool:
|
|
131
|
+
detected_error:bool = False
|
|
127
132
|
if not self.skip_processor(to_wrap, wrapped, instance, args, kwargs) and (
|
|
128
133
|
'output_processor' in to_wrap and to_wrap["output_processor"] is not None):
|
|
129
134
|
output_processor=to_wrap['output_processor']
|
|
130
|
-
arguments = {"instance": instance, "args": args, "kwargs": kwargs, "result":
|
|
135
|
+
arguments = {"instance": instance, "args": args, "kwargs": kwargs, "result": ret_result}
|
|
131
136
|
if 'events' in output_processor:
|
|
132
137
|
events = output_processor['events']
|
|
133
138
|
for event in events:
|
|
@@ -139,15 +144,25 @@ class SpanHandler:
|
|
|
139
144
|
accessor = attribute.get("accessor")
|
|
140
145
|
if accessor:
|
|
141
146
|
try:
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
147
|
+
result = accessor(arguments)
|
|
148
|
+
if result and isinstance(result, dict):
|
|
149
|
+
result = dict((key, value) for key, value in result.items() if value is not None)
|
|
150
|
+
if result and isinstance(result, (str, list, dict)):
|
|
151
|
+
if attribute_key is not None:
|
|
152
|
+
event_attributes[attribute_key] = result
|
|
153
|
+
else:
|
|
154
|
+
event_attributes.update(result)
|
|
146
155
|
except MonocleSpanException as e:
|
|
147
156
|
span.set_status(StatusCode.ERROR, e.message)
|
|
157
|
+
detected_error = True
|
|
148
158
|
except Exception as e:
|
|
149
159
|
logger.debug(f"Error evaluating accessor for attribute '{attribute_key}': {e}")
|
|
150
|
-
|
|
160
|
+
matching_timestamp = getattr(ret_result, "timestamps", {}).get(event_name, None)
|
|
161
|
+
if isinstance(matching_timestamp, int):
|
|
162
|
+
span.add_event(name=event_name, attributes=event_attributes, timestamp=matching_timestamp)
|
|
163
|
+
else:
|
|
164
|
+
span.add_event(name=event_name, attributes=event_attributes)
|
|
165
|
+
return detected_error
|
|
151
166
|
|
|
152
167
|
@staticmethod
|
|
153
168
|
def set_workflow_attributes(to_wrap, span: Span):
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import logging, json
|
|
2
2
|
import os
|
|
3
|
+
import traceback
|
|
3
4
|
from typing import Callable, Generic, Optional, TypeVar, Mapping
|
|
4
|
-
import threading, asyncio
|
|
5
5
|
|
|
6
6
|
from opentelemetry.context import attach, detach, get_current, get_value, set_value, Context
|
|
7
|
-
from opentelemetry.trace import NonRecordingSpan, Span
|
|
7
|
+
from opentelemetry.trace import NonRecordingSpan, Span
|
|
8
8
|
from opentelemetry.trace.propagation import _SPAN_KEY
|
|
9
9
|
from opentelemetry.sdk.trace import id_generator, TracerProvider
|
|
10
|
-
from opentelemetry.propagate import
|
|
10
|
+
from opentelemetry.propagate import extract
|
|
11
11
|
from opentelemetry import baggage
|
|
12
12
|
from monocle_apptrace.instrumentation.common.constants import MONOCLE_SCOPE_NAME_PREFIX, SCOPE_METHOD_FILE, SCOPE_CONFIG_PATH, llm_type_map, MONOCLE_SDK_VERSION, ADD_NEW_WORKFLOW
|
|
13
13
|
from importlib.metadata import version
|
|
@@ -17,7 +17,6 @@ U = TypeVar('U')
|
|
|
17
17
|
|
|
18
18
|
logger = logging.getLogger(__name__)
|
|
19
19
|
|
|
20
|
-
monocle_tracer_provider: TracerProvider = None
|
|
21
20
|
embedding_model_context = {}
|
|
22
21
|
scope_id_generator = id_generator.RandomIdGenerator()
|
|
23
22
|
http_scopes:dict[str:str] = {}
|
|
@@ -43,14 +42,6 @@ class MonocleSpanException(Exception):
|
|
|
43
42
|
"""String representation of the exception."""
|
|
44
43
|
return f"[Monocle Span Error: {self.message} {self.status}"
|
|
45
44
|
|
|
46
|
-
def set_tracer_provider(tracer_provider: TracerProvider):
|
|
47
|
-
global monocle_tracer_provider
|
|
48
|
-
monocle_tracer_provider = tracer_provider
|
|
49
|
-
|
|
50
|
-
def get_tracer_provider() -> TracerProvider:
|
|
51
|
-
global monocle_tracer_provider
|
|
52
|
-
return monocle_tracer_provider
|
|
53
|
-
|
|
54
45
|
def set_span_attribute(span, name, value):
|
|
55
46
|
if value is not None:
|
|
56
47
|
if value != "":
|
|
@@ -93,7 +84,12 @@ def with_tracer_wrapper(func):
|
|
|
93
84
|
except Exception as e:
|
|
94
85
|
logger.error("Exception in attaching parent context: %s", e)
|
|
95
86
|
|
|
96
|
-
|
|
87
|
+
if traceback.extract_stack().__len__() > 2:
|
|
88
|
+
filename, line_number, _, _ = traceback.extract_stack()[-2]
|
|
89
|
+
source_path = f"{filename}:{line_number}"
|
|
90
|
+
else:
|
|
91
|
+
source_path = ""
|
|
92
|
+
val = func(tracer, handler, to_wrap, wrapped, instance, source_path, args, kwargs)
|
|
97
93
|
return val
|
|
98
94
|
|
|
99
95
|
return wrapper
|
|
@@ -275,49 +271,44 @@ async def http_async_route_handler(func, *args, **kwargs):
|
|
|
275
271
|
headers = kwargs['req'].headers
|
|
276
272
|
else:
|
|
277
273
|
headers = None
|
|
278
|
-
return async_wrapper(func, None, None, headers, *args, **kwargs)
|
|
279
|
-
|
|
280
|
-
def run_async_with_scope(method, current_context, exceptions, *args, **kwargs):
|
|
281
|
-
token = None
|
|
282
274
|
try:
|
|
283
|
-
if
|
|
284
|
-
token =
|
|
285
|
-
return
|
|
286
|
-
except Exception as e:
|
|
287
|
-
exceptions['exception'] = e
|
|
288
|
-
raise e
|
|
275
|
+
if headers is not None:
|
|
276
|
+
token = extract_http_headers(headers)
|
|
277
|
+
return await func(*args, **kwargs)
|
|
289
278
|
finally:
|
|
290
|
-
if token:
|
|
291
|
-
|
|
279
|
+
if token is not None:
|
|
280
|
+
clear_http_scopes(token)
|
|
292
281
|
|
|
293
|
-
def
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
282
|
+
# def run_async_with_scope(method, current_context, exceptions, *args, **kwargs):
|
|
283
|
+
# token = None
|
|
284
|
+
# try:
|
|
285
|
+
# if current_context:
|
|
286
|
+
# token = attach(current_context)
|
|
287
|
+
# return asyncio.run(method(*args, **kwargs))
|
|
288
|
+
# except Exception as e:
|
|
289
|
+
# exceptions['exception'] = e
|
|
290
|
+
# raise e
|
|
291
|
+
# finally:
|
|
292
|
+
# if token:
|
|
293
|
+
# detach(token)
|
|
294
|
+
|
|
295
|
+
# async def async_wrapper(method, headers=None, *args, **kwargs):
|
|
296
|
+
# current_context = get_current()
|
|
297
|
+
# try:
|
|
298
|
+
# if run_loop and run_loop.is_running():
|
|
299
|
+
# results = []
|
|
300
|
+
# thread = threading.Thread(target=lambda: results.append(run_async_with_scope(method, current_context, exceptions, *args, **kwargs)))
|
|
301
|
+
# thread.start()
|
|
302
|
+
# thread.join()
|
|
303
|
+
# if 'exception' in exceptions:
|
|
304
|
+
# raise exceptions['exception']
|
|
305
|
+
# return_value = results[0] if len(results) > 0 else None
|
|
306
|
+
# return return_value
|
|
307
|
+
# else:
|
|
308
|
+
# return run_async_with_scope(method, None, exceptions, *args, **kwargs)
|
|
309
|
+
# finally:
|
|
310
|
+
# if token:
|
|
311
|
+
# remove_scope(token)
|
|
321
312
|
|
|
322
313
|
def get_monocle_version() -> str:
|
|
323
314
|
global monocle_sdk_version
|
|
@@ -365,7 +356,24 @@ def try_option(func: Callable[..., T], *args, **kwargs) -> Option[T]:
|
|
|
365
356
|
def get_llm_type(instance):
|
|
366
357
|
try:
|
|
367
358
|
t_name = type(instance).__name__.lower()
|
|
368
|
-
|
|
359
|
+
t_name = t_name.replace("async", "") if "async" in t_name else t_name
|
|
360
|
+
llm_type = llm_type_map.get(t_name)
|
|
369
361
|
return llm_type
|
|
370
362
|
except:
|
|
371
363
|
pass
|
|
364
|
+
|
|
365
|
+
def patch_instance_method(obj, method_name, func):
|
|
366
|
+
"""
|
|
367
|
+
Patch a special method (like __iter__) for a single instance.
|
|
368
|
+
|
|
369
|
+
Args:
|
|
370
|
+
obj: the instance to patch
|
|
371
|
+
method_name: the name of the method (e.g., '__iter__')
|
|
372
|
+
func: the new function, expecting (self, ...)
|
|
373
|
+
"""
|
|
374
|
+
cls = obj.__class__
|
|
375
|
+
# Dynamically create a new class that inherits from obj's class
|
|
376
|
+
new_cls = type(f"Patched{cls.__name__}", (cls,), {
|
|
377
|
+
method_name: func
|
|
378
|
+
})
|
|
379
|
+
obj.__class__ = new_cls
|