For AI agents: a documentation index is available at the root level at /llms.txt and /llms-full.txt. Append /llms.txt to any URL for a page-level index, or .md for the markdown version of any page.
Sign inTry it free
DocsGuidesSDKsIntegrationsAPI docsTutorialsFlagship blog
DocsGuidesSDKsIntegrationsAPI docsTutorialsFlagship blog
  • Tutorials
    • The AI Iteration Loop for Deploying Reliable Agents with LangGraph
    • Using LaunchDarkly feature flags and Experimentation with Wordpress
    • Migrate a Hardcoded LangGraph Agent to LaunchDarkly AgentControl in 20 Minutes
    • Offline Evaluation of RAG-Grounded Answers in AgentControl
    • Beyond n8n for Workflow Automation: Agent Graphs as Your Universal Agent Harness
    • Catch your first silent AI failure with Vega AI in under 10 minutes
    • Evaluate LLM code generation with LLM-as-judge evaluators
    • OpenTelemetry for LLM Applications: A Practical Guide with LaunchDarkly and Langfuse
    • Use LaunchDarkly Agent Skills in Claude Code and Cursor
    • Detection to Resolution: Real World Debugging with Rage Clicks and Session Replay
    • Compare AI orchestrators: LangGraph vs Strands vs OpenAI Swarm
    • Building a data extraction pipeline with LaunchDarkly
    • Day 12 | 🎊 New Year, New Observability
    • Day 11 | ✉️ Letters to Santa: What engineering teams really want from Observability in 2026
    • Day 10 | Why observability and feature flags go together like milk and cookies
    • Day 9 | 👻 The Three Ghosts Haunting Your AI This Holiday Season
    • Day 7 | 🎄✨The Rockefeller tree in NYC: SLOs that actually drive decisions
    • Day 6 | 💸 The famous green character that stole your cloud budget: the cardinality problem
    • Day 5 | 🧹 Using a Popular Tidying Method to Consolidate Your Observability Stack
    • Day 4 | ❄️ Tracing the impact of holiday styling in your Node.js app
    • Day 8 | 🎁 Observable Multi-Modal Agentic Systems
    • Day 3 | 🔔 Jingle All the Way to Zero-Config Observability
    • Day 2 | 🎅 He knows if you have been bad or good... But what if he gets it wrong?
    • Collecting user feedback in your app with feature flags
    • Day 1 | 🎄 Observability Under the Tree: What Changed in 2025
    • Build a User Frustration Detection & Response System
    • When to Add Online Evals to Your AgentControl
    • Detecting User Frustration: Understanding Rage Clicks and Session Replay
    • AgentControl config CI/CD Pipeline: Automated Quality Gates and Safe Deployment
    • A Deeper Look at LaunchDarkly Architecture: More than Feature Flags
    • Add Observability to Your React Native App in 5 minutes
    • Smart AI Agent Targeting with MCP Tools
    • Build a LangGraph Multi-Agent System in 20 Minutes with LaunchDarkly AgentControl
    • Snowflake Cortex Completion API + LaunchDarkly SDK Integration
    • Using AgentControl to review database changes
    • How to implement WebSockets and kill switches in a Python application
    • 4 hacks to turbocharge your Cursor productivity
    • Create a feature flag in your IDE in 5 minutes with LaunchDarkly's MCP server
    • Observability for Your Go ORM: OpenTelemetry Integration with GORM
    • The complete guide to OpenTelemetry in Next.js
    • How to instrument your React Native app with OpenTelemetry
    • The complete guide to OpenTelemetry in Python
    • Monitoring Browser Applications with OpenTelemetry
    • How to Use OpenTelemetry to Monitor Next.js Applications
    • What is OpenTelemetry and Why Should I Care?
    • Distributed Tracing in Next.js Apps
    • Tracing Distributed Systems in Next.js
    • Real-time Monitoring in Django: Essential Tools and Techniques
    • DeepSeek vs Qwen: local model showdown featuring LaunchDarkly AgentControl
    • Application Tracing in .NET for Performance Monitoring
    • The Ultimate Guide to Ruby Logging: Best Libraries and Practices
    • Using Materialized Views in ClickHouse (vs. Postgres)
    • Filtering and Sampling LaunchDarkly Ingest
    • How to Set Up Your Production AWS MSK Kafka Cluster
    • Publishing an NPM Package with Private pnpm Monorepo Dependencies
    • How To Use The Chrome Inspector & Debugger
    • 3 Levels of Data Validation in a Full Stack Application With React
    • The power of the monorepo: Keep your fullstack app in sync!
    • Compression: The simple, powerful upgrade for your web stack
    • Video tutorials
Sign inTry it free
LogoLogo
On this page
  • Introduction
  • The Importance of Logging in Ruby
  • Leveraging Ruby’s Built-in Logger
  • Exploring Advanced Ruby Logging Libraries
  • Conclusion
Tutorials

The Ultimate Guide to Ruby Logging: Best Libraries and Practices

