Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 34 additions & 16 deletions src/mcp_agent/cli/cloud/commands/logger/configure/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def configure_logger(
that will be used for collecting logs from your deployed MCP apps.

Examples:
mcp-agent cloud logger configure https://otel.example.com:4318/v1/logs
mcp-agent cloud logger configure https://otel.example.com:4318/v1/traces
mcp-agent cloud logger configure https://otel.example.com --headers "Authorization=Bearer token,X-Custom=value"
mcp-agent cloud logger configure --test # Test current configuration
"""
Expand All @@ -52,8 +52,13 @@ def configure_logger(
if config_path and config_path.exists():
config = _load_config(config_path)
otel_config = config.get("otel", {})
endpoint = otel_config.get("endpoint")
headers_dict = otel_config.get("headers", {})
otlp_settings = otel_config.get("otlp_settings", {})
endpoint = otlp_settings.get("endpoint")
headers_dict = otlp_settings.get("headers", {})
if not endpoint:
# Fallback to old format for backward compatibility
endpoint = otel_config.get("endpoint")
headers_dict = otel_config.get("headers", {})
else:
console.print(
"[yellow]No configuration file found. Use --endpoint to set up OTEL configuration.[/yellow]"
Expand All @@ -75,17 +80,15 @@ def configure_logger(

try:
with httpx.Client(timeout=10.0) as client:
response = client.get(
endpoint.replace("/v1/logs", "/health")
if "/v1/logs" in endpoint
else f"{endpoint}/health",
headers=headers_dict,
)
test_url = endpoint
if "/v1/traces" in endpoint or "/v1/logs" in endpoint:
test_url = endpoint.replace("/v1/traces", "/health").replace("/v1/logs", "/health")
else:
test_url = f"{endpoint.rstrip('/')}/health"

response = client.get(test_url, headers=headers_dict)

if response.status_code in [
200,
404,
]: # 404 is fine, means endpoint exists
if response.status_code in [200, 404]: # 404 is fine, means endpoint exists
console.print("[green]✓ Connection successful[/green]")
else:
console.print(
Expand All @@ -107,9 +110,22 @@ def configure_logger(

if "otel" not in config:
config["otel"] = {}

config["otel"]["endpoint"] = endpoint
config["otel"]["headers"] = headers_dict

otel_config = config["otel"]

otel_config["enabled"] = True

exporters = otel_config.get("exporters", [])
if "otlp" not in exporters:
exporters.append("otlp")
otel_config["exporters"] = exporters

if "otlp_settings" not in otel_config:
otel_config["otlp_settings"] = {}

otel_config["otlp_settings"]["endpoint"] = endpoint
if headers_dict:
otel_config["otlp_settings"]["headers"] = headers_dict

try:
config_path.parent.mkdir(parents=True, exist_ok=True)
Expand All @@ -119,6 +135,8 @@ def configure_logger(
console.print(
Panel(
f"[green]✓ OTEL configuration saved to {config_path}[/green]\n\n"
f"Enabled: true\n"
f"Exporters: {otel_config['exporters']}\n"
f"Endpoint: {endpoint}\n"
f"Headers: {len(headers_dict)} configured"
+ (f" ({', '.join(headers_dict.keys())})" if headers_dict else ""),
Expand Down
5 changes: 5 additions & 0 deletions src/mcp_agent/cli/cloud/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
whoami,
)
from mcp_agent.cli.cloud.commands.logger import tail_logs
from mcp_agent.cli.cloud.commands.logger.configure import configure_logger
from mcp_agent.cli.cloud.commands.app import (
delete_app,
get_app_status,
Expand Down Expand Up @@ -190,6 +191,10 @@ def invoke(self, ctx):
cls=HelpfulTyperGroup,
)
# Register logger commands under cloud logger
app_cmd_cloud_logger.command(
name="configure",
help="Set OTEL endpoint and headers; test and apply configuration",
)(configure_logger)
app_cmd_cloud_logger.command(
name="tail",
help="Retrieve and stream logs from deployed MCP apps",
Expand Down
Loading