Skip to content

Add GUARDRAIL span kind to arize tracing #1223

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 25 commits into from
Feb 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
2e91405
- Add OpenInference span kind attribute to Guardrails telemetry spans.
abhishek9sharma Jan 25, 2025
42073fa
Merge pull request #5 from abhishek9sharma/feat/add_span_type
abhishek9sharma Jan 25, 2025
d975a5c
Make openinference an optional dependency
CalebCourier Feb 13, 2025
d5086c9
Make openinference an optional dependency
CalebCourier Feb 13, 2025
49fd872
Make openinference an optional dependency
CalebCourier Feb 13, 2025
2e367af
Make openinference an optional dependency
CalebCourier Feb 13, 2025
8dcf880
Make openinference an optional dependency
CalebCourier Feb 13, 2025
09070d9
Make openinference an optional dependency
CalebCourier Feb 13, 2025
527ef42
Make openinference an optional dependency
CalebCourier Feb 13, 2025
cedbf21
Make openinference an optional dependency
CalebCourier Feb 13, 2025
32e7183
remove duplicate import
CalebCourier Feb 13, 2025
97f3abc
Make openinference an optional dependency
CalebCourier Feb 13, 2025
f86be8f
Make openinference an optional dependency
CalebCourier Feb 13, 2025
db99101
Make openinference an optional dependency
CalebCourier Feb 13, 2025
efa9d13
Make openinference an optional dependency
CalebCourier Feb 13, 2025
2d98002
Make openinference an optional dependency
CalebCourier Feb 13, 2025
4031762
Make openinference an optional dependency
CalebCourier Feb 13, 2025
824d584
Make openinference an optional dependency
CalebCourier Feb 13, 2025
b8fd754
Formatting
CalebCourier Feb 13, 2025
e8e4928
Formatting
CalebCourier Feb 13, 2025
e8077ed
formatting
CalebCourier Feb 13, 2025
fa0e234
type ignore optional dep
CalebCourier Feb 13, 2025
d25ecd7
type ignore optional dep
CalebCourier Feb 13, 2025
1ca9ef7
type ignore optional dep
CalebCourier Feb 13, 2025
9ab4123
type ignore optional dep
CalebCourier Feb 13, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 20 additions & 2 deletions guardrails/telemetry/guard_tracing.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
Union,
)

try:
from openinference.semconv.trace import SpanAttributes # type: ignore
except ImportError:
SpanAttributes = None
from opentelemetry import context, trace
from opentelemetry.trace import StatusCode, Tracer, Span, Link, get_tracer

