Skip to content

Commit f10ce9f

Browse files
Colby Swandalesonots
authored andcommitted
split logger classes/modules into separate files
1 parent 106ce55 commit f10ce9f

File tree

8 files changed

+308
-294
lines changed

8 files changed

+308
-294
lines changed

lib/logger.rb

Lines changed: 4 additions & 291 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@
1111
# A simple system for logging messages. See Logger for more documentation.
1212

1313
require 'monitor'
14+
require 'logger/version'
15+
require 'logger/formatter'
16+
require 'logger/log_device'
17+
require 'logger/severity'
1418

1519
# == Description
1620
#
@@ -224,7 +228,6 @@
224228
# })
225229
#
226230
class Logger
227-
VERSION = "1.3.0"
228231
_, name, rev = %w$Id$
229232
if name
230233
name = name.chomp(",v")
@@ -234,27 +237,6 @@ class Logger
234237
rev ||= "v#{VERSION}"
235238
ProgName = "#{name}/#{rev}".freeze
236239

237-
class Error < RuntimeError # :nodoc:
238-
end
239-
# not used after 1.2.7. just for compat.
240-
class ShiftingError < Error # :nodoc:
241-
end
242-
243-
# Logging severity.
244-
module Severity
245-
# Low-level information, mostly for developers.
246-
DEBUG = 0
247-
# Generic (useful) information about system operation.
248-
INFO = 1
249-
# A warning.
250-
WARN = 2
251-
# A handleable error condition.
252-
ERROR = 3
253-
# An unhandleable error that results in a program crash.
254-
FATAL = 4
255-
# An unknown message that should always be logged.
256-
UNKNOWN = 5
257-
end
258240
include Severity
259241

