Skip to content

mcp: add structured analytics logging - #319

Draft
nuclearcat wants to merge 1 commit into
kernelci:mainfrom
nuclearcat:add-mcp-logging
Draft

nuclearcat wants to merge 1 commit into
kernelci:mainfrom
nuclearcat:add-mcp-logging

Conversation

@nuclearcat

Copy link
Copy Markdown
Member

Logging is required to provide metrics to teams so they can understand use cases and identify bottlenecks early. Record tool usage, outcomes, and latency along with server lifecycle events as JSON, without including arguments, results, credentials, or exception messages.

Write analytics to stderr by default and support an append-only log file through --log-file. Document the logging behavior and cover analytics with focused tests.

Assisted-by: OpenAI Codex

Logging is required to provide metrics to teams so they can understand use cases and identify bottlenecks early. Record tool usage, outcomes, and latency along with server lifecycle events as JSON, without including arguments, results, credentials, or exception messages.

Write analytics to stderr by default and support an append-only log file through --log-file. Document the logging behavior and cover analytics with focused tests.

Assisted-by: OpenAI Codex
Signed-off-by: Denys Fedoryshchenko <denys.f@collabora.com>
Comment thread kcidev/mcp/analytics.py
call_id = uuid.uuid4().hex
outcome = "error"
try:
result = await call_tool(request)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Existing tools use tool_offload(), whose worker execution is shielded from cancellation. Check for pending cancellation after the handler returns, and add a protocol-level cancellation test using a real registered tool. The current test only covers an artificial async tool.

Comment thread kcidev/mcp/analytics.py
def analytics_logging(path=None):
"""Configure only our analytics logger; keep stdout free for MCP."""
handler = (
logging.FileHandler(path, encoding="utf-8")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The documentation delegates rotation externally, but FileHandler never reopens a replaced file. I reproduced this by renaming the log and creating its replacement: subsequent events went into the rotated file, while the current file stayed empty. Use WatchedFileHandler, provide a reopen mechanism, or explicitly document the supported rotation procedure.

Comment thread kcidev/mcp/analytics.py
try:
yield
finally:
logger.handlers, logger.level, logger.propagate = previous

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assigning logger.level directly leaves Python’s enabled-level cache stale. After restoring WARNING, I confirmed that INFO events were still emitted. Restore the level through logger.setLevel(previous_level) and test logging after the context exits.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants