Skip to main content

Lightning-fast local log search and analysis

Project description

🚀 qlog - Query Logs at Ludicrous Speed

PyPI Python

grep is too slow. Elasticsearch is too heavy. qlog is just right.

# Index your logs once
qlog index './logs/**/*.log'

# Search millions of lines in milliseconds
qlog search "status=500" --context 3

# Find errors across all services
qlog search "exception" -n 50

# Get stats
qlog stats

qlog demo

Why qlog?

Feature grep qlog Elasticsearch
Speed Slow on large files ⚡ 10-100x faster Fast but heavy
Setup None pip install qlog-cli Complex setup
Memory Low Low High (GB)
Offline ❌ Needs server
Context Lines ❌ Clunky ✅ Built-in
Beautiful Output
Auto-format Detection With config

Features

  • Blazingly Fast - Inverted index searches millions of lines/second
  • 🎯 Smart Indexing - Only re-indexes changed files
  • 🎨 Beautiful Output - Color-coded, context-aware results
  • 📊 Format Detection - Auto-detects JSON, syslog, nginx, apache, and more
  • 🔍 Context Aware - See lines before/after matches
  • 💾 Efficient - Index stored locally, works offline
  • 🐍 Pure Python - Easy to install, extend, and understand

Installation

pip install qlog-cli

Or install from source:

git clone https://github.com/Cosm00/qlog
cd qlog
pip install -e .

Quick Start

1. Index Your Logs

# Index all logs in current directory
qlog index './**/*.log'

# Index specific patterns
qlog index './app.log' './errors.log' '/var/log/nginx/*.log'

# Force re-indexing
qlog index './**/*.log' --force

Indexing is fast: 1M+ lines/second on modern hardware.

2. Search

# Simple search
qlog search "error"

# Search with context (3 lines before/after)
qlog search "connection refused" --context 3

# Limit results
qlog search "timeout" -n 50

# JSON output (for piping)
qlog search "critical" --json | jq '.[] | .file'

3. Check Statistics

qlog stats

Shows indexed files, unique terms, index size, and performance metrics.

Examples

Finding Errors Across Multiple Services

# Index all service logs
qlog index './logs/**/*.log'

# Find all 500 errors with context
qlog search "500" --context 5

Debugging Production Issues

# Search for specific request ID
qlog search "request-id-12345" -c 10

# Find all exceptions
qlog search "exception" -n 100

Analyzing Access Logs

# Index nginx logs
qlog index '/var/log/nginx/*.log'

# Find slow requests
qlog search "upstream_response_time" --context 2

Performance

Tested on a MacBook Pro (M1) with 10GB of mixed log files:

Operation Time Speed
Indexing 8.2s ~1.2M lines/sec
Search (single term) 0.003s ⚡ Instant
Search (multi-term) 0.012s ⚡ Instant
Grep equivalent 45s 💤 Slow

qlog is ~3750x faster than grep for indexed searches.

How It Works

qlog uses an inverted index (like search engines):

  1. Indexing Phase:

    • Scans log files using memory-mapped I/O (fast!)
    • Tokenizes each line (words, IPs, UUIDs, status codes)
    • Builds an inverted index: term → [(file, line, offset), ...]
    • Stores index locally in .qlog/ (efficient, fast to load)
  2. Search Phase:

    • Looks up terms in the index (O(1) hash lookup)
    • Finds intersection of matching lines (set operations)
    • Retrieves actual lines from files
    • Formats and displays with context

Format Auto-Detection

qlog automatically detects and parses common log formats:

  • JSON - Structured JSON logs
  • Syslog - Traditional Unix syslog
  • Apache/Nginx - Combined web server logs
  • ISO Timestamps - Generic YYYY-MM-DD HH:MM:SS logs
  • Plain Text - Falls back to full-text indexing

Advanced Usage

Programmatic API

from qlog import LogIndexer, LogSearcher

