lumber 0.0.2 → 0.9.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/CHANGELOG CHANGED
@@ -1,3 +1,10 @@
1
+ 0.9.0
2
+ -----
3
+
4
+ get working with nested classes, prevent rails from overriding logger <b9fecdd> [Matt Conway]
5
+ some doc changes <334f2de> [Matt Conway]
6
+ add dependency to ActiveSupport, Refactor to remove dependency on load order, Add tests <beb8769> [Matt Conway]
7
+
1
8
  0.0.2
2
9
  -----
3
10
 
data/README.rdoc CHANGED
@@ -13,19 +13,17 @@ to config/environment.rb:
13
13
  require 'lumber'
14
14
  Lumber.init()
15
15
 
16
- # If you really want all classes to have a logger
17
- # Lumber.setup_logger_hierarchy(Object, "root::object")
16
+ # Setup parent loggers for some known rails Base classes. Classes that inherit
17
+ # from these will have their logger as a parent so you can configure logging for
18
+ # subtrees of classes in log4r.yml
19
+ Lumber.setup_logger_hierarchy("ActiveRecord::Base", "rails::models")
20
+ Lumber.setup_logger_hierarchy("ActionController::Base", "rails::controllers")
21
+ Lumber.setup_logger_hierarchy("ActionMailer::Base", "rails::mailers")
18
22
 
19
- # Inside the block for Rails::Initializer.run
20
- #
21
- config.after_initialize do
22
- # setup log4r hierarchy - these need to happen after frameworks
23
- # are loaded, but before subclasses get defined
24
- Lumber.setup_logger_hierarchy(ActiveRecord::Base, "rails::models")
25
- Lumber.setup_logger_hierarchy(ActionController::Base, "rails::controllers")
26
- Lumber.setup_logger_hierarchy(ActionMailer::Base, "rails::mailers")
27
- end
23
+ # If you really want, you can make all classes have a logger
24
+ # Lumber.setup_logger_hierarchy("Object", "root::object")
28
25
 
26
+
29
27
  If you want to change the log level for a different environment, add a line like below to the config/environments/<env>.rb
30
28
 
31
29
  # Set info as the default log level for production
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.2
1
+ 0.9.0
data/lib/lumber/lumber.rb CHANGED
@@ -1,4 +1,7 @@
1
1
  require "socket"
2
+ require "active_support/core_ext/duplicable"
3
+ require "active_support/core_ext/class"
4
+ require "active_support/core_ext/module"
2
5
 
3
6
  module Lumber
4
7
 
@@ -36,16 +39,18 @@ module Lumber
36
39
  end
37
40
  Object.const_set('RAILS_DEFAULT_LOGGER', Log4r::Logger['rails'])
38
41
 
42
+ @@registered_loggers = {}
43
+ self.register_inheritance_handler()
39
44
  end
40
45
 
41
46
  # Makes :logger exist independently for subclasses and sets that logger
42
- # to one that inherits from base_class for each subclass as its created.
47
+ # to one that inherits from base_class for each subclass as it is created.
43
48
  # This allows you to have a finer level of control over logging, for example,
44
49
  # put just a single class, or hierarchy of classes, into debug log level
45
50
  #
46
51
  # for example:
47
52
  #
48
- # Lumber.setup_logger_hierarchy(ActiveRecord::Base, "rails::models")
53
+ # Lumber.setup_logger_hierarchy("ActiveRecord::Base", "rails::models")
49
54
  #
50
55
  # causes all models that get created to have a log4r logger named
51
56
  # "rails::models::<class_name>". This class can individually be
@@ -53,36 +58,96 @@ module Lumber
53
58
  # output will include "<class_name>" on every log from this class
54
59
  # so that you can tell where a log statement came from
55
60
  #
56
- def self.setup_logger_hierarchy(base_class, parent_fullname)
57
- base_class.class_eval do
58
- class_inheritable_accessor :logger
59
- self.logger = Log4r::Logger.new(parent_fullname)
61
+ def self.setup_logger_hierarchy(class_name, class_logger_fullname)
62
+ @@registered_loggers[class_name] = class_logger_fullname
63
+
64
+ obj = nil
65
+ names = class_name.split '::'
66
+ names.each do |name|
67
+ root ||= Object
68
+ if root.const_defined?(name)
69
+ obj = root.const_get(name)
70
+ root = obj
71
+ else
72
+ obj = nil
73
+ end
74
+ end
75
+
76
+ if obj
77
+ obj.class_eval do
78
+ class_inheritable_accessor :logger
79
+ self.logger = Log4r::Logger.new(class_logger_fullname)
80
+ end
81
+ end
82
+ end
60
83
 
