Compare commits
26 commits
Author | SHA1 | Date | |
---|---|---|---|
d1694702b8 | |||
6d2157caff | |||
25ff6d52d8 | |||
595f4ac6f1 | |||
8edb8ccdea | |||
26853e31e2 | |||
fd8860766b | |||
3874aa0e43 | |||
3b20edf5cf | |||
e04b61dd4a | |||
eba19017af | |||
1108a9331c | |||
e9cba75802 | |||
57896e3145 | |||
4e803a26e7 | |||
95417dec97 | |||
eee7d885cc | |||
6c9b038de0 | |||
d4dd5dfd0e | |||
c44010dd64 | |||
a7745f28a1 | |||
742bb3b01e | |||
59957f03b7 | |||
0f6eee9e91 | |||
868507672a | |||
f06b2be077 |
2
Rakefile
2
Rakefile
|
@ -43,7 +43,7 @@ end
|
||||||
|
|
||||||
#task :default => :test
|
#task :default => :test
|
||||||
|
|
||||||
require 'rake/rdoctask'
|
require 'rdoc/task'
|
||||||
Rake::RDocTask.new do |rdoc|
|
Rake::RDocTask.new do |rdoc|
|
||||||
if File.exist? 'VERSION'
|
if File.exist? 'VERSION'
|
||||||
version = File.read 'VERSION'
|
version = File.read 'VERSION'
|
||||||
|
|
124
lib/semlogger.rb
124
lib/semlogger.rb
|
@ -1,26 +1,123 @@
|
||||||
require 'json'
|
require 'json'
|
||||||
|
|
||||||
|
class Object
|
||||||
|
def to_semlogger
|
||||||
|
[
|
||||||
|
self.class.name.to_sym,
|
||||||
|
self.respond_to?( :serializable_hash) ? self.serializable_hash : self
|
||||||
|
]
|
||||||
|
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
|
||||||
|
|
||||||
class Semlogger < ::Logger
|
class Semlogger < ::Logger
|
||||||
|
class Base
|
||||||
|
class <<self
|
||||||
|
attr_accessor :logger
|
||||||
|
end
|
||||||
|
attr_accessor :logger
|
||||||
|
|
||||||
|
def initialize
|
||||||
|
@logger = self.class.logger
|
||||||
|
end
|
||||||
|
|
||||||
|
def add severity, logger = nil, &block
|
||||||
|
(logger || @logger).add severity, self, &block
|
||||||
|
end
|
||||||
|
|
||||||
|
::Semlogger::Severity.constants.each do |severity|
|
||||||
|
module_eval <<-EOC, __FILE__, __LINE__+1
|
||||||
|
def #{severity.downcase} *a, &e
|
||||||
|
add #{::Semlogger::Severity.const_get severity}, *a, &e
|
||||||
|
end
|
||||||
|
EOC
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class CustomType < Base
|
||||||
|
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
|
||||||
|
|
||||||
|
# some libs use #log_level
|
||||||
|
def log_level=( level) @level = level end
|
||||||
|
def log_level() @level end
|
||||||
|
|
||||||
|
class <<self
|
||||||
|
attr_accessor :progname, :logger
|
||||||
|
|
||||||
|
def new_rails_logger config, logdev = nil
|
||||||
|
require 'semlogger/rack'
|
||||||
|
logdev ||= ::Rails.root.join 'log', "#{::Rails.env.to_s.gsub('%', '%%')}.%Y-%m-%d.%$.log"
|
||||||
|
logdev = logdev.to_s
|
||||||
|
logger = nil
|
||||||
|
if Rails.env.production?
|
||||||
|
logger = new logdev
|
||||||
|
logger.level = Semlogger::INFO
|
||||||
|
elsif Rails.env.development?
|
||||||
|
logger = new Semlogger::Multiplex.new( Semlogger::FInfo.new( Semlogger::Printer.new), Semlogger::Writer.new( logdev))
|
||||||
|
logger.level = Semlogger::DEBUG
|
||||||
|
else
|
||||||
|
logger = new logdev
|
||||||
|
logger.level = Semlogger::DEBUG
|
||||||
|
end
|
||||||
|
config.middleware.swap Rails::Rack::Logger, Semlogger::Rack, [], {reqid: :uuid}
|
||||||
|
config.logger = logger
|
||||||
|
end
|
||||||
|
|
||||||
|
def custom( *a) CustomType.new( *a).tap {|t| t.logger = self.logger } end
|
||||||
|
end
|
||||||
|
def custom( *a) CustomType.new( *a).tap {|t| t.logger = self } end
|
||||||
|
|
||||||
|
@@progname = nil
|
||||||
|
|
||||||
def initialize logdev = nil, *a, &e
|
def initialize logdev = nil, *a, &e
|
||||||
case logdev
|
case logdev
|
||||||
when String, nil then logdev = ::Semlogger::Writer.new logdev
|
when String, nil then logdev = ::Semlogger::Writer.new logdev
|
||||||
end
|
end
|
||||||
|
@progname = a[0] || @@progname
|
||||||
@level, @data, @tags, @logdev = DEBUG, {}, [], logdev
|
@level, @data, @tags, @logdev = DEBUG, {}, [], logdev
|
||||||
|
self.class.logger = self if !self.class.logger && self.class.logger.is_a?( Semlogger::Default)
|
||||||
end
|
end
|
||||||
|
|
||||||
def tagged tags, &e
|
def tagged *tags, &e
|
||||||
@tags += tags
|
@tags += tags.flatten.compact
|
||||||
tags = tags.size
|
tags = tags.size
|
||||||
yield
|
yield
|
||||||
ensure
|
ensure
|
||||||
tags.times { @tags.pop }
|
#tags.times { @tags.pop }
|
||||||
|
@tags.slice! -tags .. -1
|
||||||
end
|
end
|
||||||
|
|
||||||
def add severity, message = nil, progname = nil, &block
|
def add severity, message = nil, progname = nil, &block
|
||||||
severity ||= UNKNOWN
|
severity ||= UNKNOWN
|
||||||
if @logdev.nil? or severity < @level
|
return true if @logdev.nil? or severity < @level
|
||||||
return true
|
|
||||||
end
|
|
||||||
progname ||= @progname
|
progname ||= @progname
|
||||||
if message.nil?
|
if message.nil?
|
||||||
if block_given?
|
if block_given?
|
||||||
|
@ -34,11 +131,10 @@ class Semlogger < ::Logger
|
||||||
end
|
end
|
||||||
|
|
||||||
def format_msg msg
|
def format_msg msg
|
||||||
|
msg = msg.to_semlogger
|
||||||
case msg
|
case msg
|
||||||
when Numeric, true, false, nil then [:const, msg]
|
when Array then msg
|
||||||
when String then [:str, msg]
|
else [msg.class.name.to_sym, msg.inspect]
|
||||||
when Exception then [:exception, msg.class.name, msg.message.to_s, msg.backtrace]
|
|
||||||
else [:obj, msg]
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -60,6 +156,7 @@ class Semlogger < ::Logger
|
||||||
end
|
end
|
||||||
|
|
||||||
def data data, &e
|
def data data, &e
|
||||||
|
return @data unless e
|
||||||
@data.update data
|
@data.update data
|
||||||
keys = data.keys
|
keys = data.keys
|
||||||
yield
|
yield
|
||||||
|
@ -78,6 +175,11 @@ end
|
||||||
|
|
||||||
require 'semlogger/rotate'
|
require 'semlogger/rotate'
|
||||||
require 'semlogger/multiplex'
|
require 'semlogger/multiplex'
|
||||||
require 'semlogger/rack'
|
|
||||||
require 'semlogger/filter'
|
require 'semlogger/filter'
|
||||||
require 'semlogger/writer'
|
require 'semlogger/writer'
|
||||||
|
|
||||||
|
class Semlogger
|
||||||
|
class Default < Semlogger
|
||||||
|
end
|
||||||
|
self.logger ||= Default.new
|
||||||
|
end
|
||||||
|
|
|
@ -1,29 +1,43 @@
|
||||||
class Semlogger::Rack < Rails::Rack::Logger
|
class Semlogger::Rack < Rails::Rack::Logger
|
||||||
def initialize app, tags = nil, data = nil
|
def initialize app, tags = nil, data = nil
|
||||||
super app, tags
|
super app, tags
|
||||||
@data = data
|
@data = data || {}
|
||||||
end
|
end
|
||||||
|
|
||||||
def call_app env
|
def call_app request, env
|
||||||
request = ActionDispatch::Request.new env
|
|
||||||
path = request.filtered_path
|
path = request.filtered_path
|
||||||
Rails.logger.info [:connection, request.ip, Thread.current.object_id, request.request_method, path]
|
Rails.logger.custom( :connection, request.ip, Thread.current.object_id, request.request_method, path).info
|
||||||
@app.call env
|
@app.call env
|
||||||
ensure
|
ensure
|
||||||
ActiveSupport::LogSubscriber.flush_all!
|
ActiveSupport::LogSubscriber.flush_all!
|
||||||
end
|
end
|
||||||
|
|
||||||
def call env
|
def call env
|
||||||
if @data
|
|
||||||
Rails.logger.data( compute_data( env)) { super env }
|
|
||||||
else
|
|
||||||
super env
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def compute_data env
|
|
||||||
request = ActionDispatch::Request.new env
|
request = ActionDispatch::Request.new env
|
||||||
|
compute_tagged_ request do
|
||||||
|
compute_data_ request do
|
||||||
|
call_app request, env
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def compute_tagged_ request
|
||||||
|
if Rails.logger.respond_to? :tagged
|
||||||
|
Rails.logger.tagged( compute_tags( request)) { yield }
|
||||||
|
else
|
||||||
|
yield
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def compute_data_ request
|
||||||
|
if Rails.logger.respond_to? :data
|
||||||
|
Rails.logger.data( compute_data( request)) { yield }
|
||||||
|
else
|
||||||
|
yield
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def compute_data request
|
||||||
data = @data.dup
|
data = @data.dup
|
||||||
data.each do |k, v|
|
data.each do |k, v|
|
||||||
case v
|
case v
|
||||||
|
|
|
@ -9,11 +9,7 @@ class Semlogger::Rotate
|
||||||
|
|
||||||
def open_if
|
def open_if
|
||||||
name = Time.now.strftime( @filename).gsub /%\$/, $$.to_s
|
name = Time.now.strftime( @filename).gsub /%\$/, $$.to_s
|
||||||
#p at: Time.now, open_if: name, cur: @file ? @file.path : nil, e: @file ? name == @file.path : nil
|
close if @file and name != @file.path
|
||||||
if @file and name == @file.path
|
|
||||||
@file.close
|
|
||||||
@file = nil
|
|
||||||
end
|
|
||||||
@file = File.open name, 'a' unless @file
|
@file = File.open name, 'a' unless @file
|
||||||
@file
|
@file
|
||||||
end
|
end
|
||||||
|
@ -24,5 +20,6 @@ class Semlogger::Rotate
|
||||||
|
|
||||||
def close
|
def close
|
||||||
@file.close
|
@file.close
|
||||||
|
@file = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,11 +3,15 @@ end
|
||||||
|
|
||||||
class Semlogger::Writer < Semlogger::Output
|
class Semlogger::Writer < Semlogger::Output
|
||||||
def initialize logdev = nil
|
def initialize logdev = nil
|
||||||
@logdev = logdev || ::Semlogger::Rotate.new( ::Rails.root.join( 'log', ::Rails.env).to_s.gsub('%', '%%') + '.%Y-%m-%d.%$.log')
|
@logdev = case logdev
|
||||||
|
when String then ::Semlogger::Rotate.new logdev
|
||||||
|
when nil then ::Semlogger::Rotate.new "log/#{File.basename $0}.%Y-%m-%d.%$.log"
|
||||||
|
else logdev
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def add severity, time, progname, data, tags, message
|
def add severity, time, progname, data, tags, message
|
||||||
@logdev.write [severity, time, progname, data, tags, message].to_json+"\n"
|
@logdev.write [severity, time.xmlschema(9), progname, data, tags, message].to_json+"\n"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -24,8 +28,7 @@ class Semlogger::Printer < Semlogger::Output
|
||||||
r = "Exception: #{message[2]} (#{message[1]}"
|
r = "Exception: #{message[2]} (#{message[1]}"
|
||||||
r << "\n\t" << message[3].join( "\n\t") if message[3]
|
r << "\n\t" << message[3].join( "\n\t") if message[3]
|
||||||
r
|
r
|
||||||
when :str, :const then message[1]
|
when :String, :const then message[1]
|
||||||
when :obj then message[1].inspect
|
|
||||||
else message.inspect
|
else message.inspect
|
||||||
end
|
end
|
||||||
reqid = data[:reqid]
|
reqid = data[:reqid]
|
||||||
|
|
|
@ -4,13 +4,13 @@
|
||||||
# -*- encoding: utf-8 -*-
|
# -*- encoding: utf-8 -*-
|
||||||
|
|
||||||
Gem::Specification.new do |s|
|
Gem::Specification.new do |s|
|
||||||
s.name = %q{semlogger}
|
s.name = "semlogger"
|
||||||
s.version = "0.0.2"
|
s.version = "0.0.10"
|
||||||
|
|
||||||
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
||||||
s.authors = ["Denis Knauf"]
|
s.authors = ["Denis Knauf"]
|
||||||
s.date = %q{2012-05-20}
|
s.date = "2012-11-21"
|
||||||
s.description = %q{(Semi-)Structured Logger for Ruby (and Rails)}
|
s.description = "(Semi-)Structured Logger for Ruby (and Rails)"
|
||||||
s.email = ["Denis.Knauf@gmail.com"]
|
s.email = ["Denis.Knauf@gmail.com"]
|
||||||
s.extra_rdoc_files = [
|
s.extra_rdoc_files = [
|
||||||
"LICENSE",
|
"LICENSE",
|
||||||
|
@ -30,13 +30,12 @@ Gem::Specification.new do |s|
|
||||||
"lib/semlogger/tailer.rb",
|
"lib/semlogger/tailer.rb",
|
||||||
"lib/semlogger/writer.rb"
|
"lib/semlogger/writer.rb"
|
||||||
]
|
]
|
||||||
s.homepage = %q{http://github.com/DenisKnauf/semlogger}
|
s.homepage = "http://github.com/DenisKnauf/semlogger"
|
||||||
s.require_paths = ["lib"]
|
s.require_paths = ["lib"]
|
||||||
s.rubygems_version = %q{1.3.7}
|
s.rubygems_version = "1.8.23"
|
||||||
s.summary = %q{(Semi-)Structured Logger}
|
s.summary = "(Semi-)Structured Logger"
|
||||||
|
|
||||||
if s.respond_to? :specification_version then
|
if s.respond_to? :specification_version then
|
||||||
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
|
||||||
s.specification_version = 3
|
s.specification_version = 3
|
||||||
|
|
||||||
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
||||||
|
|
Loading…
Reference in a new issue