Skip to content

Conversation

@xiangyan99
Copy link
Member

@xiangyan99 xiangyan99 commented Nov 10, 2025

What does this PR do?

[Provide a clear, concise description of the changes]

  • Added logging customization options to the azmcp server start command:
    • Added --log-level option to set the minimum logging level (Trace, Debug, Information, Warning, Error, Critical, None)
    • Added --log-file-path option to write logs to a specified file with automatic directory creation and thread-safe file handling

User can use

azmcp server start --log-level Debug --log-file-path c:\logs\azmcp.log

to enable debug logging

[Any additional context, screenshots, or information that helps reviewers]

GitHub issue number?

[Link to the GitHub issue this PR addresses]

Pre-merge Checklist

  • Required for All PRs
    • Read contribution guidelines
    • PR title clearly describes the change
    • Commit history is clean with descriptive messages (cleanup guide)
    • Added comprehensive tests for new/modified functionality
    • Updated servers/Azure.Mcp.Server/CHANGELOG.md and/or servers/Fabric.Mcp.Server/CHANGELOG.md for product changes (features, bug fixes, UI/UX, updated dependencies)
  • For MCP tool changes:
    • One tool per PR: This PR adds or modifies only one MCP tool for faster review cycles
    • Updated servers/Azure.Mcp.Server/README.md and/or servers/Fabric.Mcp.Server/README.md documentation
    • Validate README.md changes using script at eng/scripts/Process-PackageReadMe.ps1. See Package README
    • Updated command list in /servers/Azure.Mcp.Server/docs/azmcp-commands.md and/or /docs/fabric-commands.md
    • Run .\eng\scripts\Update-AzCommandsMetadata.ps1 to update tool metadata in azmcp-commands.md (required for CI)
    • For new or modified tool descriptions, ran ToolDescriptionEvaluator and obtained a score of 0.4 or more and a top 3 ranking for all related test prompts
    • For new tools associated with Azure services or publicly available tools/APIs/products, add URL to documentation in the PR description
  • Extra steps for Azure MCP Server tool changes:
    • Updated test prompts in /servers/Azure.Mcp.Server/docs/e2eTestPrompts.md
    • 👉 For Community (non-Microsoft team member) PRs:
      • Security review: Reviewed code for security vulnerabilities, malicious code, or suspicious activities before running tests (crypto mining, spam, data exfiltration, etc.)
      • Manual tests run: added comment /azp run mcp - pullrequest - live to run Live Test Pipeline

@joshfree joshfree moved this from Untriaged to In Progress in Azure MCP Server Nov 13, 2025
@xiangyan99 xiangyan99 marked this pull request as ready for review November 14, 2025 22:25
@xiangyan99 xiangyan99 requested review from a team as code owners November 14, 2025 22:25
Copilot finished reviewing on behalf of xiangyan99 November 14, 2025 22:26
Copy link
Contributor

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 logging customization capabilities to the azmcp server start command, enabling users to control log verbosity and output destinations.

Key Changes:

  • Added --log-level option to set minimum logging level (Trace, Debug, Information, Warning, Error, Critical, None)
  • Added --log-file-path option to write logs to a specified file with automatic directory creation
  • Implemented Azure SDK EventSource log forwarding to capture Azure SDK diagnostic events

Reviewed Changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 12 comments.

