Agent 端到端可观测性:Spring + Oracle 执行链路追踪
完整的 Agent 到数据库调用链的分布式追踪实现,含源码。对使用 Agent 框架的程序员有直接参考价值。
完整的 Agent 到数据库调用链的分布式追踪实现,含源码。对使用 Agent 框架的程序员有直接参考价值。
在 Spring Boot AI 智能体工作负载、Oracle JDBC 和 Oracle AI Database 服务器端执行之间构建一条连续的追踪。
所有源代码、配置、脚本和支持文档都在 GitHub 的 observability 文件夹中。
Oracle AI Database 让追踪能够继续进入数据库服务器端执行,而不是在数据库边界停止。
Spring Boot 和 Micrometer 创建应用追踪上下文,Oracle JDBC 添加数据库客户端 span。
DBMS_OBSERVABILITY 将 Oracle AI Database 服务器端 span 导出到 OpenTelemetry 兼容的可观测工具;本演示使用 Jaeger。
AI 智能体元数据、MODULE、ACTION 和 CLIENT_IDENTIFIER 为安全和审计关联奠定基础。
本演练回答了一个对 AI 智能体应用的实际问题:你能否看到一条追踪,从 AI 智能体请求开始,跨越 Spring Boot 和 JDBC 层,并继续在 Oracle AI Database 内部执行?答案是可以的。利用 Spring Boot、Micrometer、Oracle JDBC 可观测提供商和 DBMS_OBSERVABILITY,同一个请求可以在任何 OpenTelemetry 兼容的可观测后端中显示为应用 span、JDBC span 和 Oracle AI Database 服务器端 span。本演练使用 Jaeger,因为它易于运行且易于检查,但同样的信号可以在任何符合 OpenTelemetry 规范的可观测工具中查看。
那个数据库内部 span 是重要的部分。典型的数据库可观测在数据库边界停止:应用追踪显示 JDBC 等待了数据库,然后用户必须切换工具并手动调查数据库内部。Oracle AI Database 保持追踪连续。开发人员、DevOps 团队和安全审查人员可以看到数据库实际耗时多久,将其与数据库端证据关联起来,并使用同一条追踪进行性能分析、故障排查和安全上下文审查。
视频演练和总结:Tracing from Agents into the Oracle AI Database。
演示应用位于 observability/springboot-oracle-db-otel-demo。它是一个 Spring Boot 应用,有两个主要端点。
预期的追踪形状是:
浏览器或 curl
-> Spring Boot HTTP span
-> Micrometer observation
-> Oracle JDBC 提供商 span
-> Oracle AI Database DB Server span
-> HTTPS OTLP 端点
-> OpenTelemetry 兼容的可观测后端(本演示中为 Jaeger)
演示可以在任何配置充足的 Linux 环境或虚拟机上运行,以容纳 Oracle Database Free、Jaeger、HTTPS 代理和 Spring Boot 应用。你也可以使用 Oracle Cloud 中的 Autonomous Database 代替本地数据库;重要的要求是 JDBC 连接性和一个能够访问 HTTPS OTLP 端点的数据库服务器端导出器。
使用 Oracle Database Free 23.26.2.0 的干净 OCI Linux 虚拟机验证产生了预期的 Spring Boot、Oracle JDBC 和 oracle-db 服务器端 span,无需设置隐藏的 KSTRC 实例参数。下面的常规设置使用文档化的 DBMS_OBSERVABILITY 配置、可到达的 HTTPS OTLP 端点、网络 ACL 和数据库 disttrc 信任钱包。
安装 Java 25、Maven、Git、Podman、curl、jq 和 OpenSSL。
在 Linux 上运行 Oracle Database Free,或在 Oracle Cloud 中配置 Autonomous Database。
从 github.com/oracle-devrel/oracle-ai-for-sustainable-dev 克隆源代码,使用 observability 文件夹。
启动 Jaeger,启用 OTLP HTTP。在示例设置中,Jaeger 在 http://127.0.0.1:4318/v1/traces 接收应用和 JDBC span。
在 Jaeger 的 OTLP 端点前放置一个小的 HTTPS 代理以供数据库服务器端导出。示例使用 NGINX 作为 otel-tls-proxy,将 https://otel-tls-proxy:4318/v1/traces 转发到 Jaeger 的 http://oracle-db-otel-jaeger:4318/v1/traces。
配置 DBMS_OBSERVABILITY、网络 ACL 和数据库钱包/信任路径,以便 Oracle AI Database 可以将服务器端 span 推送到 HTTPS OTLP 端点。
配置、构建和运行 Spring Boot 应用,然后打开 AI 智能体任务视图或调用 JSON 端点生成追踪。
sudo dnf install -y podman git java-25-openjdk java-25-openjdk-devel maven jq curl openssl
export JAVA_HOME=/usr/lib/jvm/java-25-openjdk
export PATH="$JAVA_HOME/bin:$PATH"
git clone https://github.com/oracle-devrel/oracle-ai-for-sustainable-dev.git
cd oracle-ai-for-sustainable-dev/observability/springboot-oracle-db-otel-demo
mvn -DskipTests package
将数据库凭据和运行时端点保存在仓库之外:
export DB_URL='jdbc:oracle:thin:@//127.0.0.1:1521/FREEPDB1'
export DB_USERNAME='FINANCIAL'
export DB_PASSWORD='<app-user-password>'
export OTLP_TRACES_ENDPOINT='http://127.0.0.1:4318/v1/traces'
export TRACE_SAMPLE_PROBABILITY=1.0
export ORACLE_JDBC_SERVER_TELEMETRY_TRACES_ENABLED=true
export ORACLE_JDBC_SERVER_TELEMETRY_LOGGING_ENABLED=false
export ORACLE_JDBC_TRACEPARENT_CLIENT_INFO_ENABLED=true
export ORACLE_JDBC_TRACELEVEL_CLIENT_INFO_ENABLED=true
java -jar target/springboot-oracle-db-otel-demo-0.0.1-SNAPSHOT.jar
curl -sS http://127.0.0.1:8080/trace/roundtrip | jq .
curl -sS \
'http://127.0.0.1:8080/trace/agent-task?agentId=claims-investigator-agent&task=investigate_payment_anomalies' \
| jq .
对于内聚的浏览器视图,打开:
http://127.0.0.1:8080/trace/agent-task/view?agentId=claims-investigator-agent&task=investigate_payment_anomalies
应用使用 Java 25、Maven Central 的 Oracle JDBC 23.26 系列、已发布的 Maven Central ojdbc-provider-observability 工件和 Oracle JDBC 17 生产依赖。
<properties>
<java.version>25</java.version>
<oracle.jdbc.version>23.26.2.0.0</oracle.jdbc.version>
<oracle-database.version>${oracle.jdbc.version}</oracle-database.version>
<ojdbc.provider.observability.version>1.1.0</ojdbc.provider.observability.version>
</properties>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-tracing-bridge-otel</artifactId>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-exporter-otlp</artifactId>
</dependency>
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc17-production</artifactId>
<version>${oracle.jdbc.version}</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc-provider-observability</artifactId>
<version>${ojdbc.provider.observability.version}</version>
</dependency>
Spring Boot Actuator 创建 observation 基础设施,Micrometer 将这些 observation 桥接到 OpenTelemetry,OTLP 导出器将 span 发送到收集器。oracle-database.version 属性保持 Oracle JDBC、UCP、钱包/安全和相关传递工件在 23.26.2.0.0 上的一致性。
Oracle JDBC 可观测性提供商实现 JDBC 驱动程序 TraceEventListener 接口,并将 JDBC 事件发布到 OpenTelemetry。这些事件包括数据库往返和连接行为,具有连接 ID、数据库操作、数据库用户、租户和 SQL ID 等属性。SQL 文本和连接详细信息被视为敏感信息,默认情况下被禁用,除非明确启用。
Oracle JDBC OpenTelemetry 扩展期望应用已经有一个活跃的 OpenTelemetry 上下文。它们本身不创建根应用追踪。在本演示中,Spring Boot Actuator 和 Micrometer 提供 HTTP 和应用 observation,Oracle JDBC 提供商为 JDBC 驱动程序事件(例如数据库往返)添加子 span。提供商还将追踪上下文传播到 Oracle AI Database,以便数据库可以将其服务器端 span 导出到同一条追踪中。
如果你不想直接添加应用仪表化,请使用 OpenTelemetry Java agent 进行零代码 Java 仪表化。Oracle JDBC 扩展随后可以为 JDBC 驱动程序事件添加数据库往返 span 作为当前应用 span 的子级,并将该上下文传播到服务器。
Spring Boot 通过 OTLP HTTP 发送应用和 JDBC span。演示将它们发送到 Jaeger,但同样的 OpenTelemetry 信号可以由任何 OpenTelemetry 兼容的可观测平台收集。Oracle JDBC 提供商属性启用 JDBC 追踪侦听器并在收集器中标识 Java 服务。
spring:
application:
name: springboot-oracle-db-otel-demo
datasource:
url: ${DB_URL}
username: ${DB_USERNAME}
password: ${DB_PASSWORD}
oracleucp:
connection-factory-properties:
"[oracle.jdbc.provider.traceEventListener]": observability-trace-event-listener-provider
"[oracle.jdbc.provider.traceEventListener.unique_identifier]": springboot-oracle-db-otel-demo
management: otlp: tracing: endpoint: ${OTLP_TRACES_ENDPOINT:http://localhost:4318/v1/traces} tracing: sampling: probability: 1.0
## 如何导出数据库服务器端 Span?
数据库服务器端导出器需要一个可访问的 HTTPS OTLP 端点。经过验证的 Linux 演示使用 Jaeger,它在 4318 端口接收 OTLP HTTP,并在其前面放置一个小型 HTTPS 代理,用于数据库服务器端导出。在示例中,该代理是配置了受信任本地证书的 NGINX:
Oracle AI Database -> https://otel-tls-proxy:4318/v1/traces otel-tls-proxy -> http://oracle-db-otel-jaeger:4318/v1/traces
通过更改 OTLP 端点,可以将 Jaeger 替换为其他兼容 OpenTelemetry 的收集器或后端。关键要求是 Oracle AI Database 能够通过 HTTPS 访问该端点,以导出服务器端追踪数据。
使用 DBMS_OBSERVABILITY 配置数据库,向执行 SQL 会话的用户授予网络 ACL 访问权限,并将受信任的钱包放置在分布式追踪导出器所期望的位置:WALLET_ROOT/<PDB_GUID>/disttrc。
begin dbms_observability.add_endpoint( endpoint_type => dbms_observability.otel_traces, endpoint => 'https://otel-tls-proxy:4318/v1/traces', credential_name => null);
dbms_observability.enable_endpoint('https://otel-tls-proxy:4318/v1/traces'); dbms_observability.enable_service_option(dbms_observability.capture_traces); dbms_observability.enable_service_option(dbms_observability.show_extra_metadata); dbms_observability.enable_service(dbms_observability.all_services); end; /
在 Oracle Database Free 23.26.2.0 上进行的一次干净验证表明,文档中所述的 DBMS_OBSERVABILITY 端点设置、HTTPS OTLP 代理、网络 ACL,以及位于 WALLET_ROOT/<PDB_GUID>/disttrc 的信任钱包,已经足以生成数据库服务器端 Span。早期的本地诊断运行曾在调试导出失败时使用隐藏的 KSTRC 参数,但这些设置不属于正常的演示配置。
## JDBC 如何传播追踪上下文?
应用使用已发布的 ojdbc-provider-observability 依赖。目前,在启用追踪之前,需要先强制触发一次服务器遥测状态变更,以便驱动程序将遥测状态搭载传递给数据库。
EnumSet<OracleConnection.ServerTelemetry> requestedTelemetry = EnumSet.of(OracleConnection.ServerTelemetry.Traces);
oracleConnection.setServerTelemetry( EnumSet.noneOf(OracleConnection.ServerTelemetry.class)); oracleConnection.setServerTelemetry(requestedTelemetry);
## 如何让数据库 Span 更有用?
通用的 DB Server Span 可以证明追踪已跨越到数据库中,但该演示通过在 SQL 运行前设置数据库会话字段,让它提供更多有用信息。应用使用 Oracle JDBC 端到端指标 API 设置这些元数据,因此无需仅为设置 MODULE、ACTION 和 CLIENT_IDENTIFIER 而额外执行一次 PL/SQL 往返调用。
String[] metrics = new String[OracleConnection.END_TO_END_STATE_INDEX_MAX]; metrics[OracleConnection.END_TO_END_MODULE_INDEX] = "agent:claims-investigator-agent"; metrics[OracleConnection.END_TO_END_ACTION_INDEX] = "agent-workload-query"; metrics[OracleConnection.END_TO_END_CLIENTID_INDEX] = "traceId=<trace-id>"; metrics[OracleConnection.END_TO_END_ECID_INDEX] = "<trace-id>"; oracleConnection.setEndToEndMetrics(metrics, (short) 0);
随后,在 Jaeger 中,橙色的 oracle-db / DB Server Span 会携带数据库端证据,例如 oracle.db.module、oracle.db.action、oracle.db.session.id、oracle.db.pdb 和 oracle.db.query.sql.id。
其中一些名称也可能出现在客户端 JDBC Span 中,因为驱动程序可以接收数据库元数据,并且应用会主动设置 MODULE、ACTION 和 CLIENT_IDENTIFIER。关键区别在于来源和计时:oracle-db / DB Server Span 由 Oracle AI Database 自身发出,其中附带数据库端持续时间、响应状态、会话上下文,以及服务器视角下该项工作的 SQL 标识。客户端 Span 可以测量 Java 往返耗时,但它自身无法证明同一条追踪中数据库服务器自己的 Span 计时。
## 如何将追踪关联到 SQL 诊断?
该演示会从用于 DBMS_XPLAN 和 SQL Monitor 查询的游标中返回一个规范 SQL ID。Oracle JDBC Span 和数据库导出的 Span 也可以暴露 oracle.db.query.sql.id,但不要假设每一层都会报告相同的游标。本文截图所对应的一次验证运行中,演示页面返回了一个规范 SQL ID,而所选 oracle-db / DB Server Span 上显示的是另一个 SQL ID。
应使用 trace id、数据库 ECID、MODULE、ACTION 和 session id 来保持关联关系。然后,使用页面返回的规范 SQL ID,进一步查看其 V$SQL、绑定变量捕获、SQL Monitor 和 DBMS_XPLAN 信息。某个特定 Span 上的 SQL ID 仍然是有用的证据,但它标识的是该 Span 的数据库游标,而不是一个能保证跨层一致的标识符。
演示还会围绕 AI 智能体任务调用 DBMS_SQL_MONITOR.BEGIN_OPERATION。此调用与设置 JDBC 端到端指标不同:它会为 SQL Monitor 创建一个具名数据库操作,使 AI 智能体任务拥有数据库端操作 ID 和属性。即使没有它,追踪与 SQL ID 之间的桥接仍然有效,因为工作负载 SQL 使用了 MONITOR 提示,并且应用会按 SQL ID 查询 V$SQL、V$SQL_BIND_CAPTURE、SQL Monitor 和 DBMS_XPLAN。保留 BEGIN_OPERATION 能够为 AI 智能体任务提供一个具名的服务器端 SQL Monitor 操作,从而增强演示效果;移除它可以简化权限和代码,但会失去这项具名数据库操作证据。
## AI 智能体演示页面展示了什么?
浏览器端点通过在同一个页面中返回 AI 智能体场景、数据库诊断信息和 Jaeger 追踪,使整个演示保持连贯:
AI 智能体 ID 和任务名称。
Trace ID 与 SQL ID 之间的桥接。
数据库会话上下文,包括 module、action 和 client identifier。
该请求实际使用的应用绑定值。
完整 SQL 文本标题,标记为来自 SQL_ID -> V$SQL.SQL_FULLTEXT。
捕获的绑定变量样本标题,标记为来自 SQL_ID -> V$SQL_BIND_CAPTURE。
SQL Monitor 和 DBMS_XPLAN 输出。
经过短暂延迟后加载的嵌入式 Jaeger 追踪,以便 Span 有足够时间完成刷新。
## 成功时是什么样子?
在经过验证的 Linux 环境中,Jaeger 显示了一条同时包含两个服务的追踪:来自 Java 进程的 springboot-oracle-db-otel-demo,以及来自 Oracle AI Database 服务器端导出的 oracle-db。
{ "services": [ "oracle-db", "springboot-oracle-db-otel-demo" ], "ops": [ "DB Server", "Execute query", "Fetch a row", "http get /trace/agent-task", "oracle.demo.agent-database-investigation" ] }
## Oracle Database Metrics Exporter(外部)
服务器端 OpenTelemetry Span 用于回答请求范围内的问题:哪个 AI 智能体请求到达了数据库、该数据库工作耗时多久、涉及哪个 SQL ID,以及数据库 Span 如何与 Java 服务位于同一条追踪中。对于实例群级别和时间序列问题,可以搭配使用 oracle/oracle-db-appdev-monitoring 提供的外部 Oracle AI Database Metrics Exporter。
该导出器是一个独立进程或容器,它会连接一个或多个 Oracle AI Database 实例,并以标准 Prometheus/OpenTelemetry 格式公开数据库指标。Oracle 的导出器项目包含默认指标、通过 YAML 或 TOML 定义的自定义指标,并支持单实例、集群、Autonomous、云端、本地部署、Kubernetes 和基于容器的数据库,同时还提供 Grafana 仪表板示例。
一种实用的配置方式是将这两类信号发送到同一个可观测性平台。保留该演示的 OTLP 追踪路径,以提供请求级因果关系,同时在数据库环境旁部署导出器以收集数据库指标:
Spring Boot + Oracle JDBC provider -> OTLP traces -> collector/backend Oracle AI Database server-side exporter -> HTTPS OTLP traces -> collector/backend Oracle AI Database Metrics Exporter -> Prometheus/OpenTelemetry metrics -> collector/backend
结合使用追踪和指标,可以构建更强大的 AI 智能体运维视图:追踪能够解释一个请求如何一路进入 Oracle AI Database,而指标导出器则能显示该请求发生时,数据库是否正承受更广泛的压力、会话数量是否增长、等待是否激增、是否出现告警日志事件,或特定工作负载的指标是否发生变化。
## 追踪如何关联安全与审计?
该演示将追踪与 Oracle AI Database Deep Data Security 相关联。可观测性展示 AI 智能体做了什么;数据库安全机制则解释 Oracle AI Database 为什么允许或拒绝这些操作。追踪已经携带了实现这种关联所需的连接键:
trace.traceId 标识分布式请求。
agent.id 标识应用 Span 中的 AI 行为主体。
oracle.db.module=agent:<agent-id> 标识 Oracle AI Database 内部的同一行为主体。
oracle.db.action 标识数据库阶段。
CLIENT_IDENTIFIER=traceId=<trace-id> 为数据库安全性和审计策略提供了一个紧凑的关联值。
oracle.db.query.sql.id 将追踪桥接到 SQL 文本、SQL Monitor、DBMS_XPLAN 以及后续的审计记录。
示例应用现在包含一个由真实密码认证的本地深度数据安全终端用户支持的数据库安全上下文面板。它无需使用 Entra ID、OCI IAM、OAuth 令牌或 JDBC EndUserSecurityContext 调用即可工作。该页面将追踪与 ORA_END_USER_CONTEXT.username、关联的模式、MODULE、ACTION、CLIENT_IDENTIFIER、启用的数据库角色、有效权限、授予的数据角色、适用的数据授予以及此请求的 V$END_USER_DATA_ROLE 进行关联。行过滤证明在同一追踪会话中运行,同时显示数据授予允许的行数和其他智能体的零可见行。
该面板有意区分常规 Oracle Database 角色和 Oracle AI Database 深度数据安全数据角色。诸如 SELECT_CATALOG_ROLE 这样的角色是常规会话角色,出现在 SESSION_ROLES 中。诸如 AGENT_CLAIMS_INVESTIGATOR 这样的 DDS 数据角色出现在 DBA_DATA_ROLES 中,并在 DBA_DATA_GRANTS 中接收数据授予。本地设置脚本 observability/sql/setup_local_deep_data_security.sql 创建本地终端用户 claims-investigator-agent,分配带有 GRANT DATA ROLE 的 AGENT_CLAIMS_INVESTIGATOR,并授予该角色仅对代理的事件日志行的 SELECT 访问权限。FINANCIAL 数据库用户保持为所有者模式而不是运行时主体。
深度安全本地终端用户不同于常规数据库用户。数据角色不能直接授予 FINANCIAL 模式帐户。直接密码登录作为本地终端用户在 Oracle AI Database 中建立终端用户安全上下文并激活分配的数据角色,无需应用侧令牌传播。当应用程序必须通过共享池用户传播外部管理的终端用户身份时,Entra ID 和 OCI IAM 提供程序/API 示例仍然是正确的模式。
安全意识版本可以针对受保护的表运行相同的智能体工作负载,然后显示有效的数据库用户、启用的角色、策略决策、允许或过滤的行,以及被拒绝操作的示例。之后,范围化的审计策略可以记录相同的操作者、模块、操作、SQL ID 和追踪 id,因此页面显示了一个故事:此智能体提出了此请求、Oracle AI Database 执行了这些策略、审计跟踪记录了它。
追踪本身不是审计。它是可观察性:对调试、性能、因果关系和视觉关联很有用。审计需要持久的数据库记录,例如由安全控制的策略保留的统一审计或细粒度审计条目。最佳做法是使用追踪来解释执行路径,使用审计记录来证明安全相关的事实。
同伴设计说明扩展了这个方向:Agent Security Observability With Oracle AI Database。
## 如何将其连接到模型可观察性?
AI 智能体可观察性不应该止步于基础设施追踪。同一任务也可以与模型级遥测相关联:提示、模型、工具调用、检索步骤、延迟、令牌使用、评估器分数和最终答案质量。LangSmith、基于 OpenTelemetry 的 GenAI 语义约定或企业 AI 可观察性平台等工具可以捕获这些模型和智能体工作流细节。
有用的模式是通过智能体工作流、Java 服务、Oracle JDBC 和 Oracle AI Database 携带相同的任务或追踪标识符。然后一次调查可以回答:哪个智能体运行了、它使用了哪个提示或计划、哪个工具调用到达了数据库、数据库花了多长时间、哪个 SQL 运行了、哪些数据库安全策略适用了。这将模型可观察性、应用程序可观察性、数据库可观察性和安全审查联系成一个故事。
## 此演示的源代码
Oracle JDBC 可观察性提供程序
Oracle JDBC OpenTelemetry 提供程序
Oracle DBMS_OBSERVABILITY
Oracle SQL 监视和追踪
Oracle AI Database 应用程序追踪
Oracle AI Database 指标导出程序项目
Oracle Database 指标导出程序
视频《第一天及以后 - Oracle Database 多云可观察性与管理@X》,Sonali Malik
《AI 智能体可观察性:理解生成式 AI 应用和生态系统中的 AI 智能体行为》,Royce Fu 和 Alex Birzu
OpenTelemetry Java 代理
OpenTelemetry 协议导出程序
## 这是否取代了数据库审计?
不。追踪是可观察性,不是审计跟踪。当您需要关于用户、角色、对象、SQL 和策略决策的持久安全证据时,请使用 Oracle AI Database 统一审计或细粒度审计。
## 我必须使用 Jaeger 吗?
不。这里使用 Jaeger 是因为它易于运行和检查,但演示导出 OpenTelemetry 追踪。相同的方法可以供应任何可以接收应用程序/JDBC 跨度和 Oracle AI Database 服务器端跨度的 OpenTelemetry 兼容可观察性工具。
## 这与普通数据库追踪有什么不同?
普通应用程序追踪通常在数据库边缘停止。Oracle AI Database 可以将数据库服务器端跨度导出到同一追踪中,因此数据库部分在不破坏连续性或立即切换到单独的诊断工作流的情况下是可见的。
## 为什么将其框架化为 AI 智能体工作负载?
智能体应用程序需要跨应用程序和数据库边界的可解释性。添加智能体 id、任务、模块、操作、客户端标识符和 SQL_ID 使追踪对于操作、安全审查和未来审计关联很有用。