lumber 0.12.3 → 0.13.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,3 +1,8 @@
1
+ 0.13.0 (08/10/2012)
2
+ -------------------
3
+
4
+ walk heirarchy of loggers/outputters when dynamically setting levels <704b4fa>
5
+
1
6
  0.12.3 (08/09/2012)
2
7
  -------------------
3
8
 
data/README.md CHANGED
@@ -11,8 +11,9 @@ To use it in a rails project:
11
11
  * add lumber to your Gemfile
12
12
  * bundle install
13
13
  * run the lumber generator, rails generate lumber, to get a basic config/log4r.yml
14
- * enable lumber in your config/application.rb:
14
+ * enable lumber in your rails project
15
15
 
16
+ To enable lumber in your rails project, add to your config/application.rb:
16
17
 
17
18
  # To expose custom variables in log4r.yml
18
19
  # config.lumber.some_option = "some_value
@@ -57,7 +58,7 @@ Lumber also comes with a Sinatra UI for dynamically overriding log levels at run
57
58
  require 'lumber/server'
58
59
  mount Lumber::Server, :at => "/lumber"
59
60
 
60
- This will allow you to temporarily set lower log levels for specific loggers - e.g. if you want a specific model to have DEBUG logging for the next hour.
61
+ This will allow you to temporarily set lower log levels for specific loggers - e.g. if you want a specific model to have DEBUG logging for the next hour. Note that this behavior is enabled by a monitor thread running in your process, so if you want to be able to change the log levels for forked subprocesses (resque, passenger, unicorn, etc), you'll need to restart that thread in an after fork hook by calling Lumber::LevelUtil.start_monitor or use Lumber::LevelUtil.activate_levels for a oneoff activation without the thread.
61
62
 
62
63
 
63
64
  Copyright
@@ -36,6 +36,7 @@ module Lumber
36
36
  # @param [Hash] Logger fullname mapping to level name, e.g. {'rails::models::User' => 'DEBUG'}
37
37
  #
38
38
  def set_levels(levels)
39
+ levels = expand_heirarchy(levels)
39
40
  @cache_provider.write(LOG_LEVELS_KEY, levels, :expires_in => @ttl)
40
41
  end
41
42
 
@@ -52,7 +53,10 @@ module Lumber
52
53
  if levels.size == 0
53
54
  restore_levels
54
55
  else
56
+
57
+ levels = expand_heirarchy(levels)
55
58
  backup_levels(levels.keys)
59
+
56
60
  levels.each do |name, level|
57
61
  level_val = Log4r::LNAMES.index(level)
58
62
  outputter = Log4r::Outputter[name]
@@ -126,6 +130,31 @@ module Lumber
126
130
  end
127
131
  end
128
132
 
133
+ # walk the logger heirarchy and add all parents and outputters to levels
134
+ # so that the desired level of the child will take effect. Doesn't override
135
+ # any logger/levels that already have a value
136
+ def expand_heirarchy(levels)
137
+ result = levels.clone
138
+
139
+ levels.each do |name, level|
140
+ # only need to expand on loggers since outputter already in list
141
+ if Log4r::Outputter[name].nil?
142
+ logger = Lumber.find_or_create_logger(name)
143
+ while logger
144
+ logger_name = logger.fullname
145
+ break if logger_name.nil?
146
+ result[logger_name] ||= level
147
+ logger.outputters.each do |o|
148
+ result[o.name] ||= level
149
+ end
150
+ logger = logger.parent
151
+ end
152
+ end
153
+ end
154
+
155
+ return result
156
+ end
157
+
129
158
  extend self
130
159
 
131
160
  end
@@ -1,7 +1,7 @@
1
1
 
2
2
  <h1>Logger Levels</h1>
3
3
  <p>
4
- The table below shows the log levels currently overriden. You can add/remove overrides and apply them, and they will remain active for the given ttl.
4
+ The table below shows the log levels currently overriden. You can add/remove overrides and apply them, and they will remain active for the given ttl. Overrides will be applied for all parents of the given logger as well as their outputters.
5
5
  </p>
6
6
 
7
7
  <form action="<%= url(:levels) %>" method="POST">
@@ -1,3 +1,3 @@
1
1
  module Lumber
2
- VERSION = "0.12.3"
2
+ VERSION = "0.13.0"
3
3
  end
@@ -138,4 +138,94 @@ describe Lumber::LevelUtil do
138
138
  thread.join
139
139
  end
140
140
 
