Skip to content

Commit 20109aa

Browse files
lmolkoval0lawrence
authored andcommitted
AzMon exporter: Serialize complex log bodies to json and set dependency type to gen_ai.system instead of N/A (Azure#37694)
* Serialize complex log bodies to json and support gen_ai.system
1 parent 99faf6a commit 20109aa

File tree

103 files changed

+1981
-2107
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

103 files changed

+1981
-2107
lines changed

sdk/monitor/azure-monitor-opentelemetry-exporter/CHANGELOG.md

+5-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66

77
### Breaking Changes
88

9+
- Serialize complex objects provided as log or event bodies to JSON and
10+
fall back to string representation if they are not serializable.
11+
([37694](https://github.com/Azure/azure-sdk-for-python/pull/37694))
12+
913
### Bugs Fixed
1014

1115
### Other Changes
@@ -486,7 +490,7 @@
486490
([#78](https://github.com/microsoft/opentelemetry-azure-monitor-python/pull/78))
487491
- Handle status 439 - Too Many Requests over extended time
488492
([#80](https://github.com/microsoft/opentelemetry-azure-monitor-python/pull/80))
489-
- Fix breaking changes from OT release 0.7b.0
493+
- Fix breaking changes from OT release 0.7b.0
490494
([#86](https://github.com/microsoft/opentelemetry-azure-monitor-python/pull/86))
491495

492496
## 0.2b.0 (2020-03-31)
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__path__ = __import__('pkgutil').extend_path(__path__, __name__)
1+
__path__ = __import__("pkgutil").extend_path(__path__, __name__)
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__path__ = __import__('pkgutil').extend_path(__path__, __name__) # type: ignore
1+
__path__ = __import__("pkgutil").extend_path(__path__, __name__) # type: ignore

sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/_connection_string_parser.py

+9-33
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,7 @@
1010

1111
# Validate UUID format
1212
# Specs taken from https://tools.ietf.org/html/rfc4122
13-
uuid_regex_pattern = re.compile(
14-
"^[0-9a-f]{8}-"
15-
"[0-9a-f]{4}-"
16-
"[0-9a-f]{4}-"
17-
"[0-9a-f]{4}-"
18-
"[0-9a-f]{12}$"
19-
)
13+
uuid_regex_pattern = re.compile("^[0-9a-f]{8}-" "[0-9a-f]{4}-" + "[0-9a-f]{4}-" "[0-9a-f]{4}-" "[0-9a-f]{12}$")
2014

2115

2216
class ConnectionStringParser:
@@ -27,10 +21,7 @@ class ConnectionStringParser:
2721
:rtype: None
2822
"""
2923

30-
def __init__(
31-
self,
32-
connection_string: typing.Optional[str] = None
33-
) -> None:
24+
def __init__(self, connection_string: typing.Optional[str] = None) -> None:
3425
self.instrumentation_key = None
3526
self.endpoint = ""
3627
self.live_endpoint = ""
@@ -42,9 +33,7 @@ def _initialize(self) -> None:
4233
# connection string and ikey
4334
code_cs = self._parse_connection_string(self._connection_string)
4435
code_ikey = self.instrumentation_key
45-
env_cs = self._parse_connection_string(
46-
os.getenv("APPLICATIONINSIGHTS_CONNECTION_STRING")
47-
)
36+
env_cs = self._parse_connection_string(os.getenv("APPLICATIONINSIGHTS_CONNECTION_STRING"))
4837
env_ikey = os.getenv("APPINSIGHTS_INSTRUMENTATIONKEY")
4938

5039
# The priority of which value takes on the instrumentation key is:
@@ -53,27 +42,19 @@ def _initialize(self) -> None:
5342
# 3. Key from connection string in environment variable
5443
# 4. Key from instrumentation key in environment variable
5544
self.instrumentation_key = (
56-
code_cs.get(INSTRUMENTATION_KEY) # type: ignore
57-
or code_ikey
58-
or env_cs.get(INSTRUMENTATION_KEY)
59-
or env_ikey
45+
code_cs.get(INSTRUMENTATION_KEY) or code_ikey or env_cs.get(INSTRUMENTATION_KEY) or env_ikey # type: ignore
6046
)
6147
# The priority of the endpoints is as follows:
6248
# 1. The endpoint explicitly passed in connection string
6349
# 2. The endpoint from the connection string in environment variable
6450
# 3. The default breeze endpoint
6551
self.endpoint = (
66-
code_cs.get(INGESTION_ENDPOINT)
67-
or env_cs.get(INGESTION_ENDPOINT)
68-
or "https://dc.services.visualstudio.com"
52+
code_cs.get(INGESTION_ENDPOINT) or env_cs.get(INGESTION_ENDPOINT) or "https://dc.services.visualstudio.com"
6953
)
7054
self.live_endpoint = (
71-
code_cs.get(LIVE_ENDPOINT)
72-
or env_cs.get(LIVE_ENDPOINT)
73-
or "https://rt.services.visualstudio.com"
55+
code_cs.get(LIVE_ENDPOINT) or env_cs.get(LIVE_ENDPOINT) or "https://rt.services.visualstudio.com"
7456
)
7557

76-
7758
def _validate_instrumentation_key(self) -> None:
7859
"""Validates the instrumentation key used for Azure Monitor.
7960
@@ -84,8 +65,7 @@ def _validate_instrumentation_key(self) -> None:
8465
raise ValueError("Instrumentation key cannot be none or empty.")
8566
match = uuid_regex_pattern.match(self.instrumentation_key)
8667
if not match:
87-
raise ValueError(
88-
"Invalid instrumentation key. It should be a valid UUID.")
68+
raise ValueError("Invalid instrumentation key. It should be a valid UUID.")
8969

9070
def _parse_connection_string(self, connection_string) -> typing.Dict:
9171
if connection_string is None:
@@ -117,17 +97,13 @@ def _parse_connection_string(self, connection_string) -> typing.Dict:
11797
# Construct the endpoints if not passed in explicitly
11898
if result.get(INGESTION_ENDPOINT) is None:
11999
if endpoint_suffix:
120-
result[INGESTION_ENDPOINT] = "https://{0}dc.{1}".format(
121-
location_prefix, endpoint_suffix
122-
)
100+
result[INGESTION_ENDPOINT] = "https://{0}dc.{1}".format(location_prefix, endpoint_suffix)
123101
else:
124102
# Default to None if cannot construct
125103
result[INGESTION_ENDPOINT] = None
126104
if result.get(LIVE_ENDPOINT) is None:
127105
if endpoint_suffix:
128-
result[LIVE_ENDPOINT] = "https://{0}live.{1}".format(
129-
location_prefix, endpoint_suffix
130-
)
106+
result[LIVE_ENDPOINT] = "https://{0}live.{1}".format(location_prefix, endpoint_suffix)
131107
else:
132108
result[LIVE_ENDPOINT] = None
133109

sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/_constants.py

+3-4
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@
77
# Environment variables
88

99
_APPLICATIONINSIGHTS_STATSBEAT_DISABLED_ALL = "APPLICATIONINSIGHTS_STATSBEAT_DISABLED_ALL"
10-
_APPLICATIONINSIGHTS_OPENTELEMETRY_RESOURCE_METRIC_DISABLED = \
10+
_APPLICATIONINSIGHTS_OPENTELEMETRY_RESOURCE_METRIC_DISABLED = (
1111
"APPLICATIONINSIGHTS_OPENTELEMETRY_RESOURCE_METRIC_DISABLED"
12+
)
1213
_APPLICATIONINSIGHTS_METRIC_NAMESPACE_OPT_IN = "APPLICATIONINSIGHTS_METRIC_NAMESPACE_OPT_IN"
1314

1415
# RPs
@@ -22,9 +23,7 @@
2223

2324
# Network
2425

25-
_INVALID_STATUS_CODES = (
26-
400, # Invalid Instrumentation Key/data
27-
)
26+
_INVALID_STATUS_CODES = (400,) # Invalid Instrumentation Key/data
2827

2928
_REDIRECT_STATUS_CODES = (
3029
307, # Temporary redirect

sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/_generated/__init__.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@
77
# --------------------------------------------------------------------------
88

99
from ._azure_monitor_client import AzureMonitorClient
10-
__all__ = ['AzureMonitorClient']
10+
11+
__all__ = ["AzureMonitorClient"]
1112

1213
# `._patch.py` is used for handwritten extensions to the generated code
1314
# Example: https://github.com/Azure/azure-sdk-for-python/blob/main/doc/dev/customize_code/how-to-patch-sdk-code.md
1415
from ._patch import patch_sdk
16+
1517
patch_sdk()

sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/_generated/_azure_monitor_client.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
from azure.core.rest import HttpRequest, HttpResponse
2525

26+
2627
class AzureMonitorClient(AzureMonitorClientOperationsMixin):
2728
"""OpenTelemetry Exporter for Azure Monitor.
2829
@@ -37,7 +38,7 @@ def __init__(
3738
**kwargs # type: Any
3839
):
3940
# type: (...) -> None
40-
_base_url = '{Host}/v2.1'
41+
_base_url = "{Host}/v2.1"
4142
self._config = AzureMonitorClientConfiguration(host=host, **kwargs)
4243
self._client = PipelineClient(base_url=_base_url, config=self._config, **kwargs)
4344

@@ -46,7 +47,6 @@ def __init__(
4647
self._deserialize = Deserializer(client_models)
4748
self._serialize.client_side_validation = False
4849

49-
5050
def _send_request(
5151
self,
5252
request, # type: HttpRequest
@@ -72,7 +72,7 @@ def _send_request(
7272

7373
request_copy = deepcopy(request)
7474
path_format_arguments = {
75-
"Host": self._serialize.url("self._config.host", self._config.host, 'str', skip_quote=True),
75+
"Host": self._serialize.url("self._config.host", self._config.host, "str", skip_quote=True),
7676
}
7777

7878
request_copy.url = self._client.format_url(request_copy.url, **path_format_arguments)

sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/_generated/_configuration.py

+12-12
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
VERSION = "unknown"
1919

20+
2021
class AzureMonitorClientConfiguration(Configuration): # pylint: disable=too-many-instance-attributes
2122
"""Configuration for AzureMonitorClient.
2223
@@ -39,20 +40,19 @@ def __init__(
3940
raise ValueError("Parameter 'host' must not be None.")
4041

4142
self.host = host
42-
kwargs.setdefault('sdk_moniker', 'azuremonitorclient/{}'.format(VERSION))
43+
kwargs.setdefault("sdk_moniker", "azuremonitorclient/{}".format(VERSION))
4344
self._configure(**kwargs)
4445

4546
def _configure(
46-
self,
47-
**kwargs # type: Any
47+
self, **kwargs # type: Any
4848
):
4949
# type: (...) -> None
50-
self.user_agent_policy = kwargs.get('user_agent_policy') or policies.UserAgentPolicy(**kwargs)
51-
self.headers_policy = kwargs.get('headers_policy') or policies.HeadersPolicy(**kwargs)
52-
self.proxy_policy = kwargs.get('proxy_policy') or policies.ProxyPolicy(**kwargs)
53-
self.logging_policy = kwargs.get('logging_policy') or policies.NetworkTraceLoggingPolicy(**kwargs)
54-
self.http_logging_policy = kwargs.get('http_logging_policy') or policies.HttpLoggingPolicy(**kwargs)
55-
self.retry_policy = kwargs.get('retry_policy') or policies.RetryPolicy(**kwargs)
56-
self.custom_hook_policy = kwargs.get('custom_hook_policy') or policies.CustomHookPolicy(**kwargs)
57-
self.redirect_policy = kwargs.get('redirect_policy') or policies.RedirectPolicy(**kwargs)
58-
self.authentication_policy = kwargs.get('authentication_policy')
50+
self.user_agent_policy = kwargs.get("user_agent_policy") or policies.UserAgentPolicy(**kwargs)
51+
self.headers_policy = kwargs.get("headers_policy") or policies.HeadersPolicy(**kwargs)
52+
self.proxy_policy = kwargs.get("proxy_policy") or policies.ProxyPolicy(**kwargs)
53+
self.logging_policy = kwargs.get("logging_policy") or policies.NetworkTraceLoggingPolicy(**kwargs)
54+
self.http_logging_policy = kwargs.get("http_logging_policy") or policies.HttpLoggingPolicy(**kwargs)
55+
self.retry_policy = kwargs.get("retry_policy") or policies.RetryPolicy(**kwargs)
56+
self.custom_hook_policy = kwargs.get("custom_hook_policy") or policies.CustomHookPolicy(**kwargs)
57+
self.redirect_policy = kwargs.get("redirect_policy") or policies.RedirectPolicy(**kwargs)
58+
self.authentication_policy = kwargs.get("authentication_policy")

sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/_generated/_patch.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@
2525
#
2626
# --------------------------------------------------------------------------
2727

28+
2829
# This file is used for handwritten extensions to the generated code. Example:
2930
# https://github.com/Azure/azure-sdk-for-python/blob/main/doc/dev/customize_code/how-to-patch-sdk-code.md
3031
def patch_sdk():
31-
pass
32+
pass

sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/_generated/_vendor.py

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
from azure.core.pipeline.transport import HttpRequest
99

10+
1011
def _convert_request(request, files=None):
1112
data = request.content if not files else None
1213
request = HttpRequest(method=request.method, url=request.url, headers=request.headers, data=data)

sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/_generated/aio/__init__.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@
77
# --------------------------------------------------------------------------
88

99
from ._azure_monitor_client import AzureMonitorClient
10-
__all__ = ['AzureMonitorClient']
10+
11+
__all__ = ["AzureMonitorClient"]
1112

1213
# `._patch.py` is used for handwritten extensions to the generated code
1314
# Example: https://github.com/Azure/azure-sdk-for-python/blob/main/doc/dev/customize_code/how-to-patch-sdk-code.md
1415
from ._patch import patch_sdk
16+
1517
patch_sdk()

sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/_generated/aio/_azure_monitor_client.py

+5-13
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
from ._configuration import AzureMonitorClientConfiguration
1919
from .operations import AzureMonitorClientOperationsMixin
2020

21+
2122
class AzureMonitorClient(AzureMonitorClientOperationsMixin):
2223
"""OpenTelemetry Exporter for Azure Monitor.
2324
@@ -26,12 +27,8 @@ class AzureMonitorClient(AzureMonitorClientOperationsMixin):
2627
:type host: str
2728
"""
2829

29-
def __init__(
30-
self,
31-
host: str = "https://dc.services.visualstudio.com",
32-
**kwargs: Any
33-
) -> None:
34-
_base_url = '{Host}/v2.1'
30+
def __init__(self, host: str = "https://dc.services.visualstudio.com", **kwargs: Any) -> None:
31+
_base_url = "{Host}/v2.1"
3532
self._config = AzureMonitorClientConfiguration(host=host, **kwargs)
3633
self._client = AsyncPipelineClient(base_url=_base_url, config=self._config, **kwargs)
3734

@@ -40,12 +37,7 @@ def __init__(
4037
self._deserialize = Deserializer(client_models)
4138
self._serialize.client_side_validation = False
4239

43-
44-
def _send_request(
45-
self,
46-
request: HttpRequest,
47-
**kwargs: Any
48-
) -> Awaitable[AsyncHttpResponse]:
40+
def _send_request(self, request: HttpRequest, **kwargs: Any) -> Awaitable[AsyncHttpResponse]:
4941
"""Runs the network request through the client's chained policies.
5042
5143
>>> from azure.core.rest import HttpRequest
@@ -65,7 +57,7 @@ def _send_request(
6557

6658
request_copy = deepcopy(request)
6759
path_format_arguments = {
68-
"Host": self._serialize.url("self._config.host", self._config.host, 'str', skip_quote=True),
60+
"Host": self._serialize.url("self._config.host", self._config.host, "str", skip_quote=True),
6961
}
7062

7163
request_copy.url = self._client.format_url(request_copy.url, **path_format_arguments)

sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/_generated/aio/_configuration.py

+13-19
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
VERSION = "unknown"
1515

16+
1617
class AzureMonitorClientConfiguration(Configuration): # pylint: disable=too-many-instance-attributes
1718
"""Configuration for AzureMonitorClient.
1819
@@ -24,29 +25,22 @@ class AzureMonitorClientConfiguration(Configuration): # pylint: disable=too-man
2425
:type host: str
2526
"""
2627

27-
def __init__(
28-
self,
29-
host: str = "https://dc.services.visualstudio.com",
30-
**kwargs: Any
31-
) -> None:
28+
def __init__(self, host: str = "https://dc.services.visualstudio.com", **kwargs: Any) -> None:
3229
super(AzureMonitorClientConfiguration, self).__init__(**kwargs)
3330
if host is None:
3431
raise ValueError("Parameter 'host' must not be None.")
3532

3633
self.host = host
37-
kwargs.setdefault('sdk_moniker', 'azuremonitorclient/{}'.format(VERSION))
34+
kwargs.setdefault("sdk_moniker", "azuremonitorclient/{}".format(VERSION))
3835
self._configure(**kwargs)
3936

40-
def _configure(
41-
self,
42-
**kwargs: Any
43-
) -> None:
44-
self.user_agent_policy = kwargs.get('user_agent_policy') or policies.UserAgentPolicy(**kwargs)
45-
self.headers_policy = kwargs.get('headers_policy') or policies.HeadersPolicy(**kwargs)
46-
self.proxy_policy = kwargs.get('proxy_policy') or policies.ProxyPolicy(**kwargs)
47-
self.logging_policy = kwargs.get('logging_policy') or policies.NetworkTraceLoggingPolicy(**kwargs)
48-
self.http_logging_policy = kwargs.get('http_logging_policy') or policies.HttpLoggingPolicy(**kwargs)
49-
self.retry_policy = kwargs.get('retry_policy') or policies.AsyncRetryPolicy(**kwargs)
50-
self.custom_hook_policy = kwargs.get('custom_hook_policy') or policies.CustomHookPolicy(**kwargs)
51-
self.redirect_policy = kwargs.get('redirect_policy') or policies.AsyncRedirectPolicy(**kwargs)
52-
self.authentication_policy = kwargs.get('authentication_policy')
37+
def _configure(self, **kwargs: Any) -> None:
38+
self.user_agent_policy = kwargs.get("user_agent_policy") or policies.UserAgentPolicy(**kwargs)
39+
self.headers_policy = kwargs.get("headers_policy") or policies.HeadersPolicy(**kwargs)
40+
self.proxy_policy = kwargs.get("proxy_policy") or policies.ProxyPolicy(**kwargs)
41+
self.logging_policy = kwargs.get("logging_policy") or policies.NetworkTraceLoggingPolicy(**kwargs)
42+
self.http_logging_policy = kwargs.get("http_logging_policy") or policies.HttpLoggingPolicy(**kwargs)
43+
self.retry_policy = kwargs.get("retry_policy") or policies.AsyncRetryPolicy(**kwargs)
44+
self.custom_hook_policy = kwargs.get("custom_hook_policy") or policies.CustomHookPolicy(**kwargs)
45+
self.redirect_policy = kwargs.get("redirect_policy") or policies.AsyncRedirectPolicy(**kwargs)
46+
self.authentication_policy = kwargs.get("authentication_policy")

sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/_generated/aio/_patch.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@
2525
#
2626
# --------------------------------------------------------------------------
2727

28+
2829
# This file is used for handwritten extensions to the generated code. Example:
2930
# https://github.com/Azure/azure-sdk-for-python/blob/main/doc/dev/customize_code/how-to-patch-sdk-code.md
3031
def patch_sdk():
31-
pass
32+
pass

sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/_generated/aio/operations/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,5 @@
99
from ._azure_monitor_client_operations import AzureMonitorClientOperationsMixin
1010

1111
__all__ = [
12-
'AzureMonitorClientOperationsMixin',
12+
"AzureMonitorClientOperationsMixin",
1313
]

0 commit comments

Comments
 (0)