wmlog


Namewmlog JSON
Version 1.0.4 PyPI version JSON
download
home_pagehttps://github.com/tom-sapletta-com/wmlog
SummaryCentralized Structured Logging for Microservices
upload_time2025-09-18 13:42:30
maintainerNone
docs_urlNone
authorTom Sapletta
requires_python>=3.8
licenseApache-2.0
keywords logging websocket mqtt distributed microservices structured-logging real-time monitoring observability asyncio broadcasting centralized-logging
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # wmlog - Centralized Structured Logging

[![PyPI version](https://badge.fury.io/py/wmlog.svg)](https://badge.fury.io/py/wmlog)
[![Python versions](https://img.shields.io/pypi/pyversions/wmlog.svg)](https://pypi.org/project/wmlog/)
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
[![Downloads](https://pepy.tech/badge/wmlog)](https://pepy.tech/project/wmlog)
[![Code Style](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
[![Build Status](https://travis-ci.com/tom-sapletta-com/wmlog.svg?branch=main)](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[![PyPI version](https://badge.fury.io/py/wmlog.svg)](https://badge.fury.io/py/wmlog)\n[![Python versions](https://img.shields.io/pypi/pyversions/wmlog.svg)](https://pypi.org/project/wmlog/)\n[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)\n[![Downloads](https://pepy.tech/badge/wmlog)](https://pepy.tech/project/wmlog)\n[![Code Style](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)\n[![Build Status](https://travis-ci.com/tom-sapletta-com/wmlog.svg?branch=main)](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"
}
        
Elapsed time: 2.45247s