Ruby - share logger instance among module/classes

后端 未结 9 1752
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-12-04 06:45

Working on a little Ruby script that goes out to the web and crawls various services. I\'ve got a module with several classes inside:

module Crawler
  class          


        
9条回答
  •  予麋鹿
    予麋鹿 (楼主)
    2020-12-04 07:18

    I like to have a logger method available in my classes, but I don't like sprinkling @logger = Logging.logger in all my initializers. Usually, I do this:

    module Logging
      # This is the magical bit that gets mixed into your classes
      def logger
        Logging.logger
      end
    
      # Global, memoized, lazy initialized instance of a logger
      def self.logger
        @logger ||= Logger.new(STDOUT)
      end
    end
    

    Then, in your classes:

    class Widget
      # Mix in the ability to log stuff ...
      include Logging
    
      # ... and proceed to log with impunity:
      def discombobulate(whizbang)
        logger.warn "About to combobulate the whizbang"
        # commence discombobulation
      end
    end
    

    Because the Logging#logger method can access the instance that the module is mixed into, it is trivial to extend your logging module to record the classname with log messages:

    module Logging
      def logger
        @logger ||= Logging.logger_for(self.class.name)
      end
    
      # Use a hash class-ivar to cache a unique Logger per class:
      @loggers = {}
    
      class << self
        def logger_for(classname)
          @loggers[classname] ||= configure_logger_for(classname)
        end
    
        def configure_logger_for(classname)
          logger = Logger.new(STDOUT)
          logger.progname = classname
          logger
        end
      end
    end
    

    Your Widget now logs messages with its classname, and didn't need to change one bit :)

提交回复
热议问题