260242
# Logging severity threshold (e.g. <tt>Logger::INFO</tt>).
@@ -596,273 +578,4 @@ def format_severity(severity)
596578
def format_message(severity, datetime, progname, msg)
597579
(@formatter || @default_formatter).call(severity, datetime, progname, msg)
598580
end
599-
600-
601-
# Default formatter for log messages.
602-
class Formatter
603-
Format = "%s, [%s#%d] %5s -- %s: %s\n".freeze
604-
605-
attr_accessor :datetime_format
606-
607-
def initialize
608-
@datetime_format = nil
609-
end
610-
611-
def call(severity, time, progname, msg)
612-
Format % [severity[0..0], format_datetime(time), $$, severity, progname,
613-
msg2str(msg)]
614-
end
615-
616-
private
617-
618-
def format_datetime(time)
619-
time.strftime(@datetime_format || "%Y-%m-%dT%H:%M:%S.%6N ".freeze)
620-
end
621-
622-
def msg2str(msg)
623-
case msg
624-
when ::String
625-
msg
626-
when ::Exception
627-
"#{ msg.message } (#{ msg.class })\n" <<
628-
(msg.backtrace || []).join("\n")
629-
else
630-
msg.inspect
631-
end
632-
end
633-
end
634-
635-
module Period
636-
module_function
637-
638-
SiD = 24 * 60 * 60
639-
640-
def next_rotate_time(now, shift_age)
641-
case shift_age
642-
when 'daily'
643-
t = Time.mktime(now.year, now.month, now.mday) + SiD
644-
when 'weekly'
645-
t = Time.mktime(now.year, now.month, now.mday) + SiD * (7 - now.wday)
646-
when 'monthly'
647-
t = Time.mktime(now.year, now.month, 1) + SiD * 32
648-
return Time.mktime(t.year, t.month, 1)
649-
else
650-
return now
651-
end
652-
if t.hour.nonzero? or t.min.nonzero? or t.sec.nonzero?
653-
hour = t.hour
654-
t = Time.mktime(t.year, t.month, t.mday)
655-
t += SiD if hour > 12
656-
end
657-
t
658-
end
659-
660-
def previous_period_end(now, shift_age)
661-
case shift_age
662-
when 'daily'
663-
t = Time.mktime(now.year, now.month, now.mday) - SiD / 2
664-
when 'weekly'
665-
t = Time.mktime(now.year, now.month, now.mday) - (SiD * now.wday + SiD / 2)
666-
when 'monthly'
667-
t = Time.mktime(now.year, now.month, 1) - SiD / 2
668-
else
669-
return now
670-
end
671-
Time.mktime(t.year, t.month, t.mday, 23, 59, 59)
672-
end
673-
end
674-
675-
# Device used for logging messages.
676-
class LogDevice
677-
include Period
678-
679-
attr_reader :dev
680-
attr_reader :filename
681-
include MonitorMixin
682-
683-
def initialize(log = nil, shift_age: nil, shift_size: nil, shift_period_suffix: nil)
684-
@dev = @filename = @shift_age = @shift_size = @shift_period_suffix = nil
685-
mon_initialize
686-
set_dev(log)
687-
if @filename
688-
@shift_age = shift_age || 7
689-
@shift_size = shift_size || 1048576
690-
@shift_period_suffix = shift_period_suffix || '%Y%m%d'
691-
692-
unless @shift_age.is_a?(Integer)
693-
base_time = @dev.respond_to?(:stat) ? @dev.stat.mtime : Time.now
694-
@next_rotate_time = next_rotate_time(base_time, @shift_age)
695-
end
696-
end
697-
end
698-
699-
def write(message)
700-
begin
701-
synchronize do
702-
if @shift_age and @dev.respond_to?(:stat)
703-
begin
704-
check_shift_log
705-
rescue
706-
warn("log shifting failed. #{$!}")
707-
end
708-
end
709-
begin
710-
@dev.write(message)
711-
rescue
712-
warn("log writing failed. #{$!}")
713-
end
714-
end
715-
rescue Exception => ignored
716-
warn("log writing failed. #{ignored}")
717-
end
718-
end
719-
720-
def close
721-
begin
722-
synchronize do
723-
@dev.close rescue nil
724-
end
725-
rescue Exception
726-
@dev.close rescue nil
727-
end
728-
end
729-
730-
def reopen(log = nil)
731-
# reopen the same filename if no argument, do nothing for IO
732-
log ||= @filename if @filename
733-
if log
734-
synchronize do
735-
if @filename and @dev
736-
@dev.close rescue nil # close only file opened by Logger
737-
@filename = nil
738-
end
739-
set_dev(log)
740-
end
741-
end
742-
self
743-
end
744-
745-
private
746-
747-
def set_dev(log)
748-
if log.respond_to?(:write) and log.respond_to?(:close)
749-
@dev = log
750-
else
751-
@dev = open_logfile(log)
752-
@dev.sync = true
753-
@filename = log
754-
end
755-
end
756-
757-
def open_logfile(filename)
758-
begin
759-
File.open(filename, (File::WRONLY | File::APPEND))
760-
rescue Errno::ENOENT
761-
create_logfile(filename)
762-
end
763-
end
764-
765-
def create_logfile(filename)
766-
begin
767-
logdev = File.open(filename, (File::WRONLY | File::APPEND | File::CREAT | File::EXCL))
768-
logdev.flock(File::LOCK_EX)
769-
logdev.sync = true
770-
add_log_header(logdev)
771-
logdev.flock(File::LOCK_UN)
772-
rescue Errno::EEXIST
773-
# file is created by another process
774-
logdev = open_logfile(filename)
775-
logdev.sync = true
776-
end
777-
logdev
778-
end
779-
780-
def add_log_header(file)
781-
file.write(
782-
"# Logfile created on %s by %s\n" % [Time.now.to_s, Logger::ProgName]
783-
) if file.size == 0
784-
end
785-
786-
def check_shift_log
787-
if @shift_age.is_a?(Integer)
788-
# Note: always returns false if '0'.
789-
if @filename && (@shift_age > 0) && (@dev.stat.size > @shift_size)
790-
lock_shift_log { shift_log_age }
791-
end
792-
else
793-
now = Time.now
794-
if now >= @next_rotate_time
795-
@next_rotate_time = next_rotate_time(now, @shift_age)
796-
lock_shift_log { shift_log_period(previous_period_end(now, @shift_age)) }
797-
end
798-
end
799-
end
800-
801-
if /mswin|mingw/ =~ RUBY_PLATFORM
802-
def lock_shift_log
803-
yield
804-
end
805-
else
806-
def lock_shift_log
807-
retry_limit = 8
808-
retry_sleep = 0.1
809-
begin
810-
File.open(@filename, File::WRONLY | File::APPEND) do |lock|
811-
lock.flock(File::LOCK_EX) # inter-process locking. will be unlocked at closing file
812-
if File.identical?(@filename, lock) and File.identical?(lock, @dev)
813-
yield # log shifting
814-
else
815-
# log shifted by another process (i-node before locking and i-node after locking are different)
816-
@dev.close rescue nil
817-
@dev = open_logfile(@filename)
818-
@dev.sync = true
819-
end
820-
end
821-
rescue Errno::ENOENT
822-
# @filename file would not exist right after #rename and before #create_logfile
823-
if retry_limit <= 0
824-
warn("log rotation inter-process lock failed. #{$!}")
825-
else
826-
sleep retry_sleep
827-
retry_limit -= 1
828-
retry_sleep *= 2
829-
retry
830-
end
831-
end
832-
rescue
833-
warn("log rotation inter-process lock failed. #{$!}")
834-
end
835-
end
836-
837-
def shift_log_age
838-
(@shift_age-3).downto(0) do |i|
839-
if FileTest.exist?("#{@filename}.#{i}")
840-
File.rename("#{@filename}.#{i}", "#{@filename}.#{i+1}")
841-
end
842-
end
843-
@dev.close rescue nil
844-
File.rename("#{@filename}", "#{@filename}.0")
845-
@dev = create_logfile(@filename)
846-
return true
847-
end
848-
849-
def shift_log_period(period_end)
850-
suffix = period_end.strftime(@shift_period_suffix)
851-
age_file = "#{@filename}.#{suffix}"
852-
if FileTest.exist?(age_file)
853-
# try to avoid filename crash caused by Timestamp change.
854-
idx = 0
855-
# .99 can be overridden; avoid too much file search with 'loop do'
856-
while idx < 100
857-
idx += 1
858-
age_file = "#{@filename}.#{suffix}.#{idx}"
859-
break unless FileTest.exist?(age_file)
860-
end
861-
end
862-
@dev.close rescue nil
863-
File.rename("#{@filename}", age_file)
864-
@dev = create_logfile(@filename)
865-
return true
866-
end
867-
end
868581
end

lib/logger/errors.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
class Logger
2+
class Error < RuntimeError # :nodoc:
3+
end
4+
# not used after 1.2.7. just for compat.
5+
class ShiftingError < Error # :nodoc:
6+
end
7+
end

lib/logger/formatter.rb

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
class Logger
2+
# Default formatter for log messages.
3+
class Formatter
4+
Format = "%s, [%s#%d] %5s -- %s: %s\n".freeze
5+
6+
attr_accessor :datetime_format
7+
8+
def initialize
9+
@datetime_format = nil
10+
end
11+
12+
def call(severity, time, progname, msg)
13+
Format % [severity[0..0], format_datetime(time), $$, severity, progname,
14+
msg2str(msg)]
15+
end
16+
17+
private
18+
19+
def format_datetime(time)
20+
time.strftime(@datetime_format || "%Y-%m-%dT%H:%M:%S.%6N ".freeze)
21+
end
22+
23+
def msg2str(msg)
24+
case msg
25+
when ::String
26+
msg
27+
when ::Exception
28+
"#{ msg.message } (#{ msg.class })\n" <<
29+
(msg.backtrace || []).join("\n")
30+
else
31+
msg.inspect
32+
end
33+
end
34+
end
35+
end

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy