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