Expand Down Expand Up @@ -153,6 +157,10 @@ def trace_stream_guard(
guard_span = new_span
add_guard_attributes(guard_span, history, res)
add_user_attributes(guard_span)
if SpanAttributes is not None:
new_span.set_attribute(
SpanAttributes.OPENINFERENCE_SPAN_KIND, "GUARDRAIL"
)
yield res
except StopIteration:
next_exists = False
Expand All @@ -179,7 +187,10 @@ def trace_guard_execution(
guard_span.set_attribute("guardrails.version", GUARDRAILS_VERSION)
guard_span.set_attribute("type", "guardrails/guard")
guard_span.set_attribute("guard.name", guard_name)

if SpanAttributes is not None:
guard_span.set_attribute(
SpanAttributes.OPENINFERENCE_SPAN_KIND, "GUARDRAIL"
)
try:
result = _execute_fn(*args, **kwargs)
if isinstance(result, Iterator) and not isinstance(
Expand Down Expand Up @@ -218,6 +229,10 @@ async def trace_async_stream_guard(

add_guard_attributes(guard_span, history, res)
add_user_attributes(guard_span)
if SpanAttributes is not None:
guard_span.set_attribute(
SpanAttributes.OPENINFERENCE_SPAN_KIND, "GUARDRAIL"
)
yield res
except StopIteration:
next_exists = False
Expand Down Expand Up @@ -259,7 +274,10 @@ async def trace_async_guard_execution(
guard_span.set_attribute("guardrails.version", GUARDRAILS_VERSION)
guard_span.set_attribute("type", "guardrails/guard")
guard_span.set_attribute("guard.name", guard_name)

if SpanAttributes is not None:
guard_span.set_attribute(
SpanAttributes.OPENINFERENCE_SPAN_KIND, "GUARDRAIL"
)
try:
result = await _execute_fn(*args, **kwargs)
if isinstance(result, AsyncIterator):
Expand Down
8 changes: 7 additions & 1 deletion guardrails/telemetry/open_inference.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@
redact,
)

try:
from openinference.semconv.trace import SpanAttributes # type: ignore
except ImportError:
SpanAttributes = None


def trace_operation(
*,
Expand Down Expand Up @@ -82,7 +87,8 @@ def trace_llm_call(

if current_span is None:
return

if SpanAttributes is not None:
current_span.set_attribute(SpanAttributes.OPENINFERENCE_SPAN_KIND, "GUARDRAIL")
ser_function_call = serialize(function_call)
if ser_function_call:
current_span.set_attribute("llm.function_call", ser_function_call)
Expand Down
18 changes: 18 additions & 0 deletions guardrails/telemetry/runner_tracing.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@
Optional,
)

try:
from openinference.semconv.trace import SpanAttributes # type: ignore
except ImportError:
SpanAttributes = None

from opentelemetry import context, trace
from opentelemetry.trace import StatusCode, Span

Expand Down Expand Up @@ -83,6 +88,10 @@ def trace_step_wrapper(*args, **kwargs) -> Iteration:
name="step", # type: ignore
context=current_otel_context, # type: ignore
) as step_span:
if SpanAttributes is not None:
step_span.set_attribute(
SpanAttributes.OPENINFERENCE_SPAN_KIND, "GUARDRAIL"
)
try:
response = fn(*args, **kwargs)
add_step_attributes(step_span, response, *args, **kwargs)
Expand Down Expand Up @@ -111,6 +120,8 @@ def trace_stream_step_generator(
name="step", # type: ignore
context=current_otel_context, # type: ignore
) as step_span:
if SpanAttributes is not None:
step_span.set_attribute(SpanAttributes.OPENINFERENCE_SPAN_KIND, "GUARDRAIL")
try:
gen = fn(*args, **kwargs)
next_exists = True
Expand Down Expand Up @@ -157,10 +168,15 @@ async def trace_async_step_wrapper(*args, **kwargs) -> Iteration:
name="step", # type: ignore
context=current_otel_context, # type: ignore
) as step_span:
if SpanAttributes is not None:
step_span.set_attribute(
SpanAttributes.OPENINFERENCE_SPAN_KIND, "GUARDRAIL"
)
try:
response = await fn(*args, **kwargs)
add_user_attributes(step_span)
add_step_attributes(step_span, response, *args, **kwargs)

return response
except Exception as e:
step_span.set_status(status=StatusCode.ERROR, description=str(e))
Expand All @@ -186,6 +202,8 @@ async def trace_async_stream_step_generator(
name="step", # type: ignore
context=current_otel_context, # type: ignore
) as step_span:
if SpanAttributes is not None:
step_span.set_attribute(SpanAttributes.OPENINFERENCE_SPAN_KIND, "GUARDRAIL")
try:
gen = fn(*args, **kwargs)
next_exists = True
Expand Down
15 changes: 15 additions & 0 deletions guardrails/telemetry/validator_tracing.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@
from opentelemetry import context, trace
from opentelemetry.trace import StatusCode, Tracer, Span

try:
from openinference.semconv.trace import SpanAttributes # type: ignore
except ImportError:
SpanAttributes = None


from guardrails.settings import settings
from guardrails.classes.validation.validation_result import ValidationResult
Expand Down Expand Up @@ -103,6 +108,11 @@ def trace_validator_wrapper(*args, **kwargs):
name=validator_span_name, # type: ignore
context=current_otel_context, # type: ignore
) as validator_span:
if SpanAttributes is not None:
validator_span.set_attribute(
SpanAttributes.OPENINFERENCE_SPAN_KIND, "GUARDRAIL"
)

try:
resp = fn(*args, **kwargs)
add_user_attributes(validator_span)
Expand Down Expand Up @@ -167,6 +177,11 @@ async def trace_validator_wrapper(*args, **kwargs):
name=validator_span_name, # type: ignore
context=current_otel_context, # type: ignore
) as validator_span:
if SpanAttributes is not None:
validator_span.set_attribute(
SpanAttributes.OPENINFERENCE_SPAN_KIND, "GUARDRAIL"
) # 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

try:
resp = await fn(*args, **kwargs)
add_user_attributes(validator_span)
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "guardrails-ai"
version = "0.6.2"
version = "0.6.3"
description = "Adding guardrails to large language models."
authors = ["Guardrails AI <contact@guardrailsai.com>"]
license = "Apache License 2.0"
Expand Down
Loading