尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Python SDK 服务端内置 OpenTelemetry 追踪:零配置的 MCP 可观测性

Python SDK 服务端内置 OpenTelemetry 追踪:零配置的 MCP 可观测性 人工智能MCP 服务MCP Clients【免费下载链接】python-sdkThe official Python SDK for Model Context Protocol servers and clients项目地址https://gitcode.com/gh_mirrors/pythonsd/python-sdk点击查看免费下载MCP Python SDKModel Context Protocol 官方 Python SDK在服务端开箱即用地内置了 OpenTelemetry 与 docs/run/opentelemetry.md 展开结合仓库源码与测试讲清楚这些 span 携带什么信息、如何做到零成本默认开启、如何打通客户端到服务端的全链路追踪以及何时、怎样按需关闭它。你的服务器已经被追踪了这是本主题最反直觉、也最实用的一点你不需要做任何事。从你调用MCPServer(...)的那一刻起追踪就已经存在——它不是你在代码里写的也不是你显式 import 进来的。下面这份代码见 docs_src/opentelemetry/tutorial001.py就是一个完整的、已带追踪的服务器from mcp.server import MCPServer mcp MCPServer(Bookshop) mcp.tool() def search_books(query: str) - str: Search the catalog by title or author. return fFound 3 books matching {query!r}.调用search_booksSDK 就会为这次调用创建一个 span。同样的行为也适用于底层Server——追踪同时存在于高层MCPServer与低层Server两层。从源码看这一默认行为是通过低层Server初始化时向self.middleware列表头部写入的OpenTelemetryMiddleware()实现的见 src/mcp/server/lowlevel/server.py 的注释与初始化代码任何构建在其上的服务器都会继承这一行为。测试 tests/server/test_otel.py 也明确断言新建的Server的middleware中默认包含OpenTelemetryMiddleware实例。你得到了什么每个入站消息对应一个 SERVER span每个入站消息都会变成名为方法 目标的SERVERspan对search_books的一次tools/call会产生名为tools/call search_books的 span一次不带目标的tools/list则是单纯的tools/list。命名逻辑在 src/mcp/server/_otel.py 中实现namef{ctx.method}{f {target} if target else }其中target取自消息参数中的name字段。每个 span 携带的属性每个 span 都带有若干固定属性属性出现位置说明mcp.method.name每个 span被调用的 JSON-RPC 方法名如tools/callmcp.protocol.version每个 spanMCP 协议版本jsonrpc.request.id请求上通知没有该 JSON-RPC 请求的 id转为字符串写入错误处理也会自动反映到 span 状态上处理器抛出异常时span 状态被标记为错误StatusCode.ERROR工具结果带is_errorTrue时同样如此。具体实现在 src/mcp/server/_otel.py处理器抛出MCPError时写入error.type错误码与rpc.response.status_code参数校验失败ValidationError时按线上响应镜像写入INVALID_PARAMS对应属性其他异常则记录异常并置为错误状态。对tools/call还做了一层预序列化的探测只有真正会以错误形态到达线上的结果才算错误——即CallToolResult(is_errorTrue)模型形态或原始的{isError: True}字面布尔形态非布尔可强制的值如1、true因过于罕见而被有意忽略注释与测试都说明了这一点。tools/call 与 prompts/get 遵循 GenAI 语义约定由于追踪工具调用是最常见的诉求tools/call的 span 遵循 OpenTelemetry 的 GenAI 语义约定gen_ai.operation.name固定为execute_toolgen_ai.tool.name值为被调用工具的名字。prompts/get的 span 也以同样的精神携带gen_ai.prompt.name。列表类方法tools/list等不携带任何gen_ai.*键因为没有可命名的目标。[!tip] 正是这些 GenAI 属性让追踪界面把你的工具调用与其他任何 Agent 的工具调用以同样的方式分组展示。这份分组是白送的无需任何额外代码。上述属性写入逻辑集中在 src/mcp/server/_otel.py并由 tests/server/test_otel.pytools/call mytool的 span 名、gen_ai.operation.name execute_tool、gen_ai.tool.name mytool等断言与 tests/docs_src/test_opentelemetry.py 加以验证。测试还覆盖了非工具/非 prompt 方法不携带 gen_ai 属性见 tests/server/test_otel.py。它零成本直到你需要它为什么默认开启是个舒服的默认关键在于 SDK 只依赖 OpenTelemetry 的轻量半opentelemetry-api。这一点由 pyproject.toml 中的依赖声明opentelemetry-api1.28.0佐证而opentelemetry-sdk、opentelemetry-exporter-otlp、logfire等则属于测试依赖见 pyproject.toml 附近的开发依赖清单运行时并不强制安装。在没有安装 OpenTelemetry SDK 与任何 exporter 的情况下opentelemetry-api的默认追踪器是 No-Op 的——创建 span 是一个空操作。所以你的服务器此刻生成的 span 几乎不花任何成本也没有人在收集它们。当你想真正看见这些 span 的那一天装上另一半并指向某个后端即可uv add opentelemetry-sdk opentelemetry-exporter-otlp然后按 OpenTelemetry 常规方式配置 exporter——SDK 一直悄悄创建的那些 span 就会全部亮起来。服务器代码一行都不用改。[!info] Pydantic Logfire 就是这样一个后端它把配置也替你做了pip install logfire、logfire.configure()你的 MCP span 就会出现在实时视图中。它构建在 OpenTelemetry 之上因此下文的一切对它同样适用。跨网络的追踪从客户端到服务端一条 trace 最有价值的时候是它能跟随请求从客户端一路贯穿到服务端、形成一幅连贯图景的时候。当客户端和服务端都跑在 SDK 上时这种关联是自动发生的客户端向请求注入 W3C trace contexttraceparent/tracestate服务端把上下文读出来于是服务端 span 嵌套在客户端 span 之下属于同一条 trace。这是 SEP-414spec 层面的协议增强SDK 无需你申请就实现了它。从源码看注入发生在客户端出站路径mcp/shared/jsonrpc_dispatcher.py在发送请求时打开一个CLIENT类型的 spanMCP send {method} {target}并调用inject_trace_context(out_meta)把 W3C 上下文写进_meta见 src/mcp/shared/jsonrpc_dispatcher.py。而inject_trace_context/extract_trace_context这对助手位于 src/mcp/shared/_otel.py分别对应opentelemetry.propagate.inject/extract。如果入站消息没有携带 trace context——例如请求来自一个非 SDK 客户端——服务端 span 并不会开启一条全新的孤儿 trace而是直接挂到服务端当前已存在的 span 之下。这一点在extract_trace_context的实现里体现得很明确src/mcp/shared/_otel.py当载体缺失、格式非法extract抛出ValueError/TypeError或traceparent无效时返回None调用方据此退回到环境父级嵌套而不是用一个显式的空Context把 span 变成孤儿。对应的测试包括 tests/shared/test_otel.py畸形traceparent降级为无父级以及 tests/server/test_otel.py无traceparent时嵌套到环境 span 之下。如何关闭它追踪本质上是一个 middleware——而且是你服务器 middleware 列表里的第一个。如果你确实需要一个不产生任何 span 的服务器把它摘掉即可from mcp.server._otel import OpenTelemetryMiddleware mcp._lowlevel_server.middleware[:] [ m for m in mcp._lowlevel_server.middleware if not isinstance(m, OpenTelemetryMiddleware) ][!warning] 上面的 import 带有下划线前缀这是故意的。OpenTelemetryMiddleware类目前是临时性的provisional与Server.middleware同样是临时 API因此导入路径在未来版本中可能变化。你几乎永远不需要这招在没有安装 exporter 的情况下 span 是免费的所以通常的答案就是保持开启、不装 exporter。从源码结构看这一摘除方案可行正是因为OpenTelemetryMiddleware是上下文层的ServerMiddleware被默认注入到Server.middleware列表头部src/mcp/server/lowlevel/server.py过滤掉它即可彻底停止 span 生成。总结每个MCPServer和每个底层Server默认都会为每条入站消息生成一个SERVERspan——你什么都不用写span 携带mcp.method.name与mcp.protocol.versiontools/call与prompts/get还额外携带 GenAI 属性让你的工具调用像任何其他 Agent 一样被分组展示在安装 OpenTelemetry SDK 与 exporter 之前它零成本装好之后无需改动服务器代码一切即刻可见当客户端与服务端都运行在 SDK 上时客户端到服务端的 trace context 自动传播形成完整链路。追踪解决的是看清请求如何执行而决定请求是否会被执行的是 授权Authorization。赞分享人工智能MCP 服务MCP Clients【免费下载链接】python-sdkThe official Python SDK for Model Context Protocol servers and clients项目地址https://gitcode.com/gh_mirrors/pythonsd/python-sdk点击查看免费下载相关推荐MCP Python SDK 内置 OpenTelemetry 追踪零配置的服务器可观测性指南MCP Python SDK 内置 OpenTelemetry 追踪零配置的服务器可观测性指南 本篇技术指南讲解 MCP Python SDK 中 默认开启、人工智能MCP 服务MCP ClientsPython MCP SDK 服务端 OpenTelemetry 追踪零代码接入的默认可观测性机制Python MCP SDK 服务端 OpenTelemetry 追踪零代码接入的默认可观测性机制 导读 本文讲解 Model Context Protoc人工智能MCP 服务MCP ClientsMCP Python SDK 服务器可观测性开箱即用的 OpenTelemetry 追踪MCP Python SDK 服务器可观测性开箱即用的 OpenTelemetry 追踪 你写的每一个 MCP 服务器无论用高层 MCPServer 还是底人工智能MCP 服务MCP Clients上一篇从图像到代码Qwen3-VL-30B-A3B-Instruct视觉编码功能实现Draw.io/HTML生成教程下一篇Isaac Lab 3步装好10分钟跑通机器人强化学习仿真创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表