Skip to content

Commit 51b4bc6

Browse files
Add GUARDRAIL span kind to arize tracing (#1223)
* - Add OpenInference span kind attribute to Guardrails telemetry spans. - Updated version to 0.6.3 in pyproject.toml. * Make openinference an optional dependency * Make openinference an optional dependency * Make openinference an optional dependency * Make openinference an optional dependency * Make openinference an optional dependency * Make openinference an optional dependency * Make openinference an optional dependency * Make openinference an optional dependency * remove duplicate import * Make openinference an optional dependency * Make openinference an optional dependency * Make openinference an optional dependency * Make openinference an optional dependency * Make openinference an optional dependency * Make openinference an optional dependency * Make openinference an optional dependency * Formatting * Formatting * formatting * type ignore optional dep * type ignore optional dep * type ignore optional dep * type ignore optional dep --------- Co-authored-by: abhishek9sharma <[email protected]> Co-authored-by: Caleb Courier <[email protected]>
1 parent c48a4ad commit 51b4bc6

File tree

5 files changed

+61
-4
lines changed

5 files changed

+61
-4
lines changed

Diff for: guardrails/telemetry/guard_tracing.py

+20-2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@
1010
Union,
1111
)
1212

13+
try:
14+
from openinference.semconv.trace import SpanAttributes # type: ignore
15+
except ImportError:
16+
SpanAttributes = None
1317
from opentelemetry import context, trace
1418
from opentelemetry.trace import StatusCode, Tracer, Span, Link, get_tracer
1519

