Introduction
Logging in Ruby applications starts simply — the standard library Logger class gets you up and running with logger.info("Hello"). But as your Rails application scales from a single server to a distributed system, plain-text logs become impossible to search, parse, and aggregate. Structured logging, log filtering, and asynchronous writes become essential for production observability.
The Ruby ecosystem offers three distinct approaches: the built-in Logger (stdlib, zero dependencies), Lograge (3,574 ⭐, tames Rails’ verbose default output), and Semantic Logger (956 ⭐, enterprise-grade structured logging). This guide compares all three with real code examples and deployment patterns that work in production.
Comparison at a Glance
| Feature | Ruby Logger (stdlib) | Lograge | Semantic Logger |
|---|---|---|---|
| Type | Built-in standard library | Rails log formatter | Full-featured logging framework |
| Output Formats | Plain text (customizable) | JSON, Logstash, KeyValue | JSON, Hash, Raw, Syslog, Graylog, Splunk, Elasticsearch |
| Structured Logging | Manual only | Automatic (request-level) | Full structured logging |
| Async Logging | No | No (depends on app server) | Yes (built-in async appender) |
| Log Routing | Single output | Per-controller configurable | Multiple appenders with level-based routing |
| Rails Integration | Default | Drop-in replacement | Full integration |
| Performance | Synchronous writes | Same as Logger | Async, buffered, high-performance |
| Log Tagging | Manual via ActiveSupport::TaggedLogging | Automatic request tagging | Built-in named tags and metrics |
| GitHub Stars | N/A (stdlib) | 3,574 | 956 |
| Last Updated | Bundled with Ruby | July 2026 | July 2026 |
| License | Ruby License | MIT | Apache 2.0 |
Ruby Stdlib Logger: The Built-in Foundation
Ruby’s standard library Logger is the default logging mechanism in Rails applications. It’s simple, reliable, and requires zero configuration — but its default output is verbose and unstructured, making it painful to work with at scale.
Basic Usage
| |
Custom Format in Rails
| |
The Rails Log Problem
Rails’ default logging is notoriously verbose. A single controller action generates multiple lines:
| |
In production with thousands of requests per minute, this becomes unmanageable. This is exactly the problem Lograge was built to solve.
Strengths
- Zero dependencies — ships with Ruby itself
- Simple API —
debug,info,warn,error,fatal - Rails defaults — no setup needed in a new Rails app
- TaggedLogging — built-in context tagging via ActiveSupport
Weaknesses
- Verbose default output — especially painful in Rails production logs
- Synchronous writes — blocks the request thread
- No structured logging — must build JSON formatting manually
- Single output — can’t route different log levels to different destinations
Lograge: Taming Rails Log Output
Lograge was created explicitly to solve Rails’ verbose logging problem. Instead of multi-line request logs, Lograge condenses each HTTP request into a single, structured log line — making it dramatically easier to search and aggregate logs in tools like ELK, Datadog, and CloudWatch.
Architecture
Lograge hooks into Rails’ ActionController::Instrumentation and ActionView::LogSubscriber events. It intercepts the default logging pipeline and reformats the output into your chosen format — JSON, Logstash, or KeyValue — producing one line per request.
Installation
| |
| |
Basic Rails Setup
| |
Before and After Lograge
Before: 5+ lines per request with SQL queries mixed in.
After: Single structured line:
| |
Custom Configuration
| |
Strengths
- One line per request — revolutionary improvement over Rails defaults
- Multiple output formats — JSON, Logstash, KeyValue, custom
- Zero performance overhead — just reformats existing log data
- Battle-tested — used in thousands of Rails production apps
- Selective logging — filter out health checks and noisy endpoints
Weaknesses
- Request-level only — doesn’t help with background job logging
- No async writes — still writes synchronously through the Logger interface
- Rails-specific — not useful outside of Rails applications
- No log routing — single output destination
Semantic Logger: Enterprise-Grade Structured Logging
Semantic Logger is a full-featured logging framework that replaces Ruby’s standard Logger entirely. It supports asynchronous writes, multiple output destinations with level-based routing, built-in metrics collection, and structured data — making it the go-to choice for production systems where log performance and observability are critical.
Architecture
Semantic Logger operates on a pipeline model: Logger → Appender → Filter. Each logger instance routes log messages through configurable filters before dispatching to one or more appenders (output destinations). The built-in async appender buffers log messages and writes them on a background thread, eliminating I/O blocking on request threads.
Installation
| |
| |
Basic Setup
| |
Structured Logging
| |
Async + Multi-Destination Routing
| |
Rails Integration
| |
Strengths
- Async appenders — log writes never block request threads
- Multiple output destinations — split logs to Elasticsearch, files, and syslog simultaneously
- Built-in metrics — measure block durations with zero-code instrumentation
- Level-based routing — send errors to PagerDuty, info to Elasticsearch
- Structured by design — every log entry carries typed key-value pairs
- Gem-wide configuration — replace logging for all gems at once
Weaknesses
- Heavier — 956 stars, smaller community than Lograge
- Learning curve — the pipeline model takes time to master
- Overkill for small apps — unnecessary for single-server deployments
- Appender dependencies — Elasticsearch, Syslog, and Splunk appenders require additional gems
Deployment Patterns and Best Practices
Lograge + ELK Stack
| |
Semantic Logger with Elasticsearch
| |
Why Self-Host Your Ruby Logging Infrastructure?
Owning your logging pipeline means you control log retention, format, and access — no third-party SaaS can suddenly change pricing or deprecate a feature critical to your debugging workflow. Open-source logging libraries let you build exactly the observability stack you need: structured JSON logs shipped to Elasticsearch or Loki, with retention policies that match your compliance requirements.
For testing patterns that integrate with logging, see our Ruby testing frameworks guide. For micro-framework deployments where logging configuration differs, check our Ruby micro web frameworks comparison. If you’re managing internal Ruby gems alongside your logging infrastructure, see our self-hosted Ruby gem server guide.
FAQ
Should I use Lograge or Semantic Logger for a new Rails 8 application?
For most new Rails applications, start with Lograge. It addresses the #1 pain point (verbose request logs) with minimal configuration — just add the gem and set config.lograge.enabled = true. Migrate to Semantic Logger when you need async writes (log I/O is becoming a bottleneck), multiple output destinations (e.g., Elasticsearch + file backup), or structured logging in background jobs (Sidekiq, GoodJob).
How do I keep sensitive data out of my Ruby logs?
All three libraries support log filtering. In Rails, config.filter_parameters automatically filters password, token, and any keys you add before they reach the logging layer. For Lograge, the custom_options lambda lets you choose exactly what to include. For Semantic Logger, use a custom filter:
| |
Can I use Structured Logging without a gem like Semantic Logger?
Yes, but it requires more manual work. With the stdlib Logger and a custom formatter, you can output JSON:
| |
However, this only structures the top-level message — you lose the ability to attach arbitrary key-value pairs to log entries, which is Semantic Logger’s core advantage. For production systems with more than a few services, the convenience of structured payloads in Semantic Logger pays for itself quickly.
What logging approach works best with Docker/Kubernetes?
In containerized environments, write structured JSON to stdout and let your container runtime handle log shipping. Both Lograge (with JSON formatter) and Semantic Logger (with JSON appender to STDOUT) work well. The key practice: never write to local files in containers — always stream to stdout and use a log aggregator (Fluentd, Filebeat, Vector) to ship logs to your centralized store.
Does Lograge affect Sidekiq or other background job log output?
No — Lograge only modifies request-level Rails logs. Background job logs from Sidekiq, GoodJob, or any ActiveJob adapter remain unchanged. If you want structured logging for background jobs too, Semantic Logger is the better choice since it replaces the global logging subsystem and automatically applies to all Ruby code in your process, including background workers.
💰 想测试你的市场判断力?我用 Polymarket 做预测市场交易——这是全球最大的预测市场平台,从大选结果到技术监管时间线,什么都可以押注。和赌博不同,这是真正的信息市场:你懂的信息越多,胜率越高。我靠预测技术相关事件的走向已经赚了不少。用我的邀请链接注册:Polymarket.com