Skip to content

Commit cf3948d

Browse files
authored
Merge pull request #12 from undertaker86001/issue-10
[ISSUE#10] Add instrumentation for official MCP clients
2 parents b2b3e7e + 1063981 commit cf3948d

File tree

17 files changed

+1696
-0
lines changed

17 files changed

+1696
-0
lines changed
Lines changed: 293 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,293 @@
1+
# OpenTelemetry MCP Instrumentation
2+
3+
## 概述
4+
5+
这是一个为MCP (Message Control Protocol) 客户端提供OpenTelemetry可观测性的instrumentation库。它能够自动追踪MCP客户端的操作,包括连接、工具调用、资源读取等,并生成相应的spans和metrics。
6+
7+
**✅ 完全符合OpenTelemetry MCP语义约定规范**
8+
9+
## 功能特性
10+
11+
### ✅ 已实现功能
12+
- **异步MCP操作追踪**: 支持所有异步MCP客户端操作
13+
- **OpenTelemetry规范兼容**: 完全遵循官方MCP语义约定
14+
- **整合的Metrics**: 使用标签方式减少metrics数量
15+
- **异常处理优化**: 分离instrumentation和业务逻辑异常处理
16+
- **完整的测试覆盖**: 包含单元测试和集成测试
17+
- **详细的Trace信息**: 包含消息大小、请求参数、响应内容等详细信息
18+
19+
### 🔧 支持的MCP操作
20+
- `initialize` - 客户端初始化
21+
- `list_tools` - 列出可用工具
22+
- `call_tool` - 调用工具
23+
- `read_resource` - 读取资源
24+
- `send_ping` - 发送ping
25+
26+
## 安装
27+
28+
```bash
29+
pip install opentelemetry-instrumentation-mcp
30+
```
31+
32+
## 使用方法
33+
34+
### 基本使用
35+
36+
```python
37+
from opentelemetry.instrumentation.mcp import MCPClientInstrumentor
38+
from opentelemetry import trace, metrics
39+
40+
# 设置OpenTelemetry providers
41+
tracer_provider = TracerProvider()
42+
meter_provider = MeterProvider()
43+
44+
# 启用MCP instrumentation
45+
MCPClientInstrumentor().instrument(
46+
tracer_provider=tracer_provider,
47+
meter_provider=meter_provider
48+
)
49+
50+
# 现在所有MCP客户端操作都会被自动追踪
51+
```
52+
53+
### 示例代码
54+
55+
查看 `example/mcp/` 目录下的完整示例:
56+
- `demo.py` - 完整的演示脚本
57+
- `client.py` - MCP客户端包装器
58+
- `server.py` - 示例MCP服务器
59+
60+
## 配置选项
61+
62+
### 环境变量
63+
64+
- `OTEL_MCP_CAPTURE_CONTENT`: 是否捕获请求和响应内容(默认: false)
65+
66+
### 自定义配置
67+
68+
```python
69+
# 启用内容捕获
70+
MCPClientInstrumentor().instrument(
71+
capture_content=True
72+
)
73+
```
74+
75+
## 观测数据
76+
77+
### Spans
78+
79+
每个MCP操作都会生成相应的span,完全符合OpenTelemetry规范:
80+
81+
#### 标准命名格式(符合OpenTelemetry MCP语义约定)
82+
- `mcp.client.initialize` - 客户端初始化
83+
- `mcp.client.list_tools` - 列出工具
84+
- `mcp.client.call_tool` - 工具调用
85+
- `mcp.client.read_resource` - 资源读取
86+
- `mcp.client.send_ping` - 发送ping
87+
88+
#### 核心属性
89+
- `mcp.method.name` - 操作类型
90+
- `mcp.tool.name` - 工具名称(仅工具调用)
91+
- `mcp.resource.uri` - 资源URI(仅资源读取)
92+
- `mcp.resource.size` - 资源大小(仅资源读取)
93+
94+
#### 详细属性
95+
- `mcp.request.size` - 请求大小(字节)
96+
- `mcp.response.size` - 响应大小(字节)
97+
- `mcp.response.type` - 响应类型
98+
- `mcp.tool.arguments` - 工具调用参数
99+
- `mcp.tool.result` - 工具调用结果
100+
- `mcp.content.count` - 内容数量
101+
- `mcp.content.types` - 内容类型
102+
- `mcp.contents.count` - 资源内容数量
103+
- `mcp.contents.types` - 资源内容类型
104+
- `mcp.tools.count` - 工具数量
105+
- `mcp.tools.list` - 工具列表
106+
107+
#### 错误属性
108+
- `mcp.error.message` - 错误消息
109+
- `mcp.error.type` - 错误类型
110+
- `mcp.error.code` - 错误代码
111+
112+
### Metrics
113+
114+
#### 整合的Metrics
115+
- `mcp.client.operation.duration` - 操作持续时间
116+
- `mcp.client.operation.count` - 操作计数
117+
- `mcp.client.connection.duration` - 连接持续时间
118+
- `mcp.client.connection.count` - 连接计数
119+
120+
#### 标签
121+
- `mcp.method.name` - 操作类型
122+
- `mcp.tool.name` - 工具名称(低基数属性)
123+
- `mcp.resource.uri` - 资源URI
124+
- `status` - 操作状态(success/error)
125+
126+
## 业务意义说明
127+
128+
### Spans 业务意义
129+
130+
#### 1. `mcp.client.initialize`
131+
**业务意义**: 追踪MCP客户端与服务器的初始化过程
132+
- **用途**: 监控连接建立时间、协议版本兼容性
133+
- **关键指标**: 初始化耗时、成功率、协议版本信息
134+
135+
#### 2. `mcp.client.list_tools`
136+
**业务意义**: 追踪获取可用工具列表的操作
137+
- **用途**: 监控工具发现过程、可用工具数量
138+
- **关键指标**: 工具列表获取时间、工具数量、工具类型分布
139+
140+
#### 3. `mcp.client.call_tool`
141+
**业务意义**: 追踪工具调用的执行过程
142+
- **用途**: 监控工具执行性能、参数传递、结果处理
143+
- **关键指标**: 工具执行时间、参数大小、结果大小、成功率
144+
145+
#### 4. `mcp.client.read_resource`
146+
**业务意义**: 追踪资源读取操作
147+
- **用途**: 监控资源访问性能、内容大小、资源类型
148+
- **关键指标**: 资源读取时间、资源大小、内容类型分布
149+
150+
#### 5. `mcp.client.send_ping`
151+
**业务意义**: 追踪连接健康检查
152+
- **用途**: 监控连接状态、网络延迟
153+
- **关键指标**: Ping响应时间、连接稳定性
154+
155+
### Metrics 业务意义
156+
157+
#### 1. `mcp.client.operation.duration`
158+
**业务意义**: 监控所有MCP操作的执行时间
159+
- **用途**: 性能分析、瓶颈识别、SLA监控
160+
- **应用场景**:
161+
- 识别慢操作
162+
- 性能趋势分析
163+
- 容量规划
164+
165+
#### 2. `mcp.client.operation.count`
166+
**业务意义**: 统计MCP操作的调用次数
167+
- **用途**: 使用量监控、错误率统计、业务活跃度
168+
- **应用场景**:
169+
- 业务活跃度监控
170+
- 错误率计算
171+
- 使用模式分析
172+
173+
#### 3. `mcp.client.connection.duration`
174+
**业务意义**: 监控连接建立时间
175+
- **用途**: 网络性能分析、连接优化
176+
- **应用场景**:
177+
- 网络延迟监控
178+
- 连接池优化
179+
- 服务器性能评估
180+
181+
#### 4. `mcp.client.connection.count`
182+
**业务意义**: 统计连接建立次数
183+
- **用途**: 连接模式分析、资源使用监控
184+
- **应用场景**:
185+
- 连接频率监控
186+
- 资源使用分析
187+
- 异常连接检测
188+
189+
### 关键属性业务意义
190+
191+
#### 请求/响应相关
192+
- **`mcp.request.size`**: 监控请求数据量,用于网络带宽分析和性能优化
193+
- **`mcp.response.size`**: 监控响应数据量,用于存储和传输成本分析
194+
- **`mcp.response.type`**: 分析响应类型分布,了解业务模式
195+
196+
#### 工具调用相关
197+
- **`mcp.tool.name`**: 识别最常用的工具,优化热门工具性能
198+
- **`mcp.tool.arguments`**: 分析工具调用模式,优化参数传递
199+
- **`mcp.tools.count`**: 监控可用工具数量,评估服务完整性
200+
201+
#### 资源访问相关
202+
- **`mcp.resource.uri`**: 分析资源访问模式,优化热门资源
203+
- **`mcp.resource.size`**: 监控资源大小,用于存储规划
204+
- **`mcp.contents.count`**: 分析资源内容复杂度
205+
206+
#### 错误处理相关
207+
- **`mcp.error.message`**: 详细错误信息,用于问题诊断
208+
- **`mcp.error.type`**: 错误类型分类,用于错误模式分析
209+
- **`mcp.error.code`**: 标准化错误代码,用于自动化处理
210+
211+
## 开发
212+
213+
### 运行测试
214+
215+
```bash
216+
# 运行所有测试
217+
pytest tests/
218+
219+
# 运行MCP相关测试
220+
pytest tests/test_mcp_instrumentation.py -v
221+
```
222+
223+
### 运行示例
224+
225+
```bash
226+
cd example/mcp
227+
python demo.py
228+
```
229+
230+
## 更新日志
231+
232+
### 最新版本 (符合OpenTelemetry MCP语义约定规范)
233+
234+
#### 🎯 主要改进
235+
1. **OpenTelemetry规范兼容**: 完全遵循官方MCP语义约定
236+
2. **标准化命名**: 使用 `mcp.client.{method}` 格式
237+
3. **详细Trace信息**: 添加消息大小、请求参数、响应内容等详细信息
238+
4. **Metrics整合**: 将8个独立metrics整合为4个,使用标签区分操作类型
239+
5. **属性名称优化**: 使用标准化的MCP属性名称
240+
6. **代码清理**: 删除所有无用的同步函数
241+
7. **异常处理优化**: 分离instrumentation和业务逻辑异常处理
242+
243+
#### 📊 Metrics变化
244+
**之前**: 8个独立metrics
245+
- `message_count`, `message_duration`, `message_size`
246+
- `tool_call_duration`, `tool_call_count`
247+
- `resource_read_duration`, `resource_read_count`, `resource_size`
248+
249+
**现在**: 4个整合metrics
250+
- `mcp.client.operation.duration` (带标签)
251+
- `mcp.client.operation.count` (带标签)
252+
- `mcp.client.connection.duration`
253+
- `mcp.client.connection.count`
254+
255+
#### 🔍 Span命名变化
256+
**之前**:
257+
- `tools/call {tool_name}`
258+
- `resources/read {resource_uri}`
259+
260+
**现在** (符合OpenTelemetry规范):
261+
- `mcp.client.call_tool`
262+
- `mcp.client.read_resource`
263+
264+
#### 🏷️ 新增详细属性
265+
- `mcp.request.size` - 请求大小
266+
- `mcp.response.size` - 响应大小
267+
- `mcp.response.type` - 响应类型
268+
- `mcp.tool.arguments` - 工具参数
269+
- `mcp.content.count` - 内容数量
270+
- `mcp.content.types` - 内容类型
271+
- `mcp.contents.count` - 资源内容数量
272+
- `mcp.contents.types` - 资源内容类型
273+
- `mcp.tools.count` - 工具数量
274+
- `mcp.tools.list` - 工具列表
275+
276+
#### 🚨 错误处理增强
277+
- `mcp.error.message` - 详细错误消息
278+
- `mcp.error.type` - 错误类型
279+
- `mcp.error.code` - 错误代码
280+
281+
## 规范参考
282+
283+
本实现完全遵循以下OpenTelemetry规范:
284+
- [OpenTelemetry MCP语义约定](https://github.com/open-telemetry/semantic-conventions/blob/dc77673926c7b236f62440cf70f1dcc79bebc575/docs/gen-ai/mcp.md)
285+
- [OpenTelemetry通用语义约定](https://opentelemetry.io/docs/specs/semconv/)
286+
287+
## 贡献
288+
289+
欢迎提交Issue和Pull Request!
290+
291+
## 许可证
292+
293+
Apache License 2.0
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# MCP Instrumentation 示例
2+
3+
这个目录包含了使用 OpenTelemetry MCP Instrumentation 的示例代码。
4+
5+
## 文件说明
6+
7+
- `client.py` - MCP客户端封装类,提供简化的连接和操作接口
8+
- `server.py` - 简单的MCP服务器示例,提供add和echo工具
9+
- `demo.py` - 完整的演示脚本,展示如何使用MCP instrumentation
10+
11+
## 使用方法
12+
13+
### 1. 运行演示脚本
14+
15+
```bash
16+
cd example/mcp
17+
python demo.py
18+
```
19+
20+
这个脚本会:
21+
- 设置OpenTelemetry tracing和metrics
22+
- 启用MCP instrumentation
23+
- 连接到MCP服务器
24+
- 执行各种MCP操作(列出工具、调用工具、读取资源)
25+
- 输出所有操作的OpenTelemetry追踪信息
26+
27+
### 2. 单独运行服务器
28+
29+
```bash
30+
cd example/mcp
31+
python server.py
32+
```
33+
34+
### 3. 使用客户端
35+
36+
```python
37+
from client import ClientSession
38+
39+
async def main():
40+
client = ClientSession()
41+
await client.connect(command="python", args=["server.py"])
42+
43+
# 列出工具
44+
tools = await client.list_tools()
45+
46+
# 调用工具
47+
result = await client.call_tool("add", {"a": 1, "b": 2})
48+
49+
# 读取资源
50+
content, mime_type = await client.read_resource("greeting://User")
51+
52+
await client.disconnect()
53+
```
54+
55+
## 观测输出
56+
57+
启用MCP instrumentation后,你将看到以下类型的OpenTelemetry输出:
58+
59+
- **Spans**: 每个MCP操作都会生成一个span,包含操作类型、参数等信息
60+
- **Metrics**: 操作计数、持续时间等指标
61+
- **Attributes**: 工具名称、资源URI、操作类型等属性
62+
63+
## 环境变量
64+
65+
可以通过以下环境变量控制instrumentation行为:
66+
67+
- `OTEL_INSTRUMENTATION_MCP_CAPTURE_CONTENT=true` - 启用内容捕获(默认false)
68+
69+
## 注意事项
70+
71+
- 这些示例使用MCP 1.11.0版本
72+
- 所有MCP操作都是异步的
73+
- 确保已安装所需的依赖包:`mcp`, `opentelemetry-api`, `opentelemetry-sdk`
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# MCP Example Package

0 commit comments

Comments
 (0)