141
+ context "heirarchy of loggers" do
142
+
143
+ before(:each) do
144
+ @parent_name = "parent_#{Time.now.to_f}"
145
+ @child_name = "#{@parent_name}::child_#{Time.now.to_f}"
146
+ @other_name = "other_#{Time.now.to_f}"
147
+ end
148
+
149
+ it "sets levels for logger parents" do
150
+ Lumber.find_or_create_logger(@parent_name)
151
+ Lumber.find_or_create_logger(@child_name)
152
+ Lumber.find_or_create_logger(@other_name)
153
+ LevelUtil.set_levels({@child_name => "ERROR"})
154
+ Log4r::Logger[@parent_name].level.should == Log4r::LNAMES.index("DEBUG")
155
+ Log4r::Logger[@child_name].level.should == Log4r::LNAMES.index("DEBUG")
156
+ Log4r::Logger[@other_name].level.should == Log4r::LNAMES.index("DEBUG")
157
+
158
+ LevelUtil.activate_levels
159
+ Log4r::Logger[@parent_name].level.should == Log4r::LNAMES.index("ERROR")
160
+ Log4r::Logger[@child_name].level.should == Log4r::LNAMES.index("ERROR")
161
+ Log4r::Logger[@other_name].level.should == Log4r::LNAMES.index("DEBUG")
162
+ end
163
+
164
+ it "restores levels for logger parents when mapping expires" do
165
+ Lumber.find_or_create_logger(@parent_name)
166
+ Lumber.find_or_create_logger(@child_name)
167
+ Lumber.find_or_create_logger(@other_name)
168
+ LevelUtil.set_levels({@child_name => "ERROR"})
169
+ Log4r::Logger[@parent_name].level.should == Log4r::LNAMES.index("DEBUG")
170
+ Log4r::Logger[@child_name].level.should == Log4r::LNAMES.index("DEBUG")
171
+ Log4r::Logger[@other_name].level.should == Log4r::LNAMES.index("DEBUG")
172
+
173
+ LevelUtil.activate_levels
174
+ Log4r::Logger[@parent_name].level.should == Log4r::LNAMES.index("ERROR")
175
+ Log4r::Logger[@child_name].level.should == Log4r::LNAMES.index("ERROR")
176
+ Log4r::Logger[@other_name].level.should == Log4r::LNAMES.index("DEBUG")
177
+
178
+ LevelUtil.set_levels({})
179
+ LevelUtil.activate_levels
180
+ Log4r::Logger[@parent_name].level.should == Log4r::LNAMES.index("DEBUG")
181
+ Log4r::Logger[@child_name].level.should == Log4r::LNAMES.index("DEBUG")
182
+ Log4r::Logger[@other_name].level.should == Log4r::LNAMES.index("DEBUG")
183
+ end
184
+
185
+ it "sets levels for logger and parent's outputters" do
186
+ parent_outputter = Log4r::IOOutputter.new("#{@parent_name}_sbout", StringIO.new)
187
+ child_outputter = Log4r::IOOutputter.new("#{@child_name}_sbout", StringIO.new)
188
+ other_outputter = Log4r::IOOutputter.new("#{@other_name}_sbout", StringIO.new)
189
+
190
+ Lumber.find_or_create_logger(@parent_name).outputters = [parent_outputter]
191
+ Lumber.find_or_create_logger(@child_name).outputters = [child_outputter]
192
+ Lumber.find_or_create_logger(@other_name).outputters = [other_outputter]
193
+ LevelUtil.set_levels({@child_name => "ERROR"})
194
+ Log4r::Outputter["#{@parent_name}_sbout"].level.should == Log4r::LNAMES.index("DEBUG")
195
+ Log4r::Outputter["#{@child_name}_sbout"].level.should == Log4r::LNAMES.index("DEBUG")
196
+ Log4r::Outputter["#{@other_name}_sbout"].level.should == Log4r::LNAMES.index("DEBUG")
197
+
198
+ LevelUtil.activate_levels
199
+ Log4r::Outputter["#{@parent_name}_sbout"].level.should == Log4r::LNAMES.index("ERROR")
200
+ Log4r::Outputter["#{@child_name}_sbout"].level.should == Log4r::LNAMES.index("ERROR")
201
+ Log4r::Outputter["#{@other_name}_sbout"].level.should == Log4r::LNAMES.index("DEBUG")
202
+ end
203
+
204
+ it "restores levels for logger and parent's outputters when mapping expires" do
205
+ parent_outputter = Log4r::IOOutputter.new("#{@parent_name}_sbout", StringIO.new)
206
+ child_outputter = Log4r::IOOutputter.new("#{@child_name}_sbout", StringIO.new)
207
+ other_outputter = Log4r::IOOutputter.new("#{@other_name}_sbout", StringIO.new)
208
+
209
+ Lumber.find_or_create_logger(@parent_name).outputters = [parent_outputter]
210
+ Lumber.find_or_create_logger(@child_name).outputters = [child_outputter]
211
+ Lumber.find_or_create_logger(@other_name).outputters = [other_outputter]
212
+ LevelUtil.set_levels({@child_name => "ERROR"})
213
+ Log4r::Outputter["#{@parent_name}_sbout"].level.should == Log4r::LNAMES.index("DEBUG")
214
+ Log4r::Outputter["#{@child_name}_sbout"].level.should == Log4r::LNAMES.index("DEBUG")
215
+ Log4r::Outputter["#{@other_name}_sbout"].level.should == Log4r::LNAMES.index("DEBUG")
216
+
217
+ LevelUtil.activate_levels
218
+ Log4r::Outputter["#{@parent_name}_sbout"].level.should == Log4r::LNAMES.index("ERROR")
219
+ Log4r::Outputter["#{@child_name}_sbout"].level.should == Log4r::LNAMES.index("ERROR")
220
+ Log4r::Outputter["#{@other_name}_sbout"].level.should == Log4r::LNAMES.index("DEBUG")
221
+
222
+ LevelUtil.set_levels({})
223
+ LevelUtil.activate_levels
224
+ Log4r::Outputter["#{@parent_name}_sbout"].level.should == Log4r::LNAMES.index("DEBUG")
225
+ Log4r::Outputter["#{@child_name}_sbout"].level.should == Log4r::LNAMES.index("DEBUG")
226
+ Log4r::Outputter["#{@other_name}_sbout"].level.should == Log4r::LNAMES.index("DEBUG")
227
+ end
228
+
229
+ end
230
+
141
231
  end
