sawa's answer is ok, and also you can use a method like this to dynamically create logger for each class.
However, I prefer not to get all classes under a module. In able to create logger for every single class, you can do things as follow.
module Kernel
#######
private
#######
def logger
Log4r::Logger[logger_name]
end
def logger_name
clazz = self.class
unless clazz.respond_to? :logger_name
name = clazz.module_eval 'self.name'
clazz.define_singleton_method(:logger_name) { name }
end
clazz.logger_name
end
end
module A
module B
class C
def hello
logger.debug logger_name
end
end
end
end
A::B::C.new.hello
For classes within a specific module you can write a filter in the logger_name
method, for example:
module Kernel
#######
private
#######
def logger
Log4r::Logger[logger_name]
end
def logger_name
clazz = self.class
unless clazz.respond_to? :logger_name
name = clazz.module_eval 'self.name'
name = 'root' unless name.start_with?('A::B')
clazz.define_singleton_method(:logger_name) { name }
end
clazz.logger_name
end
end
module A
module B
class C
def hello
logger.debug logger_name
end
class << self
def hello
logger.debug logger_name
end
end
end
end
class D
def hello
logger.debug logger_name
end
end
end
A::B::C.new.hello # A::B::C
A::B::C.hello # A::B::C
A::D.new.hello # root
And also, you can cache the logger:
def logger
_logger = Log4r::Logger[logger_name]
self.class.send(:define_method, :logger) { _logger }
self.class.define_singleton_method(:logger) { _logger }
return _logger
end
Hope it helps.