Skip to main content

Universal Log Parser (ULP)

PyPI version Python License: MIT CI

A Python library and CLI tool to automatically detect, parse, and normalize logs from any format. Built for production workloads with streaming support for large files (1-10GB+) and cross-source log correlation.

Features

  • Auto-Detection: Automatically identifies 10+ log formats without configuration
  • Streaming Support: Memory-efficient parsing for files up to 10GB+ using memory-mapped I/O
  • Log Correlation: Correlate entries across multiple log sources by request ID, timestamp, or session
  • Normalized Output: All logs converted to a common schema with structured data extraction
  • Clean Architecture: Domain-driven design with clear separation of concerns
  • Rich CLI: Beautiful terminal output with multiple formats (table, JSON, CSV, compact)
  • Extensible: Easy to add custom parsers and normalization steps

Installation

pip install universal-log-parser

With optional dependencies:

# For GeoIP enrichment
pip install universal-log-parser[geoip]

# For benchmarking
pip install universal-log-parser[benchmark]

# Everything
pip install universal-log-parser[all]

Quick Start

CLI Usage

# Parse a log file (format auto-detected)
ulp parse /var/log/nginx/access.log

# Detect format only
ulp detect /var/log/syslog

# Parse with specific format
ulp parse --format json_structured app.log

# Filter by level and output as JSON
ulp parse --level error --output json app.log

# Grep for patterns
ulp parse --grep "user.*login" auth.log

# Limit output
ulp parse --limit 100 app.log

# Stream large files (memory-efficient)
ulp stream --format json huge-file.log

# Correlate logs across multiple files
ulp correlate app.log nginx.log --strategy request_id

Library Usage

from ulp import parse, detect_format, LogLevel

# Detect format
format_name, confidence = detect_format("access.log")
print(f"Format: {format_name} ({confidence:.0%})")

# Parse logs
entries = parse("access.log")

# Filter errors
errors = [e for e in entries if e.level >= LogLevel.ERROR]

# Access normalized fields
for entry in entries:
    print(f"{entry.timestamp} [{entry.level.name}] {entry.message}")

Streaming Large Files

For files that don't fit in memory:

from ulp import stream_parse, LogLevel

# Stream-parse a 5GB log file
for entry in stream_parse("huge.log", format="json"):
    if entry.level >= LogLevel.ERROR:
        print(f"{entry.timestamp}: {entry.message}")

Log Correlation

Correlate related log entries across multiple sources:

from ulp import correlate

# Correlate by request ID across app and web server logs
result = correlate(
    ["app.log", "nginx.log"],
    strategy="request_id"
)

for group in result.groups:
    print(f"Request {group.correlation_key}: {len(group.entries)} entries")
    for entry in group.timeline():
        print(f"  {entry.timestamp} [{entry.source.file_path}] {entry.message}")

Supported Formats

Format Parser Name Description
JSON/JSONL json_structured JSON structured logs
Apache Combined apache_combined Apache Combined Log Format
Apache Common apache_common Apache Common Log Format
Nginx Access nginx_access Nginx default access log
Nginx Error nginx_error Nginx error log
Syslog RFC 3164 syslog_rfc3164 BSD syslog format
Syslog RFC 5424 syslog_rfc5424 Modern syslog format
Python Logging python_logging Python standard logging
Docker JSON docker_json Docker JSON log driver
Kubernetes kubernetes Kubernetes container logs
Generic generic Fallback for unknown formats

Output Formats

The CLI supports multiple output formats:

# Rich table (default)
ulp parse app.log

# JSON output
ulp parse --output json app.log

# CSV output
ulp parse --output csv app.log

# Compact single-line
ulp parse --output compact app.log

Normalized Log Entry

All parsed logs are converted to a common LogEntry schema:

LogEntry(
    # Core fields
    id: UUID,
    timestamp: datetime,
    level: LogLevel,
    message: str,
    raw: str,  # Original line

    # Structured data
    structured_data: dict,

    # Source metadata
    source: LogSource(
        file_path: str,
        line_number: int,
        hostname: str,
        service: str,
    ),

    # Network context (for access logs)
    network: NetworkInfo(
        source_ip: str,
        user_agent: str,
    ),

    # HTTP context (for web logs)
    http: HTTPInfo(
        method: str,
        path: str,
        status_code: int,
        response_size: int,
    ),

    # Correlation IDs
    correlation: CorrelationIds(
        request_id: str,
        trace_id: str,
        session_id: str,
    ),
)

Architecture

ULP follows Clean Architecture principles:

src/ulp/
├── domain/          # Core entities and business rules
├── application/     # Use cases (parse, correlate)
├── infrastructure/  # Adapters (file sources, strategies)
├── parsers/         # Format-specific parsers
├── detection/       # Auto-detection logic
└── cli/             # Command-line interface

Extending ULP

Custom Parser

from ulp.core.base import BaseParser
from ulp.core.models import LogEntry, LogLevel

class MyCustomParser(BaseParser):
    name = "my_format"
    formats = ["my_format"]

    def parse_line(self, line: str) -> LogEntry:
        # Parse your format
        return LogEntry(
            message=line,
            level=LogLevel.INFO,
        )

    def can_parse(self, sample_lines: list[str]) -> float:
        # Return confidence 0.0-1.0
        return 0.8 if self._looks_like_my_format(sample_lines) else 0.0

Custom Normalization

from ulp import NormalizationPipeline, TimestampNormalizer, LevelNormalizer

pipeline = NormalizationPipeline([
    TimestampNormalizer(target_tz="UTC"),
    LevelNormalizer(),
])

normalized_entry = pipeline.process_one(entry)

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

MIT License - see LICENSE for details.

Metadata

Release files for universal-log-parser 0.2.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for universal-log-parser 0.2.2
File Size Uploaded Provenance
universal_log_parser-0.2.2.tar.gz 143.9 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for universal-log-parser 0.2.2
File Interpreter ABI Platform
universal_log_parser-0.2.2-py3-none-any.whl Python 3 none any Details

Total release size: 226.7 kB

Release files / universal_log_parser-0.2.2.tar.gz

Download URL universal_log_parser-0.2.2.tar.gz
Size 143.9 kB
Tags Source
SHA-256 checksum
How to use checksums
33e2514a7744e14dc8ab57c9ba8aa246f976bdda51643217eb1cdd4935499af7
BLAKE2b-256 checksum
How to use checksums
4454a720a2c2464ae21e213f683d058982d22ee736a5d7dae024f6246db8503d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 23, 2026.

Transparency log

Release files / universal_log_parser-0.2.2-py3-none-any.whl

Download URL universal_log_parser-0.2.2-py3-none-any.whl
Size 82.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a366cbd89a95e66a4bcf37e09eec10bb2e9bb1de3819e1688b5a3f318c0d5d8e
BLAKE2b-256 checksum
How to use checksums
41fb4f334734f344ef4fe0c727c1f3f2356b8995b7fd68f6ad3d85d03fb2adad
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 23, 2026.

Transparency log

Security for universal-log-parser 0.2.2

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for universal_log_parser-0.2.2.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 23, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page