Skip to main content
Glama

Contents

Getting started

  • Install — Cargo for the libraries, cargo install for the CLIs and the MCP server

  • Requirements — toolchain floor, platforms

  • Quick Start — one structured record, fired and flushed

The rlg ecosystem

  • The rlg ecosystem — rlg, rlg-cli, rlg-report, rlg-mcp, rlg-otlp, rlg-redact, rlg-tower, rlg-test, rlg-wasm, rlg-ebpf

Library reference

Operational


Related MCP server: log-mcp

Install

As a Rust library

[dependencies]
rlg = "0.0.18"

Satellites install the same way, all at the same version:

[dependencies]
rlg-otlp   = "0.0.18"  # ship records to an OpenTelemetry Collector
rlg-tower  = "0.0.18"  # per-request access logs for tower services
rlg-redact = "0.0.18"  # scrub secrets and PII before they are written

[dev-dependencies]
rlg-test   = "0.0.18"  # assert on captured records in tests

Command-line tools

cargo install rlg-cli      # `rlg`: filter and convert log files
cargo install rlg-report   # `rlg-report`: summaries by level, component and message
cargo install rlg-mcp      # `rlg-mcp`: log files as tools for AI agents

From a checkout, make install builds the three binaries and installs them with their manpages and bash, zsh and fish completions under /usr/local (PREFIX and DESTDIR are honoured; make uninstall reverses it). The binaries generate both themselves: rlg --manpage > rlg.1, rlg --completions zsh > _rlg.

rlg-mcp is also published as a container image, ghcr.io/sebastienrousseau/rlg-mcp, and listed in the MCP registry.


Requirements

  • Rust 1.89.0 or newer (edition 2024). CI builds every library and binary on 1.89.0; see the toolchain policy.

  • macOS or Linux for the native sinks (os_log, journald). Everywhere else, including Windows, rlg writes to a file or stdout.


Quick Start

use rlg::log::Log;
use rlg::log_format::LogFormat;

fn main() {
    // Keep the guard for the life of the program: dropping it flushes
    // pending records and stops the background thread.
    let _guard = rlg::init().unwrap();

    Log::info("User authenticated")
        .component("auth-service")
        .with("user_id", 42)
        .format(LogFormat::JSON)
        .fire();
}

fire() checks the level, pushes the record into a ring buffer and returns; the flusher thread formats it as JSON and writes it to the platform sink. This block is compiled and run by cargo test.


The rlg ecosystem

Ten crates at lockstep version 0.0.18, released together.

Component

Purpose

Use case

rlg

The engine: 65,536-slot ring buffer, background flusher, 14 formats, native sinks

Structured logging in any Rust program

rlg-cli

The rlg binary: filter by level, component or attribute, convert between formats

my-service | rlg --min-level error --format ecs

rlg-report

The rlg-report binary and library: counts by level and component, top messages, latency percentiles

On-call triage, daily error digests

rlg-mcp

MCP server: four tools, one prompt, two resources over stdio, streamable HTTP or HTTP+SSE

AI agents reading production logs

rlg-otlp

OTLP/HTTP exporter to a local OpenTelemetry Collector

Honeycomb, Datadog, Grafana through a Collector

rlg-redact

Scrubs cards, JWTs, bearer tokens, emails, IPv4 addresses and AWS keys in one pass

GDPR and audit-trail safety

rlg-tower

tower::Layer emitting one access-log record per request

axum, hyper and other tower services

rlg-test

Capture records in a test and assert on them

Libraries testing their own log output

rlg-wasm

wasm-bindgen bindings and a WASI 0.2 component interface

Browsers, Deno, Workers, wasmtime hosts

rlg-ebpf

Process enrichment, portable; an eBPF enricher scaffold on Linux

Host context on every record


Capabilities at a glance

Area

Capability

Status

Ingestion

Atomic level filter, ring-buffer push, no lock on the caller's thread

Stable

Formats

JSON, NDJSON, ECS, GELF, Logstash, OTLP, MCP, logfmt, CLF, CEF, ELF, W3C, Apache, Log4j XML

Stable

Sinks

os_log (macOS), journald (Linux), file, stdout

Stable

Sinks

io_uring file sink (Linux, uring feature)

Scaffold

Configuration

TOML load, validation, polling hot-reload (tokio feature)

Stable

Bridges

log facade via rlg::init(); tracing layer (tracing-layer feature)

Stable

Export

OTLP/HTTP to a local Collector (rlg-otlp)

