|
| 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 |
0 commit comments