Skip to content

Commit b82b0e7

Browse files
committed
fix serialization on telemetry strings and add helper to add available user information to spans
1 parent 8a0b6cb commit b82b0e7

File tree

5 files changed

+39
-6
lines changed

5 files changed

+39
-6
lines changed

guardrails/telemetry/common.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import json
22
from typing import Any, Callable, Dict, Optional, Union
3+
from opentelemetry.baggage import get_baggage
34
from opentelemetry import context
45
from opentelemetry.context import Context
56
from opentelemetry.trace import Tracer, Span
@@ -103,3 +104,23 @@ def wrapped_func(*args: Any, **kwargs: Any) -> Any:
103104
context.detach(token)
104105

105106
return wrapped_func
107+
108+
109+
def add_user_attributes(span: Span):
110+
try:
111+
client_ip = get_baggage("client.ip") or "unknown"
112+
user_agent = get_baggage("http.user_agent") or "unknown"
113+
referrer = get_baggage("http.referrer") or "unknown"
114+
user_id = get_baggage("user.id") or "unknown"
115+
organization = get_baggage("organization") or "unknown"
116+
app = get_baggage("app") or "unknown"
117+
118+
span.set_attribute("client.ip", client_ip)
119+
span.set_attribute("http.user_agent", user_agent)
120+
span.set_attribute("http.referrer", referrer)
121+
span.set_attribute("user.id", user_id)
122+
span.set_attribute("organization", organization)
123+
span.set_attribute("app", app)
124+
except Exception as e:
125+
logger.warning("Error loading baggage user information", e)
126+
pass

guardrails/telemetry/guard_tracing.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
from guardrails.classes.output_type import OT
2020
from guardrails.classes.validation_outcome import ValidationOutcome
2121
from guardrails.telemetry.open_inference import trace_operation
22+
from guardrails.telemetry.common import add_user_attributes
2223
from guardrails.version import GUARDRAILS_VERSION
2324

2425

