免费获取学习方案
ARTICLE DETAIL

资讯详情

深耕编程基础知识与建站技术分享的一线实战洞察。

Python MCP SDK 服务端 OpenTelemetry 追踪:零代码接入的默认可观测性机制

Python MCP SDK 服务端 OpenTelemetry 追踪:零代码接入的默认可观测性机制 人工智能MCP 服务MCP Clients【免费下载链接】python-sdkThe official Python SDK for Model Context Protocol servers and clients项目地址https://gitcode.com/gh_mirrors/pythonsd/python-sdk点击查看免费下载导读本文讲解 Model Context Protocol Python SDK本仓库服务端的 OpenTelemetry 追踪能力——从MCPServer(...)实例化那一刻起每个被处理的入站消息都会自动生成一个SERVERspan你无需编写或导入任何追踪代码。读完本文你将掌握默认 span 的命名规则与属性集、tools/call与prompts/get遵循 GenAI 语义约定带来的 UI 自动分组效果、从零成本 no-op到接入 exporter 的完整激活路径以及 W3C trace context 跨 client/server 自动传播的原理与关闭方式。开箱即用你的 Server 天生就是被追踪的原文档英文版印地语翻译版开宗明义你的 server 已经在产生 trace你什么都不用加。每创建一个 server它就会为处理的每一条消息发出一个 OpenTelemetry span——这段代码不是你写的你也没有 import 它它在你调用MCPServer(...)的那一刻就存在了。完整的、自带追踪的 server 只需要这些代码见 docs_src/opentelemetry/tutorial001.pyfrom 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_books发起一次tools/call就会为它创建一个 span。这一点对底层 API 同样成立无论是高层MCPServer还是 low-level 的Server追踪逻辑都内置其中。从源码看这一默认行为由 src/mcp/server/lowlevel/server.py 保证Server初始化时会将OpenTelemetryMiddleware()放在self.middleware列表的第一位注释明确写着OpenTelemetryMiddleware默认随每个 server 一起交付因此每个 server 都会发出 span。对应的测试 tests/server/test_otel.pytest_server_ships_opentelemetry_middleware_by_default也验证了一个裸Server(name..., version...)的 middleware 列表中必然包含OpenTelemetryMiddleware实例。你得到什么span 命名、属性与 GenAI 语义约定每个入站消息都会变成一个SERVER类型的 span命名规则为方法名 目标名对search_books的tools/call→ span 名tools/call search_books裸的tools/list→ span 名就是tools/list没有目标可命名。span 名称的拼接逻辑直接对应 src/mcp/server/_otel.py 中的实现namef{ctx.method}{f {target} if target else }其中target取自请求参数中的name字段。每个 span 都携带一组标准属性属性出现条件说明mcp.method.name每个 span消息方法名如tools/callmcp.protocol.version每个 span本次会话使用的 MCP 协议版本jsonrpc.request.id仅 requestJSON-RPC 请求 IDnotification 没有该属性error.type/rpc.response.status_code出错时handler 异常或工具返回错误时写入gen_ai.*仅tools/call、prompts/getGenAI 语义约定属性见下由于追踪工具调用是极常见的需求tools/callspan 遵循 OpenTelemetry 的GenAI 语义约定额外携带gen_ai.operation.name固定为execute_toolgen_ai.tool.name设置为被调用的工具名。同理prompts/getspan 会获得gen_ai.prompt.name。而tools/list这类 list 方法不带任何gen_ai.*键——它们没有可命名的对象语义上无从归属。提示正是这些 GenAI 属性让追踪 UI 把你的 tool calls 按照与其他任何 agent 相同的方式分组。这个分组能力是免费的不需要任何额外代码。源码级验证错误状态与工具错误标记src/mcp/server/_otel.py 完整展示了 span 状态管理逻辑比文档描述得更细handler 抛出MCPErrorspan 上写入error.type与rpc.response.status_code取错误码并将 span 状态置为StatusCode.ERROR随后重新抛出参数校验失败ValidationError以INVALID_PARAMS错误码标记 span 错误状态与线上返回的 sanitized 响应保持一致避免泄露客户端输入其他任意异常写入error.type取异常类的__qualname__、记录异常事件并置为StatusCode.ERROR工具返回错误结果文档说is_errorTrue的 tool result 也会置错。源码对两种情况生效——CallToolResult(is_errorTrue)模型实例或原始 dict 形式{isError: True}注意必须是字面布尔值True因为线上 wire 校验只保留 camelCase 别名。命中后写入error.typetool_error并置StatusCode.ERROR。这些分支都有对应测试覆盖见 tests/server/test_otel.pytest_emits_server_span_with_method_and_target验证了 span 名、mcp.method.name、两个gen_ai.*属性及jsonrpc.request.idtest_tool_error_dict_result_sets_error_type与test_tool_error_model_result_sets_error_type验证了两种错误结果形态test_snake_case_dict_result_is_not_a_tool_error则确认{is_error: True}这类 snake_case dict不会被误判为工具错误。它在你想要之前零成本默认开启之所以能成为一个舒适的默认值关键在于成本结构。SDK 的运行依赖只有opentelemetry-api见 pyproject.toml 中的opentelemetry-api1.28.0这是 OpenTelemetry 的轻量半壁——只提供 span/tracer 的 API 骨架。当环境中既没有 OpenTelemetry SDK 也没有任何 exporter 时创建 span 就是一个no-op你 server 此刻发出的这些 span 几乎不消耗任何东西而且也没有人在收集它们。直到你想看到它们的那一天再安装另一半并把它指向某个后端uv add opentelemetry-sdk opentelemetry-exporter-otlp仓库开发环境依赖中已包含opentelemetry-sdk1.39.1见 pyproject.toml。然后按 OpenTelemetry 的常规方式配置 exporter——例如通过环境变量OTEL_EXPORTER_OTLP_ENDPOINT指向 OTLP Collector或按所选后端的要求初始化——SDK 一直在默默创建的 span 就全部点亮了。你的 server 代码一行都不用改。文档还特别提到一类开箱即用的后端[Pydantic Logfire] 就是建立在 OpenTelemetry 之上的服务它替你完成了配置pip install logfire、调用logfire.configure()你的 MCP spans 就会出现在 live view 中。由于它基于 OpenTelemetry本文描述的一切对它同样适用。跨 wire 的 traceclient 到 server 的自动关联一条 trace 最有价值的时刻是它能以一张连续图景跟踪请求从 client 进入 server 的全过程。当client 和 server 都运行本 SDK时这种关联是自动发生的。其机制对应 src/mcp/shared/_otel.py 中两个对称的辅助函数inject_trace_context(meta)client 在发出请求前把W3C trace contexttraceparent/tracestate头注入到请求的_meta字典中使用的是 OpenTelemetry 标准propagate.injectextract_trace_context(meta)server 在收到请求后从_meta中取出上下文交给 span 创建逻辑见 src/mcp/server/_otel.py 中contextextract_trace_context(ctx.meta)。于是 server span 会嵌套到同一个 trace 中 client span 的下方形成完整链路。这就是 MCP 生态中的 SEP-414 提案所定义的 trace context 传播你无需任何额外请求就能获得。如果入站消息不携带 trace context——例如请求来自一个不使用本 SDK 的 client——那么 server span 不会强行开启一条全新的孤儿 trace而是直接作为 server 当前已激活 span 的子 span。这一设计意图在 src/mcp/shared/_otel.py 的 docstring 中有明确说明extract_trace_context在载体缺失、格式非法或无有效traceparent时返回None让调用方自然回退到 ambient parenting若返回一个显式空Context反而会孤立 span。对应的测试test_nests_under_ambient_span_when_no_traceparent见 tests/server/test_otel.py验证了嵌套关系内层 span 的parent.span_id等于外层 span 的context.span_id。关闭它移除默认的追踪中间件Tracing 本质上是middleware位于你 server 的中间件列表首位见 src/mcp/server/lowlevel/server.py。如果你确实需要一个完全不发出 span 的 server可以把它移除from mcp.server._otel import OpenTelemetryMiddleware mcp._lowlevel_server.middleware[:] [ m for m in mcp._lowlevel_server.middleware if not isinstance(m, OpenTelemetryMiddleware) ]警告上面 import 中的前导下划线是故意的——OpenTelemetryMiddleware是 provisional临时类与Server.middleware的 provisional 状态一致参见 middleware 文档import 路径未来可能会变化。而且你几乎永远不需要关闭它没有安装 exporter 时 span 是免费的所以通常的答案是保持开启、不安装 exporter。总结每个MCPServer和每个 low-levelServer都开箱即用地为每条入站消息发出一个SERVERspan你不需要写任何代码。span 携带mcp.method.name与mcp.protocol.versiontools/call和prompts/get还携带 GenAI 属性让你的 tool calls 像任何其他 agent 一样被自动分组展示。在安装 OpenTelemetry SDK 和 exporter 之前成本为零安装后无需改动 server 代码即可看到全部 span。当 client 与 server 都运行本 SDK 时client 到 server 的 trace context 自动传播无 trace context 时 span 回退到当前 server 环境的父 span。至于一条请求是否会被执行则由 Authorization 授权机制 决定——追踪记录的是发生了什么事授权决定的是这件事允不允许发生。延伸阅读想深入理解实现可直接阅读 OpenTelemetry 中间件源码、底层 server 的中间件装配、共享 OTel 辅助函数以及完整的行为测试套件也可参考文档主目录下的 opentelemetry 部署运行指南 与其他 run 系列文档。赞分享人工智能MCP 服务MCP Clients【免费下载链接】python-sdkThe official Python SDK for Model Context Protocol servers and clients项目地址https://gitcode.com/gh_mirrors/pythonsd/python-sdk点击查看免费下载相关推荐gulp-util API详解掌握文件操作、流处理与模板渲染的核心方法gulp util API详解掌握文件操作、流处理与模板渲染的核心方法 gulp util是一个功能强大的工具库为开发者提供了丰富的API来简化Gulp任务人工智能MCP 服务MCP Clientspython-sdk 服务端 OpenTelemetry 可观测性零代码开箱即用的 MCP 全链路追踪python sdk 服务端 OpenTelemetry 可观测性零代码开箱即用的 MCP 全链路追踪 导读 本文讲解 Model Context Proto人工智能MCP 服务MCP ClientsMCP Python SDK 服务端 OpenTelemetry 追踪指南默认开启的 span、GenAI 语义与零成本观测MCP Python SDK 服务端 OpenTelemetry 追踪指南默认开启的 span、GenAI 语义与零成本观测 本篇指南围绕官方 Python人工智能MCP 服务MCP Clients创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表