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.
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