yell 1.3.0 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +3 -1
  3. data/.travis.yml +1 -2
  4. data/Gemfile +5 -1
  5. data/README.md +67 -14
  6. data/examples/004.1-colorizing-the-log-output.rb +4 -4
  7. data/lib/yell.rb +19 -10
  8. data/lib/yell/adapters.rb +23 -26
  9. data/lib/yell/adapters/base.rb +8 -2
  10. data/lib/yell/adapters/datefile.rb +45 -42
  11. data/lib/yell/adapters/file.rb +10 -5
  12. data/lib/yell/adapters/io.rb +52 -48
  13. data/lib/yell/adapters/streams.rb +10 -2
  14. data/lib/yell/configuration.rb +1 -1
  15. data/lib/yell/event.rb +4 -4
  16. data/lib/yell/formatter.rb +11 -25
  17. data/lib/yell/helpers/adapters.rb +51 -0
  18. data/lib/yell/helpers/base.rb +19 -0
  19. data/lib/yell/helpers/formatter.rb +31 -0
  20. data/lib/yell/helpers/level.rb +36 -0
  21. data/lib/yell/helpers/silencer.rb +32 -0
  22. data/lib/yell/helpers/tracer.rb +48 -0
  23. data/lib/yell/level.rb +38 -47
  24. data/lib/yell/logger.rb +53 -73
  25. data/lib/yell/repository.rb +31 -29
  26. data/lib/yell/silencer.rb +69 -0
  27. data/lib/yell/version.rb +1 -1
  28. data/spec/spec_helper.rb +21 -9
  29. data/spec/yell/adapters/base_spec.rb +17 -34
  30. data/spec/yell/adapters/datefile_spec.rb +109 -66
  31. data/spec/yell/adapters/file_spec.rb +18 -18
  32. data/spec/yell/adapters/io_spec.rb +17 -13
  33. data/spec/yell/adapters/streams_spec.rb +7 -7
  34. data/spec/yell/adapters_spec.rb +18 -23
  35. data/spec/yell/configuration_spec.rb +7 -7
  36. data/spec/yell/event_spec.rb +25 -27
  37. data/spec/yell/formatter_spec.rb +89 -82
  38. data/spec/yell/level_spec.rb +119 -94
  39. data/spec/yell/loggable_spec.rb +6 -5
  40. data/spec/yell/logger_spec.rb +106 -66
  41. data/spec/yell/repository_spec.rb +23 -38
  42. data/spec/yell/silencer_spec.rb +49 -0
  43. data/spec/yell_spec.rb +24 -27
  44. 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
+
@@ -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( severity = nil )
64
- reset!( severity )
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
- severities = Yell::Severities.each.with_index.inject( [] ) do |r, (l, i)|
144
- r << l if @severities[i]
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
- case severity
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!( severities )
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
- when :> then ascending!( index+1 )
179
- when :>= then ascending!( index )
180
- when :< then descending!( index-1 )
181
- when :<= then descending!( index )
182
- else set!( index ) # :==
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
- when Integer then severity
191
- when String, Symbol then Yell::Severities.index( severity.to_s.upcase )
192
- else nil
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
 
@@ -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::Level::Helpers
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
- @adapters = []
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 @adapters.empty?
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}?; @level.at?(#{index}); end # def info?; @level.at?(1); end
144
- #
145
- def #{name}( *m, &b ) # def info( *m, &b )
146
- return false unless #{name}? # return false unless info?
147
- write Yell::Event.new(self, #{index}, *m, &b) # write Yell::Event.new(self, 1, *m, &b)
148
- #
149
- true # true
150
- end # end
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.inject( [] ) { |r, c| r << "#{c}: #{send(c).inspect}" }
157
- "#<#{self.class.name} #{inspection * ', '}, adapters: #{@adapters.map(&:inspect) * ', '}>"
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
- @adapters.each { |a| a.write(event) }
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
- [ :name, :level, :trace ]
176
+ [:name] | super
197
177
  end
198
178
 
199
179
  end
@@ -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
- class << self
23
- # Set loggers in the repository
24
- #
25
- # @example Set a logger
26
- # Yell::Repository[ 'development' ] = Yell::Logger.new :stdout
27
- #
28
- # @return [Yell::Logger] The logger instance
29
- def []=( name, logger )
30
- synchronize { instance.loggers[name] = logger }
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
- # Get loggers from the repository
34
- #
35
- # @example Get the logger
36
- # Yell::Repository[ 'development' ]
37
- #
38
- # @raise [Yell::LoggerNotFound] Raised when repository does not have that key
39
- # @return [Yell::Logger] The logger instance
40
- def []( name )
41
- synchronize { instance.fetch(name) or raise Yell::LoggerNotFound.new(name) }
42
- end
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
- # Get the list of all loggers in the repository
45
- #
46
- # @return [Hash] The map of loggers
47
- def loggers
48
- synchronize { instance.loggers }
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( name.superclass )
64
+ return fetch(name.superclass)
63
65
  end
64
66
 
65
67
  logger