Skip to content

Commit 764d36f

Browse files
kumar-tigercrivetimihaiclaude
authored
Issues/364 Add Log File Support to MCP Gateway (#643)
* added log file with rotation Signed-off-by: kumar-tiger <[email protected]> * Fix logging service integration issues - Add python-json-logger dependency to pyproject.toml - Fix circular import by removing LoggingService from retry_manager.py - Fix logging service lazy handler initialization - Clean up unused logging imports - All tests passing with 80% coverage Co-Authored-By: Claude <[email protected]> Signed-off-by: Mihai Criveti <[email protected]> * Update documentation for logging service features - Enhanced README.md logging section with comprehensive details - Updated docs/manage/logging.md with file rotation and dual-format info - Revised ADR-005 to reflect current implementation status - Added log file management, debug mode, and troubleshooting guides - Documented all new configuration options and usage examples Co-Authored-By: Claude <[email protected]> Signed-off-by: Mihai Criveti <[email protected]> * Rebase and minor fixes Signed-off-by: Mihai Criveti <[email protected]> * Rebase and minor fixes Signed-off-by: Mihai Criveti <[email protected]> * Rebase and expand logging to other python files, make logging optional Signed-off-by: Mihai Criveti <[email protected]> * Configurable rotation Signed-off-by: Mihai Criveti <[email protected]> * Update .env.exaple Signed-off-by: Mihai Criveti <[email protected]> * Fix dual logging Signed-off-by: Mihai Criveti <[email protected]> * Update test coverage Signed-off-by: Mihai Criveti <[email protected]> --------- Signed-off-by: kumar-tiger <[email protected]> Signed-off-by: Mihai Criveti <[email protected]> Co-authored-by: Mihai Criveti <[email protected]> Co-authored-by: Claude <[email protected]>
1 parent 1eee765 commit 764d36f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+1377
-108
lines changed

.env.example

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,8 +171,26 @@ LOG_LEVEL=INFO
171171
# Log format: json or text
172172
LOG_FORMAT=json
173173

174-
# Optional path to write logs to file (leave empty to log to stdout)
175-
#LOG_FILE=./logs/gateway.log
174+
# Enable file logging (default: false - logs to stdout/stderr only)
175+
LOG_TO_FILE=false
176+
177+
# Log filename (when file logging enabled)
178+
#LOG_FILE=gateway.log
179+
180+
# Log directory (when file logging enabled)
181+
#LOG_FOLDER=./logs
182+
183+
# File write mode: a+ (append) or w (overwrite)
184+
#LOG_FILEMODE=a+
185+
186+
# Enable log rotation (default: false)
187+
#LOG_ROTATION_ENABLED=false
188+
189+
# Max file size before rotation (MB)
190+
#LOG_MAX_SIZE_MB=1
191+
192+
# Number of backup files to keep
193+
#LOG_BACKUP_COUNT=5
176194

177195
#####################################
178196
# Transport Configuration

CLAUDE.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,8 +139,22 @@ MCPGATEWAY_ADMIN_API_ENABLED=true
139139
MCPGATEWAY_ENABLE_MDNS_DISCOVERY=true
140140
MCPGATEWAY_ENABLE_FEDERATION=true
141141

142-
# Development
142+
# Logging (Dual Output Support)
143143
LOG_LEVEL=INFO
144+
LOG_TO_FILE=false # Enable file logging (default: stdout/stderr only)
145+
LOG_ROTATION_ENABLED=false # Enable log rotation when file logging is enabled
146+
LOG_MAX_SIZE_MB=1 # Max file size before rotation (MB)
147+
LOG_BACKUP_COUNT=5 # Number of backup files to keep
148+
LOG_FILE=mcpgateway.log # Log filename (when file logging enabled)
149+
LOG_FOLDER=logs # Log directory (when file logging enabled)
150+
151+
# Dual Logging Features:
152+
# - Console logs: Human-readable text format (always enabled)
153+
# - File logs: Structured JSON format (when LOG_TO_FILE=true)
154+
# - All logs appear in both outputs: application, services, HTTP access logs
155+
# - File rotation: Configurable size-based rotation with backup retention
156+
157+
# Development
144158
RELOAD=true # For development hot-reload
145159
```
146160

README.md

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1016,11 +1016,53 @@ You can get started by copying the provided [.env.example](.env.example) to `.en
10161016

10171017
### Logging
10181018

1019-
| Setting | Description | Default | Options |
1020-
| ------------ | ----------------- | ------- | ------------------ |
1021-
| `LOG_LEVEL` | Minimum log level | `INFO` | `DEBUG`...`CRITICAL` |
1022-
| `LOG_FORMAT` | Log format | `json` | `json`, `text` |
1023-
| `LOG_FILE` | Log output file | (none) | path or empty |
1019+
MCP Gateway provides flexible logging with **stdout/stderr output by default** and **optional file-based logging**. When file logging is enabled, it provides JSON formatting for structured logs and text formatting for console output.
1020+
1021+
| Setting | Description | Default | Options |
1022+
| ----------------------- | ---------------------------------- | ----------------- | -------------------------- |
1023+
| `LOG_LEVEL` | Minimum log level | `INFO` | `DEBUG`...`CRITICAL` |
1024+
| `LOG_FORMAT` | Console log format | `json` | `json`, `text` |
1025+
| `LOG_TO_FILE` | **Enable file logging** | **`false`** | **`true`, `false`** |
1026+
| `LOG_FILE` | Log filename (when enabled) | `null` | `mcpgateway.log` |
1027+
| `LOG_FOLDER` | Directory for log files | `null` | `logs`, `/var/log/gateway` |
1028+
| `LOG_FILEMODE` | File write mode | `a+` | `a+` (append), `w` (overwrite)|
1029+
| `LOG_ROTATION_ENABLED` | **Enable log file rotation** | **`false`** | **`true`, `false`** |
1030+
| `LOG_MAX_SIZE_MB` | Max file size before rotation (MB) | `1` | Any positive integer |
1031+
| `LOG_BACKUP_COUNT` | Number of backup files to keep | `5` | Any non-negative integer |
1032+
1033+
**Logging Behavior:**
1034+
- **Default**: Logs only to **stdout/stderr** with human-readable text format
1035+
- **File Logging**: When `LOG_TO_FILE=true`, logs to **both** file (JSON format) and console (text format)
1036+
- **Log Rotation**: When `LOG_ROTATION_ENABLED=true`, files rotate at `LOG_MAX_SIZE_MB` with `LOG_BACKUP_COUNT` backup files (e.g., `.log.1`, `.log.2`)
1037+
- **Directory Creation**: Log folder is automatically created if it doesn't exist
1038+
- **Centralized Service**: All modules use the unified `LoggingService` for consistent formatting
1039+
1040+
**Example Configurations:**
1041+
1042+
```bash
1043+
# Default: stdout/stderr only (recommended for containers)
1044+
LOG_LEVEL=INFO
1045+
# No additional config needed - logs to stdout/stderr
1046+
1047+
# Optional: Enable file logging (no rotation)
1048+
LOG_TO_FILE=true
1049+
LOG_FOLDER=/var/log/mcpgateway
1050+
LOG_FILE=gateway.log
1051+
LOG_FILEMODE=a+
1052+
1053+
# Optional: Enable file logging with rotation
1054+
LOG_TO_FILE=true
1055+
LOG_ROTATION_ENABLED=true
1056+
LOG_MAX_SIZE_MB=10
1057+
LOG_BACKUP_COUNT=3
1058+
LOG_FOLDER=/var/log/mcpgateway
1059+
LOG_FILE=gateway.log
1060+
```
1061+
1062+
**Default Behavior:**
1063+
- Logs are written **only to stdout/stderr** in human-readable text format
1064+
- File logging is **disabled by default** (no files created)
1065+
- Set `LOG_TO_FILE=true` to enable optional file logging with JSON format
10241066

10251067
### Transport
10261068

Lines changed: 38 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# ADR-0005: Structured JSON Logging
22

3-
- *Status:* Accepted
4-
- *Date:* 2025-02-21
3+
- *Status:* Implemented
4+
- *Date:* 2025-01-09
55
- *Deciders:* Core Engineering Team
66

77
## Context
@@ -14,27 +14,38 @@ The gateway must emit logs that:
1414

1515
Our configuration supports:
1616

17-
- `LOG_FORMAT`: `json` or `plain`
18-
- `LOG_LEVEL`: standard Python levels
19-
- `LOG_FILE`: optional log file destination
17+
- `LOG_FORMAT`: `json` or `text` (console format only)
18+
- `LOG_LEVEL`: standard Python levels (`DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL`)
19+
- `LOG_TO_FILE`: enable file logging (default: `false` - stdout/stderr only)
20+
- `LOG_FILE`: log filename when file logging is enabled (default: `null`)
21+
- `LOG_FOLDER`: directory for log files when enabled (default: `null`)
22+
- `LOG_FILEMODE`: file write mode (default: `a+` for append)
23+
- `LOG_ROTATION_ENABLED`: enable automatic log rotation (default: `false`)
24+
- `LOG_MAX_SIZE_MB`: maximum file size before rotation in MB (default: `1`)
25+
- `LOG_BACKUP_COUNT`: number of backup files to keep (default: `5`)
2026

21-
Logs are initialized at startup via `LoggingService`.
27+
Logs are initialized at startup via centralized `LoggingService`. By default, logs go only to stdout/stderr. File logging with dual-format output is optional via `LOG_TO_FILE=true`.
2228

2329
## Decision
2430

25-
Use the Python standard `logging` module with:
31+
Use the Python standard `logging` module with centralized `LoggingService`:
2632

27-
- A **custom JSON formatter** for structured logs (e.g. `{"level": "INFO", "msg": ..., "request_id": ...}`)
28-
- **Plain text output** when `LOG_FORMAT=plain`
29-
- Per-request context via filters or middleware
30-
- Global setup at app startup to avoid late binding issues
33+
- **JSON formatter** for file logs using `python-json-logger` library
34+
- **Text formatter** for console logs for human readability
35+
- **Dual output**: JSON to files, text to console
36+
- **Optional rotating file handler** for automatic log management (configurable)
37+
- **Centralized service** integrated across all 22+ modules
38+
- Global setup at app startup with lazy handler initialization
3139

3240
## Consequences
3341

34-
- 📋 Easily parsed logs suitable for production observability pipelines
35-
- ⚙️ Compatible with `stdout`, file, or syslog targets
36-
- 🧪 Local development uses plain logs for readability
37-
- 🧱 Minimal dependency footprint (no third-party logging libraries)
42+
- 📋 **Structured JSON logs** suitable for production observability pipelines (ELK, Datadog, etc.)
43+
- ⚙️ **Dual format support**: JSON files for machines, text console for humans
44+
- 🔄 **Optional log rotation** prevents disk space issues when enabled
45+
- 🧪 **Development-friendly** with human-readable console output
46+
- 📁 **Organized storage** with configurable log directories and retention
47+
- 🧱 **Minimal dependencies**: Uses standard library + `python-json-logger`
48+
- 🎯 **Consistent logging** across all application modules
3849

3950
## Alternatives Considered
4051

@@ -47,4 +58,15 @@ Use the Python standard `logging` module with:
4758

4859
## Status
4960

50-
Structured logging is implemented in `LoggingService`, configurable via environment variables.
61+
**✅ Implemented** - Structured logging is fully implemented in `LoggingService` with:
62+
63+
- Centralized logging service integrated across all modules
64+
- Dual-format output (JSON to files, text to console)
65+
- HTTP access log capture (uvicorn.access and uvicorn.error loggers)
66+
- Optional log rotation with configurable size limits and retention
67+
- Environment variable configuration support
68+
- Production-ready with proper error handling and lazy initialization
69+
70+
**Files Modified**: 22 modules updated to use `LoggingService`
71+
**Dependencies Added**: `python-json-logger>=2.0.0`
72+
**Configuration**: Via `LOG_LEVEL`, `LOG_FORMAT`, `LOG_TO_FILE`, `LOG_FILE`, `LOG_FOLDER`, `LOG_FILEMODE`, `LOG_ROTATION_ENABLED`, `LOG_MAX_SIZE_MB`, `LOG_BACKUP_COUNT`

docs/docs/faq/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@
6666
???+ example "🪛 What are some advanced environment variables I can configure?"
6767
- Basic: `HOST`, `PORT`, `APP_ROOT_PATH`
6868
- Auth: `AUTH_REQUIRED`, `BASIC_AUTH_*`, `JWT_SECRET_KEY`
69-
- Logging: `LOG_LEVEL`, `LOG_FORMAT`, `LOG_FILE`
69+
- Logging: `LOG_LEVEL`, `LOG_FORMAT`, `LOG_TO_FILE`, `LOG_FILE`, `LOG_FOLDER`, `LOG_ROTATION_ENABLED`, `LOG_MAX_SIZE_MB`, `LOG_BACKUP_COUNT`
7070
- Transport: `TRANSPORT_TYPE`, `WEBSOCKET_PING_INTERVAL`, `SSE_RETRY_TIMEOUT`
7171
- Tools: `TOOL_TIMEOUT`, `MAX_TOOL_RETRIES`, `TOOL_RATE_LIMIT`, `TOOL_CONCURRENT_LIMIT`
7272
- Federation: `FEDERATION_ENABLED`, `FEDERATION_PEERS`, `FEDERATION_SYNC_INTERVAL`

docs/docs/manage/.pages

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ nav:
22
- index.md
33
- backup.md
44
- logging.md
5+
- logging-examples.md
56
- upgrade.md
67
- tuning.md
78
- securing.md

0 commit comments

Comments
 (0)