tagged_logger 0.4.0 → 0.4.2

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.
@@ -0,0 +1,11 @@
1
+ if defined?(Rails::Railtie)
2
+ module TaggedLogger
3
+ class Railtie < Rails::Railtie
4
+ ActiveSupport.on_load(:action_controller) {debugger; TaggedLogger.send(:inject_logger_method_in_call_chain, ActionController::Base)}
5
+ ActiveSupport.on_load(:active_record) {debugger; TaggedLogger.send(:inject_logger_method_in_call_chain, ActiveRecord::Base)}
6
+ ActiveSupport.on_load(:action_mailer) {debugger; TaggedLogger.send(:inject_logger_method_in_call_chain, ActionMailer::Base)}
7
+ end
8
+ end
9
+ end
10
+
11
+
@@ -0,0 +1,191 @@
1
+ require 'delegate'
2
+ require 'hashery/dictionary'
3
+
4
+ module TaggedLogger
5
+ @rename_rules = Dictionary.new
6
+ @tag_blocks = Dictionary.new
7
+ @overridees = []
8
+
9
+ class << self
10
+ def reset
11
+ @rename_rules = Dictionary.new
12
+ @tag_blocks = Dictionary.new
13
+ ObjectSpace.each_object(ClassSpecificLogger) { |obj| obj.detach }
14
+ init
15
+ end
16
+
17
+ def rules(options = {}, &block)
18
+ @options = options
19
+ @old_methods_restored = false
20
+ inject_logger_method_in_call_chain(Object)
21
+ instance_eval(&block)
22
+ end
23
+
24
+ def klass_has_method?(klass, method)
25
+ klass.instance_methods(false).include?(RUBY_VERSION >= '1.9' ? method.to_sym : method.to_s)
26
+ end
27
+
28
+ def restore_old_logger_methods
29
+ return if @old_methods_restored
30
+ @old_methods_restored = true
31
+ @overridees.each do |klass|
32
+ if klass_has_method?(klass, :tagged_logger_original_logger)
33
+ klass.class_eval {alias_method :logger, :tagged_logger_original_logger}
34
+ elsif klass_has_method?(klass, :logger)
35
+ klass.class_eval {remove_method :logger}
36
+ end
37
+ end
38
+ @overridees = []
39
+ end
40
+
41
+ def blocks_for(level, tag)
42
+ blocks = []
43
+ tag_aliases(tag) do |tag_alias|
44
+ tag_blocks(level, tag_alias) do |tag_block|
45
+ blocks << [tag_alias, tag_block]
46
+ end
47
+ end
48
+ blocks
49
+ end
50
+
51
+ def init
52
+ rules {}
53
+ end
54
+
55
+ def debug(what, where = {}, &block) output(:debug, what, where, &block) end
56
+ def info(what, where = {}, &block) output(:info, what, where, &block) end
57
+ def warn(what, where = {}, &block) output(:warn, what, where, &block) end
58
+ def error(what, where = {}, &block) output(:error, what, where, &block) end
59
+ def fatal(what, where = {}, &block) output(:fatal, what, where, &block) end
60
+
61
+ def format(&block)
62
+ @formatter = block
63
+ end
64
+
65
+ def formatter
66
+ @formatter = lambda { |level, tag, message| "#{message}\n"} unless @formatter
67
+ @formatter
68
+ end
69
+
70
+ def rename(renames)
71
+ renames.each { |from, to| @rename_rules[tag_matcher(from)] = to }
72
+ end
73
+
74
+ private
75
+ def output(level, what, where, &block)
76
+ logger = where[:to]
77
+ code = nil
78
+ if logger
79
+ #todo: hack - what about other logger classes?
80
+ logger.formatter = lambda {|severity, datetime, progname, msg| "#{msg}"} if logger.is_a? Logger
81
+ write = lambda { |level, tag, msg | logger.send(level, formatter.call(level, tag, msg)) }
82
+ code = block ? lambda { |l,t,m| write.call(l,t,m); block.call(l,t,m) } : write
83
+ elsif block
84
+ code = block
85
+ else
86
+ raise ArgumentError "Should be called with block or :to => <logger>"
87
+ end
88
+ @tag_blocks[tag_matcher(what, level)] = code
89
+ end
90
+
91
+ class TagMatcher
92
+ attr_reader :match_spec
93
+ LEVELS = { :debug => 1, :info => 2, :warn => 3, :error => 4, :fatal => 5}
94
+
95
+ def initialize(match_spec, level = nil)
96
+ @level = level || :debug
97
+ @match_spec = match_spec
98
+ end
99
+
100
+ def match?(tag, level = nil)
101
+ return false if level && !above_treshold(level)
102
+ self.class.match?(@match_spec, tag)
103
+ end
104
+
105
+ def above_treshold(level)
106
+ LEVELS[@level] <= LEVELS[level]
107
+ end
108
+
109
+ def self.match?(spec, tag)
110
+ t = tag.to_s
111
+ result = case spec
112
+ when Regexp
113
+ t =~ spec
114
+ when Class
115
+ t == spec.name
116
+ when Array
117
+ spec.any? {|s| match?(s, tag)}
118
+ else
119
+ spec.to_s == t
120
+ end
121
+ return result if result
122
+ self.match?(spec, tag.superclass) if tag.class == Class && tag.superclass != Class
123
+ end
124
+ end #TagMatcher
125
+
126
+ def tag_matcher(tag, level = nil)
127
+ TagMatcher.new(tag, level)
128
+ end
129
+
130
+ def tag_aliases(tag, &block)
131
+ current_name = tag
132
+ @rename_rules.each { |from, to| current_name = to if from.match?(tag) }
133
+ block.call(current_name)
134
+ end
135
+
136
+ def tag_blocks(level, tag, &block)
137
+ @tag_blocks.each do |matcher, block|
138
+ yield block if matcher.match?(tag, level)
139
+ end
140
+ end
141
+
142
+ def inject_logger_method_in_call_chain(definee_klass)
143
+ return if @overridees.include?(definee_klass)
144
+
145
+ if klass_has_method?(definee_klass, :logger)
146
+ return if !@options[:override]
147
+ #so we could resurrect old :logger method if we need
148
+ definee_klass.class_eval { alias_method :tagged_logger_original_logger, :logger }
149
+ end
150
+
151
+ @overridees << definee_klass
152
+
153
+ definee_klass.class_eval do
154
+ def logger
155
+ klass = self.class == Class ? self : self.class
156
+ result = klass.class_eval do
157
+ return @class_logger if @class_logger
158
+ @class_logger = ClassSpecificLogger.new(klass)
159
+ @class_logger
160
+ end
161
+ result
162
+ end
163
+ end
164
+
165
+ end
166
+
167
+ end # class methods
168
+
169
+ class ClassSpecificLogger
170
+ def eigenclass
171
+ class <<self; self; end
172
+ end
173
+
174
+ def initialize(klass)
175
+ @klass = klass
176
+ [:debug, :warn, :info, :error, :fatal].each do |level|
177
+ blocks = TaggedLogger.blocks_for(level, klass)
178
+ eigenclass.send(:define_method, level) do |msg|
179
+ blocks.each { |(tag_alias, block)| block.call(level, tag_alias, msg) }
180
+ end
181
+ end
182
+ end
183
+
184
+ def detach
185
+ @klass.class_eval do
186
+ @class_logger = nil
187
+ end
188
+ end
189
+ end
190
+
191
+ end
data/lib/tagged_logger.rb CHANGED
@@ -1,192 +1,4 @@
1
- require 'delegate'
2
- require 'hashery/dictionary'
3
-
4
- class TaggedLogger
5
- @rename_rules = Dictionary.new
6
- @tag_blocks = Dictionary.new
7
-
8
- class << self
9
- def reset
10
- @rename_rules = Dictionary.new
11
- @tag_blocks = Dictionary.new
12
- ObjectSpace.each_object(ClassSpecificLogger) { |obj| obj.detach }
13
- init
14
- end
15
-
16
- def rules(options = {}, &block)
17
- @old_methods_restored = false
18
- override = options.delete :override
19
- klasses = overridees
20
- klasses = klasses.select{ |klass| !klass.respond_to?(:logger, true)} if !override
21
- klasses.each{ |klass| inject_logger_method_in_call_chain(klass)}
22
- instance_eval(&block)
23
- end
24
-
25
- def klass_has_method?(klass, method)
26
- klass.instance_methods(false).include?(RUBY_VERSION >= '1.9' ? method.to_sym : method.to_s)
27
- end
28
-
29
- def restore_old_logger_methods
30
- return if @old_methods_restored
31
- @old_methods_restored = true
32
- overridees.each do |klass|
33
- if klass_has_method?(klass, :tagged_logger_original_logger)
34
- klass.class_eval {alias_method :logger, :tagged_logger_original_logger}
35
- elsif klass_has_method?(klass, :logger)
36
- klass.class_eval {remove_method :logger}
37
- end
38
- end
39
- end
40
-
41
- def overridees
42
- klasses = []
43
- klasses << ActionController::Base if Object.const_defined? :ActionController
44
- klasses << Object
45
- klasses
46
- end
47
-
48
-
49
- def blocks_for(level, tag)
50
- blocks = []
51
- tag_aliases(tag) do |tag_alias|
52
- tag_blocks(level, tag_alias) do |tag_block|
53
- blocks << [tag_alias, tag_block]
54
- end
55
- end
56
- blocks
57
- end
58
-
59
- def init
60
- rules {}
61
- end
62
-
63
- def debug(what, where = {}, &block) output(:debug, what, where, &block) end
64
- def info(what, where = {}, &block) output(:info, what, where, &block) end
65
- def warn(what, where = {}, &block) output(:warn, what, where, &block) end
66
- def error(what, where = {}, &block) output(:error, what, where, &block) end
67
- def fatal(what, where = {}, &block) output(:fatal, what, where, &block) end
68
-
69
- def format(&block)
70
- @formatter = block
71
- end
72
-
73
- def formatter
74
- @formatter = lambda { |level, tag, message| "#{message}\n"} unless @formatter
75
- @formatter
76
- end
77
-
78
- def rename(renames)
79
- renames.each { |from, to| @rename_rules[tag_matcher(from)] = to }
80
- end
81
-
82
- private
83
- def output(level, what, where, &block)
84
- logger = where[:to]
85
- code = nil
86
- if logger
87
- #todo: hack - what about other logger classes?
88
- logger.formatter = lambda {|severity, datetime, progname, msg| "#{msg}"} if logger.is_a? Logger
89
- write = lambda { |level, tag, msg | logger.send(level, formatter.call(level, tag, msg)) }
90
- code = block ? lambda { |l,t,m| write.call(l,t,m); block.call(l,t,m) } : write
91
- elsif block
92
- code = block
93
- else
94
- raise ArgumentError "Should be called with block or :to => <logger>"
95
- end
96
- @tag_blocks[tag_matcher(what, level)] = code
97
- end
98
-
99
- class TagMatcher
100
- attr_reader :match_spec
101
- LEVELS = { :debug => 1, :info => 2, :warn => 3, :error => 4, :fatal => 5}
102
-
103
- def initialize(match_spec, level = nil)
104
- @level = level || :debug
105
- @match_spec = match_spec
106
- end
107
-
108
- def match?(tag, level = nil)
109
- return false if level && !above_treshold(level)
110
- self.class.match?(@match_spec, tag)
111
- end
112
-
113
- def above_treshold(level)
114
- LEVELS[@level] <= LEVELS[level]
115
- end
116
-
117
- def self.match?(spec, tag)
118
- t = tag.to_s
119
- result = case spec
120
- when Regexp
121
- t =~ spec
122
- when Class
123
- t == spec.name
124
- when Array
125
- spec.any? {|s| match?(s, tag)}
126
- else
127
- spec.to_s == t
128
- end
129
- return result if result
130
- self.match?(spec, tag.superclass) if tag.class == Class && tag.superclass != Class
131
- end
132
- end #TagMatcher
133
-
134
- def tag_matcher(tag, level = nil)
135
- TagMatcher.new(tag, level)
136
- end
137
-
138
- def tag_aliases(tag, &block)
139
- current_name = tag
140
- @rename_rules.each { |from, to| current_name = to if from.match?(tag) }
141
- block.call(current_name)
142
- end
143
-
144
- def tag_blocks(level, tag, &block)
145
- @tag_blocks.each do |matcher, block|
146
- yield block if matcher.match?(tag, level)
147
- end
148
- end
149
-
150
- def inject_logger_method_in_call_chain(definee_klass)
151
- if klass_has_method?(definee_klass, :logger)
152
- #so we could resurrect old :logger method if we need
153
- definee_klass.class_eval { alias_method :tagged_logger_original_logger, :logger }
154
- end
155
- definee_klass.class_eval do
156
- def logger
157
- klass = self.class == Class ? self : self.class
158
- result = klass.class_eval do
159
- return @class_logger if @class_logger
160
- @class_logger = ClassSpecificLogger.new(klass)
161
- @class_logger
162
- end
163
- result
164
- end
165
- end
166
- end
167
-
168
- end # class methods
169
-
170
- class ClassSpecificLogger
171
- def eigenclass
172
- class <<self; self; end
173
- end
174
-
175
- def initialize(klass)
176
- @klass = klass
177
- [:debug, :warn, :info, :error, :fatal].each do |level|
178
- blocks = TaggedLogger.blocks_for(level, klass)
179
- eigenclass.send(:define_method, level) do |msg|
180
- blocks.each { |(tag_alias, block)| block.call(level, tag_alias, msg) }
181
- end
182
- end
183
- end
184
-
185
- def detach
186
- @klass.class_eval do
187
- @class_logger = nil
188
- end
189
- end
190
- end
191
-
192
- end
1
+ dir = File.dirname(__FILE__)
2
+ $LOAD_PATH.unshift dir unless $LOAD_PATH.include?(dir)
3
+ require 'tagged_logger/railtie'
4
+ require 'tagged_logger/tagged_logger'
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tagged_logger
3
3
  version: !ruby/object:Gem::Version
4
- hash: 15
4
+ hash: 11
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 4
9
- - 0
10
- version: 0.4.0
9
+ - 2
10
+ version: 0.4.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - Aleksandr Furmanov
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-10-19 00:00:00 -05:00
18
+ date: 2010-10-21 00:00:00 -05:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -90,7 +90,8 @@ files:
90
90
  - MIT-LICENSE
91
91
  - Rakefile
92
92
  - README.markdown
93
- - tagged_logger.rb
93
+ - lib/tagged_logger/railtie.rb
94
+ - lib/tagged_logger/tagged_logger.rb
94
95
  - lib/tagged_logger.rb
95
96
  - test/expected_examples_output.txt
96
97
  - test/test.rb
data/tagged_logger.rb DELETED
@@ -1 +0,0 @@
1
- require File.dirname(__FILE__) + '/lib/tagged_logger.rb'