84
+ private
85
+
86
+ # Adds a inheritance handler to Object so we can know to add loggers
87
+ # for classes as they get defined.
88
+ def self.register_inheritance_handler()
89
+ return if defined?(Object.inherited_with_lumber_log4r)
90
+
91
+ Object.class_eval do
92
+
61
93
  class << self
94
+
62
95
  def inherited_with_lumber_log4r(subclass)
63
96
  inherited_without_lumber_log4r(subclass)
64
- # p "#{self} -> #{subclass} -> #{self.logger}"
65
-
66
- # Look up the class hierarchy for a useable logger
67
- # A class may have a nil logger if it was created
68
- # before we add logger/inheritance to its superclas,
69
- # e.g. Object/Exception - something tries to subclass
70
- # Exception after we added lumber_inherited to Object,
71
- # but Exception was defined before we added lumber_inherited
72
- while self.logger.nil?
73
- next_class = (next_class ||self).superclass
74
- if next_class.nil?
75
- self.logger = Log4r::Logger.root
76
- else
77
- self.logger = next_class.logger
78
- end
97
+
98
+ # if the new class is in the list that were registered directly,
99
+ # then create their logger attribute directly, otherwise derive it
100
+ logger_name = @@registered_loggers[subclass.name]
101
+ if logger_name
102
+ Lumber.add_lumber_logger(subclass, logger_name)
103
+ else
104
+ Lumber.derive_lumber_logger(subclass)
79
105
  end
80
- subclass.logger = Log4r::Logger.new("#{logger.fullname}::#{subclass.name}")
81
106
  end
107
+
82
108
  alias_method_chain :inherited, :lumber_log4r
109
+
110
+ end
111
+
112
+ end
113
+
114
+ end
115
+
116
+ def self.add_lumber_logger(clazz, logger_name)
117
+ clazz.class_eval do
118
+
119
+ class_inheritable_accessor :logger
120
+ self.logger = Log4r::Logger.new(logger_name)
121
+
122
+ class << self
123
+
124
+ # Prevent rails from overwriting our logger
125
+ def cattr_accessor_with_lumber_log4r(*syms)
126
+ without_logger = syms.reject {|s| s == :logger}
127
+ cattr_accessor_without_lumber_log4r(*without_logger)
128
+ end
129
+ alias_method_chain :cattr_accessor, :lumber_log4r
130
+
83
131
  end
84
132
 
85
133
  end
86
134
  end
87
135
 
136
+ def self.derive_lumber_logger(clazz)
137
+ # otherwise, walk up the classes hierarchy till you find a logger
138
+ # that was registered, and use that logger as the parent for the
139
+ # logger of the new class
140
+ parent = clazz.superclass
141
+ while ! parent.nil?
142
+ if defined?(parent.logger) && parent.logger
143
+ parent_is_registered = @@registered_loggers.values.find {|v| parent.logger.fullname.index(v) == 0}
144
+ if parent_is_registered
145
+ clazz.logger = Log4r::Logger.new("#{parent.logger.fullname}::#{clazz.name}")
146
+ break
147
+ end
148
+ end
149
+ parent = parent.superclass
150
+ end
151
+ end
152
+
88
153
  end
data/test/lumber_test.rb CHANGED
@@ -1,7 +1,117 @@
1
1
  require 'test_helper'
2
2
 
3
+
4
+ def new_class(class_name, super_class=nil, super_module=nil)
5
+ s = "class #{class_name}"
6
+ s << " < #{super_class}" if super_class
7
+ s << "; end"
8
+
9
+ s = "module #{super_module}; #{s}; end" if super_module
10
+
11
+ eval s
12
+ end
13
+
3
14
  class LumberTest < Test::Unit::TestCase
