OpenTelemetry Instrumentation¶
Sentinel AI provides OpenTelemetry support through OpenTelemetryAgentExtension in the sentinel-ai-instrumentation-otel module. The extension hooks into the Sentinel event bus and emits tracing spans for agent invocations and tool execution.
Dependency¶
<dependency>
<groupId>com.phonepe.sentinel-ai</groupId>
<artifactId>sentinel-ai-instrumentation-otel</artifactId>
</dependency>
What gets emitted¶
The extension emits spans that align with the GenAI semantic conventions and follows the OpenTelemetry Semantic conventions
invoke_agent {gen_ai.agent.name}(SpanKind.INTERNAL)execute_tool {gen_ai.tool.name}(SpanKind.INTERNAL)
The extension subscribes to the existing Sentinel event bus and does not require changes in your tools, model, or session storage.
Sensitive data risk
Enabling captureToolCallArguments or captureToolCallResult can record sensitive or regulated data in traces and logs. Enable these options only when necessary, and ensure your telemetry backend has proper redaction, retention, and access controls.
Configure and register¶
import com.phonepe.sentinelai.instrumentation.otel.OpenTelemetryAgentExtension;
import com.phonepe.sentinelai.instrumentation.otel.OpenTelemetryAgentExtensionSetup;
import io.opentelemetry.api.GlobalOpenTelemetry;
final var tracingExtension = OpenTelemetryAgentExtension
.<MyRequest, MyResponse, MyAgent>builder()
.setup(OpenTelemetryAgentExtensionSetup.builder()
.tracer(GlobalOpenTelemetry.getTracer("sentinel-ai"))
.providerName("openai")
.captureToolCallArguments(false)
.captureToolCallResult(false)
.maxActiveSpanDuration(Duration.ofMinutes(10))
.build())
.build();
final var agent = new MyAgent(agentSetup, List.of(tracingExtension), Map.of());
Attributes¶
By default, spans include:
gen_ai.operation.namegen_ai.provider.namegen_ai.agent.namegen_ai.conversation.id(if session id is present)gen_ai.tool.namegen_ai.tool.call.idgen_ai.usage.input_tokensgen_ai.usage.output_tokenserror.type(on errors)
Optional attributes:
gen_ai.tool.call.arguments(captureToolCallArguments=true)gen_ai.tool.call.result(captureToolCallResult=true, only for successful tool calls)
Notes¶
- If terminal lifecycle events are missed, stale run/tool spans are force-closed after
maxActiveSpanDurationwitherror.typeset torun_incomplete/tool_call_incomplete. - Session storage (
SessionStore) remains independent; onlysessionIdis used for trace correlation.