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,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f9ecfe3dde614dc7aaa4d58f6617323dfd22aa6b
4
+ data.tar.gz: a16b4a0ed5c83a1d722570a7d4e92eb0886856ff
5
+ SHA512:
6
+ metadata.gz: dbfd34addbe7e79d5a0264f927f64bd9808a1cc09dbe4e56fda1b09677e66cdcb20c527e86a75cbb0954bc9f9f3cfd4ef5b67b052c1d19527888fe856d43f116
7
+ data.tar.gz: 438d38c8cdd63f08eb32d991eacb04eb1aa1b3bd7020a017d44b954d80bc268c69132ddcc36bdd967c809a57804abfe14656d90912ab2833d878808302e936aa
data/.gitignore CHANGED
@@ -8,4 +8,6 @@ Gemfile.lock
8
8
 
9
9
  # vim
10
10
  *.swp
11
- **/*.swp
11
+
12
+ # coverage
13
+ /coverage
@@ -4,9 +4,8 @@ script: "rspec"
4
4
 
5
5
  rvm:
6
6
  - 1.8.7
7
- - 1.9.2
8
7
  - 1.9.3
9
- - ruby-head
8
+ - 2.0.0
10
9
  - jruby-18mode
11
10
  - jruby-19mode
12
11
  - rbx-18mode
data/Gemfile CHANGED
@@ -6,8 +6,12 @@ gemspec
6
6
  group :development, :test do
7
7
  gem "rake"
8
8
 
9
- gem "rspec"
9
+ gem 'rspec-core'
10
+ gem 'rspec-expectations'
10
11
  gem "rr"
11
12
  gem "timecop"
13
+
14
+ gem 'simplecov', :require => false, :platform => :ruby_20
15
+ gem 'coveralls', :require => false, :platform => :ruby_20
12
16
  end
13
17
 
data/README.md CHANGED
@@ -1,11 +1,12 @@
1
- **Yell - Your Extensible Logging Library**
1
+ # Yell [![Gem Version](https://badge.fury.io/rb/yell.png)](http://badge.fury.io/rb/yell) [![Build Status](https://travis-ci.org/rudionrails/yell.png?branch=master)](https://travis-ci.org/rudionrails/yell) [![Code Climate](https://codeclimate.com/github/rudionrails/yell.png)](https://codeclimate.com/github/rudionrails/yell) [![Coverage Status](https://coveralls.io/repos/rudionrails/yell/badge.png?branch=master)](https://coveralls.io/r/rudionrails/yell)
2
2
 
3
- [![Build Status](https://secure.travis-ci.org/rudionrails/yell.png?branch=master)](http://travis-ci.org/rudionrails/yell)
4
- [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/rudionrails/yell)
5
3
 
6
- Yell works and is tested with ruby 1.8.7, 1.9.x, jruby 1.8 and 1.9 mode, rubinius 1.8 and 1.9 as well as ree.
4
+ **Yell - Your Extensible Logging Library** is a comprehensive logging replacement for Ruby.
5
+
6
+ Yell works and is tested with ruby 1.8.7, 1.9.x, 2.0.0, jruby 1.8 and 1.9 mode, rubinius 1.8 and 1.9 as well as ree.
7
+
8
+ If you want to conveniently use Yell with Rails, then head over to [yell-rails](https://github.com/rudionrails/yell-rails). You'll find all the documentation in this repository, though.
7
9
 
8
- **If you want to use Yell with Rails, then head over to [yell-rails](https://github.com/rudionrails/yell-rails).**
9
10
 
10
11
  ## Installation
11
12
 
@@ -55,8 +56,8 @@ Here are some short examples on how to combine them:
55
56
 
56
57
  ```ruby
57
58
  logger = Yell.new do |l|
58
- l.adapter STDOUT, :level => [:debug, :info, :warn]
59
- l.adapter STDERR, :level => [:error, :fatal]
59
+ l.adapter STDOUT, level: [:debug, :info, :warn]
60
+ l.adapter STDERR, level: [:error, :fatal]
60
61
  end
61
62
  ```
62
63
 
@@ -68,10 +69,25 @@ into the 'error.log'.
68
69
 
69
70
  ```ruby
70
71
  logger = Yell.new do |l|
71
- l.level = :info # will only pass :info and above to the adapters
72
+ l.level = 'gte.info' # will only pass :info and above to the adapters
72
73
 
73
- l.adapter :datefile, 'production.log', :level => Yell.level.lte(:warn)
74
- l.adapter :datefile, 'error.log', :level => Yell.level.gte(:error)
74
+ l.adapter :datefile, 'production.log', level: 'lte.warn' # anything lower or equal to :warn
75
+ l.adapter :datefile, 'error.log', level: 'gte.error' # anything greater or equal to :error
76
+ end
77
+ ```
78
+
79
+ ##### Example: Typical production Logger for Heroku
80
+
81
+ When deploying to Heroku, the "rails_log_stdout" gem gets injected to your Rails project.
82
+ Yell does not need that when properly configured (see [yell-rails](https://github.com/rudionrails/yell-rails)
83
+ for a more convenient integration with Rails).
84
+
85
+ ```ruby
86
+ logger = Yell.new do |l|
87
+ l.level = 'gte.info'
88
+
89
+ l.adapter :stdout, level: 'lte.warn'
90
+ l.adapter :stderr, level: 'gte.error'
75
91
  end
76
92
  ```
77
93
 
@@ -98,7 +114,7 @@ With Yell you can do the same thing with less:
98
114
  require 'yell'
99
115
 
100
116
  # create a logger named 'mylog' that logs to stdout
101
- Yell.new :stdout, :name => 'mylog'
117
+ Yell.new :stdout, name: 'mylog'
102
118
 
103
119
  # later in the code, you can get the logger back
104
120
  Yell['mylog']
@@ -107,7 +123,7 @@ Yell['mylog']
107
123
  There is no need to define outputters separately and you don't have to taint
108
124
  you global namespace with Yell's subclasses.
109
125
 
110
- ### You want any class to have a logger?
126
+ ### Adding a logger to an existing class
111
127
 
112
128
  Yell comes with a simple module: +Yell::Loggable+. Simply include this in a class and
113
129
  you are good to go.
@@ -115,13 +131,14 @@ you are good to go.
115
131
  ```ruby
116
132
  # Before you can use it, you will need to define a logger and
117
133
  # provide it with the `:name` of your class.
118
- Yell.new :stdout, :name => 'Foo'
134
+ Yell.new :stdout, name: 'Foo'
119
135
 
120
136
  class Foo
121
137
  include Yell::Loggable
122
138
  end
123
139
 
124
140
  # Now you can log
141
+ Foo.logger.info "Hello World"
125
142
  Foo.new.logger.info "Hello World"
126
143
  ```
127
144
 
@@ -133,9 +150,45 @@ class Bar < Foo
133
150
  end
134
151
 
135
152
  # The logger will fallback to the Foo superclass
153
+ Bar.logger.info "Hello World"
136
154
  Bar.new.logger.info "Hello World"
137
155
  ```
138
156
 
157
+ ### Adding a logger to all classes at once (global logger)
158
+
159
+ Derived from the example above, simply do the following.
160
+
161
+ ```ruby
162
+ # Define a logger and pass `Object` as name. Internally, Yell adds this
163
+ # logger to the repository where you can access it later on.
164
+ Yell.new :stdout, name: Object
165
+
166
+ # Enable logging for the class that (almost) every Ruby class inherits from
167
+ Object.send :include, Yell::Loggable
168
+
169
+ # now you are good to go... from wherever you are
170
+ logger.info "Hello from anything"
171
+ Integer.logger.info "Hello from Integer"
172
+ ```
173
+
174
+ ### Suppress log messages with silencers
175
+
176
+ In case you woul like to suppress certain log messages, you may define
177
+ silencers with Yell. Use this to get control of a noisy log environment. For
178
+ instance, you can suppress logging messages that contain secure information or
179
+ more simply, to skip information about serving your Rails assets. Provide a
180
+ string or a regular expression of the message patterns you would like to exclude.
181
+
182
+ ```ruby
183
+ logger = Yell.new do |l|
184
+ l.silence /^Started GET "\/assets/
185
+ l.silence /^Served asset/
186
+ end
187
+
188
+ logger.debug 'Started GET "/assets/logo.png" for 127.0.0.1 at 2013-06-20 10:18:38 +0200'
189
+ logger.debug 'Served asset /logo.png - 304 Not Modified (0ms)'
190
+ ```
191
+
139
192
 
140
193
  ## Further Readings
141
194
 
@@ -159,5 +212,5 @@ You can find further examples and additional adapters in the [wiki](https://gith
159
212
  or have a look into the examples folder.
160
213
 
161
214
 
162
- Copyright &copy; 2011-2012 Rudolf Schmidt, released under the MIT license
215
+ Copyright &copy; 2011-2013 Rudolf Schmidt, released under the MIT license
163
216
 
@@ -8,8 +8,8 @@ You may colorize the log output on your io-based loggers loke so:
8
8
 
9
9
  logger = Yell.new STDOUT, :colors => true
10
10
 
11
- [:debug, :info, :warn, :error, :fatal, :unknown].each do |level|
12
- logger.send level, level
11
+ Yell::Severities.each do |level|
12
+ logger.send level.downcase, level
13
13
  end
14
14
 
15
15
  EOS
@@ -17,7 +17,7 @@ EOS
17
17
  puts "=== actuale example ==="
18
18
  logger = Yell.new STDOUT, :colors => true
19
19
 
20
- [:debug, :info, :warn, :error, :fatal, :unknown].each do |level|
21
- logger.send level, level
20
+ Yell::Severities.each do |level|
21
+ logger.send level.downcase, level
22
22
  end
23
23
 
@@ -24,7 +24,7 @@
24
24
  module Yell #:nodoc:
25
25
 
26
26
  # Holds all Yell severities
27
- Severities = [ 'DEBUG', 'INFO', 'WARN', 'ERROR', 'FATAL', 'UNKNOWN' ]
27
+ Severities = ['DEBUG', 'INFO', 'WARN', 'ERROR', 'FATAL', 'UNKNOWN'].freeze
28
28
 
29
29
  class << self
30
30
  # Creates a new logger instance.
@@ -33,35 +33,35 @@ module Yell #:nodoc:
33
33
  #
34
34
  # @return [Yell::Logger] The logger instance
35
35
  def new( *args, &block )
36
- Yell::Logger.new( *args, &block )
36
+ Yell::Logger.new(*args, &block)
37
37
  end
38
38
 
39
39
  # Shortcut to Yell::Level.new
40
40
  #
41
41
  # @return [Yell::Level] The level instance
42
42
  def level( val = nil )
43
- Yell::Level.new( val )
43
+ Yell::Level.new(val)
44
44
  end
45
45
 
46
46
  # Shortcut to Yell::Repository[]
47
47
  #
48
48
  # @return [Yell::Logger] The logger instance
49
49
  def []( name )
50
- Yell::Repository[ name ]
50
+ Yell::Repository[name]
51
51
  end
52
52
 
53
53
  # Shortcut to Yell::Repository[]=
54
54
  #
55
55
  # @return [Yell::Logger] The logger instance
56
56
  def []=( name, logger )
57
- Yell::Repository[ name ] = logger
57
+ Yell::Repository[name] = logger
58
58
  end
59
59
 
60
60
  # Shortcut to Yell::Fomatter.new
61
61
  #
62
62
  # @return [Yell::Formatter] A Yell::Formatter instance
63
63
  def format( pattern, date_pattern = nil )
64
- Yell::Formatter.new( pattern, date_pattern )
64
+ Yell::Formatter.new(pattern, date_pattern)
65
65
  end
66
66
 
67
67
  # Loads a config from a YAML file
@@ -77,7 +77,7 @@ module Yell #:nodoc:
77
77
  return ENV['RACK_ENV'] if ENV.key? 'RACK_ENV'
78
78
  return ENV['RAILS_ENV'] if ENV.key? 'RAILS_ENV'
79
79
 
80
- if defined?( Rails )
80
+ if defined?(Rails)
81
81
  Rails.env
82
82
  else
83
83
  'development'
@@ -90,25 +90,34 @@ module Yell #:nodoc:
90
90
  messages << " before: #{options[:before]}" if options[:before]
91
91
  messages << " after: #{options[:after]}" if options[:after]
92
92
 
93
- _warn( *messages )
93
+ _warn(*messages)
94
94
  end
95
95
 
96
96
  # @private
97
97
  def _warn( *messages )
98
- $stderr.puts "[Yell] " + messages.join( "\n" )
99
- rescue Exception
98
+ $stderr.puts "[Yell] " + messages.join("\n")
99
+ rescue Exception => e
100
100
  # do nothing
101
101
  end
102
102
  end
103
103
 
104
104
  end
105
105
 
106
+ # helpers
107
+ require File.dirname(__FILE__) + '/yell/helpers/base'
108
+ require File.dirname(__FILE__) + '/yell/helpers/adapters'
109
+ require File.dirname(__FILE__) + '/yell/helpers/formatter'
110
+ require File.dirname(__FILE__) + '/yell/helpers/level'
111
+ require File.dirname(__FILE__) + '/yell/helpers/tracer'
112
+ require File.dirname(__FILE__) + '/yell/helpers/silencer'
113
+
106
114
  # classes
107
115
  require File.dirname(__FILE__) + '/yell/configuration'
108
116
  require File.dirname(__FILE__) + '/yell/repository'
109
117
  require File.dirname(__FILE__) + '/yell/event'
110
118
  require File.dirname(__FILE__) + '/yell/level'
111
119
  require File.dirname(__FILE__) + '/yell/formatter'
120
+ require File.dirname(__FILE__) + '/yell/silencer'
112
121
  require File.dirname(__FILE__) + '/yell/adapters'
113
122
  require File.dirname(__FILE__) + '/yell/logger'
114
123
 
@@ -1,5 +1,4 @@
1
1
  # encoding: utf-8
2
-
3
2
  module Yell #:nodoc:
4
3
 
5
4
  # AdapterNotFound is raised whenever you want to instantiate an
@@ -10,36 +9,34 @@ module Yell #:nodoc:
10
9
  # the logger. You should not have to call the corresponding classes
11
10
  # directly.
12
11
  module Adapters
13
- @@adapters = {}
14
-
15
- class << self
16
-
17
- # Register your own adapter here
18
- #
19
- # @example
20
- # Yell::Adapters.register( :myadapter, MyAdapter )
21
- def register( name, klass )
22
- @@adapters[name] = klass
23
- end
24
12
 
25
- # Returns an instance of the given processor type.
26
- #
27
- # @example A simple file adapter
28
- # Yell::Adapters.new( :file )
29
- def new( name, options = {}, &block )
30
- return name if name.is_a?( Yell::Adapters::Base )
13
+ # holds the list of known adapters
14
+ @adapters = {}
31
15
 
32
- adapter = case name
33
- when STDOUT then @@adapters[:stdout]
34
- when STDERR then @@adapters[:stderr]
35
- else @@adapters[name]
36
- end
37
-
38
- raise AdapterNotFound.new( name ) unless adapter
16
+ # Register your own adapter here
17
+ #
18
+ # @example
19
+ # Yell::Adapters.register( :myadapter, MyAdapter )
20
+ def self.register( name, klass )
21
+ @adapters[name] = klass
22
+ end
39
23
 
40
- adapter.new( options, &block )
24
+ # Returns an instance of the given processor type.
25
+ #
26
+ # @example A simple file adapter
27
+ # Yell::Adapters.new( :file )
28
+ def self.new( name, options = {}, &block )
29
+ return name if name.is_a?(Yell::Adapters::Base)
30
+
31
+ adapter = case name
32
+ when STDOUT then @adapters[:stdout]
33
+ when STDERR then @adapters[:stderr]
34
+ else @adapters[name]
41
35
  end
42
36
 
37
+ raise AdapterNotFound.new(name) if adapter.nil?
38
+
39
+ adapter.new(options, &block)
43
40
  end
44
41
 
45
42
  end
@@ -41,7 +41,8 @@ module Yell #:nodoc:
41
41
  # logger = Yell.new :puts
42
42
  # logger.info "Hello World!"
43
43
  class Base < Monitor
44
- include Yell::Level::Helpers
44
+ include Yell::Helpers::Base
45
+ include Yell::Helpers::Level
45
46
 
46
47
  class << self
47
48
  # Setup your adapter with this helper method.
@@ -137,6 +138,7 @@ module Yell #:nodoc:
137
138
  def initialize( options = {}, &block )
138
139
  super() # init the monitor superclass
139
140
 
141
+ reset!
140
142
  setup!(options)
141
143
 
142
144
  # eval the given block
@@ -166,12 +168,16 @@ module Yell #:nodoc:
166
168
 
167
169
  # Get a pretty string representation of the adapter, including
168
170
  def inspect
169
- inspection = inspectables.inject( [] ) { |r, c| r << "#{c}: #{send(c).inspect}" }
171
+ inspection = inspectables.map { |m| "#{m}: #{send(m).inspect}" }
170
172
  "#<#{self.class.name} #{inspection * ', '}>"
171
173
  end
172
174
 
173
175
  private
174
176
 
177
+ # def reset!
178
+ # super()
179
+ # end
180
+
175
181
  # Setup the adapter instance.
176
182
  #
177
183
  # Adapter classes should provide their own implementation
@@ -14,46 +14,6 @@ module Yell #:nodoc:
14
14
  Header = lambda { |date, pattern| "# -*- #{date.iso8601} (#{date.to_f}) [#{pattern}] -*-" }
15
15
  HeaderRegexp = /^# -\*- (.+) \((\d+\.\d+)\) \[(.+)\] -\*-$/
16
16
 
17
-
18
- setup do |options|
19
- @date, @date_strftime = nil, nil # default; do not override --R
20
-
21
- # check whether to write the log header (default true)
22
- self.header = options.fetch(:header, true)
23
-
24
- # check the date pattern on the filename (default "%Y%m%d")
25
- self.date_pattern = options.fetch(:date_pattern, DefaultDatePattern)
26
-
27
- # check whether to cleanup old files of the same pattern (default false)
28
- self.keep = options.fetch(:keep, false)
29
-
30
- # check whether to symlink the otiginal filename (default true)
31
- self.symlink = options.fetch(:symlink, true)
32
-
33
- @original_filename = ::File.expand_path options.fetch(:filename, default_filename)
34
- options[:filename] = @original_filename
35
- end
36
-
37
- write do |event|
38
- # do nothing when not closing
39
- return unless close?
40
- close
41
-
42
- # exit when file ready present
43
- return if ::File.exist?( @filename )
44
-
45
- # write the header if applicable
46
- stream.puts( Header.call(@date, date_pattern) ) if header?
47
-
48
- symlink! if symlink?
49
- cleanup! if cleanup?
50
- end
51
-
52
- close do
53
- @filename = filename_for( @date )
54
- end
55
-
56
-
57
17
  # The pattern to be used for the files
58
18
  #
59
19
  # @example
@@ -92,6 +52,44 @@ module Yell #:nodoc:
92
52
 
93
53
  private
94
54
 
55
+ # @overload setup!( options )
56
+ def setup!( options )
57
+ @date, @date_strftime = nil, nil # default; do not override --R
58
+
59
+ self.header = options.fetch(:header, true)
60
+ self.date_pattern = options.fetch(:date_pattern, DefaultDatePattern)
61
+ self.keep = options.fetch(:keep, false)
62
+ self.symlink = options.fetch(:symlink, true)
63
+
64
+ @original_filename = ::File.expand_path options.fetch(:filename, default_filename)
65
+ options[:filename] = @original_filename
66
+
67
+ super
68
+ end
69
+
70
+ # @overload write!( event )
71
+ def write!( event )
72
+ # do nothing when not closing
73
+ return super unless close?
74
+ close
75
+
76
+ # exit when file ready present
77
+ return super if ::File.exist?(@filename)
78
+
79
+ header! if header?
80
+ symlink! if symlink?
81
+ cleanup! if cleanup?
82
+
83
+ super
84
+ end
85
+
86
+ # @overload close!
87
+ def close!
88
+ @filename = filename_for( @date )
89
+
90
+ super
91
+ end
92
+
95
93
  # Determine whether to close the file handle or not.
96
94
  #
97
95
  # It is based on the `:date_pattern` (can be passed as option upon initialize).
@@ -119,7 +117,7 @@ module Yell #:nodoc:
119
117
  # in false cleanups).
120
118
  def cleanup!
121
119
  files = Dir[ @original_filename.sub( /(\.\w+)?$/, ".*\\1" ) ].sort.select do |file|
122
- created, pattern = header_from(file)
120
+ _, pattern = header_from(file)
123
121
 
124
122
  # Select if the date pattern is nil (no header info available within the file) or
125
123
  # when the pattern matches.
@@ -150,6 +148,11 @@ module Yell #:nodoc:
150
148
  # @return [Boolean] true or false
151
149
  def symlink?; !!symlink; end
152
150
 
151
+ # Write the header information into the file
152
+ def header!
153
+ stream.puts( Header.call(@date, date_pattern) )
154
+ end
155
+
153
156
  # Write header into the file?
154
157
  #
155
158
  # @return [Boolean] true or false
@@ -174,7 +177,7 @@ module Yell #:nodoc:
174
177
  end
175
178
  end
176
179
 
177
- # @override
180
+ # @overload inspectables
178
181
  def inspectables
179
182
  super.concat [:date_pattern, :header, :keep, :symlink ]
180
183
  end