Stable

Agents

MCP server over stdio, streamable HTTP and HTTP+SSE (rlg-mcp)

Stable

Enrichment

eBPF kernel context (rlg-ebpf, Linux)

Scaffold


Ecosystem comparison

rlg trades tracing's span model for an event-only engine that keeps formatting and I/O off the application thread and ships native sinks, many formats and an agent interface in the box.

Project

Formatting off the caller's thread

Built-in formats

Native journald / os_log

rlg

yes

14

yes

tracing + tracing-subscriber

add-on

text, JSON

add-on

slog

add-on

add-on

add-on

log + env_logger

no

text

no

See docs/COMPARISON.md for the evidence and complete matrix.


Benchmarks

The competitive_bench suite times rlg's fire() against tracing::info! and log::info! for single records, records with attributes, 10,000-record bursts and latency distribution. It runs in CI on every release tag, and its results are published as workflow artifacts.

Scenario

Result

Environment

rlg fire(), one record

598 ns

GitHub-hosted ubuntu-latest, release profile

tracing::info! to a discarding writer

591 ns

same run

rlg fire() with 3 attributes

947 ns (tracing: 1,117 ns)

same run

On the calling thread rlg now costs about what tracing costs, without formatting there; what it buys is that the caller never waits on the sink's I/O.

See docs/BENCHMARKS.md for methodology and full results.


Features

Everything optional is off by default.

Feature

Crate

Adds

tokio

rlg

Config::load_async and polling hot-reload

tui

rlg

A live terminal dashboard, started with RLG_TUI=1

tracing-layer

rlg

RlgLayer, a tracing_subscriber::Layer

fast-queue

rlg

An eight-shard ring buffer for many concurrent producers

uring

rlg

The io_uring file sink on Linux

async

rlg-otlp

AsyncOtlpExporter on Tokio


Configuration

Config loads from TOML, validates, and creates the log paths it needs.

# rlg.toml
version              = "1.0"
profile              = "production"
log_file_path        = "/var/log/rlg.log"
log_level            = "INFO"
logging_destinations = [
    { type = "File", value = "/var/log/rlg.log" },
    { type = "Stdout" },
]
log_rotation         = { Size = 10485760 }  # 10 MiB

Load it with Config::load(Some("rlg.toml")), or with the tokio feature Config::load_async, and follow edits with Config::hot_reload_async. RUST_LOG sets the level too. The crate README lists every field.


Examples

Example

Shows

Run

example_log_format

All 14 formats side by side

cargo run -p rlg --example example_log_format

example_config

TOML config, async load, hot-reload

cargo run -p rlg --example example_config --features tokio

example_macros

The logging macros

cargo run -p rlg --example example_macros

serve_a_session

A full MCP session against rlg-mcp

cargo run -p rlg-mcp --example serve_a_session

honeycomb

Exporting through a local Collector

cargo run -p rlg-otlp --example honeycomb

CI runs every example on each pull request (examples-smoke.yml), except example_config and example_utils, async demos whose behaviour the crate's own tests cover.


When not to use rlg

  • Low volume. Below about a hundred records a second, a background thread and a 65k-slot buffer buy nothing a synchronous logger does not already give you.

  • Spans are your model. rlg records events. If hierarchical spans are what you analyse, use tracing directly; rlg's layer only bridges its events.

  • Windows Event Log. There is no native Windows sink; rlg writes to a file or stdout there.

  • Every record must survive a crash. Records wait in memory until the flusher writes them; a process killed before the FlushGuard drops loses what is still buffered.

  • You need a stable API. rlg is at 0.0.x: any release may break, and it has one maintainer.


Development

make verify   # everything CI runs on a pull request
make demo     # re-render .github/demo.gif from .github/demo.tape

DEVELOPMENT.md lists every gate with its local command: Miri, Loom and Kani for the engine's concurrency and memory safety, four fuzz targets, cargo-deny and cargo-vet for the dependency tree, cargo-semver-checks, a 95% coverage floor and complexity ceilings. Contribution and signing rules are in CONTRIBUTING.md and AGENTS.md.