Was this page helpful?
Previous

Using Materialized Views in ClickHouse (vs. Postgres)

Next
Built with

Published February 9, 2024

portrait of Vadim Korolik.

by Vadim Korolik

Introduction

In any Ruby application, logging is more than just a means to record errors or track operations. It is a powerful tool that provides insight into the performance, behavior, and health of your application. This comprehensive guide will delve into the nuances of Ruby logging, highlighting the top libraries and practices that will elevate your logging strategy.

The Importance of Logging in Ruby

Ruby developers often find themselves sifting through logs to diagnose issues or optimize performance. Understanding the significance of logging is key to harnessing its full potential. Logs are not just for error reporting; they are invaluable for monitoring application health, understanding user interactions, and making data-driven decisions.

Leveraging Ruby’s Built-in Logger

The Ruby standard library comes with a built-in Logger class, which provides a basic yet effective logging mechanism. Let’s dive into a comprehensive example:

1require 'logger'
2
3# Creating a new logger instance that outputs to the console
4logger = Logger.new(STDOUT)
5logger.level = Logger::INFO # Setting the log level to INFO
6
7# Customizing the log format for better readability
8logger.formatter = proc do |severity, datetime, progname, msg|
9 "#{datetime}: #{severity} - #{msg}\n"
10end
11
12# Example log messages at different severity levels
13logger.info("Application initialized")
14logger.warn("Low disk space warning")
15logger.error("Error processing user data")

This snippet demonstrates the creation of a logger, setting a severity level, and customizing the log format. Each log message is now more informative and easier to read, aiding in quicker debugging and analysis.

Exploring Advanced Ruby Logging Libraries

  1. Lograge for Rails Applications

Lograge is an excellent choice for Rails developers who prefer a cleaner and more condensed logging format. Here’s an in-depth look at setting up Lograge:

1# In config/environments/production.rb
2config.lograge.enabled = true
3config.lograge.base_controller_class = 'ActionController::API'
4config.lograge.logger = ActiveSupport::Logger.new(STDOUT)
5config.lograge.formatter = Lograge::Formatters::Json.new

This configuration streamlines Rails logs into a single line per request, with JSON formatting for easier parsing and analysis.

  1. The Logging Gem: A Flexible Alternative

The Logging gem offers a robust and customizable logging solution. Here’s a highly-customized setup that emits INFO level logs to a file named development.log and WARN level logs to a file named warn.log:

1require 'logging'
2
3# Configuring the root logger
4Logging.logger.root.appenders = Logging.appenders.file('development.log')
5Logging.logger.root.level = :info
6
7# Setting up a logger for a specific class
8my_logger = Logging.logger['MyClass']
9my_logger.level = :warn
10my_logger.add_appenders(
11 Logging.appenders.file('warn.log')
12)
13
14# Utilizing the logger in a Ruby class
15class MyClass
16 def initialize
17 @logger = Logging.logger[self]
18 end
19
20 def perform_action
21 @logger.warn "Action performed with warning"
22 end
23end

This example illustrates how to set up different loggers for specific parts of your application, providing granular control over logging outputs.

LaunchDarkly supports all of these logging libraries and other ways to ingest your logs. 3. Log4r: Multi-Output Logging

Log4r extends the flexibility of logging by allowing multiple outputs. Here’s how you can set it up:

1require 'log4r'
2include Log4r
3
4# Creating a logger
5logger = Logger.new('application_logger')
6
7# Adding a console outputter
8stdout_outputter = Outputter.stdout
9stdout_outputter.formatter = PatternFormatter.new(pattern: "[%l] %d :: %m")
10logger.add(stdout_outputter)
11
12# Adding a file outputter
13file_outputter = FileOutputter.new('file_outputter', filename: 'app.log', trunc: false)
14file_outputter.formatter = PatternFormatter.new(pattern: "[%l] %d :: %m")
15logger.add(file_outputter)
16
17# Logging an informational message
18logger.info('Application is up and running')

This setup allows you to direct your logs to both the console and a file, offering more flexibility in log management.

  1. Semantic Logger: Structured and Asynchronous Logging

Semantic Logger is ideal for creating structured, JSON-formatted logs, particularly useful in asynchronous environments. Here’s a practical example:

1require 'semantic_logger'
2
3# Adding a JSON-formatted file appender
4SemanticLogger.add_appender(file_name: 'application.log', formatter: :json)
5
6# Logging an informational message with additional context
7SemanticLogger['MyApp'].info('Application started', { environment: 'production', version: '1.2.3' })

This example demonstrates the utility of Semantic Logger in producing logs that are easily parseable by modern log analysis tools.

Conclusion

Mastering logging in Ruby is an art that involves selecting the right tools and practices for your specific needs. Through this guide, we have explored various libraries and methods that can enhance the logging capabilities of your Ruby applications. Effective logging is key to gaining insights into your applications and ensuring their optimal performance.

We invite you to integrate these logging strategies into your Ruby projects. Share your experiences and insights in the comments below.