4
- should "probably rename this file and start testing for real" do
5
- flunk "hey buddy, you should probably rename this file and start testing for real"
15
+
16
+ def setup
17
+ root = "#{File.dirname(__FILE__)}/.."
18
+ Lumber.init(:root => root,
19
+ :env => 'test',
20
+ :config_file => "#{root}/generators/lumber/templates/log4r.yml",
21
+ :log_file => "/tmp/lumber-test.log")
22
+ end
23
+
24
+ def teardown
25
+ Object.constants.grep(/^Foo/).each do |c|
26
+ Object.send(:remove_const, c)
27
+ end
28
+ end
29
+
30
+ def assert_valid_logger(class_name, logger_name)
31
+ clazz = eval class_name
32
+ assert clazz
33
+ assert clazz.respond_to?(:logger)
34
+ lgr = clazz.logger
35
+ assert lgr.instance_of?(Log4r::Logger)
36
+ assert_equal logger_name, lgr.fullname
37
+ end
38
+
39
+ should "not do anything if no loggers registered" do
40
+ assert defined?(Object.inherited_with_lumber_log4r)
41
+ assert ! defined?(Object.logger)
42
+ end
43
+
44
+ should "allow registering logger for a class before the class is defined" do
45
+ assert !defined?(Foo1)
46
+ Lumber.setup_logger_hierarchy("Foo1", "root::foo1")
47
+ new_class('Foo1')
48
+ assert_valid_logger('Foo1', "root::foo1")
49
+ end
50
+
51
+ should "prevent cattr_accessor for a class registered before the class is defined" do
52
+ assert !defined?(Foo1)
53
+ Lumber.setup_logger_hierarchy("Foo1", "root::foo1")
54
+ new_class('Foo1')
55
+ Foo1.class_eval do
56
+ cattr_accessor :logger, :foo
57
+ end
58
+ assert defined?(Foo1.foo)
59
+ assert_valid_logger('Foo1', "root::foo1")
60
+ end
61
+
62
+ should "allow registering logger for a nested class before the class is defined" do
63
+ assert !defined?(Bar1::Foo1)
64
+ Lumber.setup_logger_hierarchy("Bar1::Foo1", "root::foo1")
65
+ new_class('Foo1', nil, 'Bar1')
66
+ assert_valid_logger('Bar1::Foo1', "root::foo1")
67
+ end
68
+
69
+ should "allow registering logger for a class after the class is defined" do
70
+ assert !defined?(Foo1)
71
+ new_class('Foo1')
72
+ assert defined?(Foo1)
73
+
74
+ Lumber.setup_logger_hierarchy("Foo1", "root::Foo1")
75
+ assert_valid_logger('Foo1', "root::Foo1")
76
+ end
77
+
78
+ should "register loggers for subclasses of registered classes" do
79
+ assert !defined?(Foo1)
80
+ assert !defined?(Foo2)
81
+ assert !defined?(Foo3)
82
+ Lumber.setup_logger_hierarchy("Foo1", "root::Foo1")
83
+ new_class('Foo1')
84
+ new_class('Foo2', 'Foo1')
85
+ new_class('Foo3')
86
+ assert_valid_logger('Foo1', "root::Foo1")
87
+ assert_valid_logger('Foo2', "root::Foo1::Foo2")
88
+ assert ! defined?(Foo3.logger)
89
+ end
90
+
91
+ should "register loggers for sub-subclasses of registered classes" do
92
+ assert !defined?(Foo1)
93
+ assert !defined?(Foo2)
94
+ assert !defined?(Foo3)
95
+ Lumber.setup_logger_hierarchy("Foo1", "root::Foo1")
96
+ new_class('Foo1')
97
+ new_class('Foo2', 'Foo1')
98
+ new_class('Foo3', 'Foo2')
99
+ assert_valid_logger('Foo1', "root::Foo1")
100
+ assert_valid_logger('Foo2', "root::Foo1::Foo2")
101
+ assert_valid_logger('Foo3', "root::Foo1::Foo2::Foo3")
102
+ end
103
+
104
+ should "register loggers for sub-subclasses of registered classes even when middle class not a logger" do
105
+ assert !defined?(Foo1)
106
+ assert !defined?(Foo2)
107
+ assert !defined?(Foo3)
108
+ new_class('Foo1')
109
+ new_class('Foo2', 'Foo1')
110
+ Lumber.setup_logger_hierarchy("Foo1", "root::Foo1")
111
+ new_class('Foo3', 'Foo2')
112
+ assert_valid_logger('Foo1', "root::Foo1")
113
+ assert !defined?(Foo2.logger) || Foo2.logger.nil?
114
+ assert_valid_logger('Foo3', "root::Foo1::Foo3")
6
115
  end
116
+
7
117
  end
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.0.2
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Conway
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-10-15 00:00:00 -04:00
12
+ date: 2009-10-16 00:00:00 -04:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -32,6 +32,16 @@ dependencies:
32
32
  - !ruby/object:Gem::Version
33
33
  version: "0"
34
34
  version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: active_support
37
+ type: :runtime
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: "0"
44
+ version:
35
45
  description: Lumber tries to make it easy to use the more robust log4r logging system within your rails application. To do this it sets up log4r configuration from a yml file, and provides utility methods for adding a :logger accessor to classes dynamicaly as they get created.
36
46
  email: matt@conwaysplace.com
37
47
  executables: []
@@ -77,7 +87,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
77
87
  requirements: []
78
88
 
79
89
  rubyforge_project:
80
- rubygems_version: 1.3.4
90
+ rubygems_version: 1.3.5
81
91
  signing_key:
82
92
  specification_version: 3
83
93
  summary: Lumber integrates the log4r logging system within your application.