# File lib/needle/log-factory.rb, line 80
    def initialize( opts={} )
      opts = convert_keys_to_symbols( opts )
      bad = opts.keys - VALID_OPTIONS
      raise ArgumentError,
        "invalid option(s) to LogFactory (#{bad.inspect})" unless bad.empty?

      if opts[:device]
        @device = opts[:device]
      else
        filename = opts[:filename] || DEFAULT_LOG_FILENAME
        roll_age = opts[:roll_age ] || opts[:roll_frequency] || 0
        roll_size = opts[:roll_size] || 0
        @device = Logger::LogDevice.new( filename,
          :shift_age=>roll_age, :shift_size=>roll_size )
      end

      @default_date_format = opts[:default_date_format]
      @default_message_format = opts[:default_message_format] ||
        DEFAULT_MESSAGE_FORMAT
      @default_level = opts[:default_level]

      if @default_level.is_a?( String ) || @default_level.is_a?( Symbol )
        @default_level = LEVEL_TRANSLATOR[@default_level.to_s.upcase]
        if @default_level.nil?
          raise ArgumentError,
            "invalid logging level (#{@default_level.inspect})"
        end
      end

      @levels = Hash.new :level => nil, :date_format => nil,
        :message_format => nil

      ( opts[:levels] || {} ).each_pair do |key, value|
        key = Regexp.new( "^" + key.gsub( /\./, "\\." ).gsub( /\*/, ".*" ) )

        if value.is_a?( String ) || value.is_a?( Symbol )
          value = { :level => value.to_s }
        else
          value = convert_keys_to_symbols( value )
        end

        bad = value.keys - VALID_LEVEL_OPTIONS
        raise ArgumentError, 
          "invalid log level option(s) #{bad.inspect}" unless bad.empty?

        value[ :level ] = LEVEL_TRANSLATOR[ value[:level].to_s.upcase ]
        if value[:level].nil?
          raise ArgumentError,
            "invalid logging level (#{value[:level].inspect})"
        end

        @levels[ key ] = value
      end

      @loggers = Hash.new
      @mutex = Mutex.new
      @closed = false
    end