# Create indexer
indexer = LogIndexer(index_dir=".qlog")

# Index files
stats = indexer.index_files(["./logs/**/*.log"])
print(f"Indexed {stats['lines']:,} lines in {stats['elapsed']:.2f}s")

# Search
searcher = LogSearcher(indexer)
results = searcher.search("error", context=3, max_results=100)

for result in results:
    print(f"{result['file']}:{result['line_num']}")
    print(f"  {result['line']}")

Custom Tokenization

Extend the indexer to recognize domain-specific patterns:

from qlog import LogIndexer

class CustomIndexer(LogIndexer):
    def _tokenize(self, line):
        tokens = super()._tokenize(line)
        # Add custom patterns
        # e.g., extract trace IDs, custom codes, etc.
        return tokens

Comparison with Other Tools

vs. grep

  • Pros: qlog is 10-100x faster on repeated searches
  • Cons: Requires one-time indexing step

vs. Elasticsearch

  • Pros: Much simpler, no server, works offline, lower resource usage
  • Cons: Single-machine only, no clustering

vs. Splunk

  • Pros: Free, open-source, no licensing, simpler
  • Cons: Fewer features, no distributed search

Changelog

0.2.1

  • Faster result retrieval (mmap offset reads; no full-file readlines per match)
  • Index hygiene: stable file IDs + purge old postings on reindex
  • New command: qlog watch <patterns> [--filter QUERY]
  • GitHub issue templates

Roadmap

  • Live tail with search filtering (qlog tail --filter "error")
  • Time-based queries (qlog search "error" --since "1h ago")
  • Cross-service correlation (trace IDs)
  • Export to CSV/JSON with aggregations
  • TUI (interactive terminal UI)
  • Watch mode (auto-reindex on file changes)
  • Regular expression queries
  • Fuzzy search

Contributing

Contributions welcome! This is a community project.

# Clone repo
git clone https://github.com/Cosm00/qlog
cd qlog

# Install dev dependencies
pip install -e '.[dev]'

# Run tests
pytest

# Run benchmarks
python benchmarks/bench.py

Support qlog

If qlog saves you time, consider supporting development:

(Once GitHub Sponsors is approved, I’ll add it here too.)

License

MIT License - see LICENSE for details.

Credits

Built with:

  • rich - Beautiful terminal output
  • click - CLI framework

Inspired by:

  • grep, ag, ripgrep - Fast text search
  • Elasticsearch - Inverted index architecture
  • lnav - Log file navigation

Made with ❤️ for developers who hate waiting for grep

⭐ Star this repo if qlog saved you time!

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

qlog_cli-0.2.1.tar.gz (16.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

qlog_cli-0.2.1-py3-none-any.whl (15.2 kB view details)

Uploaded Python 3

File details

Details for the file qlog_cli-0.2.1.tar.gz.

File metadata

  • Download URL: qlog_cli-0.2.1.tar.gz
  • Upload date:
  • Size: 16.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for qlog_cli-0.2.1.tar.gz
Algorithm Hash digest
SHA256 bf7f6ff67289aa9bd2b3c6d7a9d6b7a4224bee034e992ea6d9f777e810392510
MD5 c4a9a2fbedaeb05df4105c30c536f98a
BLAKE2b-256 82b49fbdaf3ac17ed9e4b1e895eb9e187bdba7407cb94fd0b0d6bff191b0a931

See more details on using hashes here.

File details

Details for the file qlog_cli-0.2.1-py3-none-any.whl.

File metadata

  • Download URL: qlog_cli-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 15.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for qlog_cli-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 bba8f3d60da6712b261d21431ad37e99ca1fc469437f7a2392aa9fae7a52be45
MD5 439e3a53f37eea784e2f304e95726017
BLAKE2b-256 59e8a3b70eaed3bd4e6798d4854e52d517c8665048bd2f977855f5925dc5073c

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page