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
@@ -7,16 +7,21 @@ module Yell #:nodoc:
7
7
  # for logging into files.
8
8
  class File < Yell::Adapters::Io
9
9
 
10
- setup do |options|
10
+ private
11
+
12
+ # @overload setup!( options )
13
+ def setup!( options )
11
14
  @filename = ::File.expand_path options.fetch(:filename, default_filename)
12
- end
13
15
 
14
- open do
15
- @stream = ::File.open( @filename, ::File::WRONLY|::File::APPEND|::File::CREAT )
16
+ super
16
17
  end
17
18
 
19
+ # @overload open!
20
+ def open!
21
+ @stream = ::File.open( @filename, ::File::WRONLY|::File::APPEND|::File::CREAT )
18
22
 
19
- private
23
+ super
24
+ end
20
25
 
21
26
  def default_filename #:nodoc:
22
27
  logdir = ::File.expand_path("log")
@@ -4,57 +4,19 @@ module Yell #:nodoc:
4
4
  module Adapters #:nodoc:
5
5
 
6
6
  class Io < Yell::Adapters::Base
7
- include Yell::Formatter::Helpers
7
+ include Yell::Helpers::Formatter
8
8
 
9
9
  # The possible unix log colors
10
- Colors = {
11
- 0 => "\e[32;1m", # green;bold
12
- # 1 => "\e[0m", # white
13
- 2 => "\e[33;1m", # yello;bold
14
- 3 => "\e[31;1m", # red;bold
15
- 4 => "\e[35;1m", # magenta;bold
16
- 5 => "\e[36m", # cyan
17
- -1 => "\e[0m" # NONE
10
+ TTYColors = {
11
+ 0 => "\033[1;32m", # green
12
+ 1 => "\033[0m", # normal
13
+ 2 => "\033[1;33m", # yellow
14
+ 3 => "\033[1;31m", # red
15
+ 4 => "\033[1;35m", # magenta
16
+ 5 => "\033[1;36m", # cyan
17
+ -1 => "\033[0m" # normal
18
18
  }
19
19
 
20
- setup do |options|
21
- @stream = nil
22
-
23
- # colorize the log output (default: false)
24
- self.colors = options.fetch(:colors, false)
25
-
26
- # format the log message (default: nil)
27
- self.format = options.fetch(:format, nil)
28
-
29
- # sync immediately to IO (default: true)
30
- self.sync = options.fetch(:sync, true)
31
- end
32
-
33
- write do |event|
34
- message = format.format(event)
35
-
36
- # colorize if applicable
37
- if colors and color = Colors[event.level]
38
- message = color + message + Colors[-1]
39
- end
40
-
41
- # add new line if there is none
42
- message << "\n" unless message[-1] == ?\n
43
-
44
- stream.syswrite( message )
45
- end
46
-
47
- open do
48
- @stream.sync = self.sync if @stream.respond_to? :sync
49
- @stream.flush if @stream.respond_to? :flush
50
- end
51
-
52
- close do
53
- @stream.close if @stream.respond_to? :close
54
- @stream = nil
55
- end
56
-
57
-
58
20
  # Sets the “sync mode” to true or false.
59
21
  #
60
22
  # When true (default), every log event is immediately written to the file.
@@ -79,6 +41,48 @@ module Yell #:nodoc:
79
41
 
80
42
  private
81
43
 
44
+ # @overload setup!( options )
45
+ def setup!( options )
46
+ @stream = nil
47
+
48
+ self.colors = options.fetch(:colors, false)
49
+ self.format = options.fetch(:format, nil)
50
+ self.sync = options.fetch(:sync, true)
51
+
52
+ super
53
+ end
54
+
55
+ # @overload write!( event )
56
+ def write!( event )
57
+ message = format.format(event)
58
+
59
+ # colorize if applicable
60
+ if colors and color = TTYColors[event.level]
61
+ message = color + message + TTYColors[-1]
62
+ end
63
+
64
+ message << "\n" unless message[-1] == ?\n
65
+ stream.syswrite( message )
66
+
67
+ super
68
+ end
69
+
70
+ # @overload open!
71
+ def open!
72
+ @stream.sync = self.sync if @stream.respond_to? :sync
73
+ @stream.flush if @stream.respond_to? :flush
74
+
75
+ super
76
+ end
77
+
78
+ # @overload close!
79
+ def close!
80
+ @stream.close if @stream.respond_to? :close
81
+ @stream = nil
82
+
83
+ super
84
+ end
85
+
82
86
  # The IO stream
83
87
  #
84
88
  # Adapter classes should provide their own implementation
@@ -87,7 +91,7 @@ module Yell #:nodoc:
87
91
  synchronize { open! if @stream.nil?; @stream }
88
92
  end
89
93
 
90
- # @override
94
+ # @overload inspectables
91
95
  def inspectables
92
96
  super.concat [:format, :colors, :sync]
93
97
  end
@@ -5,16 +5,24 @@ module Yell #:nodoc:
5
5
 
6
6
  class Stdout < Yell::Adapters::Io
7
7
 
8
- open do
8
+ private
9
+
10
+ # @overload open!
11
+ def open!
9
12
  @stream = $stdout.clone
13
+ super
10
14
  end
11
15
 
12
16
  end
13
17
 
14
18
  class Stderr < Yell::Adapters::Io
15
19
 
16
- open do
20
+ private
21
+
22
+ # @overload open!
23
+ def open!
17
24
  @stream = $stderr.clone
25
+ super
18
26
  end
19
27
 
20
28
  end
@@ -13,7 +13,7 @@ module Yell #:nodoc:
13
13
  yaml = YAML.load( ERB.new(File.read(file)).result )
14
14
 
15
15
  # in case we have ActiveSupport
16
- if yaml.respond_to?( :with_indifference_access )
16
+ if yaml.respond_to?(:with_indifference_access)
17
17
  yaml = yaml.with_indifferent_access
18
18
  end
19
19
 
@@ -65,23 +65,23 @@ module Yell #:nodoc:
65
65
 
66
66
  # Accessor to filename the log event occured
67
67
  def file
68
- @file || (_caller!; @file)
68
+ @file || (backtrace!; @file)
69
69
  end
70
70
 
71
71
  # Accessor to the line the log event occured
72
72
  def line
73
- @line || (_caller!; @line)
73
+ @line || (backtrace!; @line)
74
74
  end
75
75
 
76
76
  # Accessor to the method the log event occured
77
77
  def method
78
- @method || (_caller!; @method)
78
+ @method || (backtrace!; @method)
79
79
  end
80
80
 
81
81
 
82
82
  private
83
83
 
84
- def _caller!
84
+ def backtrace!
85
85
  if m = CallerRegexp.match(@caller)
86
86
  @file, @line, @method = m[1..-1]
87
87
  else
@@ -1,5 +1,4 @@
1
1
  # encoding: utf-8
2
-
3
2
  require 'time'
4
3
 
5
4
  module Yell #:nodoc:
@@ -46,21 +45,8 @@ module Yell #:nodoc:
46
45
 
47
46
  # The +Formatter+ provides a handle to configure your log message style.
48
47
  class Formatter
49
- module Helpers
50
- # Accessor to the format
51
- attr_reader :format
52
-
53
- # Set the format for your message.
54
- def format=( pattern )
55
- @format = case pattern
56
- when Yell::Formatter then pattern
57
- when false then Yell::Formatter.new( Yell::NoFormat )
58
- else Yell::Formatter.new( *pattern )
59
- end
60
- end
61
- end
62
48
 
63
- PatternTable = {
49
+ Table = {
64
50
  "m" => "message(*event.messages)", # Message
65
51
  "l" => "level(event.level)[0,1]", # Level (short), e.g.'I', 'W'
66
52
  "L" => "level(event.level)", # Level, e.g. 'INFO', 'WARN'
@@ -75,7 +61,7 @@ module Yell #:nodoc:
75
61
  "n" => "event.line" # Line where the logger was called
76
62
  }
77
63
 
78
- PatternRegexp = /([^%]*)(%\d*)?(#{PatternTable.keys.join('|')})?(.*)/
64
+ Matcher = /([^%]*)(%\d*)?(#{Table.keys.join('|')})?(.*)/
79
65
 
80
66
 
81
67
  # Initializes a new +Yell::Formatter+.
@@ -91,7 +77,7 @@ module Yell #:nodoc:
91
77
  define_format_method!
92
78
  end
93
79
 
94
- # Get a pretty string representation of the formatter, including the pattern and date pattern.
80
+ # Get a pretty string
95
81
  def inspect
96
82
  "#<#{self.class.name} pattern: #{@pattern.inspect}, date_pattern: #{@date_pattern.inspect}>"
97
83
  end
@@ -117,26 +103,27 @@ module Yell #:nodoc:
117
103
  buff, args, _pattern = "", [], @pattern.dup
118
104
 
119
105
  while true
120
- match = PatternRegexp.match( _pattern )
106
+ match = Matcher.match(_pattern)
121
107
 
122
108
  buff << match[1] unless match[1].empty?
123
109
  break if match[2].nil?
124
110
 
125
111
  buff << match[2] + 's'
126
- args << PatternTable[ match[3] ]
112
+ args << Table[ match[3] ]
127
113
 
128
114
  _pattern = match[4]
129
115
  end
130
116
 
131
- instance_eval %-
117
+ instance_eval <<-EOS, __FILE__, __LINE__
132
118
  def format( event )
133
- sprintf( "#{buff}", #{args.join(',')} )
119
+ sprintf("#{buff}", #{args.join(',')})
134
120
  end
135
- -
121
+ EOS
136
122
  end
137
123
 
138
124
  # The iso8601 implementation of the standard Time library is more than
139
- # twice as slow than using strftime. So, we just implement it ourselves.
125
+ # twice as slow compared to using strftime. So, we just implement
126
+ # it ourselves --R
140
127
  def iso8601( t )
141
128
  zone = if t.utc?
142
129
  "-00:00"
@@ -163,8 +150,7 @@ module Yell #:nodoc:
163
150
  m.map { |k,v| "#{k}: #{v}" }.join( ", " )
164
151
  when Exception
165
152
  backtrace = m.backtrace ? "\n\t#{m.backtrace.join("\n\t")}" : ""
166
-
167
- "%s: %s%s" % [m.class, m.message, backtrace]
153
+ sprintf("%s: %s%s", m.class, m.message, backtrace)
168
154
  else
169
155
  m
170
156
  end
@@ -0,0 +1,51 @@
1
+ # encoding: utf-8
2
+ module Yell #:nodoc:
3
+ module Helpers #:nodoc:
4
+ module Adapters #:nodoc:
5
+
6
+ # Define an adapter to be used for logging.
7
+ #
8
+ # @example Standard adapter
9
+ # adapter :file
10
+ #
11
+ # @example Standard adapter with filename
12
+ # adapter :file, 'development.log'
13
+ #
14
+ # # Alternative notation for filename in options
15
+ # adapter :file, :filename => 'developent.log'
16
+ #
17
+ # @example Standard adapter with filename and additional options
18
+ # adapter :file, 'development.log', :level => :warn
19
+ #
20
+ # @example Set the adapter directly from an adapter instance
21
+ # adapter( Yell::Adapter::File.new )
22
+ #
23
+ # @param [Symbol] type The type of the adapter, may be `:file` or `:datefile` (default `:file`)
24
+ # @return [Yell::Adapter] The instance
25
+ # @raise [Yell::NoSuchAdapter] Will be thrown when the adapter is not defined
26
+ def adapter( type = :file, *args, &block )
27
+ options = [@options, *args].inject( Hash.new ) do |h, c|
28
+ h.merge( [String, Pathname].include?(c.class) ? {:filename => c} : c )
29
+ end
30
+
31
+ @adapters << Yell::Adapters.new(type, options, &block)
32
+ end
33
+
34
+ # @private
35
+ def adapters
36
+ @adapters
37
+ end
38
+
39
+
40
+ private
41
+
42
+ def reset!
43
+ @adapters = []
44
+
45
+ super
46
+ end
47
+
48
+ end
49
+ end
50
+ end
51
+
@@ -0,0 +1,19 @@
1
+ # encoding: utf-8
2
+ module Yell #:nodoc:
3
+ module Helpers #:nodoc:
4
+ module Base #:nodoc:
5
+
6
+ private
7
+
8
+ # stub
9
+ def reset!
10
+ end
11
+
12
+ def inspectables
13
+ []
14
+ end
15
+
16
+ end
17
+ end
18
+ end
19
+
@@ -0,0 +1,31 @@
1
+ # encoding: utf-8
2
+ module Yell #:nodoc:
3
+ module Helpers #:nodoc:
4
+ module Formatter #:nodoc:
5
+
6
+ # Set the format for your message.
7
+ def format=( pattern )
8
+ @formatter = case pattern
9
+ when Yell::Formatter then pattern
10
+ when false then Yell::Formatter.new(Yell::NoFormat)
11
+ else Yell::Formatter.new(*pattern)
12
+ end
13
+ end
14
+
15
+ # @private
16
+ def format
17
+ @formatter
18
+ end
19
+
20
+ private
21
+
22
+ def reset!
23
+ @formatter = Yell::Formatter.new
24
+
25
+ super
26
+ end
27
+
28
+ end
29
+ end
30
+ end
31
+
@@ -0,0 +1,36 @@
1
+ # encoding: utf-8
2
+ module Yell #:nodoc:
3
+ module Helpers #:nodoc:
4
+ module Level
5
+
6
+ # Set the minimum log level.
7
+ #
8
+ # @example Set the level to :warn
9
+ # level = :warn
10
+ #
11
+ # @param [String, Symbol, Integer] severity The minimum log level
12
+ def level=( severity )
13
+ @level.set(severity)
14
+ end
15
+
16
+ # @private
17
+ def level
18
+ @level
19
+ end
20
+
21
+ private
22
+
23
+ def reset!
24
+ @level = Yell::Level.new
25
+
26
+ super
27
+ end
28
+
29
+ def inspectables
30
+ [:level] | super
31
+ end
32
+
33
+ end
34
+ end
35
+ end
36
+