@@ -153,6 +157,10 @@ def trace_stream_guard(
153157
guard_span = new_span
154158
add_guard_attributes(guard_span, history, res)
155159
add_user_attributes(guard_span)
160+
if SpanAttributes is not None:
161+
new_span.set_attribute(
162+
SpanAttributes.OPENINFERENCE_SPAN_KIND, "GUARDRAIL"
163+
)
156164
yield res
157165
except StopIteration:
158166
next_exists = False
@@ -179,7 +187,10 @@ def trace_guard_execution(
179187
guard_span.set_attribute("guardrails.version", GUARDRAILS_VERSION)
180188
guard_span.set_attribute("type", "guardrails/guard")
181189
guard_span.set_attribute("guard.name", guard_name)
182-
190+
if SpanAttributes is not None:
191+
guard_span.set_attribute(
192+
SpanAttributes.OPENINFERENCE_SPAN_KIND, "GUARDRAIL"
193+
)
183194
try:
184195
result = _execute_fn(*args, **kwargs)
185196
if isinstance(result, Iterator) and not isinstance(
@@ -218,6 +229,10 @@ async def trace_async_stream_guard(
218229

219230
add_guard_attributes(guard_span, history, res)
220231
add_user_attributes(guard_span)
232+
if SpanAttributes is not None:
233+
guard_span.set_attribute(
234+
SpanAttributes.OPENINFERENCE_SPAN_KIND, "GUARDRAIL"
235+
)
221236
yield res
222237
except StopIteration:
223238
next_exists = False
@@ -259,7 +274,10 @@ async def trace_async_guard_execution(
259274
guard_span.set_attribute("guardrails.version", GUARDRAILS_VERSION)
260275
guard_span.set_attribute("type", "guardrails/guard")
261276
guard_span.set_attribute("guard.name", guard_name)
262-
277+
if SpanAttributes is not None:
278+
guard_span.set_attribute(
279+
SpanAttributes.OPENINFERENCE_SPAN_KIND, "GUARDRAIL"
280+
)
263281
try:
264282
result = await _execute_fn(*args, **kwargs)
265283
if isinstance(result, AsyncIterator):

Diff for: guardrails/telemetry/open_inference.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@
99
redact,
1010
)
1111

12+
try:
13+
from openinference.semconv.trace import SpanAttributes # type: ignore
14+
except ImportError:
15+
SpanAttributes = None
16+
1217

1318
def trace_operation(
1419
*,
@@ -82,7 +87,8 @@ def trace_llm_call(
8287

8388
if current_span is None:
8489
return
85-
90+
if SpanAttributes is not None:
91+
current_span.set_attribute(SpanAttributes.OPENINFERENCE_SPAN_KIND, "GUARDRAIL")
8692
ser_function_call = serialize(function_call)
8793
if ser_function_call:
8894
current_span.set_attribute("llm.function_call", ser_function_call)

Diff for: guardrails/telemetry/runner_tracing.py

+18
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@
88
Optional,
99
)
1010

11+
try:
12+
from openinference.semconv.trace import SpanAttributes # type: ignore
13+
except ImportError:
14+
SpanAttributes = None
15+
1116
from opentelemetry import context, trace
1217
from opentelemetry.trace import StatusCode, Span
1318

@@ -83,6 +88,10 @@ def trace_step_wrapper(*args, **kwargs) -> Iteration:
8388
name="step", # type: ignore
8489
context=current_otel_context, # type: ignore
8590
) as step_span:
91+
if SpanAttributes is not None:
92+
step_span.set_attribute(
93+
SpanAttributes.OPENINFERENCE_SPAN_KIND, "GUARDRAIL"
94+
)
8695
try:
8796
response = fn(*args, **kwargs)
8897
add_step_attributes(step_span, response, *args, **kwargs)
@@ -111,6 +120,8 @@ def trace_stream_step_generator(
111120
name="step", # type: ignore
112121
context=current_otel_context, # type: ignore
113122
) as step_span:
123+
if SpanAttributes is not None:
124+
step_span.set_attribute(SpanAttributes.OPENINFERENCE_SPAN_KIND, "GUARDRAIL")
114125
try:
115126
gen = fn(*args, **kwargs)
116127
next_exists = True
@@ -157,10 +168,15 @@ async def trace_async_step_wrapper(*args, **kwargs) -> Iteration:
157168
name="step", # type: ignore
158169
context=current_otel_context, # type: ignore
159170
) as step_span:
171+
if SpanAttributes is not None:
172+
step_span.set_attribute(
173+
SpanAttributes.OPENINFERENCE_SPAN_KIND, "GUARDRAIL"
174+
)
160175
try:
161176
response = await fn(*args, **kwargs)
162177
add_user_attributes(step_span)
163178
add_step_attributes(step_span, response, *args, **kwargs)
179+
164180
return response
165181
except Exception as e:
166182
step_span.set_status(status=StatusCode.ERROR, description=str(e))
@@ -186,6 +202,8 @@ async def trace_async_stream_step_generator(
186202
name="step", # type: ignore
187203
context=current_otel_context, # type: ignore
188204
) as step_span:
205+
if SpanAttributes is not None:
206+
step_span.set_attribute(SpanAttributes.OPENINFERENCE_SPAN_KIND, "GUARDRAIL")
189207
try:
190208
gen = fn(*args, **kwargs)
191209
next_exists = True

Diff for: guardrails/telemetry/validator_tracing.py

+15
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@
1010
from opentelemetry import context, trace
1111
from opentelemetry.trace import StatusCode, Tracer, Span
1212

13+
try:
14+
from openinference.semconv.trace import SpanAttributes # type: ignore
15+
except ImportError:
16+
SpanAttributes = None
17+
1318

1419
from guardrails.settings import settings
1520
from guardrails.classes.validation.validation_result import ValidationResult
@@ -103,6 +108,11 @@ def trace_validator_wrapper(*args, **kwargs):
103108
name=validator_span_name, # type: ignore
104109
context=current_otel_context, # type: ignore
105110
) as validator_span:
111+
if SpanAttributes is not None:
112+
validator_span.set_attribute(
113+
SpanAttributes.OPENINFERENCE_SPAN_KIND, "GUARDRAIL"
114+
)
115+
106116
try:
107117
resp = fn(*args, **kwargs)
108118
add_user_attributes(validator_span)
@@ -167,6 +177,11 @@ async def trace_validator_wrapper(*args, **kwargs):
167177
name=validator_span_name, # type: ignore
168178
context=current_otel_context, # type: ignore
169179
) as validator_span:
180+
if SpanAttributes is not None:
181+
validator_span.set_attribute(
182+
SpanAttributes.OPENINFERENCE_SPAN_KIND, "GUARDRAIL"
183+
) # see here for a list of span kinds: https://github.com/Arize-ai/openinference/blob/main/python/openinference-semantic-conventions/src/openinference/semconv/trace/__init__.py#L271
184+
170185
try:
171186
resp = await fn(*args, **kwargs)
172187
add_user_attributes(validator_span)

Diff for: pyproject.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "guardrails-ai"
3-
version = "0.6.2"
3+
version = "0.6.3"
44
description = "Adding guardrails to large language models."
55
authors = ["Guardrails AI <[email protected]>"]
66
license = "Apache License 2.0"

0 commit comments

Comments
 (0)