Logger (Standard Library)
Ruby標準ライブラリのロギング機能。外部依存関係なしで基本的なロギング機能を提供。ログレベル、ローテーション、カスタムフォーマッターをサポート。シンプルなRubyアプリケーションやスクリプトに適している。
GitHub概要
ruby/logger
simple logging utility
スター134
ウォッチ34
フォーク69
作成日:2018年5月17日
言語:Ruby
ライセンス:Other
トピックス
hacktoberfestloggerruby
スター履歴
データ取得日時: 2025/10/22 10:04
logger
loggerは、Ruby標準ライブラリに含まれるロギングユーティリティです。シンプルながら洗練された機能を提供し、メッセージの重要度に応じたレベル管理、ログローテーション、カスタマイズ可能なフォーマッターなど、本格的なロギングに必要な機能を備えています。
主な特徴
- 5段階のログレベル - DEBUG、INFO、WARN、ERROR、FATAL
- 自動ログローテーション - サイズまたは期間ベースのローテーション
- カスタマイズ可能なフォーマッター - 出力形式を柔軟に設定
- スレッドセーフ - マルチスレッド環境で安全に使用可能
- 標準ライブラリ - 追加のGemインストール不要
インストール
Rubyの標準ライブラリのため、追加のインストールは不要です。
require 'logger'
基本的な使い方
シンプルな例
require 'logger'
# 標準出力へのロガーを作成
logger = Logger.new(STDOUT)
# ログレベルを設定(デフォルトはDEBUG)
logger.level = Logger::INFO
# 各レベルでメッセージを記録
logger.debug("デバッグメッセージ") # 表示されない
logger.info("アプリケーションが起動しました")
logger.warn("警告: メモリ使用量が高くなっています")
logger.error("エラーが発生しました")
logger.fatal("致命的なエラー: システムを停止します")
# ブロック構文も使用可能
logger.info { "処理完了: #{Time.now}" }
ログレベル
# 利用可能なログレベル(重要度順)
Logger::FATAL # 致命的なエラー
Logger::ERROR # エラー
Logger::WARN # 警告
Logger::INFO # 情報
Logger::DEBUG # デバッグ
Logger::UNKNOWN # 不明なレベル
# レベルの設定方法
logger.level = Logger::WARN # WARN以上のみ記録
# 文字列でも設定可能
logger.level = "INFO"
# 動的なレベル変更
if ENV['DEBUG']
logger.level = Logger::DEBUG
else
logger.level = Logger::INFO
end
ファイルへのロギング
基本的なファイル出力
# ファイルへのロガーを作成
logger = Logger.new('application.log')
# 複数の出力先を管理
file_logger = Logger.new('app.log')
stdout_logger = Logger.new(STDOUT)
class MultiLogger
def initialize(*loggers)
@loggers = loggers
end
[:debug, :info, :warn, :error, :fatal].each do |level|
define_method(level) do |message = nil, &block|
@loggers.each do |logger|
if block_given?
logger.send(level, &block)
else
logger.send(level, message)
end
end
end
end
end
# 使用例
multi_logger = MultiLogger.new(file_logger, stdout_logger)
multi_logger.info("両方のロガーに記録されます")
ログローテーション
サイズベースのローテーション
# 10MBを超えたらローテーション、最大5ファイル保持
logger = Logger.new('app.log', 5, 10 * 1024 * 1024)
# 1MBごとにローテーション、10ファイル保持
logger = Logger.new('small.log', 10, 1024 * 1024)
期間ベースのローテーション
# 毎日ローテーション
logger = Logger.new('daily.log', 'daily')
# 毎週ローテーション
logger = Logger.new('weekly.log', 'weekly')
# 毎月ローテーション
logger = Logger.new('monthly.log', 'monthly')
# カスタム期間(秒単位)
logger = Logger.new('custom.log', 3600) # 1時間ごと
フォーマッターのカスタマイズ
基本的なフォーマット変更
# 日時フォーマットの変更
logger.datetime_format = '%Y-%m-%d %H:%M:%S'
# カスタムフォーマッター
logger.formatter = proc do |severity, datetime, progname, msg|
"[#{datetime}] #{severity}: #{msg}\n"
end
# より詳細なフォーマッター
logger.formatter = proc do |severity, datetime, progname, msg|
date_format = datetime.strftime('%Y-%m-%d %H:%M:%S.%L')
if progname
"[#{date_format}] #{severity.ljust(5)} (#{progname}): #{msg}\n"
else
"[#{date_format}] #{severity.ljust(5)}: #{msg}\n"
end
end
構造化ログ(JSON形式)
require 'json'
require 'logger'
class JsonFormatter
def call(severity, time, progname, msg)
{
timestamp: time.iso8601,
level: severity,
program: progname,
message: msg,
pid: Process.pid,
hostname: Socket.gethostname
}.to_json + "\n"
end
end
logger = Logger.new(STDOUT)
logger.formatter = JsonFormatter.new
logger.info("ユーザーがログインしました")
# => {"timestamp":"2024-01-15T10:30:45+09:00","level":"INFO","program":null,"message":"ユーザーがログインしました","pid":12345,"hostname":"server01"}
高度な使い方
プログラム名の設定
logger = Logger.new(STDOUT)
logger.progname = 'MyApp'
logger.info("起動しました")
# => I, [2024-01-15T10:30:45.123456 #12345] INFO -- MyApp: 起動しました
# 一時的なプログラム名の変更
logger.info('UserAuth') { 'ログイン成功' }
# => I, [2024-01-15T10:30:45.123456 #12345] INFO -- UserAuth: ログイン成功
エラーとスタックトレースの記録
begin
# 何かエラーが発生する処理
raise StandardError, "何かが壊れました"
rescue => e
logger.error("処理中にエラーが発生しました: #{e.message}")
logger.error(e.backtrace.join("\n"))
# または1行で
logger.error { "エラー: #{e.message}\n#{e.backtrace.join("\n")}" }
end
条件付きロギング
class ConditionalLogger
def initialize(logger, condition)
@logger = logger
@condition = condition
end
[:debug, :info, :warn, :error, :fatal].each do |level|
define_method(level) do |message = nil, &block|
return unless @condition.call
if block_given?
@logger.send(level, &block)
else
@logger.send(level, message)
end
end
end
end
# 開発環境でのみログを出力
dev_logger = ConditionalLogger.new(
Logger.new(STDOUT),
-> { ENV['RACK_ENV'] == 'development' }
)
dev_logger.debug("この情報は開発環境でのみ表示されます")
パフォーマンスロギング
class PerformanceLogger
def initialize(logger)
@logger = logger
end
def measure(operation_name)
start_time = Time.now
result = nil
begin
result = yield
rescue => e
@logger.error("#{operation_name} failed: #{e.message}")
raise
ensure
duration = Time.now - start_time
@logger.info("#{operation_name} completed in #{(duration * 1000).round(2)}ms")
end
result
end
end
perf_logger = PerformanceLogger.new(Logger.new(STDOUT))
perf_logger.measure("データベースクエリ") do
# 重い処理
sleep(0.1)
"結果"
end
# => I, [...] INFO -- : データベースクエリ completed in 100.12ms
Railsでの使用
Rails.logger
# Railsではデフォルトでloggerが設定されている
Rails.logger.info "Railsアプリケーションからのログ"
# コントローラーやモデルでの使用
class UsersController < ApplicationController
def create
logger.info "新規ユーザー作成開始: #{params[:email]}"
@user = User.new(user_params)
if @user.save
logger.info "ユーザー作成成功: ID=#{@user.id}"
redirect_to @user
else
logger.error "ユーザー作成失敗: #{@user.errors.full_messages.join(', ')}"
render :new
end
end
end
タグ付きロギング
# config/application.rb
config.logger = ActiveSupport::TaggedLogging.new(Logger.new(STDOUT))
# 使用例
class ApplicationController < ActionController::Base
around_action :add_request_tags
private
def add_request_tags
logger.tagged(request.uuid, current_user&.id) do
yield
end
end
end
# ログ出力例
# [a1b2c3d4-e5f6-7890] [12345] Processing by UsersController#show as HTML
ベストプラクティス
1. 適切なログレベルの使用
# 良い例
logger.debug { "SQLクエリ: #{sql}" } # 開発時の詳細情報
logger.info "ユーザー#{user_id}がログインしました" # 通常の動作情報
logger.warn "API呼び出しがタイムアウトしました。リトライします" # 警告
logger.error "支払い処理に失敗しました: #{error.message}" # エラー
logger.fatal "データベース接続が切断されました" # 致命的なエラー
2. 環境別設定
class AppLogger
def self.create
logger = Logger.new(log_destination)
logger.level = log_level
logger.formatter = formatter
logger
end
private
def self.log_destination
case ENV['RACK_ENV']
when 'production'
'log/production.log'
when 'test'
'log/test.log'
else
STDOUT
end
end
def self.log_level
case ENV['RACK_ENV']
when 'production'
Logger::INFO
when 'test'
Logger::ERROR
else
Logger::DEBUG
end
end
def self.formatter
if ENV['RACK_ENV'] == 'production'
JsonFormatter.new
else
Logger::Formatter.new
end
end
end
3. センシティブな情報の除外
class SafeLogger
def initialize(logger)
@logger = logger
@filters = [/password/i, /token/i, /secret/i]
end
def info(message)
@logger.info(filter_message(message))
end
private
def filter_message(message)
filtered = message.dup
@filters.each do |pattern|
filtered.gsub!(pattern, '[FILTERED]')
end
filtered
end
end
他のロギングライブラリとの比較
semantic_logger
より高度な機能を提供する代替ライブラリ:
# semantic_loggerの特徴
# - 構造化ログのネイティブサポート
# - 高パフォーマンス
# - 豊富な出力先オプション
require 'semantic_logger'
SemanticLogger.add_appender(io: STDOUT, formatter: :json)
logger = SemanticLogger['MyApp']
logger.info('ユーザー登録', user_id: 123, email: '[email protected]')
選択の指針
- logger - シンプルで標準的なロギングが必要な場合
- semantic_logger - 高度な構造化ログや複数の出力先が必要な場合
- Rails.logger - Railsアプリケーションの場合
まとめ
Ruby標準のloggerライブラリは、シンプルながら十分な機能を持つロギングソリューションです。標準ライブラリとして提供されているため追加の依存関係なしに使用でき、基本的なロギング要件を満たします。より高度な要件がある場合は、semantic_loggerなどの代替ライブラリを検討することもできますが、多くのアプリケーションではloggerで十分対応可能です。