Skip to content

feat: Add structured logging to MCP server#13

Open
timothywarner wants to merge 1 commit intomainfrom
feature/add-basic-logging
Open

feat: Add structured logging to MCP server#13
timothywarner wants to merge 1 commit intomainfrom
feature/add-basic-logging

Conversation

@timothywarner
Copy link
Owner

🎯 Summary

This PR adds structured logging to the MCP server to improve debugging and monitoring capabilities.

📝 Changes Made

  • ✅ Added Python logging module with INFO level configuration
  • ✅ Configured dual output: log file (logs/mcp_server.log) and console
  • ✅ Added logging to server initialization
  • ✅ Logged tip loading with count information
  • ✅ Logged all tool invocations with parameters
  • ✅ Logged search results and patterns
  • ✅ Logged warnings for missing tips
  • ✅ Auto-creates logs/ directory
  • ✅ Updated README with logging documentation

🔍 What Gets Logged

  • Server startup: Initialization messages
  • Data loading: Number of tips loaded
  • Tool calls: Every tool invocation with parameters
  • Search operations: Search terms and result counts
  • Tip access: Which tips are retrieved
  • Errors/Warnings: Missing tips, failed operations

📚 Documentation

Added new section in README explaining:

  • Log file location
  • How to view logs
  • What information is logged
  • PowerShell and Bash commands for tailing logs

🧪 Testing

  • Server starts without errors
  • Logs directory is created automatically
  • Log messages appear in both file and console
  • All existing tests still pass
  • Tool invocations are logged correctly

🔗 Related Issues

Closes #11

💡 Future Enhancements

This PR implements basic logging. Future improvements could include:

  • Configurable log levels via environment variable
  • Log rotation to prevent disk space issues
  • Performance timing for slow operations
  • Structured JSON logging for better parsing
  • Error tracking with stack traces

Ready for review by GitHub Copilot! 🤖

- Add logging configuration with file and console handlers
- Log server initialization and tip loading
- Log all tool invocations with parameters
- Log search results and tip access patterns
- Log warnings for missing tips and errors
- Create logs directory automatically
- Update README with logging documentation

Resolves #11
@timothywarner timothywarner requested a review from Copilot January 14, 2026 00:41
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds comprehensive structured logging to the MCP server to improve debugging and monitoring capabilities. The implementation includes dual output to both file and console with INFO level logging for all critical operations.

Changes:

  • Added Python logging module with file and console handlers
  • Instrumented all tool invocations and data operations with log statements
  • Updated README with logging documentation and usage examples

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.

File Description
src/copilot_tips_server.py Added logging configuration, initialized logger, and instrumented tool functions with log statements
src/README.md Added new "Logging" section documenting log location, contents, and viewing commands

Comment on lines 30 to +35

from fastmcp import FastMCP, Context

# Configure logging
LOG_DIR = Path(__file__).parent / "logs"
LOG_DIR.mkdir(exist_ok=True)
Copy link

Copilot AI Jan 14, 2026

Choose a reason for hiding this comment

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

The log directory path uses Path(__file__).parent / 'logs', which places logs in the src/ directory. Consider using a project root-relative path or making this configurable, as logs are typically stored at the project root or in a dedicated directory outside the source tree.

Suggested change
from fastmcp import FastMCP, Context
# Configure logging
LOG_DIR = Path(__file__).parent / "logs"
LOG_DIR.mkdir(exist_ok=True)
import os
from fastmcp import FastMCP, Context
# Configure logging
# Prefer a project-root-relative logs directory, with optional override via environment variable.
PROJECT_ROOT = Path(__file__).resolve().parent.parent
DEFAULT_LOG_DIR = PROJECT_ROOT / "logs"
LOG_DIR = Path(os.getenv("COPILOT_TIPS_LOG_DIR", str(DEFAULT_LOG_DIR)))
LOG_DIR.mkdir(parents=True, exist_ok=True)

Copilot uses AI. Check for mistakes.

def load_tips() -> list[dict]:
"""Load tips from the JSON data file."""
logger.debug(f"Loading tips from {DATA_FILE}")
Copy link

Copilot AI Jan 14, 2026

Choose a reason for hiding this comment

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

Using f-strings in log statements creates the formatted string even when the log level would filter it out. Use lazy formatting with logger.debug('Loading tips from %s', DATA_FILE) to avoid unnecessary string construction when DEBUG level is disabled.

Suggested change
logger.debug(f"Loading tips from {DATA_FILE}")
logger.debug("Loading tips from %s", DATA_FILE)

Copilot uses AI. Check for mistakes.
Returns:
List of matching tips sorted by relevance.
"""
logger.info(f"Tool invoked: get_tip_by_topic(search_term='{search_term}', category={category}, difficulty={difficulty})")
Copy link

Copilot AI Jan 14, 2026

Choose a reason for hiding this comment

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

Using f-strings in log statements creates the formatted string even when the log level would filter it out. Use lazy formatting with logger.info('Tool invoked: get_tip_by_topic(search_term=%r, category=%s, difficulty=%s)', search_term, category, difficulty) to avoid unnecessary string construction.

Copilot uses AI. Check for mistakes.
Comment on lines +37 to +44
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler(LOG_DIR / "mcp_server.log"),
logging.StreamHandler()
]
)
Copy link

Copilot AI Jan 14, 2026

Choose a reason for hiding this comment

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

The log file will grow indefinitely without rotation. Consider using RotatingFileHandler or TimedRotatingFileHandler from logging.handlers to prevent disk space issues in long-running deployments. For example: RotatingFileHandler(LOG_DIR / 'mcp_server.log', maxBytes=10485760, backupCount=5) for 10MB files with 5 backups.

Copilot uses AI. Check for mistakes.
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.

Add logging and error tracking to MCP server

2 participants