Centralized Structured Logging for Microservices
Project description
wmlog - Centralized Structured Logging
wmlog is a production-ready centralized logging system that enables structured logging with real-time broadcasting over WebSocket and MQTT. Designed for microservices, embedded systems, and distributed applications that need unified, observable logging across multiple services and environments.
๐ Part of the modular ecosystem: ProServe (core framework) โข Servos (isolation) โข EDPMT (hardware) โข wmlog (logging) โข SELLM (AI-powered manifest generator)
๐ Features
- Structured Logging: Built on
structlogwith rich context and metadata - Real-time Broadcasting: WebSocket and MQTT streaming for live log monitoring
- Multiple Formatters: JSON, Rich Console, Compact, and Structured output
- Custom Handlers: WebSocket, MQTT, Redis, File, and more
- CLI Tools: Command-line interface for log management and monitoring
- Context Enrichment: Automatic service, environment, and request context
- Async Support: Full async/await support for high-performance applications
- Redis Integration: Optional Redis backend for log storage and analysis
- Rich Console Output: Beautiful console logging with syntax highlighting
๐ฆ Installation
# Install from PyPI
pip install wmlog
# Install with optional dependencies
pip install wmlog[redis,mqtt,websocket]
# Development installation
git clone https://github.com/tom-sapletta-com/wmlog.git
cd wmlog
pip install -e .
๐๏ธ Architecture
wmlog Ecosystem Integration
graph TB
subgraph "Modular Ecosystem"
ProServe[ProServe Framework<br/>Core Microservices]
Servos[Servos<br/>Environment Isolation]
EDPMT[EDPMT Framework<br/>Hardware Control]
wmlog[wmlog<br/>Centralized Logging]
SELLM[SELLM<br/>AI-powered Manifest Generation]
end
ProServe --> wmlog
Servos --> wmlog
EDPMT --> wmlog
SELLM --> wmlog
subgraph "wmlog Core Architecture"
WMLLogger[WMLLogger<br/>Singleton Instance]
LogContext[LogContext<br/>Enrichment]
LoggingConfig[LoggingConfig<br/>Configuration]
end
wmlog --> WMLLogger
wmlog --> LogContext
wmlog --> LoggingConfig
subgraph "Formatters"
JSON[JSON Formatter]
Rich[Rich Console]
Compact[Compact Format]
Structured[Structured Text]
end
WMLLogger --> JSON
WMLLogger --> Rich
WMLLogger --> Compact
WMLLogger --> Structured
subgraph "Handlers & Outputs"
Console[Console Output]
FileHandler[File Logging]
WebSocket[WebSocket Broadcasting]
MQTT[MQTT Publishing]
Redis[Redis Storage]
end
JSON --> Console
Rich --> Console
JSON --> FileHandler
JSON --> WebSocket
JSON --> MQTT
JSON --> Redis
subgraph "External Systems"
WebClients[Web Clients<br/>Real-time Monitoring]
MQTTBroker[MQTT Broker<br/>Message Distribution]
RedisDB[Redis Database<br/>Log Storage]
LogFiles[Log Files<br/>Persistent Storage]
end
WebSocket --> WebClients
MQTT --> MQTTBroker
Redis --> RedisDB
FileHandler --> LogFiles
Detailed wmlog Architecture
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ wmlog Architecture โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โ
โ โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ โ
โ โ ProServe โ โ Servos โ โ EDPMT โ โ
โ โ Services โโโโ Isolation โโโโ Framework โ โ
โ โ โ โ โ โ โ โ
โ โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ โ
โ โ โ โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ โ
โ โผ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ wmlog Core โ โ
โ โ โ โ
โ โ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโ โ โ
โ โ โ WMLLogger โ โ LogContext โ โ LoggingConfig โ โ โ
โ โ โ โ โ โ โ โ โ โ
โ โ โโข Singleton โ โโข Service โ โโข Environment Vars โ โ โ
โ โ โโข Async โ โโข Environmentโ โโข File/Console โ โ โ
โ โ โโข Structured โ โโข Custom โ โโข WebSocket/MQTT โ โ โ
โ โ โโข Context โ โ Fields โ โโข Redis Integration โ โ โ
โ โ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโ โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ โ
โ โผ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ Formatters โ โ
โ โ โโโโโโโโโโโโ โโโโโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโ โ โ
โ โ โ JSON โ โ Rich โ โ Compact โ โ Structured โ โ โ
โ โ โ โ โ Console โ โ Format โ โ Text โ โ โ
โ โ โโข Strict โ โโข Colors โ โโข Minimal โ โโข Key-Value Pairs โ โ โ
โ โ โโข Machine โ โโข Syntax โ โโข High โ โโข Human Readable โ โ โ
โ โ โ Readableโ โ Highlight โ โ Volume โ โโข Debugging โ โ โ
โ โ โโโโโโโโโโโโ โโโโโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโ โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ โ
โ โผ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ Handlers & Broadcasting โ โ
โ โ โโโโโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโ โ โ
โ โ โ Console โ โ File โ โ WebSocketโ โ MQTT โ โ Redis โ โ โ
โ โ โ โ โ โ โ โ โ โ โ โ โ โ
โ โ โโข Stdout โ โโข Rotationโ โโข Real- โ โโข Pub/Sub โ โโข Storage โ โ โ
โ โ โโข Stderr โ โโข Size โ โ time โ โโข Topics โ โโข TTL โ โ โ
โ โ โโข Colors โ โ Limits โ โโข Live โ โโข QoS โ โโข Search โ โ โ
โ โ โโข Rich โ โโข Backup โ โ Monitor โ โโข Retain โ โโข Analysisโ โ โ
โ โ โ Format โ โ Count โ โโข Multipleโ โโข Auth โ โโข Metrics โ โ โ
โ โ โ โ โ โ โ Clients โ โ โ โ โ โ โ
โ โ โโโโโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโ โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ โ
โ โผ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ External Systems โ โ
โ โ โโโโโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโ โ โ
โ โ โ Local โ โ Log โ โ Web โ โ MQTT โ โ Redis โ โ โ
โ โ โ Terminal โ โ Files โ โ Clients โ โ Broker โ โ Database โ โ โ
โ โ โ โ โ โ โ โ โ โ โ โ โ โ
โ โ โโข Developmentโ โโข Prod โ โโข Dashbd โ โโข Message โ โโข Analyticsโ โ โ
โ โ โโข Debugging โ โโข Audit โ โโข Monitorโ โ Queue โ โโข Long-termโ โ โ
โ โ โโข Rich UI โ โโข Archive โ โโข Alerts โ โโข Fanout โ โ Storage โ โ โ
โ โ โโโโโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโ โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
๐ ๏ธ Quick Start
Basic Logging
from wmlog import WMLLogger, LoggingConfig
# Create logging configuration
config = LoggingConfig(
service_name="my-service",
log_level="info",
console_enabled=True,
console_format="rich"
)
# Get logger instance
logger = WMLLogger.get_logger(config)
# Log messages with structured data
logger.logger.info("Service started", port=8080, environment="production")
logger.logger.error("Database connection failed",
error="Connection timeout",
retry_count=3)
WebSocket Broadcasting
from wml import WMLLogger, LoggingConfig
config = LoggingConfig(
service_name="websocket-service",
websocket_enabled=True,
websocket_port=8765,
websocket_host="0.0.0.0"
)
logger = WMLLogger.get_logger(config)
# Logs will be automatically broadcast to WebSocket clients
logger.logger.info("WebSocket message", client_count=42)
MQTT Integration
from wml import WMLLogger, LoggingConfig
config = LoggingConfig(
service_name="mqtt-service",
mqtt_enabled=True,
mqtt_broker="mqtt://localhost:1883",
mqtt_topic="logs/my-service"
)
logger = WMLLogger.get_logger(config)
# Logs will be published to MQTT broker
logger.logger.warning("High memory usage", memory_percent=85)
Context Enrichment
from wml import WMLLogger, LoggingConfig, LogContext
# Create context with additional metadata
context = LogContext(
service_name="api-service",
environment="staging",
version="1.2.3",
custom_data={"region": "us-east-1", "datacenter": "dc-01"}
)
config = LoggingConfig(service_name="api-service")
logger = WMLLogger.get_logger(config, context)
# All logs will include context information
logger.logger.info("Request processed",
request_id="req-123",
response_time=0.045)
๐ฅ๏ธ CLI Usage
WML provides a comprehensive CLI for log management and monitoring:
Send Log Messages
# Send a simple log message
wmlog log "Hello, World!"
# Send with specific service and level
wmlog log --service my-service --level error "Something went wrong"
# Send with MQTT broadcasting
wmlog log --mqtt-broker localhost:1883 --mqtt-topic logs/test "MQTT log message"
Monitor Logs
# Monitor MQTT logs
wmlog monitor --broker localhost:1883 --topic "logs/#"
# Monitor with filtering
wmlog monitor --broker localhost:1883 --filter-service my-service --filter-level error
# Monitor WebSocket logs
wmlog websocket-monitor --port 8765 --host localhost
Start Broadcasting Server
# Start WebSocket and MQTT broadcasting server
wmlog server --websocket-port 8765 --mqtt-broker localhost:1883
# Start WebSocket-only server
wmlog server --websocket-port 8765
Test Configuration
# Test with default configuration
wmlog test
# Test with custom configuration file
wmlog test --config-file config.json
Package Information
# Show package information
wmlog info
๐ Documentation
- API Documentation - Detailed reference for wmlog APIs
Python Packages
Explore the ecosystem of Python packages related to wmlog:
- ProServe - Core microservices framework
- Servos - Environment isolation and orchestration
- wmlog - Centralized structured logging
- SELLM - AI-powered manifest generator
- EDPMT - Hardware control framework for IoT
Why wmlog?
- Unified Logging: Centralized logging for microservices and distributed systems
- Real-time Monitoring: Live log streaming with WebSocket and MQTT
- Flexible Configuration: Customizable logging formats, handlers, and outputs
- Async Support: High-performance logging for async applications
- Redis Integration: Optional Redis backend for log storage and analysis
- Rich Console Output: Beautiful console logging with syntax highlighting
๐ง Advanced Usage
Custom Formatters
from wml.formatters import JSONFormatter, RichConsoleFormatter
# Custom JSON formatter with additional fields
json_formatter = JSONFormatter(
include_extra_fields=True,
timestamp_format="iso",
pretty_print=True
)
# Custom Rich formatter with specific styling
rich_formatter = RichConsoleFormatter(
show_time=True,
show_level=True,
show_path=False,
markup=True
)
Custom Handlers
from wml.handlers import WebSocketHandler, MQTTHandler, RedisHandler
# WebSocket handler for real-time streaming
ws_handler = WebSocketHandler(
host="0.0.0.0",
port=8765,
path="/logs"
)
# MQTT handler for pub/sub messaging
mqtt_handler = MQTTHandler(
broker_url="mqtt://localhost:1883",
topic="logs/my-service",
qos=1,
retain=False
)
# Redis handler for log storage
redis_handler = RedisHandler(
redis_url="redis://localhost:6379/0",
key_prefix="logs:",
expire_seconds=86400
)
Async Logging
import asyncio
from wml import WMLLogger, LoggingConfig
async def async_application():
config = LoggingConfig(
service_name="async-service",
websocket_enabled=True
)
logger = WMLLogger.get_logger(config)
# Async logging with context
async with logger.context(request_id="req-456"):
logger.logger.info("Processing async request")
# Simulate async work
await asyncio.sleep(1)
logger.logger.info("Async request completed")
# Run async application
asyncio.run(async_application())
๐ Integration Examples
Flask Application
from flask import Flask, request
from wml import WMLLogger, LoggingConfig, LogContext
app = Flask(__name__)
# Initialize WML logger
config = LoggingConfig(
service_name="flask-api",
console_format="rich",
websocket_enabled=True,
mqtt_enabled=True,
mqtt_broker="mqtt://localhost:1883"
)
logger = WMLLogger.get_logger(config)
@app.before_request
def log_request_info():
logger.logger.info("Request started",
method=request.method,
url=request.url,
remote_addr=request.remote_addr)
@app.after_request
def log_response_info(response):
logger.logger.info("Request completed",
status_code=response.status_code,
content_length=response.content_length)
return response
@app.route('/api/health')
def health():
logger.logger.info("Health check requested")
return {"status": "healthy"}
if __name__ == '__main__':
app.run(debug=True)
FastAPI Application
from fastapi import FastAPI, Request
from wml import WMLLogger, LoggingConfig
import time
app = FastAPI()
# Initialize WML logger
config = LoggingConfig(
service_name="fastapi-service",
console_format="rich",
websocket_enabled=True
)
logger = WMLLogger.get_logger(config)
@app.middleware("http")
async def log_requests(request: Request, call_next):
start_time = time.time()
logger.logger.info("Request started",
method=request.method,
url=str(request.url))
response = await call_next(request)
process_time = time.time() - start_time
logger.logger.info("Request completed",
status_code=response.status_code,
process_time=process_time)
return response
@app.get("/")
async def root():
logger.logger.info("Root endpoint accessed")
return {"message": "Hello World"}
Docker Integration
FROM python:3.9-slim
WORKDIR /app
# Install WML
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
# Set environment variables for WML
ENV WML_SERVICE_NAME=docker-service
ENV WML_LOG_LEVEL=info
ENV WML_CONSOLE_FORMAT=json
ENV WML_WEBSOCKET_ENABLED=true
ENV WML_WEBSOCKET_PORT=8765
ENV WML_MQTT_ENABLED=true
ENV WML_MQTT_BROKER=mqtt://mqtt-broker:1883
EXPOSE 8000 8765
CMD ["python", "app.py"]
# docker-compose.yml
version: '3.8'
services:
app:
build: .
ports:
- "8000:8000"
- "8765:8765"
environment:
- WML_MQTT_BROKER=mqtt://mqtt:1883
depends_on:
- mqtt
- redis
mqtt:
image: eclipse-mosquitto:2.0
ports:
- "1883:1883"
- "9001:9001"
volumes:
- ./mosquitto.conf:/mosquitto/config/mosquitto.conf
redis:
image: redis:7-alpine
ports:
- "6379:6379"
log-monitor:
image: wml-cli
command: wml monitor --broker mqtt:1883 --topic "logs/#"
depends_on:
- mqtt
๐ Monitoring and Observability
Grafana Dashboard
WML integrates seamlessly with monitoring stacks:
# Send metrics alongside logs
logger.logger.info("Request processed",
request_count=1,
response_time=0.045,
memory_usage=256.5,
cpu_percent=12.3)
Prometheus Integration
from prometheus_client import Counter, Histogram, Gauge
from wml import WMLLogger, LoggingConfig
# Prometheus metrics
REQUEST_COUNT = Counter('requests_total', 'Total requests', ['method', 'endpoint'])
REQUEST_DURATION = Histogram('request_duration_seconds', 'Request duration')
MEMORY_USAGE = Gauge('memory_usage_bytes', 'Memory usage')
config = LoggingConfig(service_name="metrics-service")
logger = WMLLogger.get_logger(config)
def process_request(method, endpoint):
REQUEST_COUNT.labels(method=method, endpoint=endpoint).inc()
with REQUEST_DURATION.time():
# Process request
logger.logger.info("Request processed",
method=method,
endpoint=endpoint,
metrics_exported=True)
๐งช Testing
Run the test suite:
# Install test dependencies
pip install -e .[dev]
# Run unit tests
pytest tests/
# Run integration tests
pytest tests/integration/
# Run with coverage
pytest tests/ --cov=wml --cov-report=html
# Test CLI commands
wml test
wml info
๐ API Reference
Core Classes
WMLLogger: Main logging class with structured logging supportLoggingConfig: Configuration class for logger settingsLogContext: Context enrichment for adding metadata to logs
Formatters
JSONFormatter: JSON output with structured dataRichConsoleFormatter: Rich console output with colors and stylingStructuredFormatter: Structured text format with key-value pairsCompactFormatter: Minimal compact format for high-volume logging
Handlers
WebSocketHandler: Real-time WebSocket broadcastingMQTTHandler: MQTT pub/sub messagingRedisHandler: Redis storage and retrievalBufferedHandler: Buffered output with configurable flushing
Broadcasters
WebSocketBroadcaster: WebSocket server for real-time log streamingMQTTBroadcaster: MQTT client for pub/sub log distribution
๐ค Contributing
We welcome contributions! Please see our Contributing Guide for details.
Development Setup
# Clone the repository
git clone https://github.com/your-org/wml.git
cd wml
# Create virtual environment
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install development dependencies
pip install -e .[dev]
# Install pre-commit hooks
pre-commit install
# Run tests
pytest
Code Style
We use:
- Black for code formatting
- isort for import sorting
- flake8 for linting
- mypy for type checking
๐ License
wmlog is released under the Apache Software License 2.0. See the LICENSE file for details.
๐จโ๐ป Author
Tom Sapletta
- Email: info@softreck.dev
- GitHub: @tom-sapletta-com
- Website: softreck.dev
๐ Acknowledgments
- Built with structlog for structured logging
- Uses rich for beautiful console output
- MQTT support via paho-mqtt
- WebSocket support via aiohttp and websockets
๐ Related Projects
- ProServe: Professional microservice framework using wmlog
- Servos: Environment isolation and Docker orchestration
- EDPMT Framework: Embedded development platform with wmlog integration
- SELLM: AI-powered manifest generator
wmlog - Unifying logs across services, platforms, and environments. ๐
Made with โค๏ธ by Tom Sapletta โข Part of the modular microservices ecosystem
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file wmlog-1.0.3.tar.gz.
File metadata
- Download URL: wmlog-1.0.3.tar.gz
- Upload date:
- Size: 45.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
17f28ca10c3b38206d01a0b67cafdbabd4e07f7d2eee8d163cf1f5b0ee2016c2
|
|
| MD5 |
c4a2b516e3b06529b2aef8f39f3f451e
|
|
| BLAKE2b-256 |
72d533a71704b90e06dd3312ecdbde7bf38393e12ad85ab0f850b19ef53ef8e4
|
File details
Details for the file wmlog-1.0.3-py3-none-any.whl.
File metadata
- Download URL: wmlog-1.0.3-py3-none-any.whl
- Upload date:
- Size: 37.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1bbb10cf34f0ff51d612b2060b16d781acf7876d14a2df60e76462911fd70e2e
|
|
| MD5 |
826dae6f0e76355eb647597963cf2e18
|
|
| BLAKE2b-256 |
8435a9b52d9567774fbb824ae158fd1a1ee45a67c87935c8ba6628179380aff0
|