2012-05-14 11:52:45 +02:00
|
|
|
require 'json'
|
|
|
|
|
2012-05-21 13:54:21 +02:00
|
|
|
class Object
|
|
|
|
def to_semlogger
|
2012-10-18 19:34:04 +02:00
|
|
|
[
|
|
|
|
self.class.name.to_sym,
|
|
|
|
self.respond_to?( :serializable_hash) ? self.serializable_hash : self
|
|
|
|
]
|
2012-05-21 13:54:21 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class Exception
|
|
|
|
def to_semlogger
|
|
|
|
[:exception] + super
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class String
|
|
|
|
def to_semlogger
|
|
|
|
[:String, self]
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
%w[Numeric FalseClass TrueClass NilClass].each do |cl|
|
|
|
|
Object.const_get( cl).class_eval do
|
|
|
|
def to_semlogger
|
|
|
|
[:const, self]
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2012-05-14 12:02:50 +02:00
|
|
|
class Semlogger < ::Logger
|
2012-10-17 23:14:09 +02:00
|
|
|
class Base
|
2012-10-18 19:34:04 +02:00
|
|
|
class <<self
|
|
|
|
attr_accessor :logger
|
|
|
|
end
|
2012-10-15 16:08:35 +02:00
|
|
|
attr_accessor :logger
|
|
|
|
|
2012-10-18 19:34:04 +02:00
|
|
|
def initialize
|
|
|
|
@logger = self.class.logger
|
|
|
|
end
|
|
|
|
|
|
|
|
def add severity, logger = nil, &block
|
|
|
|
(logger || @logger).add severity, self, &block
|
2012-10-17 23:14:09 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
::Semlogger::Severity.constants.each do |severity|
|
2012-10-18 19:34:04 +02:00
|
|
|
module_eval <<-EOC, __FILE__, __LINE__+1
|
|
|
|
def #{severity.downcase} *a, &e
|
|
|
|
add #{::Semlogger::Severity.const_get severity}, *a, &e
|
|
|
|
end
|
|
|
|
EOC
|
2012-10-17 23:14:09 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class CustomType < Base
|
2012-05-21 13:54:21 +02:00
|
|
|
def initialize name, *obj
|
|
|
|
@name, @obj = name.to_s.to_sym, obj
|
|
|
|
end
|
|
|
|
|
|
|
|
def to_semlogger
|
|
|
|
[@name] + @obj
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
attr_accessor :logdev, :level, :progname
|
2012-11-19 17:07:39 +01:00
|
|
|
|
|
|
|
# some libs use #log_level
|
|
|
|
def log_level=( level) @level = level end
|
|
|
|
def log_level() @level end
|
|
|
|
|
2012-05-21 13:54:21 +02:00
|
|
|
class <<self
|
2012-10-18 19:34:04 +02:00
|
|
|
attr_accessor :progname, :logger
|
2012-10-19 11:32:29 +02:00
|
|
|
|
|
|
|
def new_rails_logger config
|
|
|
|
require 'semlogger/rack'
|
2012-10-19 11:38:12 +02:00
|
|
|
logdev = ::Rails.root.join( 'log', "#{::Rails.env.to_s.gsub('%', '%%')}.%Y-%m-%d.%$.log").to_s
|
2012-10-19 11:32:29 +02:00
|
|
|
logger = nil
|
|
|
|
if Rails.env.production?
|
2012-10-19 11:38:12 +02:00
|
|
|
logger = new logdev
|
|
|
|
logger.level = Semlogger::INFO
|
2012-10-19 11:32:29 +02:00
|
|
|
elsif Rails.env.development?
|
2012-10-19 11:38:12 +02:00
|
|
|
logger = new Semlogger::Multiplex.new( Semlogger::FInfo.new( Semlogger::Printer.new), Semlogger::Writer.new( logdev))
|
|
|
|
logger.level = Semlogger::DEBUG
|
2012-10-19 11:32:29 +02:00
|
|
|
else
|
2012-10-19 11:38:12 +02:00
|
|
|
logger = new logdev
|
|
|
|
logger.level = Semlogger::DEBUG
|
2012-10-19 11:32:29 +02:00
|
|
|
end
|
|
|
|
config.middleware.swap Rails::Rack::Logger, Semlogger::Rack, [], {reqid: :uuid}
|
|
|
|
config.logger = logger
|
|
|
|
end
|
|
|
|
|
2012-10-18 19:34:04 +02:00
|
|
|
def custom( *a) CustomType.new( *a).tap {|t| t.logger = self.logger } end
|
2012-05-21 13:54:21 +02:00
|
|
|
end
|
2012-10-18 19:34:04 +02:00
|
|
|
def custom( *a) CustomType.new( *a).tap {|t| t.logger = self } end
|
2012-05-21 13:54:21 +02:00
|
|
|
|
|
|
|
@@progname = nil
|
|
|
|
|
2012-05-14 11:52:45 +02:00
|
|
|
def initialize logdev = nil, *a, &e
|
|
|
|
case logdev
|
2012-05-14 12:02:50 +02:00
|
|
|
when String, nil then logdev = ::Semlogger::Writer.new logdev
|
2012-05-14 11:52:45 +02:00
|
|
|
end
|
2012-05-21 13:54:21 +02:00
|
|
|
@progname = a[0] || @@progname
|
2012-05-14 11:52:45 +02:00
|
|
|
@level, @data, @tags, @logdev = DEBUG, {}, [], logdev
|
2012-10-18 19:34:04 +02:00
|
|
|
self.class.logger = self if !self.class.logger && self.class.logger.is_a?( Semlogger::Default)
|
2012-05-14 11:52:45 +02:00
|
|
|
end
|
|
|
|
|
2012-10-15 16:08:35 +02:00
|
|
|
def tagged *tags, &e
|
2012-05-14 11:52:45 +02:00
|
|
|
@tags += tags
|
|
|
|
tags = tags.size
|
|
|
|
yield
|
|
|
|
ensure
|
|
|
|
tags.times { @tags.pop }
|
|
|
|
end
|
|
|
|
|
|
|
|
def add severity, message = nil, progname = nil, &block
|
|
|
|
severity ||= UNKNOWN
|
2012-11-19 17:07:39 +01:00
|
|
|
return true if @logdev.nil? or severity < @level
|
2012-05-14 11:52:45 +02:00
|
|
|
progname ||= @progname
|
|
|
|
if message.nil?
|
|
|
|
if block_given?
|
|
|
|
message = yield
|
|
|
|
else
|
|
|
|
message = progname
|
|
|
|
progname = @progname
|
|
|
|
end
|
|
|
|
end
|
|
|
|
@logdev.add severity, Time.new, progname, format_data( @data), format_tags( @tags), format_msg( message)
|
|
|
|
end
|
|
|
|
|
|
|
|
def format_msg msg
|
2012-05-21 13:54:21 +02:00
|
|
|
msg = msg.to_semlogger
|
2012-05-14 11:52:45 +02:00
|
|
|
case msg
|
2012-05-21 13:54:21 +02:00
|
|
|
when Array then msg
|
|
|
|
else [msg.class.name.to_sym, msg.inspect]
|
2012-05-14 11:52:45 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def format_obj obj
|
|
|
|
case obj
|
|
|
|
when Proc then obj.call
|
|
|
|
else obj
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def format_tags tags
|
|
|
|
tags = tags ? tags.dup : []
|
|
|
|
tags.map &method( :format_obj)
|
|
|
|
end
|
|
|
|
|
|
|
|
def format_data data
|
|
|
|
data = data ? data.dup : {}
|
|
|
|
data.each {|k,v| data[k] = format_obj v }
|
|
|
|
end
|
|
|
|
|
|
|
|
def data data, &e
|
2012-05-21 13:54:21 +02:00
|
|
|
return @data unless e
|
2012-05-14 11:52:45 +02:00
|
|
|
@data.update data
|
|
|
|
keys = data.keys
|
|
|
|
yield
|
|
|
|
ensure
|
|
|
|
keys.each &data.method( :delete)
|
|
|
|
end
|
|
|
|
|
|
|
|
def caller &e
|
|
|
|
data caller: Kernel.method(:caller), &e
|
|
|
|
end
|
|
|
|
|
|
|
|
def thread &e
|
|
|
|
data thread: Proc.new { Thread.current.object_id }, &e
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2012-05-14 12:02:50 +02:00
|
|
|
require 'semlogger/rotate'
|
|
|
|
require 'semlogger/multiplex'
|
|
|
|
require 'semlogger/filter'
|
|
|
|
require 'semlogger/writer'
|
2012-10-18 19:34:04 +02:00
|
|
|
|
|
|
|
class Semlogger
|
|
|
|
class Default < Semlogger
|
|
|
|
end
|
|
|
|
self.logger ||= Default.new
|
|
|
|
end
|