Skip to content

Commit 05be4e4

Browse files
authored
fix(telemetry): attribute internal SDK calls to their caller module (#200)
1 parent fa22801 commit 05be4e4

19 files changed

Lines changed: 179 additions & 27 deletions

File tree

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "sap-cloud-sdk"
3-
version = "0.33.1"
3+
version = "0.33.2"
44
description = "SAP Cloud SDK for Python"
55
readme = "README.md"
66
license = "Apache-2.0"

src/sap_cloud_sdk/agentgateway/_fragments.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
)
1717

1818
from sap_cloud_sdk.agentgateway.exceptions import MCPServerNotFoundError
19+
from sap_cloud_sdk.core.telemetry import Module
1920

2021
logger = logging.getLogger(__name__)
2122

@@ -35,7 +36,10 @@ class FragmentLabel(str, Enum):
3536

3637

3738
def _list_fragments_by_label(label: FragmentLabel, tenant_subdomain: str) -> list:
38-
client = create_fragment_client(instance=_DESTINATION_INSTANCE)
39+
client = create_fragment_client(
40+
instance=_DESTINATION_INSTANCE,
41+
_telemetry_source=Module.AGENTGATEWAY,
42+
)
3943
return client.list_instance_fragments(
4044
filter=ListOptions(filter_labels=[Label(key=LABEL_KEY, values=[label.value])]),
4145
tenant=tenant_subdomain,

src/sap_cloud_sdk/agentgateway/_lob.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
ConsumptionLevel,
1919
ConsumptionOptions,
2020
)
21+
from sap_cloud_sdk.core.telemetry import Module
2122

2223
from sap_cloud_sdk.agentgateway._fragments import (
2324
LABEL_KEY,
@@ -88,7 +89,10 @@ def _fetch_auth_token(
8889
Raises:
8990
MCPServerNotFoundError: If no auth token is returned.
9091
"""
91-
client = create_destination_client(instance=_DESTINATION_INSTANCE)
92+
client = create_destination_client(
93+
instance=_DESTINATION_INSTANCE,
94+
_telemetry_source=Module.AGENTGATEWAY,
95+
)
9296
dest = client.get_destination(
9397
dest_name,
9498
level=ConsumptionLevel.PROVIDER_SUBACCOUNT,
@@ -130,7 +134,10 @@ def get_ias_client_id_lob() -> str:
130134
Any exception raised by the destination client.
131135
"""
132136
dest_name = _ias_dest_name()
133-
client = create_destination_client(instance=_DESTINATION_INSTANCE)
137+
client = create_destination_client(
138+
instance=_DESTINATION_INSTANCE,
139+
_telemetry_source=Module.AGENTGATEWAY,
140+
)
134141
dest = client.get_destination(
135142
dest_name,
136143
level=ConsumptionLevel.PROVIDER_SUBACCOUNT,

src/sap_cloud_sdk/agentgateway/agw_client.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ def __init__(
107107
self,
108108
tenant_subdomain: str | Callable[[], str] | None = None,
109109
config: ClientConfig | None = None,
110+
_telemetry_source: Module | None = None,
110111
):
111112
"""Initialize the Agent Gateway client.
112113
@@ -115,11 +116,13 @@ def __init__(
115116
Can be a string or a callable returning a string.
116117
Required for LoB agents, ignored for Customer agents.
117118
config: Client configuration. Uses defaults if not provided.
119+
_telemetry_source: Internal telemetry source identifier. Not intended for external use.
118120
"""
119121
self._tenant_subdomain = tenant_subdomain
120122
self._config = config or ClientConfig()
121123
self._token_cache = _TokenCache(self._config)
122124
self._gateway_url_cache = _GatewayUrlCache()
125+
self._telemetry_source = _telemetry_source
123126

124127
@staticmethod
125128
def _resolve_value(
@@ -580,6 +583,8 @@ def _unwrap_exception_group(exc: BaseException) -> BaseException:
580583
def create_client(
581584
tenant_subdomain: str | Callable[[], str] | None = None,
582585
config: ClientConfig | None = None,
586+
*,
587+
_telemetry_source: Module | None = None,
583588
) -> AgentGatewayClient:
584589
"""Create an Agent Gateway client for discovering and invoking MCP tools.
585590
@@ -591,6 +596,7 @@ def create_client(
591596
Can be a string or a callable returning a string.
592597
Required for LoB agents, ignored for Customer agents.
593598
config: Client configuration. Uses defaults if not provided.
599+
_telemetry_source: Internal telemetry source identifier. Not intended for external use.
594600
595601
Returns:
596602
AgentGatewayClient instance.
@@ -644,4 +650,8 @@ def create_client(
644650
user_auth = await agw_client.get_user_auth(user_token="user-jwt")
645651
```
646652
"""
647-
return AgentGatewayClient(tenant_subdomain=tenant_subdomain, config=config)
653+
return AgentGatewayClient(
654+
tenant_subdomain=tenant_subdomain,
655+
config=config,
656+
_telemetry_source=_telemetry_source,
657+
)

src/sap_cloud_sdk/core/auditlog_ng/__init__.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,10 @@ def _get_config_from_destination(
116116
create_client as _dest_create_client,
117117
)
118118

119-
dest_client = _dest_create_client(instance=destination_instance)
119+
dest_client = _dest_create_client(
120+
instance=destination_instance,
121+
_telemetry_source=Module.AUDITLOG_NG,
122+
)
120123
options = (
121124
ConsumptionOptions(
122125
fragment_name=fragment_name, fragment_level=ConsumptionLevel.SUBACCOUNT

src/sap_cloud_sdk/core/data_anonymization/_http_transport.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -357,13 +357,16 @@ def _cert_from_inline_values(
357357
def _cert_from_destination(self, name: str) -> str:
358358
"""Resolve a combined PEM bundle via Destination and write it to a temp file."""
359359
try:
360+
from sap_cloud_sdk.core.telemetry import Module
360361
from sap_cloud_sdk.destination import (
361362
AccessStrategy,
362363
create_certificate_client,
363364
create_client,
364365
)
365366

366-
destination_client = create_client()
367+
destination_client = create_client(
368+
_telemetry_source=Module.DATA_ANONYMIZATION,
369+
)
367370
destination = destination_client.get_instance_destination(name)
368371
if destination is None:
369372
destination = destination_client.get_subaccount_destination(
@@ -376,7 +379,9 @@ def _cert_from_destination(self, name: str) -> str:
376379
key_store_location = self._get_destination_keystore_location(
377380
destination, name
378381
)
379-
cert_client = create_certificate_client()
382+
cert_client = create_certificate_client(
383+
_telemetry_source=Module.DATA_ANONYMIZATION,
384+
)
380385
cert = cert_client.get_instance_certificate(key_store_location)
381386
if cert is None:
382387
cert = cert_client.get_subaccount_certificate(

src/sap_cloud_sdk/destination/__init__.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import os
2727
from typing import Optional
2828

29+
from sap_cloud_sdk.core.telemetry import Module
2930
from sap_cloud_sdk.destination._models import (
3031
Destination,
3132
AuthToken,
@@ -83,6 +84,7 @@ def create_client(
8384
instance: Optional[str] = None,
8485
config: Optional[DestinationConfig] = None,
8586
use_default_proxy: bool = False,
87+
_telemetry_source: Optional[Module] = None,
8688
):
8789
"""Creates a Destination client with local/cloud detection.
8890
@@ -98,6 +100,7 @@ def create_client(
98100
will attempt to load transparent proxy configuration from APPFND_CONHOS_TRANSP_PROXY
99101
environment variable. To use a custom proxy, use client.set_proxy() after creation.
100102
Defaults to False.
103+
_telemetry_source: Internal telemetry source identifier. Not intended for external use.
101104
102105
Returns:
103106
DestinationClient or LocalDevDestinationClient: Client implementing the Destination interface.
@@ -118,7 +121,9 @@ def create_client(
118121
tp = TokenProvider(binding)
119122
http = DestinationHttp(config=binding, token_provider=tp)
120123

121-
return DestinationClient(http, use_default_proxy)
124+
return DestinationClient(
125+
http, use_default_proxy, _telemetry_source=_telemetry_source
126+
)
122127

123128
except Exception as e:
124129
raise ClientCreationError(f"failed to create destination client: {e}")
@@ -128,6 +133,7 @@ def create_fragment_client(
128133
*,
129134
instance: Optional[str] = None,
130135
config: Optional[DestinationConfig] = None,
136+
_telemetry_source: Optional[Module] = None,
131137
):
132138
"""Creates a Fragment client with local/cloud detection.
133139
@@ -139,6 +145,7 @@ def create_fragment_client(
139145
Args:
140146
instance: Instance name used for secret resolution in cloud mode. Defaults to "default".
141147
config: Optional explicit DestinationConfig.
148+
_telemetry_source: Internal telemetry source identifier. Not intended for external use.
142149
143150
Returns:
144151
FragmentClient or LocalDevFragmentClient: Client for managing destination fragments.
@@ -159,7 +166,7 @@ def create_fragment_client(
159166
tp = TokenProvider(binding)
160167
http = DestinationHttp(config=binding, token_provider=tp)
161168

162-
return FragmentClient(http)
169+
return FragmentClient(http, _telemetry_source=_telemetry_source)
163170

164171
except Exception as e:
165172
raise ClientCreationError(f"failed to create fragment client: {e}")
@@ -169,6 +176,7 @@ def create_certificate_client(
169176
*,
170177
instance: Optional[str] = None,
171178
config: Optional[DestinationConfig] = None,
179+
_telemetry_source: Optional[Module] = None,
172180
):
173181
"""Creates a Certificate client with local/cloud detection.
174182
@@ -180,6 +188,7 @@ def create_certificate_client(
180188
Args:
181189
instance: Instance name used for secret resolution in cloud mode. Defaults to "default".
182190
config: Optional explicit DestinationConfig.
191+
_telemetry_source: Internal telemetry source identifier. Not intended for external use.
183192
184193
Returns:
185194
CertificateClient or LocalDevCertificateClient: Client for managing certificates.
@@ -200,7 +209,7 @@ def create_certificate_client(
200209
tp = TokenProvider(binding)
201210
http = DestinationHttp(config=binding, token_provider=tp)
202211

203-
return CertificateClient(http)
212+
return CertificateClient(http, _telemetry_source=_telemetry_source)
204213

205214
except Exception as e:
206215
raise ClientCreationError(f"failed to create certificate client: {e}")

src/sap_cloud_sdk/destination/certificate_client.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,16 +61,22 @@ class CertificateClient:
6161
```
6262
"""
6363

64-
def __init__(self, http: DestinationHttp) -> None:
64+
def __init__(
65+
self,
66+
http: DestinationHttp,
67+
_telemetry_source: Optional[Module] = None,
68+
) -> None:
6569
"""Initialize CertificateClient with dependency injection.
6670
6771
Args:
6872
http: Configured HTTP transport for the Destination Service.
73+
_telemetry_source: Internal telemetry source identifier. Not intended for external use.
6974
7075
Raises:
7176
DestinationOperationError: If initialization fails.
7277
"""
7378
self._http = http
79+
self._telemetry_source = _telemetry_source
7480

7581
# ---------- Read operations ----------
7682

src/sap_cloud_sdk/destination/client.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,12 @@ class DestinationClient:
9595
```
9696
"""
9797

98-
def __init__(self, http: DestinationHttp, use_default_proxy: bool = False) -> None:
98+
def __init__(
99+
self,
100+
http: DestinationHttp,
101+
use_default_proxy: bool = False,
102+
_telemetry_source: Optional[Module] = None,
103+
) -> None:
99104
"""Initialize DestinationClient with dependency injection.
100105
101106
Note:
@@ -108,13 +113,15 @@ def __init__(self, http: DestinationHttp, use_default_proxy: bool = False) -> No
108113
use_default_proxy: Whether to use the default transparent proxy for all get operations.
109114
When True, will attempt to load transparent proxy configuration from
110115
APPFND_CONHOS_TRANSP_PROXY environment variable. Defaults to False.
116+
_telemetry_source: Internal telemetry source identifier. Not intended for external use.
111117
112118
Raises:
113119
DestinationOperationError: If initialization fails.
114120
"""
115121
self._http = http
116122
self._client_proxy_enabled = use_default_proxy
117123
self._transparent_proxy = load_transparent_proxy()
124+
self._telemetry_source = _telemetry_source
118125

119126
def set_proxy(self, transparent_proxy: TransparentProxy) -> None:
120127
"""Set or update the transparent proxy configuration for this client.

src/sap_cloud_sdk/destination/fragment_client.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,16 +57,22 @@ class FragmentClient:
5757
```
5858
"""
5959

60-
def __init__(self, http: DestinationHttp) -> None:
60+
def __init__(
61+
self,
62+
http: DestinationHttp,
63+
_telemetry_source: Optional[Module] = None,
64+
) -> None:
6165
"""Initialize FragmentClient with dependency injection.
6266
6367
Args:
6468
http: Configured HTTP transport for the Destination Service.
69+
_telemetry_source: Internal telemetry source identifier. Not intended for external use.
6570
6671
Raises:
6772
DestinationOperationError: If initialization fails.
6873
"""
6974
self._http = http
75+
self._telemetry_source = _telemetry_source
7076

7177
# ---------- Read operations ----------
7278

0 commit comments

Comments
 (0)