Show a summary per file
File Description
servers/Azure.Mcp.Server/docs/azmcp-commands.md Documents the new --log-level and --log-file-path options with security warnings
servers/Azure.Mcp.Server/CHANGELOG.md Records the new logging customization features
core/Azure.Mcp.Core/src/Areas/Server/Options/ServiceStartOptions.cs Adds LogLevel and LogFilePath properties to configuration options
core/Azure.Mcp.Core/src/Areas/Server/Options/ServiceOptionDefinitions.cs Defines CLI option definitions for log level and log file path
core/Azure.Mcp.Core/src/Areas/Server/Commands/ServiceStartCommand.cs Implements logging configuration logic and integrates new options
core/Azure.Mcp.Core/src/Areas/Server/Services/SimpleFileLoggerProvider.cs Implements a simple file logger provider with thread-safe file writing
core/Azure.Mcp.Core/src/Logging/AzureSdkEventSourceLogForwarder.cs Forwards Azure SDK EventSource events to logging infrastructure
core/Azure.Mcp.Core/src/Logging/AzureSdkLogForwarderHostedService.cs Hosted service to manage the lifecycle of the Azure SDK log forwarder
core/Azure.Mcp.Core/src/Extensions/OpenTelemetryExtensions.cs Integrates Azure SDK logging with configurable event levels
core/Azure.Mcp.Core/tests/Azure.Mcp.Core.UnitTests/Areas/Server/SimpleFileLoggerProviderTests.cs Comprehensive tests for the file logger provider
core/Azure.Mcp.Core/tests/Azure.Mcp.Core.UnitTests/Areas/Server/ServiceStartCommandTests.cs Tests for parsing and binding the new logging options

{
Directory.CreateDirectory(directory);
}
File.AppendAllText(_filePath, logEntry + Environment.NewLine);
Copy link

Copilot AI Nov 14, 2025

Choose a reason for hiding this comment

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

Using File.AppendAllText for each log entry causes frequent file open/close operations, which is inefficient for high-frequency logging. Consider using a StreamWriter with auto-flush or implement buffering for better performance.

Copilot uses AI. Check for mistakes.
Copy link
Contributor

@alzimmermsft alzimmermsft Nov 19, 2025

Choose a reason for hiding this comment

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

@xiangyan99, this is probably not a bad idea and can be implemented in a way where the provider owns the stream for its lifetime and the stream is opened in a way where deletion of the file is prevented. That way we don't need to check directory existence and open a new file handle every time we're trying to log.

Copy link
Member

Choose a reason for hiding this comment

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

Additionally, it might be good to do the I/O on a background thread. Have the Log method write to a buffer, and use a BackgroundService to write to that file as the buffer fills.

@xiangyan99 xiangyan99 changed the title add log-level support add logging-level support Nov 17, 2025
@KarishmaGhiya
Copy link
Member

PR changes look good to me. We should definitely add docs for how to access logging for the customers. Especially with scenarios - What happens when only one of the params is set:
If only log-file-path is set
If only log-level is set

  • What happens when both the params is not set, the default scenario
  • How to access logging via Opentelemetry, if you can point to those steps through the docs, it will be useful for customers.

// Get or create a logger for this event source
if (!_loggers.TryGetValue(eventData.EventSource.Name, out var logger))
{
logger = _loggerFactory.CreateLogger($"Azure.SDK.{eventData.EventSource.Name}");
Copy link
Member

Choose a reason for hiding this comment

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

Do we need to worry about concurrent execution of this method?

Copy link
Member Author

Choose a reason for hiding this comment

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

In the file logging case, it is thread-safe.

DefaultValueFactory = _ => Options.OutgoingAuthStrategy.NotSet
};

public static readonly Option<string?> LogLevel = new(
Copy link
Member

Choose a reason for hiding this comment

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

Can we avoid creating a new argument for log levels? Controlling log levels with configurations is built into the ILogger infrastructure with log categories and log levels. These can both be controlled using any number of sources of configurations, including command line and environment variables.

// If LogLevel.None is specified, clear all providers to disable logging
if (logLevel == LogLevel.None)
{
logging.ClearProviders();
Copy link
Member

Choose a reason for hiding this comment

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

@xiangyan99, please chat with @srnagar on the changes that he's making for logging. We're trying to improve the situation for remote MCP servers, and Srikanta's changes similarly have a switch to shut off all telemetry.

@kvenkatrajan kvenkatrajan added the Do Not Merge Do Not Merge / WIP PRs label Nov 20, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Do Not Merge Do Not Merge / WIP PRs

Projects

Status: In Progress

Development

Successfully merging this pull request may close these issues.

7 participants