-
Notifications
You must be signed in to change notification settings - Fork 3.3k
Expand file tree
/
Copy path_otel.py
More file actions
84 lines (65 loc) · 2.24 KB
/
_otel.py
File metadata and controls
84 lines (65 loc) · 2.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
"""OpenTelemetry helpers for MCP."""
from __future__ import annotations
from collections.abc import Iterator
from contextlib import contextmanager
from typing import Any
from opentelemetry.context import Context
from opentelemetry.propagate import extract, inject
from opentelemetry.trace import SpanKind, get_tracer
_tracer = get_tracer("mcp-python-sdk")
MCP_RPC_SYSTEM = "mcp"
@contextmanager
def otel_span(
name: str,
*,
kind: SpanKind,
attributes: dict[str, Any] | None = None,
context: Context | None = None,
) -> Iterator[Any]:
"""Create an OTel span."""
with _tracer.start_as_current_span(name, kind=kind, attributes=attributes, context=context) as span:
yield span
def inject_trace_context(meta: dict[str, Any]) -> None:
"""Inject W3C trace context (traceparent/tracestate) into a `_meta` dict."""
inject(meta)
def extract_trace_context(meta: dict[str, Any]) -> Context:
"""Extract W3C trace context from a `_meta` dict."""
return extract(meta)
def build_client_span_attributes(
*,
method: str,
request_id: str | int,
params: dict[str, Any] | None = None,
) -> dict[str, Any]:
"""Build OTel attributes for an MCP client request span."""
attributes: dict[str, Any] = {
"rpc.system": MCP_RPC_SYSTEM,
"rpc.method": method,
"mcp.method.name": method,
"jsonrpc.request.id": request_id,
}
if params is not None and (resource_uri := params.get("uri")) is not None:
attributes["mcp.resource.uri"] = resource_uri
return attributes
def build_server_span_attributes(
*,
service_name: str,
method: str,
request_id: str | int,
params: Any = None,
session_id: str | None = None,
) -> dict[str, Any]:
"""Build OTel attributes for an MCP server request span."""
attributes: dict[str, Any] = {
"rpc.system": MCP_RPC_SYSTEM,
"rpc.service": service_name,
"rpc.method": method,
"mcp.method.name": method,
"jsonrpc.request.id": request_id,
}
resource_uri = getattr(params, "uri", None)
if resource_uri is not None:
attributes["mcp.resource.uri"] = str(resource_uri)
if session_id is not None:
attributes["mcp.session.id"] = session_id
return attributes