Security

  • Reporting: privately, by email or GitHub's advisory form; never in a public issue. The process and response time are in SECURITY.md.

  • Memory safety: unsafe is denied across the workspace except the documented macOS os_log FFI in crates/rlg/src/sink.rs. The engine runs under Miri on every push.

  • Resource limits: the ring buffer is bounded at 65,536 records and evicts the oldest when full; rlg-otlp caps a collector's response headers at 16 KiB and times out every request.

  • Fuzzing: four cargo-fuzz targets (record parsing, format names, config loading, redaction) run on every pull request; see docs/OSS-FUZZ.md for OSS-Fuzz status.

  • Supply chain: every dependency passes cargo-deny and cargo-vet; releases publish through crates.io Trusted Publishing with sigstore-signed SBOMs (pkg/VERIFY.md).

Report vulnerabilities according to SECURITY.md.


Documentation

Document

For

User manual

Tutorials, how-to guides, architecture, ADRs (source)

API reference

Every public item, per crate on docs.rs

DEVELOPMENT.md

Toolchain, local gates, test layout, release model

docs/ARCHITECTURE.md

How the engine and satellites fit together

CHANGELOG.md

What changed in each release

Migration guides

Coming from log, slog or tracing


Stability guarantees

  • SemVer axis: rlg is at 0.0.x, so under Cargo's rules every release may be breaking. Breaking changes are marked Breaking in the CHANGELOG, and cargo-semver-checks runs on every pull request so none slips through unannounced.

  • Output stability: the bytes a format produces are an interface. A change to them for the same record is breaking even when no signature moves, and is recorded the same way.

  • Minimum toolchain: Rust 1.89.0, enforced in CI; a rise is its own CHANGELOG entry with the reason. docs/POLICIES.md has the full policy.


License

Dual-licensed under either of

at your option. Unless you state otherwise, any contribution you submit for inclusion in rlg is dual-licensed as above, without additional terms.

Available Tools

3 tools
filter_logFilter rlg log recordsA
Read-onlyIdempotent

Select rlg records by minimum severity and/or component and render them in any rlg LogFormat. Use this to narrow a log to what matters (e.g. WARN-and-above for one service); use tail_log for a raw recent slice and summarize_errors when you only need per-component error totals.

Inputs: path (required), format, component, min_level.

summarize_errorsSummarize rlg errors by componentA
Read-onlyIdempotent

Group ERROR-and-above rlg records by component and count them, giving a quick error taxonomy for triage. Use this for an at-a-glance failure breakdown; use filter_log when you need the underlying records rather than counts.

Inputs: path (required).

tail_logTail rlg log fileA
Read-onlyIdempotent

Return the last N parseable rlg (RustLogs) records from a log file, newest last. Use this to glance at the most recent activity in a log; use filter_log when you need to select records by level or component, and summarize_errors for an aggregated error count.

Inputs: path (required), n.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A4.7/5.0

    Scored across 3 tools

    Disambiguation5/5

    Each tool has a clearly distinct purpose: filter_log selects by severity/component, summarize_errors provides aggregated counts, and tail_log returns recent raw records. There is no overlap, and the descriptions explicitly guide when to use which.

    Naming Consistency5/5

    All tool names follow a consistent verb_noun pattern in snake_case: filter_log, summarize_errors, tail_log. The verbs (filter, summarize, tail) are descriptive and predictable.

    Tool Count5/5

    Three tools is an appropriate count for a focused logging server. Each tool provides a necessary operation (tail, filter, summarize) without redundancy or bloat.

    Completeness4/5

    The tool set covers the core operations for log analysis: tailing raw logs, filtering by severity/component, and summarizing errors. Minor gaps like searching by pattern could exist, but for the stated domain of rlg records, it is largely complete.

    Maintenance

    ActivityActive
    ResponsivenessOutdated data

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      B
      maintenance
      An MCP server that connects Claude (or any MCP compatible client) to your existing log infrastructure. Query, summarize, and trace logs in plain English across GCP Cloud Logging, AWS CloudWatch, Azure Log Analytics, Grafana Loki, and Elasticsearch without writing filter expressions or leaving your editor.
      49 npm
      5
      MIT
    • A
      license
      A
      quality
      D
      maintenance
      MCP server for log file analysis. Gives LLMs the ability to efficiently analyze large log files without loading them into context.
      7
      101
      MIT
    • A
      license
      A
      quality
      B
      maintenance
      A read-only MCP server that exposes local coding-agent session logs as three tools for introspection of recent work, debugging tool failures, and tracking token usage and estimated cost without parsing log files.
      3
      MIT
    • A
      license
      A
      quality
      D
      maintenance
      MCP server that stream-parses NDJSON log files without loading them into memory — filter by pattern, detect error spikes via Z-score analysis, summarize severity timelines by time window.
      8
      57 npm
      MIT