Skip to content

Commit 41fbbaa

Browse files
committed
Be more explicit about options and warnings
1 parent c197328 commit 41fbbaa

File tree

2 files changed

+86
-22
lines changed

2 files changed

+86
-22
lines changed

instrumentation/opentelemetry-instrumentation-arangodb/src/opentelemetry/instrumentation/arangodb/__init__.py

Lines changed: 71 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,34 @@
22
import json
33
import logging
44
import textwrap
5-
from typing import Any, Callable
5+
from typing import Any, Callable, Union
6+
from urllib.parse import urlparse
67

78
from arango.api import ApiGroup
89
from arango.request import Request
910
from arango.response import Response
1011
from wrapt import wrap_function_wrapper
1112

1213
from opentelemetry import trace
14+
from opentelemetry.instrumentation.arangodb import arangodb_attributes
1315
from opentelemetry.instrumentation.arangodb.package import _instruments
1416
from opentelemetry.instrumentation.arangodb.version import __version__
1517
from opentelemetry.instrumentation.instrumentor import BaseInstrumentor
1618
from opentelemetry.instrumentation.utils import unwrap
17-
from opentelemetry.semconv.attributes import db_attributes, error_attributes
18-
from opentelemetry.trace import SpanKind
19+
from opentelemetry.semconv.attributes import (
20+
db_attributes,
21+
error_attributes,
22+
server_attributes,
23+
)
24+
from opentelemetry.trace import Span, SpanKind
1925
from opentelemetry.trace.status import StatusCode
2026

2127
logger = logging.getLogger(__name__)
2228

2329

2430
class ArangoDBInstrumentor(BaseInstrumentor):
25-
"""An instrumentor for arangodb module
31+
"""An instrumentor for arangodb module.
32+
2633
See `BaseInstrumentor`
2734
"""
2835

@@ -65,7 +72,7 @@ def execute_with_span(
6572
)
6673

6774
with tracer.start_as_current_span(
68-
span_name, kind=SpanKind.CLIENT
75+
span_name, kind=SpanKind.CLIENT, attributes=span_attributes
6976
) as span:
7077
# We install a custom response handler to get access to the raw response,
7178
# before the arango client attempts to convert it to one of many different
@@ -74,9 +81,9 @@ def execute_with_span(
7481

7582
def custom_response_handler(response: Response):
7683
span.set_attributes(self._get_response_attributes(response))
77-
return original_response_handler(response)
84+
self._add_span_events(span, response)
7885

79-
span.set_attributes(span_attributes)
86+
return original_response_handler(response)
8087

8188
try:
8289
result = wrapped(request, custom_response_handler)
@@ -96,8 +103,8 @@ def _get_request_attributes(
96103
attributes = {}
97104

98105
query: str = ""
99-
bind_vars: dict[str, Any] | None = None
100-
options: Any | None = None
106+
bind_vars: Union[dict[str, Any], None] = None
107+
options: Union[Any, None] = None
101108

102109
span_name = f"ArangoDB: {request.method.upper()} {request.endpoint}"
103110

@@ -113,8 +120,12 @@ def _get_request_attributes(
113120
else:
114121
query = str(request.data)
115122

116-
attributes = {
123+
endpoint = urlparse(instance.conn._hosts[0])
124+
125+
attributes: dict[str, Any] = {
117126
db_attributes.DB_SYSTEM_NAME: "arangodb",
127+
server_attributes.SERVER_ADDRESS: endpoint.hostname,
128+
server_attributes.SERVER_PORT: endpoint.port,
118129
db_attributes.DB_NAMESPACE: instance.db_name,
119130
db_attributes.DB_OPERATION_NAME: request.endpoint,
120131
db_attributes.DB_QUERY_TEXT: textwrap.dedent(query.strip("\n")),
@@ -124,7 +135,35 @@ def _get_request_attributes(
124135
for key, value in bind_vars.items():
125136
attributes[f"db.query.parameter.{key}"] = json.dumps(value)
126137

127-
attributes["db.query.options"] = json.dumps(options)
138+
if options and isinstance(options, dict):
139+
if "allowDirtyReads" in options:
140+
attributes[arangodb_attributes.ALLOW_DIRTY_READS] = (
141+
options.get("allowDirtyReads")
142+
)
143+
if "allowRetry" in options:
144+
attributes[arangodb_attributes.ALLOW_RETRY] = options.get(
145+
"allowRetry"
146+
)
147+
if "cache" in options:
148+
attributes[arangodb_attributes.CACHE] = options.get("cache")
149+
if "failOnWarning" in options:
150+
attributes[arangodb_attributes.FAIL_ON_WARNING] = options.get(
151+
"failOnWarning"
152+
)
153+
if "fullCount" in options:
154+
attributes[arangodb_attributes.FULL_COUNT] = options.get(
155+
"fullCount"
156+
)
157+
if "maxRuntime" in options:
158+
attributes[arangodb_attributes.MAX_RUNTIME] = options.get(
159+
"maxRuntime"
160+
)
161+
if "stream" in options:
162+
attributes[arangodb_attributes.STREAM] = options.get("stream")
163+
if "usePlanCache" in options:
164+
attributes[arangodb_attributes.USE_PLAN_CACHE] = options.get(
165+
"usePlanCache"
166+
)
128167

129168
return span_name, attributes
130169

@@ -133,17 +172,27 @@ def _get_response_attributes(self, response: Response) -> dict[str, Any]:
133172
db_attributes.DB_RESPONSE_STATUS_CODE: response.status_code
134173
}
135174

136-
attributes["db.execution.cached"] = response.body.get("cached", False)
175+
if "cached" in response.body:
176+
attributes["arangodb.response.cached"] = response.body.get(
177+
"cached"
178+
)
179+
if "count" in response.body:
180+
attributes["arangodb.response.count"] = response.body.get("count")
181+
if "hasMore" in response.body:
182+
attributes["arangodb.response.hasMore"] = response.body.get(
183+
"hasMore"
184+
)
137185

138-
if (count := response.body.get("count")) is not None:
139-
attributes["db.execution.count"] = count
186+
return attributes
140187

188+
def _add_span_events(self, span: Span, response: Response):
141189
if extra := response.body.get("extra"):
142-
stats = extra.get("stats")
143-
for key, value in stats.items():
144-
attributes["db.execution.stats." + key] = value
145-
146-
warnings = extra.get("warnings")
147-
attributes["db.execution.warnings"] = json.dumps(warnings)
148-
149-
return attributes
190+
if warnings := extra.get("warnings"):
191+
for warning in warnings:
192+
span.add_event(
193+
"ArangoDB Warning",
194+
{
195+
"code": warning.get("code"),
196+
"message": warning.get("message"),
197+
},
198+
)
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
ALLOW_DIRTY_READS = "arangodb.options.allowDirtyReads"
2+
3+
ALLOW_RETRY = "arangodb.options.allowRetry"
4+
5+
CACHE = "arangodb.options.cache"
6+
7+
FAIL_ON_WARNING = "arangodb.options.failOnWarning"
8+
9+
FULL_COUNT = "arangodb.options.fullCount"
10+
11+
MAX_RUNTIME = "arangodb.options.maxRuntime"
12+
13+
STREAM = "arangodb.options.stream"
14+
15+
USE_PLAN_CACHE = "arangodb.options.usePlanCache"

0 commit comments

Comments
 (0)