require 'singleton' module Bio module Log class LoggerPlusGlobal include Singleton attr_accessor :outputter_type, :trace end module CLI # Parse and store global logger type def CLI::logger name LoggerPlusGlobal.instance.outputter_type = case name when 'stderr' then :stderr when 'stdout' then :stdout else {:file => { :filename => name }} end end # Parse and store trace options def CLI::trace s level = nil sub_level = nil filter = nil opts = {} # ---- split fields a = s.split(':') if a.last =~ /^=(\d+)$/ # ---- set exact filter filter = "sub_level==#{$1}" a.pop elsif a.last =~ /^=/ # ---- set filter filter = $' a.pop elsif a.last =~ /^\d+$/ # ---- the last field is the sub level sub_level = a.pop.to_i # ---- The fore-last field is the level level = a.pop.downcase else level = a.pop.downcase end # ---- If there is another field it contains logger name(s) # otherwise it is a global outputter = if a.size == 2 a.shift end if a.size == 0 a = [:default] # global else a = a[0].split(',') # one or more logger name(s) end # ---- update every logger a.each do | type | opts[type] = {} opts[type][:level] = level if level opts[type][:sub_level] = sub_level if sub_level opts[type][:filter] = filter if filter opts[type][:outputter_name] = outputter if outputter # p [type,opts[type]] end # ---- Set the globals LoggerPlusGlobal.instance.trace ||= {} LoggerPlusGlobal.instance.trace = LoggerPlusGlobal.instance.trace.merge(opts) end def CLI::configure logname = nil include Bio::Log type = LoggerPlusGlobal.instance.outputter_type trace = LoggerPlusGlobal.instance.trace trace ||= {} default = {} default = trace[:default] if trace[:default] trace[logname] ||= {} if logname trace.each do | name, opts | # p [name, opts] next if name == :default logger_type = type logger_type = default[:outputter_name] if default[:outputter_name] logger_type = opts[:outputter_name] if opts[:outputter_name] logger = LoggerPlus[name] raise "Unknown logger <#{name}>" if logger == nil logger.outputters = case logger_type when 'stderr', :stderr then logger.outputters = Outputter.stderr when nil, 'stdout', :stdout then logger.outputters = Outputter.stdout else # p [name, logger_type] FileOutputter.new(name, logger_type[:file]) end set_levels(logger, default) if default set_levels(logger, opts) filter = default[:filter] filter = opts[:filter] if opts[:filter] if filter # p filter filter2 = "logger.filter { |level,sub_level,msg| #{filter} }" # p filter2 eval(filter2) end end end private def CLI::set_levels logger, opts logger.level = case opts[:level] when 'debug' then DEBUG when 'info' then INFO when 'warn' then WARN when 'error' then ERROR when 'fatal' then FATAL end if opts[:level] logger.sub_level = opts[:sub_level] if opts[:sub_level] end end end end