yell 1.3.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +3 -1
- data/.travis.yml +1 -2
- data/Gemfile +5 -1
- data/README.md +67 -14
- data/examples/004.1-colorizing-the-log-output.rb +4 -4
- data/lib/yell.rb +19 -10
- data/lib/yell/adapters.rb +23 -26
- data/lib/yell/adapters/base.rb +8 -2
- data/lib/yell/adapters/datefile.rb +45 -42
- data/lib/yell/adapters/file.rb +10 -5
- data/lib/yell/adapters/io.rb +52 -48
- data/lib/yell/adapters/streams.rb +10 -2
- data/lib/yell/configuration.rb +1 -1
- data/lib/yell/event.rb +4 -4
- data/lib/yell/formatter.rb +11 -25
- data/lib/yell/helpers/adapters.rb +51 -0
- data/lib/yell/helpers/base.rb +19 -0
- data/lib/yell/helpers/formatter.rb +31 -0
- data/lib/yell/helpers/level.rb +36 -0
- data/lib/yell/helpers/silencer.rb +32 -0
- data/lib/yell/helpers/tracer.rb +48 -0
- data/lib/yell/level.rb +38 -47
- data/lib/yell/logger.rb +53 -73
- data/lib/yell/repository.rb +31 -29
- data/lib/yell/silencer.rb +69 -0
- data/lib/yell/version.rb +1 -1
- data/spec/spec_helper.rb +21 -9
- data/spec/yell/adapters/base_spec.rb +17 -34
- data/spec/yell/adapters/datefile_spec.rb +109 -66
- data/spec/yell/adapters/file_spec.rb +18 -18
- data/spec/yell/adapters/io_spec.rb +17 -13
- data/spec/yell/adapters/streams_spec.rb +7 -7
- data/spec/yell/adapters_spec.rb +18 -23
- data/spec/yell/configuration_spec.rb +7 -7
- data/spec/yell/event_spec.rb +25 -27
- data/spec/yell/formatter_spec.rb +89 -82
- data/spec/yell/level_spec.rb +119 -94
- data/spec/yell/loggable_spec.rb +6 -5
- data/spec/yell/logger_spec.rb +106 -66
- data/spec/yell/repository_spec.rb +23 -38
- data/spec/yell/silencer_spec.rb +49 -0
- data/spec/yell_spec.rb +24 -27
- metadata +16 -9
@@ -0,0 +1,32 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Yell #:nodoc:
|
3
|
+
module Helpers #:nodoc:
|
4
|
+
module Silencer
|
5
|
+
|
6
|
+
# Set the silence pattern
|
7
|
+
def silence( *patterns )
|
8
|
+
silencer.add(*patterns)
|
9
|
+
end
|
10
|
+
|
11
|
+
# @private
|
12
|
+
def silencer
|
13
|
+
@silencer
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def reset!
|
20
|
+
@silencer = Yell::Silencer.new
|
21
|
+
|
22
|
+
super
|
23
|
+
end
|
24
|
+
|
25
|
+
def silence!( *messages )
|
26
|
+
silencer.silence!(*messages) if silencer.silence?
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Yell #:nodoc:
|
3
|
+
module Helpers #:nodoc:
|
4
|
+
module Tracer #:nodoc:
|
5
|
+
|
6
|
+
# Set whether the logger should allow tracing or not. The trace option
|
7
|
+
# will tell the logger when to provider caller information.
|
8
|
+
#
|
9
|
+
# @example No tracing at all
|
10
|
+
# trace = false
|
11
|
+
#
|
12
|
+
# @example Trace every time
|
13
|
+
# race = true
|
14
|
+
#
|
15
|
+
# @example Trace from the error level onwards
|
16
|
+
# trace = :error
|
17
|
+
# trace = 'gte.error'
|
18
|
+
#
|
19
|
+
# @return [Yell::Level] a level representation of the tracer
|
20
|
+
def trace=( severity )
|
21
|
+
case severity
|
22
|
+
when false then @tracer.set("gt.#{Yell::Severities.last}")
|
23
|
+
else @tracer.set(severity)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# @private
|
28
|
+
def trace
|
29
|
+
@tracer
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def reset!
|
36
|
+
@tracer = Yell::Level.new
|
37
|
+
|
38
|
+
super
|
39
|
+
end
|
40
|
+
|
41
|
+
def inspectables
|
42
|
+
[:trace] | super
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
data/lib/yell/level.rb
CHANGED
@@ -23,28 +23,9 @@ module Yell #:nodoc:
|
|
23
23
|
# @example Set at :info only
|
24
24
|
# Yell::Level.new.at(:info)
|
25
25
|
class Level
|
26
|
-
module Helpers
|
27
|
-
# Accessor to the log level
|
28
|
-
attr_reader :level
|
29
|
-
|
30
|
-
# Set the minimum log level.
|
31
|
-
#
|
32
|
-
# @example Set the level to :warn
|
33
|
-
# level = :warn
|
34
|
-
#
|
35
|
-
# @param [String, Symbol, Integer] severity The minimum log level
|
36
|
-
def level=( severity )
|
37
|
-
@level = case severity
|
38
|
-
when Yell::Level then severity
|
39
|
-
else Yell::Level.new( severity )
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
26
|
|
44
27
|
InterpretRegexp = /(at|gt|gte|lt|lte)?\.?(#{Yell::Severities.join('|')})/i
|
45
28
|
|
46
|
-
attr_reader :severities
|
47
|
-
|
48
29
|
# Create a new level instance.
|
49
30
|
#
|
50
31
|
# @example Enable all severities
|
@@ -60,8 +41,22 @@ module Yell #:nodoc:
|
|
60
41
|
# Yell::Level.new (:info..:error)
|
61
42
|
#
|
62
43
|
# @param [Integer,String,Symbol,Array,Range,nil] severity The severity for the level.
|
63
|
-
def initialize(
|
64
|
-
|
44
|
+
def initialize( *severities )
|
45
|
+
set( *severities )
|
46
|
+
end
|
47
|
+
|
48
|
+
# Set the severity to the given format
|
49
|
+
def set( *severities )
|
50
|
+
@severities = Yell::Severities.map { true }
|
51
|
+
severity = severities.length > 1 ? severities : severities.first
|
52
|
+
|
53
|
+
case severity
|
54
|
+
when Array then at( *severity )
|
55
|
+
when Range then gte( severity.first ).lte( severity.last )
|
56
|
+
when Integer, Symbol then gte( severity )
|
57
|
+
when String then interpret( severity )
|
58
|
+
when Yell::Level then @severities = severity.severities
|
59
|
+
end
|
65
60
|
end
|
66
61
|
|
67
62
|
# Returns whether the level is allowed at the given severity
|
@@ -77,7 +72,7 @@ module Yell #:nodoc:
|
|
77
72
|
index.nil? ? false : @severities[index]
|
78
73
|
end
|
79
74
|
|
80
|
-
# Set the level at specific severities
|
75
|
+
# Set the level at specific severities
|
81
76
|
#
|
82
77
|
# @example Set at :debug and :error only
|
83
78
|
# at :debug, :error
|
@@ -140,29 +135,25 @@ module Yell #:nodoc:
|
|
140
135
|
|
141
136
|
# Get a pretty string representation of the level, including the severities.
|
142
137
|
def inspect
|
143
|
-
|
144
|
-
|
145
|
-
r
|
146
|
-
end
|
147
|
-
|
148
|
-
"#<#{self.class.name} severities: #{severities * ', '}>"
|
138
|
+
inspectables = Yell::Severities.select.with_index { |l, i| !!@severities[i] }
|
139
|
+
"#<#{self.class.name} severities: #{inspectables * ', '}>"
|
149
140
|
end
|
150
141
|
|
142
|
+
# @private
|
143
|
+
def severities
|
144
|
+
@severities
|
145
|
+
end
|
151
146
|
|
152
|
-
private
|
147
|
+
# @private
|
148
|
+
def ==(other)
|
149
|
+
return super unless other.respond_to?(:severities)
|
150
|
+
severities == other.severities
|
151
|
+
end
|
153
152
|
|
154
|
-
def reset!( severity )
|
155
|
-
@severities = Yell::Severities.map { true }
|
156
153
|
|
157
|
-
|
158
|
-
when Array then at( *severity )
|
159
|
-
when Range then gte( severity.first ).lte( severity.last )
|
160
|
-
when Integer, Symbol then gte( severity )
|
161
|
-
when String then interpret!( severity )
|
162
|
-
end
|
163
|
-
end
|
154
|
+
private
|
164
155
|
|
165
|
-
def interpret
|
156
|
+
def interpret( severities )
|
166
157
|
severities.split( ' ' ).each do |severity|
|
167
158
|
if m = InterpretRegexp.match(severity)
|
168
159
|
m[1].nil? ? __send__( :gte, m[2] ) : __send__( m[1], m[2] )
|
@@ -175,11 +166,11 @@ module Yell #:nodoc:
|
|
175
166
|
return if index.nil?
|
176
167
|
|
177
168
|
case modifier
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
169
|
+
when :> then ascending!( index+1 )
|
170
|
+
when :>= then ascending!( index )
|
171
|
+
when :< then descending!( index-1 )
|
172
|
+
when :<= then descending!( index )
|
173
|
+
else set!( index ) # :==
|
183
174
|
end
|
184
175
|
|
185
176
|
taint unless tainted?
|
@@ -187,9 +178,9 @@ module Yell #:nodoc:
|
|
187
178
|
|
188
179
|
def index_from( severity )
|
189
180
|
case severity
|
190
|
-
|
191
|
-
|
192
|
-
|
181
|
+
when Integer then severity
|
182
|
+
when String, Symbol then Yell::Severities.index( severity.to_s.upcase )
|
183
|
+
else nil
|
193
184
|
end
|
194
185
|
end
|
195
186
|
|
data/lib/yell/logger.rb
CHANGED
@@ -2,6 +2,32 @@
|
|
2
2
|
|
3
3
|
require 'pathname'
|
4
4
|
|
5
|
+
# TODO: DSL improvements
|
6
|
+
#
|
7
|
+
# Initlalize an empty logger
|
8
|
+
# logger = Yell.new(adapters: false)
|
9
|
+
# logger.adapters.add :stdout
|
10
|
+
#
|
11
|
+
# Or shorthand for adapters.add
|
12
|
+
# logger.add :stdout
|
13
|
+
#
|
14
|
+
# Or with a block
|
15
|
+
# logger = Yell.new do |l|
|
16
|
+
# l.add :stdout
|
17
|
+
# l.add :stderr
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# logger = Yell.new do |l|
|
21
|
+
# l.adapters.add :stdout
|
22
|
+
# l.adapters.add :stderr
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
#
|
26
|
+
# Define Silencers
|
27
|
+
# logger = Yell.new do |l|
|
28
|
+
# l.silence /password/
|
29
|
+
# end
|
30
|
+
#
|
5
31
|
module Yell #:nodoc:
|
6
32
|
|
7
33
|
# The +Yell::Logger+ is your entrypoint. Anything onwards is derived from here.
|
@@ -9,14 +35,16 @@ module Yell #:nodoc:
|
|
9
35
|
# A +Yell::Logger+ instance holds all your adapters and sends the log events
|
10
36
|
# to them if applicable. There are multiple ways of how to create a new logger.
|
11
37
|
class Logger
|
12
|
-
include Yell::
|
38
|
+
include Yell::Helpers::Base
|
39
|
+
include Yell::Helpers::Level
|
40
|
+
include Yell::Helpers::Formatter
|
41
|
+
include Yell::Helpers::Adapters
|
42
|
+
include Yell::Helpers::Tracer
|
43
|
+
include Yell::Helpers::Silencer
|
13
44
|
|
14
45
|
# The name of the logger instance
|
15
46
|
attr_reader :name
|
16
47
|
|
17
|
-
# Stacktrace or not
|
18
|
-
attr_reader :trace
|
19
|
-
|
20
48
|
# Initialize a new Logger
|
21
49
|
#
|
22
50
|
# @example A standard file logger
|
@@ -40,7 +68,7 @@ module Yell #:nodoc:
|
|
40
68
|
# l.level = :info
|
41
69
|
# end
|
42
70
|
def initialize( *args, &block )
|
43
|
-
|
71
|
+
reset!
|
44
72
|
|
45
73
|
# extract options
|
46
74
|
@options = args.last.is_a?(Hash) ? args.pop : {}
|
@@ -57,6 +85,9 @@ module Yell #:nodoc:
|
|
57
85
|
self.name = @options.fetch(:name, nil) # no name by default
|
58
86
|
self.trace = @options.fetch(:trace, :error) # trace from :error level onwards
|
59
87
|
|
88
|
+
# silencer
|
89
|
+
self.silence(*@options[:silence])
|
90
|
+
|
60
91
|
# extract adapter
|
61
92
|
self.adapter(args.pop) if args.any?
|
62
93
|
|
@@ -64,7 +95,7 @@ module Yell #:nodoc:
|
|
64
95
|
block.arity > 0 ? block.call(self) : instance_eval(&block) if block_given?
|
65
96
|
|
66
97
|
# default adapter when none defined
|
67
|
-
self.adapter(:file) if
|
98
|
+
self.adapter(:file) if adapters.empty?
|
68
99
|
end
|
69
100
|
|
70
101
|
|
@@ -79,57 +110,6 @@ module Yell #:nodoc:
|
|
79
110
|
@name
|
80
111
|
end
|
81
112
|
|
82
|
-
# Set whether the logger should allow tracing or not. The trace option
|
83
|
-
# will tell the logger when to provider caller information.
|
84
|
-
#
|
85
|
-
# @example No tracing at all
|
86
|
-
# trace = false
|
87
|
-
#
|
88
|
-
# @example Trace every time
|
89
|
-
# race = true
|
90
|
-
#
|
91
|
-
# @example Trace from the error level onwards
|
92
|
-
# trace = :error
|
93
|
-
# trace = 'gte.error'
|
94
|
-
#
|
95
|
-
# @return [Yell::Level] a level representation of the tracer
|
96
|
-
def trace=( severity )
|
97
|
-
@trace = case severity
|
98
|
-
when true then Yell::Level.new
|
99
|
-
when false then Yell::Level.new( "gt.#{Yell::Severities.last}" )
|
100
|
-
when Yell::Level then severity
|
101
|
-
else Yell::Level.new( severity )
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
# Define an adapter to be used for logging.
|
106
|
-
#
|
107
|
-
# @example Standard adapter
|
108
|
-
# adapter :file
|
109
|
-
#
|
110
|
-
# @example Standard adapter with filename
|
111
|
-
# adapter :file, 'development.log'
|
112
|
-
#
|
113
|
-
# # Alternative notation for filename in options
|
114
|
-
# adapter :file, :filename => 'developent.log'
|
115
|
-
#
|
116
|
-
# @example Standard adapter with filename and additional options
|
117
|
-
# adapter :file, 'development.log', :level => :warn
|
118
|
-
#
|
119
|
-
# @example Set the adapter directly from an adapter instance
|
120
|
-
# adapter( Yell::Adapter::File.new )
|
121
|
-
#
|
122
|
-
# @param [Symbol] type The type of the adapter, may be `:file` or `:datefile` (default `:file`)
|
123
|
-
# @return [Yell::Adapter] The instance
|
124
|
-
# @raise [Yell::NoSuchAdapter] Will be thrown when the adapter is not defined
|
125
|
-
def adapter( type = :file, *args, &block )
|
126
|
-
options = [@options, *args].inject( Hash.new ) do |h, c|
|
127
|
-
h.merge( [String, Pathname].include?(c.class) ? {:filename => c} : c )
|
128
|
-
end
|
129
|
-
|
130
|
-
@adapters << Yell::Adapters.new( type, options, &block )
|
131
|
-
end
|
132
|
-
|
133
113
|
# Creates instance methods for every log level:
|
134
114
|
# `debug` and `debug?`
|
135
115
|
# `info` and `info?`
|
@@ -140,21 +120,25 @@ module Yell #:nodoc:
|
|
140
120
|
name = s.downcase
|
141
121
|
|
142
122
|
class_eval <<-EOS, __FILE__, __LINE__
|
143
|
-
def #{name}?;
|
144
|
-
|
145
|
-
def #{name}( *m, &b )
|
146
|
-
return false unless #{name}?
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
123
|
+
def #{name}?; level.at?(#{index}); end # def info?; level.at?(1); end
|
124
|
+
#
|
125
|
+
def #{name}( *m, &b ) # def info( *m, &b )
|
126
|
+
return false unless #{name}? # return false unless info?
|
127
|
+
#
|
128
|
+
m = silencer.silence(*m) if silencer.silence? # m = silencer.silence(*m) if silencer.silence?
|
129
|
+
return false if m.empty? # return false if m.empty?
|
130
|
+
#
|
131
|
+
event = Yell::Event.new(self, #{index}, *m, &b) # event = Yell::Event.new(self, 1, *m, &b)
|
132
|
+
write(event) # write(event)
|
133
|
+
true # true
|
134
|
+
end # end
|
151
135
|
EOS
|
152
136
|
end
|
153
137
|
|
154
138
|
# Get a pretty string representation of the logger.
|
155
139
|
def inspect
|
156
|
-
inspection = inspectables.
|
157
|
-
"#<#{self.class.name} #{inspection * ', '}, adapters: #{
|
140
|
+
inspection = inspectables.map { |m| "#{m}: #{send(m).inspect}" }
|
141
|
+
"#<#{self.class.name} #{inspection * ', '}, adapters: #{adapters.map(&:inspect) * ', '}>"
|
158
142
|
end
|
159
143
|
|
160
144
|
# @private
|
@@ -162,10 +146,6 @@ module Yell #:nodoc:
|
|
162
146
|
@adapters.each(&:close)
|
163
147
|
end
|
164
148
|
|
165
|
-
# @private
|
166
|
-
def adapters
|
167
|
-
@adapters
|
168
|
-
end
|
169
149
|
|
170
150
|
private
|
171
151
|
|
@@ -188,12 +168,12 @@ module Yell #:nodoc:
|
|
188
168
|
|
189
169
|
# Cycles all the adapters and writes the message
|
190
170
|
def write( event )
|
191
|
-
|
171
|
+
adapters.each { |a| a.write(event) }
|
192
172
|
end
|
193
173
|
|
194
174
|
# Get an array of inspected attributes for the adapter.
|
195
175
|
def inspectables
|
196
|
-
[
|
176
|
+
[:name] | super
|
197
177
|
end
|
198
178
|
|
199
179
|
end
|
data/lib/yell/repository.rb
CHANGED
@@ -13,43 +13,45 @@ module Yell #:nodoc:
|
|
13
13
|
extend MonitorMixin
|
14
14
|
include Singleton
|
15
15
|
|
16
|
-
attr_accessor :loggers
|
17
|
-
|
18
16
|
def initialize
|
19
17
|
@loggers = {}
|
20
18
|
end
|
21
19
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
end
|
20
|
+
# Set loggers in the repository
|
21
|
+
#
|
22
|
+
# @example Set a logger
|
23
|
+
# Yell::Repository[ 'development' ] = Yell::Logger.new :stdout
|
24
|
+
#
|
25
|
+
# @return [Yell::Logger] The logger instance
|
26
|
+
def self.[]=( name, logger )
|
27
|
+
synchronize { instance.loggers[name] = logger }
|
28
|
+
end
|
32
29
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
30
|
+
# Get loggers from the repository
|
31
|
+
#
|
32
|
+
# @example Get the logger
|
33
|
+
# Yell::Repository[ 'development' ]
|
34
|
+
#
|
35
|
+
# @raise [Yell::LoggerNotFound] Raised when repository does not have that key
|
36
|
+
# @return [Yell::Logger] The logger instance
|
37
|
+
def self.[]( name )
|
38
|
+
synchronize { instance.fetch(name) or raise Yell::LoggerNotFound.new(name) }
|
39
|
+
end
|
43
40
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
end
|
41
|
+
# Get the list of all loggers in the repository
|
42
|
+
#
|
43
|
+
# @return [Hash] The map of loggers
|
44
|
+
def self.loggers
|
45
|
+
synchronize { instance.loggers }
|
50
46
|
end
|
51
47
|
|
48
|
+
# @private
|
49
|
+
def loggers
|
50
|
+
@loggers
|
51
|
+
end
|
52
52
|
|
53
|
+
# @private
|
54
|
+
#
|
53
55
|
# Fetch the logger by the given name.
|
54
56
|
#
|
55
57
|
# If the logger could not be found and has a superclass, it
|
@@ -59,7 +61,7 @@ module Yell #:nodoc:
|
|
59
61
|
logger = loggers[name] || loggers[name.to_s]
|
60
62
|
|
61
63
|
if logger.nil? && name.respond_to?(:superclass)
|
62
|
-
return fetch(
|
64
|
+
return fetch(name.superclass)
|
63
65
|
end
|
64
66
|
|
65
67
|
logger
|