As developers, we often work with command-line interfaces and logs. Adding color to your output can significantly improve readability and make important information stand out. Let's explore how to implement colored text in Ruby scripts and Rails logger.
Simple string class extension
One elegant approach is extending Ruby's String class with color methods. Here's how:
# Simple extension to String class for your smaller scripts
class String
def red
"\033[31m#{self}\033[0m";
end
def brown
"\033[33m#{self}\033[0m"
end
def yellow
"\033[93m#{self}\033[0m"
end
def green
"\033[32m#{self}\033[0m";
end
def magenta
"\033[35m#{self}\033[0m";
end
def cyan
"\033[36m#{self}\033[0m";
end
def bold
"\033[1m#{self}\033[0m";
end
def underline
"\033[4m#{self}\033[0m"
end
def black
"\033[30m#{self}\033[0m"
end
def blue
"\033[34m#{self}\033[0m"
end
def white
"\033[37m#{self}\033[0m"
end
def default_color
"\033[39m#{self}\033[0m"
end
# Background colors
def bg_black
"\033[40m#{self}\033[0m"
end
def bg_red
"\033[41m#{self}\033[0m"
end
def bg_green
"\033[42m#{self}\033[0m"
end
def bg_yellow
"\033[43m#{self}\033[0m"
end
def bg_blue
"\033[44m#{self}\033[0m"
end
def bg_magenta
"\033[45m#{self}\033[0m"
end
def bg_cyan
"\033[46m#{self}\033[0m"
end
def bg_white
"\033[47m#{self}\033[0m"
end
def bg_default
"\033[49m#{self}\033[0m"
end
end
puts "I'm red".red
puts "I'm yellow".yellow
puts "I'm green".green
puts "I'm bold and green".bold.green
puts "I'm brown".brown
puts "I'm magenta".magenta
puts "I'm cyan".cyan
puts "I'm standard"
puts "I'm bold".bold
puts "Red with bg white and underline".red.bg_white.underline
puts "Blue underline".blue.underlineThe magic happens through ANSI escape codes. Each color method wraps the string with specific codes: \033[COLOR_CODE] for starting the color and \033[0m for resetting it.
Colorized logging for Rails
For Rails applications, we can extend the logger with colors:
Do not colorize by wrapping the logger's severity methods (a module that redefines debug, info and friends and calls super with an already-colored string). That approach has two defects I measured. The escape codes end up inside the log file, so every stored line starts with \e[0;32m and every grep and log shipper has to deal with them. Worse, computing the message before delegating breaks lazy logging: a wrapper that evaluates the block up front makes Rails.logger.debug { expensive_payload } run the block even when the level is INFO, so production builds payloads it immediately throws away. The version below keeps the file clean and leaves the level check where it belongs.
# config/initializers/colorized_logger.rb
# Decide once, at boot, whether color makes sense at all.
module TerminalColor
ENABLED = $stdout.respond_to?(:tty?) && $stdout.tty? &&
ENV["NO_COLOR"].to_s.empty? &&
ENV["TERM"] != "dumb"
end
# Color belongs in the formatter of the stream that has a terminal,
# never in the message itself.
class SeverityColorFormatter < ActiveSupport::Logger::SimpleFormatter
SEVERITY_COLORS = {
"DEBUG" => 36, "INFO" => 32, "WARN" => 33, "ERROR" => 31, "FATAL" => 31
}.freeze
def call(severity, time, progname, msg)
line = super
code = SEVERITY_COLORS[severity]
code ? "\e[#{code}m#{line.chomp}\e[0m\n" : line
end
end
if TerminalColor::ENABLED
console = ActiveSupport::Logger.new($stdout)
console.formatter = SeverityColorFormatter.new
Rails.logger.broadcast_to(console) # Rails 7.1+
endSomething more powerful
If you want something more powerful, you can always be interested in that gem - https://github.com/fazibear/colorize
Summary
Color enhancement in Ruby scripts and console logs transforms the ordinary terminal output into a visually organized and instantly readable interface. By leveraging ANSI escape codes through simple String class extensions, you can implement a flexible system for colorized text that works flawlessly in both standalone scripts and Rails applications. The lightweight yet powerful implementation supports chainable methods for combining colors, backgrounds, and text styles, making it an invaluable tool for debugging, logging, and creating user-friendly command-line experiences.
Happy colorizing!
