# wmlog - Centralized Structured Logging
[](https://badge.fury.io/py/wmlog)
[](https://pypi.org/project/wmlog/)
[](https://opensource.org/licenses/Apache-2.0)
[](https://pepy.tech/project/wmlog)
[](https://github.com/psf/black)
[](https://travis-ci.com/tom-sapletta-com/wmlog)
**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](https://pypi.org/project/proserve/) (core framework) β’ [Servos](https://pypi.org/project/servos/) (isolation) β’ [EDPMT](https://pypi.org/project/edpmt/) (hardware) β’ **wmlog** (logging) β’ [SELLM](https://pypi.org/project/sellm/) (AI-powered manifest generator)
## π Features
- **Structured Logging**: Built on `structlog` with 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
```bash
# 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
```mermaid
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
```python
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
```python
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
```python
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
```python
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
```bash
# 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
```bash
# 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
```bash
# 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
```bash
# Test with default configuration
wmlog test
# Test with custom configuration file
wmlog test --config-file config.json
```
### Package Information
```bash
# Show package information
wmlog info
```
## π Documentation
- [API Documentation](docs/API_DOCUMENTATION.md) - Detailed reference for wmlog APIs
### Python Packages
Explore the ecosystem of Python packages related to wmlog:
- [ProServe](https://pypi.org/project/proserve/) - Core microservices framework
- [Servos](https://pypi.org/project/servos/) - Environment isolation and orchestration
- [wmlog](https://pypi.org/project/wmlog/) - Centralized structured logging
- [SELLM](https://pypi.org/project/sellm/) - AI-powered manifest generator
- [EDPMT](https://pypi.org/project/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
```python
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
```python
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
```python
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
```python
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
```python
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
```dockerfile
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"]
```
```yaml
# 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:
```python
# 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
```python
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:
```bash
# 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 support
- **`LoggingConfig`**: Configuration class for logger settings
- **`LogContext`**: Context enrichment for adding metadata to logs
### Formatters
- **`JSONFormatter`**: JSON output with structured data
- **`RichConsoleFormatter`**: Rich console output with colors and styling
- **`StructuredFormatter`**: Structured text format with key-value pairs
- **`CompactFormatter`**: Minimal compact format for high-volume logging
### Handlers
- **`WebSocketHandler`**: Real-time WebSocket broadcasting
- **`MQTTHandler`**: MQTT pub/sub messaging
- **`RedisHandler`**: Redis storage and retrieval
- **`BufferedHandler`**: Buffered output with configurable flushing
### Broadcasters
- **`WebSocketBroadcaster`**: WebSocket server for real-time log streaming
- **`MQTTBroadcaster`**: MQTT client for pub/sub log distribution
## π€ Contributing
We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.
### Development Setup
```bash
# 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](LICENSE) file for details.
## π¨βπ» Author
**Tom Sapletta**
- Email: info@softreck.dev
- GitHub: [@tom-sapletta-com](https://github.com/tom-sapletta-com)
- Website: [softreck.dev](https://softreck.dev)
## π Acknowledgments
- Built with [structlog](https://www.structlog.org/) for structured logging
- Uses [rich](https://github.com/Textualize/rich) for beautiful console output
- MQTT support via [paho-mqtt](https://pypi.org/project/paho-mqtt/)
- WebSocket support via [aiohttp](https://aiohttp.readthedocs.io/) and [websockets](https://websockets.readthedocs.io/)
## π Related Projects
- **[ProServe](https://pypi.org/project/proserve/)**: Professional microservice framework using wmlog
- **[Servos](https://pypi.org/project/servos/)**: Environment isolation and Docker orchestration
- **[EDPMT Framework](https://github.com/tom-sapletta-com/edpmt)**: Embedded development platform with wmlog integration
- **[SELLM](https://pypi.org/project/sellm/)**: AI-powered manifest generator
---
**wmlog** - Unifying logs across services, platforms, and environments. π
---
**Made with β€οΈ by [Tom Sapletta](https://softreck.dev) β’ Part of the modular microservices ecosystem**
Raw data
{
"_id": null,
"home_page": "https://github.com/tom-sapletta-com/wmlog",
"name": "wmlog",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": null,
"keywords": "logging, websocket, mqtt, distributed, microservices, structured-logging, real-time, monitoring, observability, asyncio, broadcasting, centralized-logging",
"author": "Tom Sapletta",
"author_email": "info@softreck.dev",
"download_url": "https://files.pythonhosted.org/packages/d8/75/3ef7edd059fbe6e3c209fc6ab952261f050d6be659c275771b72485e457d/wmlog-1.0.4.tar.gz",
"platform": null,
"description": "# wmlog - Centralized Structured Logging\n\n[](https://badge.fury.io/py/wmlog)\n[](https://pypi.org/project/wmlog/)\n[](https://opensource.org/licenses/Apache-2.0)\n[](https://pepy.tech/project/wmlog)\n[](https://github.com/psf/black)\n[](https://travis-ci.com/tom-sapletta-com/wmlog)\n\n**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.\n\n> \ud83d\ude80 **Part of the modular ecosystem**: [ProServe](https://pypi.org/project/proserve/) (core framework) \u2022 [Servos](https://pypi.org/project/servos/) (isolation) \u2022 [EDPMT](https://pypi.org/project/edpmt/) (hardware) \u2022 **wmlog** (logging) \u2022 [SELLM](https://pypi.org/project/sellm/) (AI-powered manifest generator)\n\n## \ud83d\ude80 Features\n\n- **Structured Logging**: Built on `structlog` with rich context and metadata\n- **Real-time Broadcasting**: WebSocket and MQTT streaming for live log monitoring\n- **Multiple Formatters**: JSON, Rich Console, Compact, and Structured output\n- **Custom Handlers**: WebSocket, MQTT, Redis, File, and more\n- **CLI Tools**: Command-line interface for log management and monitoring\n- **Context Enrichment**: Automatic service, environment, and request context\n- **Async Support**: Full async/await support for high-performance applications\n- **Redis Integration**: Optional Redis backend for log storage and analysis\n- **Rich Console Output**: Beautiful console logging with syntax highlighting\n\n## \ud83d\udce6 Installation\n\n```bash\n# Install from PyPI\npip install wmlog\n\n# Install with optional dependencies\npip install wmlog[redis,mqtt,websocket]\n\n# Development installation\ngit clone https://github.com/tom-sapletta-com/wmlog.git\ncd wmlog\npip install -e .\n```\n\n## \ud83c\udfd7\ufe0f Architecture\n\n### wmlog Ecosystem Integration\n```mermaid\ngraph TB\n subgraph \"Modular Ecosystem\"\n ProServe[ProServe Framework<br/>Core Microservices]\n Servos[Servos<br/>Environment Isolation] \n EDPMT[EDPMT Framework<br/>Hardware Control]\n wmlog[wmlog<br/>Centralized Logging]\n SELLM[SELLM<br/>AI-powered Manifest Generation]\n end\n \n ProServe --> wmlog\n Servos --> wmlog\n EDPMT --> wmlog\n SELLM --> wmlog\n \n subgraph \"wmlog Core Architecture\"\n WMLLogger[WMLLogger<br/>Singleton Instance]\n LogContext[LogContext<br/>Enrichment]\n LoggingConfig[LoggingConfig<br/>Configuration]\n end\n \n wmlog --> WMLLogger\n wmlog --> LogContext\n wmlog --> LoggingConfig\n \n subgraph \"Formatters\"\n JSON[JSON Formatter]\n Rich[Rich Console]\n Compact[Compact Format]\n Structured[Structured Text]\n end\n \n WMLLogger --> JSON\n WMLLogger --> Rich\n WMLLogger --> Compact\n WMLLogger --> Structured\n \n subgraph \"Handlers & Outputs\"\n Console[Console Output]\n FileHandler[File Logging]\n WebSocket[WebSocket Broadcasting]\n MQTT[MQTT Publishing]\n Redis[Redis Storage]\n end\n \n JSON --> Console\n Rich --> Console\n JSON --> FileHandler\n JSON --> WebSocket\n JSON --> MQTT\n JSON --> Redis\n \n subgraph \"External Systems\"\n WebClients[Web Clients<br/>Real-time Monitoring]\n MQTTBroker[MQTT Broker<br/>Message Distribution]\n RedisDB[Redis Database<br/>Log Storage]\n LogFiles[Log Files<br/>Persistent Storage]\n end\n \n WebSocket --> WebClients\n MQTT --> MQTTBroker\n Redis --> RedisDB\n FileHandler --> LogFiles\n```\n\n### Detailed wmlog Architecture\n```\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502 wmlog Architecture \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 \u2502\n\u2502 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502\n\u2502 \u2502 ProServe \u2502 \u2502 Servos \u2502 \u2502 EDPMT \u2502 \u2502\n\u2502 \u2502 Services \u2502\u2500\u2500\u2502 Isolation \u2502\u2500\u2500\u2502 Framework \u2502 \u2502\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502\n\u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2502\n\u2502 \u2502 \u2502 \u2502 \u2502\n\u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2502\n\u2502 \u2502 \u2502\n\u2502 \u25bc \u2502\n\u2502 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502\n\u2502 \u2502 wmlog Core \u2502 \u2502\n\u2502 \u2502 \u2502 \u2502\n\u2502 \u2502 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502 \u2502\n\u2502 \u2502 \u2502 WMLLogger \u2502 \u2502 LogContext \u2502 \u2502 LoggingConfig \u2502 \u2502 \u2502\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502\n\u2502 \u2502 \u2502\u2022 Singleton \u2502 \u2502\u2022 Service \u2502 \u2502\u2022 Environment Vars \u2502 \u2502 \u2502\n\u2502 \u2502 \u2502\u2022 Async \u2502 \u2502\u2022 Environment\u2502 \u2502\u2022 File/Console \u2502 \u2502 \u2502\n\u2502 \u2502 \u2502\u2022 Structured \u2502 \u2502\u2022 Custom \u2502 \u2502\u2022 WebSocket/MQTT \u2502 \u2502 \u2502\n\u2502 \u2502 \u2502\u2022 Context \u2502 \u2502 Fields \u2502 \u2502\u2022 Redis Integration \u2502 \u2502 \u2502\n\u2502 \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2502 \u2502\n\u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2502\n\u2502 \u2502 \u2502\n\u2502 \u25bc \u2502\n\u2502 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502\n\u2502 \u2502 Formatters \u2502 \u2502\n\u2502 \u2502 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502 \u2502\n\u2502 \u2502 \u2502 JSON \u2502 \u2502 Rich \u2502 \u2502 Compact \u2502 \u2502 Structured \u2502 \u2502 \u2502\n\u2502 \u2502 \u2502 \u2502 \u2502 Console \u2502 \u2502 Format \u2502 \u2502 Text \u2502 \u2502 \u2502\n\u2502 \u2502 \u2502\u2022 Strict \u2502 \u2502\u2022 Colors \u2502 \u2502\u2022 Minimal \u2502 \u2502\u2022 Key-Value Pairs \u2502 \u2502 \u2502\n\u2502 \u2502 \u2502\u2022 Machine \u2502 \u2502\u2022 Syntax \u2502 \u2502\u2022 High \u2502 \u2502\u2022 Human Readable \u2502 \u2502 \u2502\n\u2502 \u2502 \u2502 Readable\u2502 \u2502 Highlight \u2502 \u2502 Volume \u2502 \u2502\u2022 Debugging \u2502 \u2502 \u2502\n\u2502 \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2502 \u2502\n\u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2502\n\u2502 \u2502 \u2502\n\u2502 \u25bc \u2502\n\u2502 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502\n\u2502 \u2502 Handlers & Broadcasting \u2502 \u2502\n\u2502 \u2502 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502 \u2502\n\u2502 \u2502 \u2502 Console \u2502 \u2502 File \u2502 \u2502 WebSocket\u2502 \u2502 MQTT \u2502 \u2502 Redis \u2502 \u2502 \u2502\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502\n\u2502 \u2502 \u2502\u2022 Stdout \u2502 \u2502\u2022 Rotation\u2502 \u2502\u2022 Real- \u2502 \u2502\u2022 Pub/Sub \u2502 \u2502\u2022 Storage \u2502 \u2502 \u2502\n\u2502 \u2502 \u2502\u2022 Stderr \u2502 \u2502\u2022 Size \u2502 \u2502 time \u2502 \u2502\u2022 Topics \u2502 \u2502\u2022 TTL \u2502 \u2502 \u2502\n\u2502 \u2502 \u2502\u2022 Colors \u2502 \u2502 Limits \u2502 \u2502\u2022 Live \u2502 \u2502\u2022 QoS \u2502 \u2502\u2022 Search \u2502 \u2502 \u2502\n\u2502 \u2502 \u2502\u2022 Rich \u2502 \u2502\u2022 Backup \u2502 \u2502 Monitor \u2502 \u2502\u2022 Retain \u2502 \u2502\u2022 Analysis\u2502 \u2502 \u2502\n\u2502 \u2502 \u2502 Format \u2502 \u2502 Count \u2502 \u2502\u2022 Multiple\u2502 \u2502\u2022 Auth \u2502 \u2502\u2022 Metrics \u2502 \u2502 \u2502\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 Clients \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502\n\u2502 \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2502 \u2502\n\u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2502\n\u2502 \u2502 \u2502\n\u2502 \u25bc \u2502\n\u2502 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502\n\u2502 \u2502 External Systems \u2502 \u2502\n\u2502 \u2502 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502 \u2502\n\u2502 \u2502 \u2502 Local \u2502 \u2502 Log \u2502 \u2502 Web \u2502 \u2502 MQTT \u2502 \u2502 Redis \u2502 \u2502 \u2502\n\u2502 \u2502 \u2502 Terminal \u2502 \u2502 Files \u2502 \u2502 Clients \u2502 \u2502 Broker \u2502 \u2502 Database \u2502 \u2502 \u2502\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2502\n\u2502 \u2502 \u2502\u2022 Development\u2502 \u2502\u2022 Prod \u2502 \u2502\u2022 Dashbd \u2502 \u2502\u2022 Message \u2502 \u2502\u2022 Analytics\u2502 \u2502 \u2502\n\u2502 \u2502 \u2502\u2022 Debugging \u2502 \u2502\u2022 Audit \u2502 \u2502\u2022 Monitor\u2502 \u2502 Queue \u2502 \u2502\u2022 Long-term\u2502 \u2502 \u2502\n\u2502 \u2502 \u2502\u2022 Rich UI \u2502 \u2502\u2022 Archive \u2502 \u2502\u2022 Alerts \u2502 \u2502\u2022 Fanout \u2502 \u2502 Storage \u2502 \u2502 \u2502\n\u2502 \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2502 \u2502\n\u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n```\n\n## \ud83d\udee0\ufe0f Quick Start\n\n### Basic Logging\n\n```python\nfrom wmlog import WMLLogger, LoggingConfig\n\n# Create logging configuration\nconfig = LoggingConfig(\n service_name=\"my-service\",\n log_level=\"info\",\n console_enabled=True,\n console_format=\"rich\"\n)\n\n# Get logger instance\nlogger = WMLLogger.get_logger(config)\n\n# Log messages with structured data\nlogger.logger.info(\"Service started\", port=8080, environment=\"production\")\nlogger.logger.error(\"Database connection failed\", \n error=\"Connection timeout\", \n retry_count=3)\n```\n\n### WebSocket Broadcasting\n\n```python\nfrom wml import WMLLogger, LoggingConfig\n\nconfig = LoggingConfig(\n service_name=\"websocket-service\",\n websocket_enabled=True,\n websocket_port=8765,\n websocket_host=\"0.0.0.0\"\n)\n\nlogger = WMLLogger.get_logger(config)\n\n# Logs will be automatically broadcast to WebSocket clients\nlogger.logger.info(\"WebSocket message\", client_count=42)\n```\n\n### MQTT Integration\n\n```python\nfrom wml import WMLLogger, LoggingConfig\n\nconfig = LoggingConfig(\n service_name=\"mqtt-service\",\n mqtt_enabled=True,\n mqtt_broker=\"mqtt://localhost:1883\",\n mqtt_topic=\"logs/my-service\"\n)\n\nlogger = WMLLogger.get_logger(config)\n\n# Logs will be published to MQTT broker\nlogger.logger.warning(\"High memory usage\", memory_percent=85)\n```\n\n### Context Enrichment\n\n```python\nfrom wml import WMLLogger, LoggingConfig, LogContext\n\n# Create context with additional metadata\ncontext = LogContext(\n service_name=\"api-service\",\n environment=\"staging\",\n version=\"1.2.3\",\n custom_data={\"region\": \"us-east-1\", \"datacenter\": \"dc-01\"}\n)\n\nconfig = LoggingConfig(service_name=\"api-service\")\nlogger = WMLLogger.get_logger(config, context)\n\n# All logs will include context information\nlogger.logger.info(\"Request processed\", \n request_id=\"req-123\", \n response_time=0.045)\n```\n\n## \ud83d\udda5\ufe0f CLI Usage\n\nWML provides a comprehensive CLI for log management and monitoring:\n\n### Send Log Messages\n\n```bash\n# Send a simple log message\nwmlog log \"Hello, World!\"\n\n# Send with specific service and level\nwmlog log --service my-service --level error \"Something went wrong\"\n\n# Send with MQTT broadcasting\nwmlog log --mqtt-broker localhost:1883 --mqtt-topic logs/test \"MQTT log message\"\n```\n\n### Monitor Logs\n\n```bash\n# Monitor MQTT logs\nwmlog monitor --broker localhost:1883 --topic \"logs/#\"\n\n# Monitor with filtering\nwmlog monitor --broker localhost:1883 --filter-service my-service --filter-level error\n\n# Monitor WebSocket logs\nwmlog websocket-monitor --port 8765 --host localhost\n```\n\n### Start Broadcasting Server\n\n```bash\n# Start WebSocket and MQTT broadcasting server\nwmlog server --websocket-port 8765 --mqtt-broker localhost:1883\n\n# Start WebSocket-only server\nwmlog server --websocket-port 8765\n```\n\n### Test Configuration\n\n```bash\n# Test with default configuration\nwmlog test\n\n# Test with custom configuration file\nwmlog test --config-file config.json\n```\n\n### Package Information\n\n```bash\n# Show package information\nwmlog info\n```\n\n## \ud83d\udcda Documentation\n\n- [API Documentation](docs/API_DOCUMENTATION.md) - Detailed reference for wmlog APIs\n\n### Python Packages\n\nExplore the ecosystem of Python packages related to wmlog:\n\n- [ProServe](https://pypi.org/project/proserve/) - Core microservices framework\n- [Servos](https://pypi.org/project/servos/) - Environment isolation and orchestration\n- [wmlog](https://pypi.org/project/wmlog/) - Centralized structured logging\n- [SELLM](https://pypi.org/project/sellm/) - AI-powered manifest generator\n- [EDPMT](https://pypi.org/project/edpmt/) - Hardware control framework for IoT\n\n## Why wmlog?\n\n- **Unified Logging**: Centralized logging for microservices and distributed systems\n- **Real-time Monitoring**: Live log streaming with WebSocket and MQTT\n- **Flexible Configuration**: Customizable logging formats, handlers, and outputs\n- **Async Support**: High-performance logging for async applications\n- **Redis Integration**: Optional Redis backend for log storage and analysis\n- **Rich Console Output**: Beautiful console logging with syntax highlighting\n\n## \ud83d\udd27 Advanced Usage\n\n### Custom Formatters\n\n```python\nfrom wml.formatters import JSONFormatter, RichConsoleFormatter\n\n# Custom JSON formatter with additional fields\njson_formatter = JSONFormatter(\n include_extra_fields=True,\n timestamp_format=\"iso\",\n pretty_print=True\n)\n\n# Custom Rich formatter with specific styling\nrich_formatter = RichConsoleFormatter(\n show_time=True,\n show_level=True,\n show_path=False,\n markup=True\n)\n```\n\n### Custom Handlers\n\n```python\nfrom wml.handlers import WebSocketHandler, MQTTHandler, RedisHandler\n\n# WebSocket handler for real-time streaming\nws_handler = WebSocketHandler(\n host=\"0.0.0.0\",\n port=8765,\n path=\"/logs\"\n)\n\n# MQTT handler for pub/sub messaging\nmqtt_handler = MQTTHandler(\n broker_url=\"mqtt://localhost:1883\",\n topic=\"logs/my-service\",\n qos=1,\n retain=False\n)\n\n# Redis handler for log storage\nredis_handler = RedisHandler(\n redis_url=\"redis://localhost:6379/0\",\n key_prefix=\"logs:\",\n expire_seconds=86400\n)\n```\n\n### Async Logging\n\n```python\nimport asyncio\nfrom wml import WMLLogger, LoggingConfig\n\nasync def async_application():\n config = LoggingConfig(\n service_name=\"async-service\",\n websocket_enabled=True\n )\n \n logger = WMLLogger.get_logger(config)\n \n # Async logging with context\n async with logger.context(request_id=\"req-456\"):\n logger.logger.info(\"Processing async request\")\n \n # Simulate async work\n await asyncio.sleep(1)\n \n logger.logger.info(\"Async request completed\")\n\n# Run async application\nasyncio.run(async_application())\n```\n\n## \ud83d\udd0c Integration Examples\n\n### Flask Application\n\n```python\nfrom flask import Flask, request\nfrom wml import WMLLogger, LoggingConfig, LogContext\n\napp = Flask(__name__)\n\n# Initialize WML logger\nconfig = LoggingConfig(\n service_name=\"flask-api\",\n console_format=\"rich\",\n websocket_enabled=True,\n mqtt_enabled=True,\n mqtt_broker=\"mqtt://localhost:1883\"\n)\n\nlogger = WMLLogger.get_logger(config)\n\n@app.before_request\ndef log_request_info():\n logger.logger.info(\"Request started\",\n method=request.method,\n url=request.url,\n remote_addr=request.remote_addr)\n\n@app.after_request\ndef log_response_info(response):\n logger.logger.info(\"Request completed\",\n status_code=response.status_code,\n content_length=response.content_length)\n return response\n\n@app.route('/api/health')\ndef health():\n logger.logger.info(\"Health check requested\")\n return {\"status\": \"healthy\"}\n\nif __name__ == '__main__':\n app.run(debug=True)\n```\n\n### FastAPI Application\n\n```python\nfrom fastapi import FastAPI, Request\nfrom wml import WMLLogger, LoggingConfig\nimport time\n\napp = FastAPI()\n\n# Initialize WML logger\nconfig = LoggingConfig(\n service_name=\"fastapi-service\",\n console_format=\"rich\",\n websocket_enabled=True\n)\n\nlogger = WMLLogger.get_logger(config)\n\n@app.middleware(\"http\")\nasync def log_requests(request: Request, call_next):\n start_time = time.time()\n \n logger.logger.info(\"Request started\",\n method=request.method,\n url=str(request.url))\n \n response = await call_next(request)\n \n process_time = time.time() - start_time\n logger.logger.info(\"Request completed\",\n status_code=response.status_code,\n process_time=process_time)\n \n return response\n\n@app.get(\"/\")\nasync def root():\n logger.logger.info(\"Root endpoint accessed\")\n return {\"message\": \"Hello World\"}\n```\n\n### Docker Integration\n\n```dockerfile\nFROM python:3.9-slim\n\nWORKDIR /app\n\n# Install WML\nCOPY requirements.txt .\nRUN pip install -r requirements.txt\n\nCOPY . .\n\n# Set environment variables for WML\nENV WML_SERVICE_NAME=docker-service\nENV WML_LOG_LEVEL=info\nENV WML_CONSOLE_FORMAT=json\nENV WML_WEBSOCKET_ENABLED=true\nENV WML_WEBSOCKET_PORT=8765\nENV WML_MQTT_ENABLED=true\nENV WML_MQTT_BROKER=mqtt://mqtt-broker:1883\n\nEXPOSE 8000 8765\n\nCMD [\"python\", \"app.py\"]\n```\n\n```yaml\n# docker-compose.yml\nversion: '3.8'\n\nservices:\n app:\n build: .\n ports:\n - \"8000:8000\"\n - \"8765:8765\"\n environment:\n - WML_MQTT_BROKER=mqtt://mqtt:1883\n depends_on:\n - mqtt\n - redis\n\n mqtt:\n image: eclipse-mosquitto:2.0\n ports:\n - \"1883:1883\"\n - \"9001:9001\"\n volumes:\n - ./mosquitto.conf:/mosquitto/config/mosquitto.conf\n\n redis:\n image: redis:7-alpine\n ports:\n - \"6379:6379\"\n\n log-monitor:\n image: wml-cli\n command: wml monitor --broker mqtt:1883 --topic \"logs/#\"\n depends_on:\n - mqtt\n```\n\n## \ud83d\udcca Monitoring and Observability\n\n### Grafana Dashboard\n\nWML integrates seamlessly with monitoring stacks:\n\n```python\n# Send metrics alongside logs\nlogger.logger.info(\"Request processed\",\n request_count=1,\n response_time=0.045,\n memory_usage=256.5,\n cpu_percent=12.3)\n```\n\n### Prometheus Integration\n\n```python\nfrom prometheus_client import Counter, Histogram, Gauge\nfrom wml import WMLLogger, LoggingConfig\n\n# Prometheus metrics\nREQUEST_COUNT = Counter('requests_total', 'Total requests', ['method', 'endpoint'])\nREQUEST_DURATION = Histogram('request_duration_seconds', 'Request duration')\nMEMORY_USAGE = Gauge('memory_usage_bytes', 'Memory usage')\n\nconfig = LoggingConfig(service_name=\"metrics-service\")\nlogger = WMLLogger.get_logger(config)\n\ndef process_request(method, endpoint):\n REQUEST_COUNT.labels(method=method, endpoint=endpoint).inc()\n \n with REQUEST_DURATION.time():\n # Process request\n logger.logger.info(\"Request processed\",\n method=method,\n endpoint=endpoint,\n metrics_exported=True)\n```\n\n## \ud83e\uddea Testing\n\nRun the test suite:\n\n```bash\n# Install test dependencies\npip install -e .[dev]\n\n# Run unit tests\npytest tests/\n\n# Run integration tests\npytest tests/integration/\n\n# Run with coverage\npytest tests/ --cov=wml --cov-report=html\n\n# Test CLI commands\nwml test\nwml info\n```\n\n## \ud83d\udcda API Reference\n\n### Core Classes\n\n- **`WMLLogger`**: Main logging class with structured logging support\n- **`LoggingConfig`**: Configuration class for logger settings\n- **`LogContext`**: Context enrichment for adding metadata to logs\n\n### Formatters\n\n- **`JSONFormatter`**: JSON output with structured data\n- **`RichConsoleFormatter`**: Rich console output with colors and styling\n- **`StructuredFormatter`**: Structured text format with key-value pairs\n- **`CompactFormatter`**: Minimal compact format for high-volume logging\n\n### Handlers\n\n- **`WebSocketHandler`**: Real-time WebSocket broadcasting\n- **`MQTTHandler`**: MQTT pub/sub messaging\n- **`RedisHandler`**: Redis storage and retrieval\n- **`BufferedHandler`**: Buffered output with configurable flushing\n\n### Broadcasters\n\n- **`WebSocketBroadcaster`**: WebSocket server for real-time log streaming\n- **`MQTTBroadcaster`**: MQTT client for pub/sub log distribution\n\n## \ud83e\udd1d Contributing\n\nWe welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.\n\n### Development Setup\n\n```bash\n# Clone the repository\ngit clone https://github.com/your-org/wml.git\ncd wml\n\n# Create virtual environment\npython -m venv venv\nsource venv/bin/activate # On Windows: venv\\Scripts\\activate\n\n# Install development dependencies\npip install -e .[dev]\n\n# Install pre-commit hooks\npre-commit install\n\n# Run tests\npytest\n```\n\n### Code Style\n\nWe use:\n- **Black** for code formatting\n- **isort** for import sorting\n- **flake8** for linting\n- **mypy** for type checking\n\n## \ud83d\udcc4 License\n\nwmlog is released under the Apache Software License 2.0. See the [LICENSE](LICENSE) file for details.\n\n## \ud83d\udc68\u200d\ud83d\udcbb Author\n\n**Tom Sapletta**\n- Email: info@softreck.dev\n- GitHub: [@tom-sapletta-com](https://github.com/tom-sapletta-com)\n- Website: [softreck.dev](https://softreck.dev)\n\n## \ud83d\ude4f Acknowledgments\n\n- Built with [structlog](https://www.structlog.org/) for structured logging\n- Uses [rich](https://github.com/Textualize/rich) for beautiful console output\n- MQTT support via [paho-mqtt](https://pypi.org/project/paho-mqtt/)\n- WebSocket support via [aiohttp](https://aiohttp.readthedocs.io/) and [websockets](https://websockets.readthedocs.io/)\n\n## \ud83d\udd17 Related Projects\n\n- **[ProServe](https://pypi.org/project/proserve/)**: Professional microservice framework using wmlog\n- **[Servos](https://pypi.org/project/servos/)**: Environment isolation and Docker orchestration\n- **[EDPMT Framework](https://github.com/tom-sapletta-com/edpmt)**: Embedded development platform with wmlog integration\n- **[SELLM](https://pypi.org/project/sellm/)**: AI-powered manifest generator\n\n---\n\n**wmlog** - Unifying logs across services, platforms, and environments. \ud83d\ude80\n\n---\n\n**Made with \u2764\ufe0f by [Tom Sapletta](https://softreck.dev) \u2022 Part of the modular microservices ecosystem**\n",
"bugtrack_url": null,
"license": "Apache-2.0",
"summary": "Centralized Structured Logging for Microservices",
"version": "1.0.4",
"project_urls": {
"Documentation": "https://wml.softreck.dev/docs",
"Homepage": "https://github.com/tom-sapletta-com/wmlog",
"Source": "https://github.com/wml-org/wml",
"Tracker": "https://github.com/wml-org/wml/issues"
},
"split_keywords": [
"logging",
" websocket",
" mqtt",
" distributed",
" microservices",
" structured-logging",
" real-time",
" monitoring",
" observability",
" asyncio",
" broadcasting",
" centralized-logging"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "db29088a1a7fbfff3ab49cb45b92250ca6b42e900fd6b45ad4e9ae058262472a",
"md5": "d0e3376e4754de1697236e3d23aee467",
"sha256": "0522f1d1ab0abe90a0c8c15f5082336dec9e888725cf7a13ae975927cc11beac"
},
"downloads": -1,
"filename": "wmlog-1.0.4-py3-none-any.whl",
"has_sig": false,
"md5_digest": "d0e3376e4754de1697236e3d23aee467",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 37729,
"upload_time": "2025-09-18T13:42:28",
"upload_time_iso_8601": "2025-09-18T13:42:28.970987Z",
"url": "https://files.pythonhosted.org/packages/db/29/088a1a7fbfff3ab49cb45b92250ca6b42e900fd6b45ad4e9ae058262472a/wmlog-1.0.4-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "d8753ef7edd059fbe6e3c209fc6ab952261f050d6be659c275771b72485e457d",
"md5": "8c2fe2948d907cd06ef34a04360bbe50",
"sha256": "225a4644181ed5d7858d765ead153fa2173dd5306631c58ec165627707216555"
},
"downloads": -1,
"filename": "wmlog-1.0.4.tar.gz",
"has_sig": false,
"md5_digest": "8c2fe2948d907cd06ef34a04360bbe50",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 45485,
"upload_time": "2025-09-18T13:42:30",
"upload_time_iso_8601": "2025-09-18T13:42:30.233852Z",
"url": "https://files.pythonhosted.org/packages/d8/75/3ef7edd059fbe6e3c209fc6ab952261f050d6be659c275771b72485e457d/wmlog-1.0.4.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-09-18 13:42:30",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "tom-sapletta-com",
"github_project": "wmlog",
"github_not_found": true,
"lcname": "wmlog"
}