-
Notifications
You must be signed in to change notification settings - Fork 705
feat(logging): add support for send log message notifications and implemented the SessionWithLogging
interface on streamableHttpSession
#484
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
- Introduced `LoggingLevel.ShouldSendTo` for log level comparison - Added `SendLogMessageToSpecificClient` to send log notifications to a specific client - Added `SendLogMessageToClient` to send log notifications to the current session client - Implemented `SessionWithLogging` interface for `streamableHttpSession` - Added `sessionLogLevelsStore` to manage per-session log levels - Updated `StreamableHTTPServer` to support setting and retrieving log levels - Added tests covering log notification sending logic and format validation
WalkthroughThis update introduces per-session logging level management and log message notification functionality. It adds log-level filtering, methods for sending log notifications to clients, and a thread-safe store for session log levels. The notification sending logic is refactored for modularity, and comprehensive tests are added for logging-related server behavior. Changes
Possibly related PRs
Suggested labels
Suggested reviewers
✨ Finishing Touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (1)
server/session.go (1)
250-250
: Address linter suggestion for field accessThe static analysis tool suggests using the promoted field directly for cleaner code.
- method := notification.Notification.Method + method := notification.Method
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
mcp/types.go
(1 hunks)server/session.go
(6 hunks)server/session_test.go
(1 hunks)server/streamable_http.go
(11 hunks)server/streamable_http_test.go
(1 hunks)
🧰 Additional context used
🧠 Learnings (3)
server/session_test.go (2)
Learnt from: octo
PR: mark3labs/mcp-go#149
File: mcptest/mcptest.go:0-0
Timestamp: 2025-04-21T21:26:32.945Z
Learning: In the mcptest package, prefer returning errors from helper functions rather than calling t.Fatalf() directly, giving callers flexibility in how to handle errors.
Learnt from: ezynda3
PR: mark3labs/mcp-go#461
File: server/sampling.go:22-26
Timestamp: 2025-06-30T07:13:17.052Z
Learning: In the mark3labs/mcp-go project, the MCPServer.capabilities field is a struct value (serverCapabilities), not a pointer, so it cannot be nil and doesn't require nil checking. Only pointer fields within the capabilities struct should be checked for nil.
server/streamable_http.go (1)
Learnt from: ezynda3
PR: mark3labs/mcp-go#461
File: server/sampling.go:22-26
Timestamp: 2025-06-30T07:13:17.052Z
Learning: In the mark3labs/mcp-go project, the MCPServer.capabilities field is a struct value (serverCapabilities), not a pointer, so it cannot be nil and doesn't require nil checking. Only pointer fields within the capabilities struct should be checked for nil.
server/session.go (1)
Learnt from: ezynda3
PR: mark3labs/mcp-go#461
File: server/sampling.go:22-26
Timestamp: 2025-06-30T07:13:17.052Z
Learning: In the mark3labs/mcp-go project, the MCPServer.capabilities field is a struct value (serverCapabilities), not a pointer, so it cannot be nil and doesn't require nil checking. Only pointer fields within the capabilities struct should be checked for nil.
🧬 Code Graph Analysis (1)
server/streamable_http.go (2)
mcp/types.go (2)
LoggingLevel
(751-751)LoggingLevelError
(758-758)server/session.go (2)
SessionWithTools
(32-40)SessionWithLogging
(23-29)
🪛 GitHub Check: lint
server/session.go
[failure] 250-250:
QF1008: could remove embedded field "Notification" from selector (staticcheck)
🪛 GitHub Actions: golangci-lint
server/session.go
[error] 250-250: golangci-lint (staticcheck): could remove embedded field "Notification" from selector (QF1008)
🔇 Additional comments (15)
mcp/types.go (1)
764-783
: LGTM!The logging level severity mapping and comparison logic are correctly implemented. The severity ordering follows the syslog standard (RFC-5424) as documented, and the
ShouldSendTo
method safely handles unknown levels by returning false.server/streamable_http_test.go (1)
728-795
: LGTM!The test thoroughly validates the session logging functionality. Good use of hooks to capture the session context and proper synchronization with mutex for thread-safe access.
server/session_test.go (4)
1131-1222
: Well-structured test coverage for log message filtering.The test properly validates that log messages are filtered based on the session's configured log level, ensuring that only messages at or above the minimum severity are sent.
1224-1344
: Comprehensive test for sending logs to specific clients.Good coverage of edge cases including non-existent sessions and uninitialized sessions. The test properly validates error types using
errors.Is
.
1346-1431
: Excellent test for mixed session types.This test effectively validates the behavior when sessions have different capabilities (logging-supported, logging-unsupported, and uninitialized). The error assertions correctly verify the expected error types.
1433-1509
: Thorough validation of log data format preservation.The test ensures that various data types (strings, maps, errors, nil) are correctly preserved in log notifications. Good coverage of different data formats that might be logged.
server/streamable_http.go (3)
516-547
: Thread-safe implementation of session log levels store.The
sessionLogLevelsStore
correctly implements thread-safe operations with proper mutex usage. The default log level ofLoggingLevelError
is a reasonable choice.
132-140
: Proper integration of logging levels throughout the session lifecycle.The session log levels store is correctly initialized, passed to sessions, and cleaned up on deletion. The lifecycle management ensures no memory leaks.
Also applies to: 260-260, 370-370, 473-473
586-597
: Clean implementation of SessionWithLogging interface.The
streamableHttpSession
properly implements theSessionWithLogging
interface by delegating to the shared store. The interface assertions confirm the implementation.Also applies to: 617-624, 635-638
server/session.go (6)
99-113
: LGTM!The
buildLogNotification
method correctly constructs a JSON-RPC notification from the logging message parameters, properly mapping all required fields.
115-128
: Well-structured log notification implementation!The method properly validates the session, checks for logging support, and implements log level filtering before sending notifications. Good defensive programming with appropriate error handling.
184-201
: LGTM!The implementation correctly handles session lookup, validation, and log level filtering before sending notifications to specific clients.
217-232
: Good refactoring!The separation of notification building from the sending logic improves code organization and reduces duplication.
266-286
: Clean refactoring!The method now properly delegates to the core notification logic, reducing code duplication while maintaining the same public interface.
289-312
: LGTM!The refactoring successfully reduces code duplication by delegating to the helper method.
- Replaced `notification.Notification.Method` with `notification.Method` to resolve QF1008 from staticcheck - No functional change; improves code clarity and eliminates linter warning
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (2)
server/session.go (2)
146-146
: Fix field access inconsistencyFor consistency with the rest of the codebase, access the Method field through the Notification embedded field.
- "method": notification.Method, + "method": notification.Notification.Method,
175-175
: Fix field access inconsistencyFor consistency with the rest of the codebase, access the Method field through the Notification embedded field.
- "method": notification.Method, + "method": notification.Notification.Method,
🧹 Nitpick comments (1)
server/session.go (1)
250-250
: Consider consistency with field access pattern.For consistency with the codebase pattern, consider accessing the Method field through the Notification embedded field, similar to the pattern used elsewhere in error handling.
- method := notification.Method + method := notification.Notification.Method
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
server/session.go
(6 hunks)
🧰 Additional context used
🧠 Learnings (1)
server/session.go (1)
Learnt from: ezynda3
PR: mark3labs/mcp-go#461
File: server/sampling.go:22-26
Timestamp: 2025-06-30T07:13:17.052Z
Learning: In the mark3labs/mcp-go project, the MCPServer.capabilities field is a struct value (serverCapabilities), not a pointer, so it cannot be nil and doesn't require nil checking. Only pointer fields within the capabilities struct should be checked for nil.
🔇 Additional comments (6)
server/session.go (6)
22-29
: Well-designed interface extension.The
SessionWithLogging
interface cleanly extendsClientSession
with logging capabilities, following Go's composition patterns correctly.
99-113
: Clean notification builder implementation.The
buildLogNotification
method properly constructs JSON-RPC notifications fromLoggingMessageNotification
objects with correct field mapping.
115-128
: Robust log message sending with proper validation.The method correctly validates session state, logging support, and log level filtering before sending notifications. The use of
ShouldSendTo
for level filtering is appropriate.
184-201
: Comprehensive validation and log level filtering.The method properly validates session existence, initialization, logging support, and applies log level filtering before sending notifications. Error handling is appropriate for each validation step.
235-264
: Well-extracted core notification logic.The
sendNotificationCore
method effectively consolidates notification sending logic, including SSE upgrade handling and proper error handling for blocked channels. Good refactoring to eliminate code duplication.
266-286
: Improved notification sending with better error handling.The refactored method now uses the centralized
sendNotificationCore
for consistent behavior and error handling across all notification sending methods.
LoggingLevel.ShouldSendTo
for log level comparisonSendLogMessageToSpecificClient
to send log notifications to a specific clientSendLogMessageToClient
to send log notifications to the current session clientSessionWithLogging
interface forstreamableHttpSession
sessionLogLevelsStore
to manage per-session log levelsStreamableHTTPServer
to support setting and retrieving log levelsDescription
This PR adds support for sent structured log message notifications in MCP sessions.
This enables server-to-client structured logging over the MCP notification channel, respecting the client’s configured verbosity.
For example:
Type of Change
Checklist
MCP Spec Compliance
Additional Information
This PR lays the foundation for server-driven structured logging toward clients via MCP protocol. It supports log filtering by level and ensures format consistency for different
data
. The mechanism respects client preferences and ensures graceful degradation in unsupported or uninitialized cases.Summary by CodeRabbit
New Features
Bug Fixes
Tests