@@ -141,6 +142,7 @@ def trace_stream_guard(
141142
# FIXME: This should only be called once;
142143
# Accumulate the validated output and call at the end
143144
add_guard_attributes(guard_span, history, res)
145+
add_user_attributes(guard_span)
144146
yield res
145147
except StopIteration:
146148
next_exists = False
@@ -175,6 +177,7 @@ def trace_guard_execution(
175177
):
176178
return trace_stream_guard(guard_span, result, history)
177179
add_guard_attributes(guard_span, history, result)
180+
add_user_attributes(guard_span)
178181
return result
179182
except Exception as e:
180183
guard_span.set_status(status=StatusCode.ERROR, description=str(e))
@@ -193,6 +196,7 @@ async def trace_async_stream_guard(
193196
try:
194197
res = await anext(result) # type: ignore
195198
add_guard_attributes(guard_span, history, res)
199+
add_user_attributes(guard_span)
196200
yield res
197201
except StopIteration:
198202
next_exists = False
@@ -244,9 +248,11 @@ async def trace_async_guard_execution(
244248
if inspect.isawaitable(result):
245249
res = await result
246250
add_guard_attributes(guard_span, history, res) # type: ignore
251+
add_user_attributes(guard_span)
247252
return res
248253
except Exception as e:
249254
guard_span.set_status(status=StatusCode.ERROR, description=str(e))
255+
add_user_attributes(guard_span)
250256
raise e
251257
else:
252258
return await _execute_fn(*args, **kwargs)

guardrails/telemetry/open_inference.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
from typing import Any, Dict, List, Optional
22

3-
from guardrails.telemetry.common import get_span, to_dict
4-
from guardrails.utils.serialization_utils import serialize
3+
from guardrails.telemetry.common import get_span, to_dict, serialize
54

65

76
def trace_operation(

guardrails/telemetry/runner_tracing.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,8 @@
1717
from guardrails.classes.output_type import OT
1818
from guardrails.classes.validation_outcome import ValidationOutcome
1919
from guardrails.stores.context import get_guard_name
20-
from guardrails.telemetry.common import get_tracer
20+
from guardrails.telemetry.common import get_tracer, add_user_attributes, serialize
2121
from guardrails.utils.safe_get import safe_get
22-
from guardrails.utils.serialization_utils import serialize
2322
from guardrails.version import GUARDRAILS_VERSION
2423

2524

@@ -73,10 +72,12 @@ def trace_step_wrapper(*args, **kwargs) -> Iteration:
7372
try:
7473
response = fn(*args, **kwargs)
7574
add_step_attributes(step_span, response, *args, **kwargs)
75+
add_user_attributes(step_span)
7676
return response
7777
except Exception as e:
7878
step_span.set_status(status=StatusCode.ERROR, description=str(e))
7979
add_step_attributes(step_span, None, *args, **kwargs)
80+
add_user_attributes(step_span)
8081
raise e
8182
else:
8283
return fn(*args, **kwargs)
@@ -112,6 +113,7 @@ def trace_stream_step_generator(
112113
call = safe_get(args, 8, kwargs.get("call_log", None))
113114
iteration = call.iterations.last if call else None
114115
add_step_attributes(step_span, iteration, *args, **kwargs)
116+
add_user_attributes(step_span)
115117
if exception:
116118
raise exception
117119

@@ -145,10 +147,12 @@ async def trace_async_step_wrapper(*args, **kwargs) -> Iteration:
145147
) as step_span:
146148
try:
147149
response = await fn(*args, **kwargs)
150+
add_user_attributes(step_span)
148151
add_step_attributes(step_span, response, *args, **kwargs)
149152
return response
150153
except Exception as e:
151154
step_span.set_status(status=StatusCode.ERROR, description=str(e))
155+
add_user_attributes(step_span)
152156
add_step_attributes(step_span, None, *args, **kwargs)
153157
raise e
154158

guardrails/telemetry/validator_tracing.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,10 @@
1313

1414
from guardrails.settings import settings
1515
from guardrails.classes.validation.validation_result import ValidationResult
16-
from guardrails.telemetry.common import get_tracer
16+
from guardrails.telemetry.common import get_tracer, add_user_attributes, serialize
1717
from guardrails.telemetry.open_inference import trace_operation
1818
from guardrails.utils.casting_utils import to_string
1919
from guardrails.utils.safe_get import safe_get
20-
from guardrails.utils.serialization_utils import serialize
2120
from guardrails.version import GUARDRAILS_VERSION
2221

2322

@@ -106,6 +105,7 @@ def trace_validator_wrapper(*args, **kwargs):
106105
) as validator_span:
107106
try:
108107
resp = fn(*args, **kwargs)
108+
add_user_attributes(validator_span)
109109
add_validator_attributes(
110110
*args,
111111
validator_span=validator_span,
@@ -122,6 +122,7 @@ def trace_validator_wrapper(*args, **kwargs):
122122
validator_span.set_status(
123123
status=StatusCode.ERROR, description=str(e)
124124
)
125+
add_user_attributes(validator_span)
125126
add_validator_attributes(
126127
*args,
127128
validator_span=validator_span,
@@ -168,6 +169,7 @@ async def trace_validator_wrapper(*args, **kwargs):
168169
) as validator_span:
169170
try:
170171
resp = await fn(*args, **kwargs)
172+
add_user_attributes(validator_span)
171173
add_validator_attributes(
172174
*args,
173175
validator_span=validator_span,
@@ -184,6 +186,7 @@ async def trace_validator_wrapper(*args, **kwargs):
184186
validator_span.set_status(
185187
status=StatusCode.ERROR, description=str(e)
186188
)
189+
add_user_attributes(validator_span)
187190
add_validator_attributes(
188191
*args,
189192
validator_span=validator_span,

0 commit comments

Comments
 (0)