data/spec/server_spec.rb CHANGED
@@ -77,6 +77,30 @@ describe Lumber::Server, :type => :request do
77
77
  LevelUtil.get_levels.should == {"foo" => "DEBUG"}
78
78
  end
79
79
 
80
+ it "shows heirarchy overrides after assigning", :js => true do
81
+ @parent_name = "parent_#{Time.now.to_f}"
82
+ @child_name = "#{@parent_name}::child_#{Time.now.to_f}"
83
+ @other_name = "other_#{Time.now.to_f}"
84
+ Lumber.find_or_create_logger(@parent_name)
85
+ Lumber.find_or_create_logger(@child_name)
86
+ Lumber.find_or_create_logger(@other_name)
87
+
88
+ LevelUtil.set_levels({})
89
+
90
+ visit "/levels"
91
+ click_link('Add')
92
+ fill_in 'levels[][name]', :with => @child_name
93
+ fill_in 'levels[][level]', :with => "DEBUG"
94
+ click_button 'Apply'
95
+
96
+ page.should_not have_selector("div.alert-error")
97
+
98
+ find(:xpath, "//input[@value='#{@child_name}']/ancestor::tr//input[@value='DEBUG']").should_not be_nil
99
+ find(:xpath, "//input[@value='#{@parent_name}']/ancestor::tr//input[@value='DEBUG']").should_not be_nil
100
+
101
+ LevelUtil.get_levels.should == {@child_name => "DEBUG", @parent_name => "DEBUG"}
102
+ end
103
+
80
104
  it "modifies level overrides", :js => true do
81
105
  LevelUtil.set_levels({"foo" => "INFO"})
82
106
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lumber
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.12.3
4
+ version: 0.13.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-08-09 00:00:00.000000000 Z
12
+ date: 2012-08-10 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: log4r
@@ -235,7 +235,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
235
235
  version: '0'
236
236
  segments:
237
237
  - 0
238
- hash: 2358509895133458004
238
+ hash: 2273159776171190626
239
239
  required_rubygems_version: !ruby/object:Gem::Requirement
240
240
  none: false
241
241
  requirements:
@@ -244,7 +244,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
244
244
  version: '0'
245
245
  segments:
246
246
  - 0
247
- hash: 2358509895133458004
247
+ hash: 2273159776171190626
248
248
  requirements: []
249
249
  rubyforge_project:
250
250
  rubygems_version: 1.8.24