OpenTelemetry
Машинний переклад
Цю сторінку перекладено автоматично з англомовної документації, і основною версією є англомовна сторінка. Якщо щось читається неправильно, на сторінці Переклади пояснено, як про це повідомити.
Ваш сервер уже трасується. Нічого додавати не потрібно.
Кожен створений вами сервер генерує спан OpenTelemetry для кожного
повідомлення, яке обробляє. Ви цього не писали й нічого не імпортуєте. Воно з'являється тієї ж миті,
коли ви викликаєте MCPServer(...).
from mcp.server import MCPServer
mcp = MCPServer("Bookshop")
@mcp.tool()
def search_books(query: str) -> str:
"""Search the catalog by title or author."""
return f"Found 3 books matching {query!r}."
Це вже готовий сервер із трасуванням. Викличте search_books — і для нього створиться спан. Те саме
стосується низькорівневого Server: трасування є в обох.
Що отримуєте
Кожне вхідне повідомлення стає спаном SERVER, названим за методом і його ціллю. Тож
tools/call для search_books — це спан tools/call search_books, а простий tools/list —
це просто tools/list.
Кожен спан має кілька атрибутів:
mcp.method.nameіmcp.protocol.version— на кожному спані.jsonrpc.request.id— на запиті (у сповіщення його немає).- Обробник, що викидає виняток, встановлює для спана статус помилки. Так само діє результат інструмента з
is_error=True.
А оскільки трасувати виклики інструментів хочеться дуже часто, спани tools/call дотримуються
семантичних угод GenAI від OpenTelemetry:
gen_ai.operation.nameзі значенням"execute_tool".gen_ai.tool.nameз назвою інструмента, який викликають.
У тому ж дусі спан prompts/get отримує gen_ai.prompt.name. Методи списків не мають жодних
ключів gen_ai.*, бо називати там нічого.
Tip
Саме завдяки цим атрибутам GenAI інтерфейс трасування групує ваші виклики інструментів так само, як і виклики будь-якого іншого агента. Це групування дістається задарма, без додаткового коду.
Це нічого не коштує, поки вам це не знадобиться
Ось чому «увімкнено за замовчуванням» — зручне типове значення.
SDK залежить лише від opentelemetry-api, легкої половини OpenTelemetry. Якщо не встановлено
ні SDK, ні експортера, створення спана — порожня операція. Тож спани, які ваш сервер генерує просто
зараз, майже нічого не коштують, і ніхто їх не збирає.
Того дня, коли ви захочете їх побачити, встановіть другу половину й спрямуйте її кудись:
uv add opentelemetry-sdk opentelemetry-exporter-otlp
Налаштуйте експортер у звичний для OpenTelemetry спосіб — і кожен спан, який SDK досі тихо створював, стане видимим. Код сервера не змінюється. Ні на рядок.
Info
Pydantic Logfire — один із таких бекендів, і він бере
налаштування на себе: pip install logfire, logfire.configure() — і ваші MCP-спани з'являються
в живому перегляді. Він побудований на OpenTelemetry, тож усе сказане нижче стосується і його.
Трасування, що перетинає мережу
Трасування найкорисніше, коли воно супроводжує запит від клієнта до сервера в одній зв'язній картині.
Коли й клієнт, і сервер працюють на SDK, цей зв'язок утворюється автоматично. Клієнт вставляє в запит контекст трасування W3C, а сервер зчитує його назад, тож спан сервера вкладається під спан клієнта в тому самому трасуванні. Це SEP-414, і ви отримуєте його, не просячи.
Якщо вхідне повідомлення не містить контексту трасування, наприклад запит від клієнта, який не є SDK, спан сервера просто стає дочірнім до того спана, який уже є поточним на сервері, замість того щоб починати нове осиротіле трасування.
Вимкнення
Трасування — це middleware, перше у списку вашого сервера. Якщо справді потрібен сервер, що не генерує жодних спанів, приберіть його:
from mcp.server._otel import OpenTelemetryMiddleware
mcp._lowlevel_server.middleware[:] = [
m for m in mcp._lowlevel_server.middleware if not isinstance(m, OpenTelemetryMiddleware)
]
Warning
Цей імпорт починається з підкреслення, і це навмисно. Клас попередній, так само як
попереднім є Server.middleware, тож варто очікувати, що шлях імпорту
зміниться. Це майже ніколи не потрібно: без встановленого експортера спани безкоштовні, тому
звична відповідь — залишити їх увімкненими й не встановлювати експортер.
Підсумки
- Кожен
MCPServerі кожен низькорівневийServerза замовчуванням генерує один спанSERVERна кожне вхідне повідомлення. Ви нічого не пишете. - Спани містять
mcp.method.nameіmcp.protocol.version;tools/callіprompts/getтакож містять атрибути GenAI, тож ваші виклики інструментів групуються, як у будь-якого іншого агента. - Це нічого не коштує, доки ви не встановите OpenTelemetry SDK і експортер, а тоді все вмикається без жодних змін у сервері.
- Контекст трасування від клієнта до сервера передається автоматично, коли обидві сторони працюють на SDK.
Чи виконуватиметься запит узагалі, вирішує Авторизація.