yell 0.5.1 → 0.6.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.
- data/Gemfile +2 -5
- data/Rakefile +21 -1
- data/examples/004.1-colorizing-the-log-output.rb +23 -0
- data/lib/yell.rb +6 -6
- data/lib/yell/adapters/base.rb +128 -25
- data/lib/yell/adapters/datefile.rb +6 -19
- data/lib/yell/adapters/file.rb +4 -6
- data/lib/yell/adapters/io.rb +25 -50
- data/lib/yell/adapters/streams.rb +4 -0
- data/lib/yell/formatter.rb +14 -0
- data/lib/yell/level.rb +22 -2
- data/lib/yell/logger.rb +27 -44
- data/lib/yell/version.rb +1 -1
- data/spec/spec_helper.rb +5 -0
- data/spec/yell/adapters/base_spec.rb +0 -8
- data/spec/yell/adapters/datefile_spec.rb +45 -0
- data/spec/yell/adapters/file_spec.rb +45 -0
- data/spec/yell/adapters/io_spec.rb +75 -0
- data/spec/yell/adapters/streams_spec.rb +26 -0
- data/spec/yell/logger_spec.rb +3 -3
- data/yell.gemspec +1 -0
- metadata +24 -16
data/Gemfile
CHANGED
data/Rakefile
CHANGED
@@ -3,7 +3,27 @@ $LOAD_PATH.unshift( 'lib' )
|
|
3
3
|
require 'bundler'
|
4
4
|
Bundler::GemHelper.install_tasks
|
5
5
|
|
6
|
-
|
6
|
+
task :examples do
|
7
|
+
require 'benchmark'
|
8
|
+
|
9
|
+
seconds = Benchmark.realtime do
|
10
|
+
Dir[ './examples/*.rb' ].sort.each do |file|
|
11
|
+
begin
|
12
|
+
puts "\n*** Running #{file}"
|
13
|
+
|
14
|
+
require file
|
15
|
+
rescue Exception => e
|
16
|
+
puts "#{e.class}: #{e.message}:\n\t#{e.backtrace.join("\n\t")}"
|
17
|
+
|
18
|
+
exit 1
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
puts "\n\t[ Examples took #{seconds} seconds to run ]"
|
24
|
+
end
|
25
|
+
|
26
|
+
# RSpec
|
7
27
|
begin
|
8
28
|
require 'rspec/core/rake_task'
|
9
29
|
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require_relative '../lib/yell'
|
4
|
+
|
5
|
+
puts <<-EOS
|
6
|
+
|
7
|
+
You may colorize the log output on your io-based loggers loke so:
|
8
|
+
|
9
|
+
logger = Yell.new STDOUT, :colors => true
|
10
|
+
|
11
|
+
[:debug, :info, :warn, :error, :fatal, :unknown].each do |level|
|
12
|
+
logger.send level, level
|
13
|
+
end
|
14
|
+
|
15
|
+
EOS
|
16
|
+
|
17
|
+
puts "=== actuale example ==="
|
18
|
+
logger = Yell.new STDOUT, :colors => true
|
19
|
+
|
20
|
+
[:debug, :info, :warn, :error, :fatal, :unknown].each do |level|
|
21
|
+
logger.send level, level
|
22
|
+
end
|
23
|
+
|
data/lib/yell.rb
CHANGED
@@ -24,12 +24,6 @@
|
|
24
24
|
require 'time'
|
25
25
|
require 'socket'
|
26
26
|
|
27
|
-
require File.dirname(__FILE__) + '/yell/event'
|
28
|
-
require File.dirname(__FILE__) + '/yell/level'
|
29
|
-
require File.dirname(__FILE__) + '/yell/formatter'
|
30
|
-
require File.dirname(__FILE__) + '/yell/adapters'
|
31
|
-
require File.dirname(__FILE__) + '/yell/logger'
|
32
|
-
|
33
27
|
module Yell #:nodoc:
|
34
28
|
Severities = [ 'DEBUG', 'INFO', 'WARN', 'ERROR', 'FATAL', 'UNKNOWN' ]
|
35
29
|
|
@@ -73,3 +67,9 @@ module Yell #:nodoc:
|
|
73
67
|
|
74
68
|
end
|
75
69
|
|
70
|
+
require File.dirname(__FILE__) + '/yell/event'
|
71
|
+
require File.dirname(__FILE__) + '/yell/level'
|
72
|
+
require File.dirname(__FILE__) + '/yell/formatter'
|
73
|
+
require File.dirname(__FILE__) + '/yell/adapters'
|
74
|
+
require File.dirname(__FILE__) + '/yell/logger'
|
75
|
+
|
data/lib/yell/adapters/base.rb
CHANGED
@@ -3,23 +3,115 @@
|
|
3
3
|
module Yell #:nodoc:
|
4
4
|
module Adapters #:nodoc:
|
5
5
|
|
6
|
-
# This class provides the basic interface for all allowed
|
7
|
-
#
|
6
|
+
# This class provides the basic interface for all allowed operations on any
|
7
|
+
# adapter implementation. Other adapters should inherit from it for the methods
|
8
|
+
# used by the {Yell::Logger}.
|
8
9
|
#
|
9
|
-
#
|
10
|
-
#
|
10
|
+
# Writing your own adapter is really simple. Inherit from the base class and use
|
11
|
+
# the `setup`, `write` and `close` methods. Yell requires the `write` method to be
|
12
|
+
# specified (`setup` and `close` are optional).
|
13
|
+
#
|
14
|
+
#
|
15
|
+
# The following example shows how to define a basic Adapter to format and print
|
16
|
+
# log events to STDOUT:
|
17
|
+
#
|
18
|
+
# class PutsAdapter < Yell::Adapters::Base
|
19
|
+
# include Yell::Formatter::Helpers
|
20
|
+
#
|
21
|
+
# setup do |options|
|
22
|
+
# self.format = options[:format]
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
# write do |event|
|
26
|
+
# message = format.format(event)
|
27
|
+
#
|
28
|
+
# STDOUT.puts message
|
29
|
+
# end
|
30
|
+
# end
|
31
|
+
#
|
32
|
+
#
|
33
|
+
# After the Adapter has been written, we need to register it to Yell:
|
34
|
+
#
|
35
|
+
# Yell::Adapters.register :puts, PutsAdapter
|
36
|
+
#
|
37
|
+
# Now, we can use it like so:
|
38
|
+
#
|
39
|
+
# logger = Yell.new :puts
|
40
|
+
# logger.info "Hello World!"
|
11
41
|
class Base
|
42
|
+
include Yell::Level::Helpers
|
43
|
+
|
44
|
+
class << self
|
45
|
+
# Setup your adapter with this helper method.
|
46
|
+
#
|
47
|
+
# @example
|
48
|
+
# setup do |options|
|
49
|
+
# @file_handle = File.new( '/dev/null', 'w' )
|
50
|
+
# end
|
51
|
+
def setup( &block )
|
52
|
+
compile!( :setup!, &block )
|
53
|
+
end
|
54
|
+
|
55
|
+
# Define your write method with this helper.
|
56
|
+
#
|
57
|
+
# @example Printing messages to file
|
58
|
+
# write do |event|
|
59
|
+
# @file_handle.puts event.message
|
60
|
+
# end
|
61
|
+
def write( &block )
|
62
|
+
compile!( :write!, &block )
|
63
|
+
end
|
64
|
+
|
65
|
+
# Define your close method with this helper.
|
66
|
+
#
|
67
|
+
# @example Closing a file handle
|
68
|
+
# close do
|
69
|
+
# @file_handle.close
|
70
|
+
# end
|
71
|
+
def close( &block )
|
72
|
+
compile!( :close!, &block )
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
# Pretty funky code block, I know but here is what it basically does:
|
79
|
+
#
|
80
|
+
# @example
|
81
|
+
# compile! :write! do |event|
|
82
|
+
# puts event.message
|
83
|
+
# end
|
84
|
+
#
|
85
|
+
# # Is actually defining the `:write!` instance method with a call to super:
|
86
|
+
#
|
87
|
+
# def write!( event )
|
88
|
+
# puts event.method
|
89
|
+
# super
|
90
|
+
# end
|
91
|
+
def compile!( name, &block )
|
92
|
+
# Get the already defined method
|
93
|
+
m = instance_method name
|
94
|
+
|
95
|
+
# Create a new method with leading underscore
|
96
|
+
define_method "_#{name}", &block
|
97
|
+
_m = instance_method "_#{name}"
|
98
|
+
remove_method "_#{name}"
|
99
|
+
|
100
|
+
# Define instance method
|
101
|
+
if block.arity == 0
|
102
|
+
define_method(name) { _m.bind(self).call; m.bind(self).call }
|
103
|
+
else
|
104
|
+
define_method(name) { |*args| _m.bind(self).call(*args); m.bind(self).call(*args) }
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
12
108
|
|
13
|
-
# Accessor to the level
|
14
|
-
attr_reader :level
|
15
|
-
|
16
|
-
# Accessor to the options
|
17
|
-
attr_reader :options
|
18
109
|
|
110
|
+
# Initializes a new Adapter.
|
111
|
+
#
|
112
|
+
# You should not overload the constructor, use #setup instead.
|
19
113
|
def initialize( options = {}, &block )
|
20
|
-
|
21
|
-
|
22
|
-
self.level = options[:level]
|
114
|
+
setup!(options)
|
23
115
|
|
24
116
|
block.call(self) if block
|
25
117
|
end
|
@@ -30,6 +122,11 @@ module Yell #:nodoc:
|
|
30
122
|
# actually write or not.
|
31
123
|
def write( event )
|
32
124
|
write!( event ) if write?( event )
|
125
|
+
rescue Exception => e
|
126
|
+
# make sure the adapter is closed and re-raise the exception
|
127
|
+
close
|
128
|
+
|
129
|
+
raise( e )
|
33
130
|
end
|
34
131
|
|
35
132
|
# Close the adapter (stream, connection, etc).
|
@@ -37,28 +134,34 @@ module Yell #:nodoc:
|
|
37
134
|
# Adapter classes should provide their own implementation
|
38
135
|
# of this method.
|
39
136
|
def close
|
40
|
-
|
41
|
-
end
|
42
|
-
|
43
|
-
# Set the log level.
|
44
|
-
#
|
45
|
-
# @example Set minimum level to :info
|
46
|
-
# level :info
|
47
|
-
#
|
48
|
-
# For more examples, refer to {Yell::Level}.
|
49
|
-
def level=( severity )
|
50
|
-
@level = Yell::Level.new( severity )
|
137
|
+
close!
|
51
138
|
end
|
52
139
|
|
53
140
|
|
54
141
|
private
|
55
142
|
|
56
|
-
#
|
143
|
+
# Setup the adapter instance.
|
57
144
|
#
|
58
145
|
# Adapter classes should provide their own implementation
|
146
|
+
# of this method (if applicable).
|
147
|
+
def setup!( options )
|
148
|
+
self.level = options[:level]
|
149
|
+
end
|
150
|
+
|
151
|
+
# Perform the actual write.
|
152
|
+
#
|
153
|
+
# Adapter classes must provide their own implementation
|
59
154
|
# of this method.
|
60
155
|
def write!( event )
|
61
|
-
|
156
|
+
# Not implemented
|
157
|
+
end
|
158
|
+
|
159
|
+
# Perform the actual close.
|
160
|
+
#
|
161
|
+
# Adapter classes should provide their own implementation
|
162
|
+
# of this method.
|
163
|
+
def close!
|
164
|
+
# Not implemented
|
62
165
|
end
|
63
166
|
|
64
167
|
# Determine whether to write at the given severity.
|
@@ -10,34 +10,26 @@ module Yell #:nodoc:
|
|
10
10
|
# The default date pattern, e.g. "19820114" (14 Jan 1982)
|
11
11
|
DefaultDatePattern = "%Y%m%d"
|
12
12
|
|
13
|
-
|
13
|
+
setup do |options|
|
14
14
|
@date_pattern = options[:date_pattern] || DefaultDatePattern
|
15
15
|
|
16
16
|
@file_basename = options[:filename] || default_filename
|
17
17
|
options[:filename] = @file_basename
|
18
18
|
|
19
19
|
@date = nil # default; do not override --R
|
20
|
-
|
21
|
-
super
|
22
20
|
end
|
23
21
|
|
24
|
-
|
25
|
-
|
26
|
-
|
22
|
+
write do |event|
|
23
|
+
close if close?
|
24
|
+
end
|
27
25
|
|
28
|
-
|
26
|
+
close do
|
27
|
+
@filename = @file_basename.sub( /(\.\w+)?$/, ".#{@date}\\1" )
|
29
28
|
end
|
30
29
|
|
31
30
|
|
32
31
|
private
|
33
32
|
|
34
|
-
# @overload Close the file if date is expired
|
35
|
-
def write!( event )
|
36
|
-
close if close?
|
37
|
-
|
38
|
-
super( event )
|
39
|
-
end
|
40
|
-
|
41
33
|
# Determines whether to close the file handle or not.
|
42
34
|
#
|
43
35
|
# It is based on the `:date_pattern` (can be passed as option upon initialize).
|
@@ -54,11 +46,6 @@ module Yell #:nodoc:
|
|
54
46
|
false
|
55
47
|
end
|
56
48
|
|
57
|
-
# Sets the filename with the `:date_pattern` appended to it.
|
58
|
-
def new_filename
|
59
|
-
@file_basename.sub( /(\.\w+)?$/, ".#{@date}\\1" )
|
60
|
-
end
|
61
|
-
|
62
49
|
end
|
63
50
|
|
64
51
|
register( :datefile, Yell::Adapters::Datefile )
|
data/lib/yell/adapters/file.rb
CHANGED
@@ -7,20 +7,18 @@ module Yell #:nodoc:
|
|
7
7
|
# for logging into files.
|
8
8
|
class File < Yell::Adapters::Io
|
9
9
|
|
10
|
-
|
11
|
-
super
|
12
|
-
|
10
|
+
setup do |options|
|
13
11
|
@filename = options.fetch(:filename, default_filename)
|
14
12
|
end
|
15
13
|
|
14
|
+
|
15
|
+
private
|
16
|
+
|
16
17
|
# @overload Lazily open the file handle
|
17
18
|
def stream
|
18
19
|
@stream ||= ::File.open( @filename, ::File::WRONLY|::File::APPEND|::File::CREAT )
|
19
20
|
end
|
20
21
|
|
21
|
-
|
22
|
-
private
|
23
|
-
|
24
22
|
def default_filename #:nodoc:
|
25
23
|
::File.directory?("log") ? "log/#{Yell.env}.log" : "#{Yell.env}.log"
|
26
24
|
end
|
data/lib/yell/adapters/io.rb
CHANGED
@@ -4,6 +4,7 @@ module Yell #:nodoc:
|
|
4
4
|
module Adapters #:nodoc:
|
5
5
|
|
6
6
|
class Io < Yell::Adapters::Base
|
7
|
+
include Yell::Formatter::Helpers
|
7
8
|
|
8
9
|
# The possible unix log colors
|
9
10
|
Colors = {
|
@@ -16,73 +17,47 @@ module Yell #:nodoc:
|
|
16
17
|
'DEFAULT' => "\e[0m" # NONE
|
17
18
|
}
|
18
19
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
def initialize( options = {}, &block )
|
23
|
-
colorize options.fetch(:colorize, false)
|
24
|
-
|
20
|
+
setup do |options|
|
21
|
+
self.colors = options[:colors]
|
25
22
|
self.format = options[:format]
|
26
|
-
|
27
|
-
super( options, &block )
|
28
23
|
end
|
29
24
|
|
30
|
-
|
31
|
-
|
32
|
-
# Adapter classes should provide their own implementation
|
33
|
-
# of this method.
|
34
|
-
def stream
|
35
|
-
raise 'Not implemented'
|
36
|
-
end
|
25
|
+
write do |event|
|
26
|
+
message = format.format(event)
|
37
27
|
|
38
|
-
|
39
|
-
|
40
|
-
|
28
|
+
# colorize if applicable
|
29
|
+
if colors and color = Colors[event.level]
|
30
|
+
message = color + message + Colors['DEFAULT']
|
31
|
+
end
|
41
32
|
|
42
|
-
|
43
|
-
end
|
33
|
+
message << "\n" unless message[-1] == ?\n # add new line if there is none
|
44
34
|
|
45
|
-
|
46
|
-
|
47
|
-
@format = case pattern
|
48
|
-
when Yell::Formatter then pattern
|
49
|
-
when false then Yell::Formatter.new( "%m" )
|
50
|
-
else Yell::Formatter.new( *pattern )
|
51
|
-
end
|
35
|
+
stream.print( message )
|
36
|
+
stream.flush
|
52
37
|
end
|
53
38
|
|
54
|
-
|
55
|
-
|
56
|
-
@
|
39
|
+
close do
|
40
|
+
@stream.close if @stream.respond_to? :close
|
41
|
+
@stream = nil
|
57
42
|
end
|
58
|
-
alias :colorize! :colorize
|
59
43
|
|
60
44
|
|
61
|
-
|
62
|
-
|
63
|
-
# The method formats the message and writes it to the file handle.
|
64
|
-
def write!( event )
|
65
|
-
message = @format.format( event )
|
45
|
+
attr_accessor :colors
|
66
46
|
|
67
|
-
|
68
|
-
|
69
|
-
message = color + message + Colors['DEFAULT']
|
70
|
-
end
|
47
|
+
# Shortcut to enable colors
|
48
|
+
def colorize!; @colors = true; end
|
71
49
|
|
72
|
-
message << "\n" unless message[-1] == ?\n # add new line if there is none
|
73
50
|
|
74
|
-
|
75
|
-
stream.flush
|
76
|
-
# rescue Exception => e
|
77
|
-
# close
|
51
|
+
private
|
78
52
|
|
79
|
-
#
|
80
|
-
#
|
53
|
+
# The IO stream
|
54
|
+
#
|
55
|
+
# Adapter classes should provide their own implementation
|
56
|
+
# of this method.
|
57
|
+
def stream
|
58
|
+
raise 'Not implemented'
|
81
59
|
end
|
82
60
|
|
83
|
-
# Determie whether to colorize the log output or nor
|
84
|
-
def colorize?; !!@colorize; end
|
85
|
-
|
86
61
|
end
|
87
62
|
|
88
63
|
end
|
@@ -5,6 +5,8 @@ module Yell #:nodoc:
|
|
5
5
|
|
6
6
|
class Stdout < Yell::Adapters::Io
|
7
7
|
|
8
|
+
private
|
9
|
+
|
8
10
|
# @overload Lazily open the STDOUT stream
|
9
11
|
def stream
|
10
12
|
@stream ||= $stdout.clone
|
@@ -13,6 +15,8 @@ module Yell #:nodoc:
|
|
13
15
|
|
14
16
|
class Stderr < Yell::Adapters::Io
|
15
17
|
|
18
|
+
private
|
19
|
+
|
16
20
|
# @overload Lazily open the STDERR stream
|
17
21
|
def stream
|
18
22
|
@stream ||= $stderr.clone
|
data/lib/yell/formatter.rb
CHANGED
@@ -44,6 +44,19 @@ module Yell #:nodoc:
|
|
44
44
|
|
45
45
|
# The +Formatter+ provides a handle to configure your log message style.
|
46
46
|
class Formatter
|
47
|
+
module Helpers
|
48
|
+
# Accessor to the format
|
49
|
+
attr_reader :format
|
50
|
+
|
51
|
+
# Set the format for your message.
|
52
|
+
def format=( pattern )
|
53
|
+
@format = case pattern
|
54
|
+
when Yell::Formatter then pattern
|
55
|
+
when false then Yell::Formatter.new( Yell::NoFormat )
|
56
|
+
else Yell::Formatter.new( *pattern )
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
47
60
|
|
48
61
|
PatternTable = {
|
49
62
|
"m" => "event.message", # Message
|
@@ -74,6 +87,7 @@ module Yell #:nodoc:
|
|
74
87
|
define!
|
75
88
|
end
|
76
89
|
|
90
|
+
|
77
91
|
private
|
78
92
|
|
79
93
|
# defines the format method
|
data/lib/yell/level.rb
CHANGED
@@ -23,6 +23,23 @@ 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] val 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
|
26
43
|
|
27
44
|
attr_reader :severities
|
28
45
|
|
@@ -42,16 +59,19 @@ module Yell #:nodoc:
|
|
42
59
|
#
|
43
60
|
# @param [Integer,String,Symbol,Array,Range,nil] severity The severity for the level.
|
44
61
|
def initialize( severity = nil )
|
45
|
-
|
62
|
+
reset!
|
46
63
|
|
47
64
|
case severity
|
48
|
-
when Yell::Level then @severities = severity.severities
|
49
65
|
when Array then at( *severity )
|
50
66
|
when Range then gte(severity.first).lte(severity.last)
|
51
67
|
when Integer, String, Symbol then gte(severity)
|
52
68
|
end
|
53
69
|
end
|
54
70
|
|
71
|
+
def reset!
|
72
|
+
@severities = Yell::Severities.map { true }
|
73
|
+
end
|
74
|
+
|
55
75
|
# Returns whether the level is allowed at the given severity
|
56
76
|
#
|
57
77
|
# @example
|
data/lib/yell/logger.rb
CHANGED
@@ -29,9 +29,7 @@ module Yell #:nodoc:
|
|
29
29
|
# l.level = :info
|
30
30
|
# end
|
31
31
|
class Logger
|
32
|
-
|
33
|
-
# Accessor to the log level
|
34
|
-
attr_reader :level
|
32
|
+
include Yell::Level::Helpers
|
35
33
|
|
36
34
|
def initialize( *args, &block )
|
37
35
|
@adapters = []
|
@@ -51,10 +49,11 @@ module Yell #:nodoc:
|
|
51
49
|
self.adapter args.pop if args.any?
|
52
50
|
|
53
51
|
# eval the given block
|
54
|
-
|
55
|
-
_call( &block ) if block
|
52
|
+
block.call(self) if block
|
53
|
+
# _call( &block ) if block
|
56
54
|
|
57
|
-
|
55
|
+
# default adapter when none defined
|
56
|
+
adapter :file if @adapters.empty?
|
58
57
|
end
|
59
58
|
|
60
59
|
# Define an adapter to be used for logging.
|
@@ -87,16 +86,6 @@ module Yell #:nodoc:
|
|
87
86
|
@adapters << Yell::Adapters.new( type, options, &block )
|
88
87
|
end
|
89
88
|
|
90
|
-
# Set the minimum log level.
|
91
|
-
#
|
92
|
-
# @example Set the level to :warn
|
93
|
-
# level = :warn
|
94
|
-
#
|
95
|
-
# @param [String, Symbol, Integer] val The minimum log level
|
96
|
-
def level=( severity )
|
97
|
-
@level = Yell::Level.new( severity )
|
98
|
-
end
|
99
|
-
|
100
89
|
# Deprecated: Use attr_reader in future
|
101
90
|
def level( val = nil )
|
102
91
|
if val.nil?
|
@@ -119,6 +108,28 @@ module Yell #:nodoc:
|
|
119
108
|
@adapters.each(&:close)
|
120
109
|
end
|
121
110
|
|
111
|
+
# Creates instance methods for every log level:
|
112
|
+
# `debug` and `debug?`
|
113
|
+
# `info` and `info?`
|
114
|
+
# `warn` and `warn?`
|
115
|
+
# `error` and `error?`
|
116
|
+
# `unknown` and `unknown?`
|
117
|
+
Yell::Severities.each_with_index do |s, index|
|
118
|
+
name = s.downcase
|
119
|
+
|
120
|
+
class_eval <<-EOS, __FILE__, __LINE__
|
121
|
+
def #{name}?; @level.at?(#{index}); end # def info?; @level.at?(1); end
|
122
|
+
#
|
123
|
+
def #{name}( m = nil, &b ) # def info( m = nil, &b )
|
124
|
+
return unless #{name}? # return unless info?
|
125
|
+
#
|
126
|
+
write Yell::Event.new( '#{s}', m, &b ) # write Yell::Event.new( "INFO", m, &b )
|
127
|
+
#
|
128
|
+
true # true
|
129
|
+
end # end
|
130
|
+
EOS
|
131
|
+
end
|
132
|
+
|
122
133
|
|
123
134
|
private
|
124
135
|
|
@@ -136,34 +147,6 @@ module Yell #:nodoc:
|
|
136
147
|
end
|
137
148
|
end
|
138
149
|
|
139
|
-
# Sets a default adapter if none was given explicitly and defines the log methods on
|
140
|
-
# the logger instance.
|
141
|
-
def define!
|
142
|
-
adapter :file if @adapters.empty? # default adapter when none defined
|
143
|
-
|
144
|
-
define_log_methods!
|
145
|
-
end
|
146
|
-
|
147
|
-
# Creates instance methods for every defined log level (debug, info, ...) depending
|
148
|
-
# on whether anything should be logged upon, for instance, #info.
|
149
|
-
def define_log_methods!
|
150
|
-
Yell::Severities.each_with_index do |s, index|
|
151
|
-
name = s.downcase
|
152
|
-
|
153
|
-
instance_eval %-
|
154
|
-
def #{name}?; @level.at?(#{index}); end # def info?; @level.at?(1); end
|
155
|
-
#
|
156
|
-
def #{name}( m = nil, &b ) # def info( m = nil, &b )
|
157
|
-
return unless #{name}? # return unless info?
|
158
|
-
#
|
159
|
-
write Yell::Event.new( '#{s}', m, &b ) # write Yell::Event.new( "INFO", m, &b )
|
160
|
-
#
|
161
|
-
true # true
|
162
|
-
end # end
|
163
|
-
-
|
164
|
-
end
|
165
|
-
end
|
166
|
-
|
167
150
|
# Cycles all the adapters and writes the message
|
168
151
|
def write( event )
|
169
152
|
@adapters.each { |a| a.write(event) }
|
data/lib/yell/version.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
$:.unshift File.expand_path('..', __FILE__)
|
2
2
|
$:.unshift File.expand_path('../../lib', __FILE__)
|
3
3
|
|
4
|
+
require 'ostruct'
|
5
|
+
|
4
6
|
require 'yell'
|
5
7
|
|
6
8
|
require 'rspec'
|
@@ -10,5 +12,8 @@ require 'timecop'
|
|
10
12
|
RSpec.configure do |config|
|
11
13
|
config.mock_framework = :rr
|
12
14
|
|
15
|
+
config.after do
|
16
|
+
Dir[ "*.log" ].each { |f| File.delete f }
|
17
|
+
end
|
13
18
|
end
|
14
19
|
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Yell::Adapters::Datefile do
|
4
|
+
let( :time ) { Time.now }
|
5
|
+
let( :filename ) { 'filename.log' }
|
6
|
+
|
7
|
+
let( :event ) { Yell::Event.new("INFO", "Hello World") }
|
8
|
+
|
9
|
+
describe :filename do
|
10
|
+
let( :adapter ) { Yell::Adapters::Datefile.new(:filename => filename) }
|
11
|
+
let( :date_filename ) { "filename.#{time.strftime(Yell::Adapters::Datefile::DefaultDatePattern)}.log" }
|
12
|
+
|
13
|
+
before do
|
14
|
+
Timecop.freeze( time )
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should be replaced with date_pattern" do
|
18
|
+
adapter.write( event )
|
19
|
+
|
20
|
+
File.exist?(date_filename).should be_true
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should open file handle only once" do
|
24
|
+
mock( File ).open( date_filename, anything ) { File.new('/dev/null', 'w') }
|
25
|
+
|
26
|
+
adapter.write( event )
|
27
|
+
adapter.write( event )
|
28
|
+
end
|
29
|
+
|
30
|
+
context "rollover" do
|
31
|
+
let( :tomorrow ) { time + 86400 }
|
32
|
+
let( :tomorrow_date_filename ) { "filename.#{tomorrow.strftime(Yell::Adapters::Datefile::DefaultDatePattern)}.log" }
|
33
|
+
|
34
|
+
it "should rollover when date has passed" do
|
35
|
+
mock( File ).open( date_filename, anything ) { File.new('/dev/null', 'w') }
|
36
|
+
adapter.write( event )
|
37
|
+
|
38
|
+
Timecop.freeze( tomorrow ) # tomorrow
|
39
|
+
|
40
|
+
mock( File ).open( tomorrow_date_filename, anything ) { File.new('/dev/null', 'w') }
|
41
|
+
adapter.write( event )
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Yell::Adapters::File do
|
4
|
+
let( :devnull ) { File.new('/dev/null', 'w') }
|
5
|
+
|
6
|
+
before do
|
7
|
+
stub( File ).open( anything, anything ) { devnull }
|
8
|
+
end
|
9
|
+
|
10
|
+
it { should be_kind_of Yell::Adapters::Io }
|
11
|
+
|
12
|
+
context :stream do
|
13
|
+
subject { Yell::Adapters::File.new.send :stream }
|
14
|
+
|
15
|
+
it { should be_kind_of File }
|
16
|
+
end
|
17
|
+
|
18
|
+
context :write do
|
19
|
+
let( :event ) { Yell::Event.new("INFO", "Hello World") }
|
20
|
+
|
21
|
+
context "default filename" do
|
22
|
+
let( :filename ) { "#{Yell.env}.log" }
|
23
|
+
let( :adapter ) { Yell::Adapters::File.new }
|
24
|
+
|
25
|
+
it "should print to file" do
|
26
|
+
mock( File ).open( filename, File::WRONLY|File::APPEND|File::CREAT ) { devnull }
|
27
|
+
|
28
|
+
adapter.write( event )
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context "with given filename" do
|
33
|
+
let( :filename ) { 'filename.log' }
|
34
|
+
let( :adapter ) { Yell::Adapters::File.new( :filename => filename ) }
|
35
|
+
|
36
|
+
it "should print to file" do
|
37
|
+
mock( File ).open( filename, File::WRONLY|File::APPEND|File::CREAT ) { devnull }
|
38
|
+
|
39
|
+
adapter.write( event )
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Yell::Adapters::Io do
|
4
|
+
|
5
|
+
it { should be_kind_of Yell::Adapters::Base }
|
6
|
+
|
7
|
+
context "initialize" do
|
8
|
+
it "should set default :format" do
|
9
|
+
adapter = Yell::Adapters::Io.new
|
10
|
+
|
11
|
+
adapter.format.should be_kind_of Yell::Formatter
|
12
|
+
end
|
13
|
+
|
14
|
+
context :level do
|
15
|
+
let( :level ) { Yell::Level.new(:warn) }
|
16
|
+
|
17
|
+
it "should set the level" do
|
18
|
+
adapter = Yell::Adapters::Io.new :level => level
|
19
|
+
adapter.level.should == level
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should set the level when block was given" do
|
23
|
+
adapter = Yell::Adapters::Io.new { |a| a.level = level }
|
24
|
+
adapter.level.should == level
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context :format do
|
29
|
+
let( :format ) { Yell::Formatter.new }
|
30
|
+
|
31
|
+
it "should set the level" do
|
32
|
+
adapter = Yell::Adapters::Io.new :format => format
|
33
|
+
adapter.format.should == format
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should set the level when block was given" do
|
37
|
+
adapter = Yell::Adapters::Io.new { |a| a.format = format }
|
38
|
+
adapter.format.should == format
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context :stream do
|
44
|
+
it "should raise" do
|
45
|
+
lambda { Yell::Adapters::Io.new.send :stream }.should raise_error("Not implemented" )
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context :write do
|
50
|
+
let( :event ) { Yell::Event.new("INFO", "Hello World") }
|
51
|
+
let( :adapter ) { Yell::Adapters::Io.new }
|
52
|
+
let( :stream ) { File.new('/dev/null', 'w') }
|
53
|
+
|
54
|
+
before do
|
55
|
+
stub( adapter ).stream { stream }
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should format the message" do
|
59
|
+
mock.proxy( adapter.format ).format( event )
|
60
|
+
|
61
|
+
adapter.write( event )
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should print formatted message to stream" do
|
65
|
+
formatted = Yell::Formatter.new.format( event )
|
66
|
+
|
67
|
+
mock( stream ).print( formatted << "\n" )
|
68
|
+
mock( stream ).flush
|
69
|
+
|
70
|
+
adapter.write( event )
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Yell::Adapters::Stdout do
|
4
|
+
|
5
|
+
it { should be_kind_of Yell::Adapters::Io }
|
6
|
+
|
7
|
+
context :stream do
|
8
|
+
subject { Yell::Adapters::Stdout.new.send :stream }
|
9
|
+
|
10
|
+
it { should be_kind_of IO }
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
describe Yell::Adapters::Stderr do
|
16
|
+
|
17
|
+
it { should be_kind_of Yell::Adapters::Io }
|
18
|
+
|
19
|
+
context :stream do
|
20
|
+
subject { Yell::Adapters::Stderr.new.send :stream }
|
21
|
+
|
22
|
+
it { should be_kind_of IO }
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
data/spec/yell/logger_spec.rb
CHANGED
@@ -75,15 +75,15 @@ describe Yell::Logger do
|
|
75
75
|
let( :level ) { Yell::Level.new :error }
|
76
76
|
let( :adapter ) { Yell::Adapters::Stdout.new }
|
77
77
|
|
78
|
-
let( :logger ) do
|
79
|
-
Yell::Logger.new do |l|
|
78
|
+
let( :logger ) do
|
79
|
+
Yell::Logger.new do |l|
|
80
80
|
l.level = level
|
81
81
|
l.adapter adapter
|
82
82
|
end
|
83
83
|
end
|
84
84
|
|
85
85
|
it "should set the level" do
|
86
|
-
logger.level.
|
86
|
+
logger.level.should == level
|
87
87
|
end
|
88
88
|
|
89
89
|
it "should define adapter" do
|
data/yell.gemspec
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: yell
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-04-
|
12
|
+
date: 2012-04-12 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
16
|
-
requirement: &
|
16
|
+
requirement: &17866520 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *17866520
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rr
|
27
|
-
requirement: &
|
27
|
+
requirement: &17866000 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,7 +32,18 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *17866000
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: timecop
|
38
|
+
requirement: &17865580 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *17865580
|
36
47
|
description: Yell - Your Extensible Logging Library. Define multiple adapters, various
|
37
48
|
log level combinations or message formatting options like you've never done before
|
38
49
|
email:
|
@@ -54,6 +65,7 @@ files:
|
|
54
65
|
- examples/003.2-formatting-BasicFormat.rb
|
55
66
|
- examples/003.3-formatting-ExtendedFormat.rb
|
56
67
|
- examples/003.4-formatting-on-your-own.rb
|
68
|
+
- examples/004.1-colorizing-the-log-output.rb
|
57
69
|
- lib/yell.rb
|
58
70
|
- lib/yell/adapters.rb
|
59
71
|
- lib/yell/adapters/base.rb
|
@@ -68,6 +80,10 @@ files:
|
|
68
80
|
- lib/yell/version.rb
|
69
81
|
- spec/spec_helper.rb
|
70
82
|
- spec/yell/adapters/base_spec.rb
|
83
|
+
- spec/yell/adapters/datefile_spec.rb
|
84
|
+
- spec/yell/adapters/file_spec.rb
|
85
|
+
- spec/yell/adapters/io_spec.rb
|
86
|
+
- spec/yell/adapters/streams_spec.rb
|
71
87
|
- spec/yell/adapters_spec.rb
|
72
88
|
- spec/yell/event_spec.rb
|
73
89
|
- spec/yell/formatter_spec.rb
|
@@ -95,17 +111,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
95
111
|
version: '0'
|
96
112
|
requirements: []
|
97
113
|
rubyforge_project: yell
|
98
|
-
rubygems_version: 1.8.
|
114
|
+
rubygems_version: 1.8.10
|
99
115
|
signing_key:
|
100
116
|
specification_version: 3
|
101
117
|
summary: Yell - Your Extensible Logging Library
|
102
|
-
test_files:
|
103
|
-
- spec/spec_helper.rb
|
104
|
-
- spec/yell/adapters/base_spec.rb
|
105
|
-
- spec/yell/adapters_spec.rb
|
106
|
-
- spec/yell/event_spec.rb
|
107
|
-
- spec/yell/formatter_spec.rb
|
108
|
-
- spec/yell/level_spec.rb
|
109
|
-
- spec/yell/logger_spec.rb
|
110
|
-
- spec/yell_spec.rb
|
118
|
+
test_files: []
|
111
119
|
has_rdoc:
|