timberio/timber-ruby

View on GitHub
lib/timber/config.rb

Summary

Maintainability
A
0 mins
Test Coverage
require "logger"
require "singleton"

module Timber
  # Singleton class for reading and setting Timber configuration.
  #
  # For Rails apps, this is installed into `config.timber`. See examples below.
  #
  # @example Rails example
  #   config.timber.append_metadata = false
  # @example Everything else
  #   config = Timber::Config.instance
  #   config.append_metdata = false
  class Config
    # @private
    class NoLoggerError < StandardError; end

    # @private
    class SimpleLogFormatter < ::Logger::Formatter
      # This method is invoked when a log event occurs
      def call(severity, timestamp, progname, msg)
        "[Timber] #{String === msg ? msg : msg.inspect}\n"
      end
    end

    DEVELOPMENT_NAME = "development".freeze
    PRODUCTION_NAME = "production".freeze
    STAGING_NAME = "staging".freeze
    TEST_NAME = "test".freeze

    include Singleton

    attr_writer :http_body_limit

    # Convenience method for logging debug statements to the debug logger
    # set in this class.
    # @private
    def debug(&block)
      debug_logger = Config.instance.debug_logger
      if debug_logger
        message = yield
        debug_logger.debug(message)
      end
      true
    end

    # This is useful for debugging. This Sets a debug_logger to view internal Timber library
    # log messages. The default is `nil`. Meaning log to nothing.
    #
    # See {#debug_to_file!} and {#debug_to_stdout!} for convenience methods that handle creating
    # and setting the logger.
    #
    # @example Rails
    #   config.timber.debug_logger = ::Logger.new(STDOUT)
    # @example Everything else
    #   Timber::Config.instance.debug_logger = ::Logger.new(STDOUT)
    def debug_logger=(value)
      @debug_logger = value
    end

    # Accessor method for {#debug_logger=}.
    def debug_logger
      @debug_logger
    end

    # A convenience method for writing internal Timber debug messages to a file.
    #
    # @example Rails
    #   config.timber.debug_to_file!("#{Rails.root}/log/timber.log")
    # @example Everything else
    #   Timber::Config.instance.debug_to_file!("log/timber.log")
    def debug_to_file!(file_path)
      FileUtils.mkdir_p( File.dirname(file_path) )
      file = File.open(file_path, "ab")
      file_logger = ::Logger.new(file)
      file_logger.formatter = SimpleLogFormatter.new
      self.debug_logger = file_logger
    end

    # A convenience method for writing internal Timber debug messages to STDOUT.
    #
    # @example Rails
    #   config.timber.debug_to_stdout!
    # @example Everything else
    #   Timber::Config.instance.debug_to_stdout!
    def debug_to_stdout!
      stdout_logger = ::Logger.new(STDOUT)
      stdout_logger.formatter = SimpleLogFormatter.new
      self.debug_logger = stdout_logger
    end

    # The environment your app is running in. Defaults to `RACK_ENV` and `RAILS_ENV`.
    # It should be rare that you have to set this. If the aforementioned env vars are not
    # set please do.
    #
    # @example If you do not set `RACK_ENV` or `RAILS_ENV`
    #   Timber::Config.instance.environment = "staging"
    def environment=(value)
      @environment = value
    end

    # Accessor method for {#environment=}
    def environment
      @environment ||= ENV["RACK_ENV"] || ENV["RAILS_ENV"] || "development"
    end

    # Convenience method for accessing the various `Timber::Integrations::*` class
    # settings. These provides settings for enabling, disabled, and silencing integrations.
    # See {Integrations} for a full list of available methods.
    def integrations
      Integrations
    end

    # This is the _main_ logger Timber writes to. All of the Timber integrations write to
    # this logger instance. It should be set to your global logger. For Rails, this is set
    # automatically to `Rails.logger`, you should not have to set this.
    #
    # @example Non-rails frameworks
    #   my_global_logger = Timber::Logger.new(STDOUT)
    #   Timber::Config.instance.logger = my_global_logger
    def logger=(value)
      @logger = value
    end

    # Accessor method for {#logger=}.
    def logger
      if @logger.is_a?(Proc)
        @logger.call()
      else
        @logger ||= Logger.new(STDOUT)
      end
    end

    # @private
    def development?
      environment == DEVELOPMENT_NAME
    end

    # @private
    def test?
      environment == TEST_NAME
    end

    # @private
    def production?
      environment == PRODUCTION_NAME
    end

    # @private
    def staging?
      environment == STAGING_NAME
    end
  end
end