require'logger'require'concurrent/atomic/atomic_reference'moduleConcurrentmoduleConcern# Include where logging is needed## @!visibility privatemoduleLoggingincludeLogger::Severity# Logs through {Concurrent.global_logger}, it can be overridden by setting @logger# @param [Integer] level one of Logger::Severity constants# @param [String] progname e.g. a path of an Actor# @param [String, nil] message when nil block is used to generate the message# @yieldreturn [String] a messagedeflog(level,progname,message=nil,&block)logger=ifdefined?(@logger)&&@logger@loggerelseConcurrent.global_loggerendlogger.calllevel,progname,message,&blockrescue=>error$stderr.puts"`Concurrent.configuration.logger` failed to log #{[level,progname,message,block]}\n"+"#{error.message} (#{error.class})\n#{error.backtrace.join"\n"}"endendendendmoduleConcurrentextendConcern::Logging# @return [Logger] Logger with provided level and output.defself.create_simple_logger(level=Logger::FATAL,output=$stderr)# TODO (pitr-ch 24-Dec-2016): figure out why it had to be replaced, stdlogger was deadlockinglambdado|severity,progname,message=nil,&block|returnfalseifseverity<levelmessage=block?block.call:messageformatted_message=casemessagewhenStringmessagewhenExceptionformat"%s (%s)\n%s",message.message,message.class,(message.backtrace||[]).join("\n")elsemessage.inspectendoutput.printformat"[%s] %5s -- %s: %s\n",Time.now.strftime('%Y-%m-%d %H:%M:%S.%L'),Logger::SEV_LABEL[severity],progname,formatted_messagetrueendend# Use logger created by #create_simple_logger to log concurrent-ruby messages.defself.use_simple_logger(level=Logger::FATAL,output=$stderr)Concurrent.global_logger=create_simple_loggerlevel,outputend# @return [Logger] Logger with provided level and output.# @deprecateddefself.create_stdlib_logger(level=Logger::FATAL,output=$stderr)logger=Logger.new(output)logger.level=levellogger.formatter=lambdado|severity,datetime,progname,msg|formatted_message=casemsgwhenStringmsgwhenExceptionformat"%s (%s)\n%s",msg.message,msg.class,(msg.backtrace||[]).join("\n")elsemsg.inspectendformat"[%s] %5s -- %s: %s\n",datetime.strftime('%Y-%m-%d %H:%M:%S.%L'),severity,progname,formatted_messageendlambdado|loglevel,progname,message=nil,&block|logger.addloglevel,message,progname,&blockendend# Use logger created by #create_stdlib_logger to log concurrent-ruby messages.# @deprecateddefself.use_stdlib_logger(level=Logger::FATAL,output=$stderr)Concurrent.global_logger=create_stdlib_loggerlevel,outputend# TODO (pitr-ch 27-Dec-2016): remove deadlocking stdlib_logger methods# Suppresses all output when used for logging.NULL_LOGGER=lambda{|level,progname,message=nil,&block|}# @!visibility privateGLOBAL_LOGGER=AtomicReference.new(create_simple_logger(Logger::WARN))private_constant:GLOBAL_LOGGERdefself.global_loggerGLOBAL_LOGGER.valueenddefself.global_logger=(value)GLOBAL_LOGGER.value=valueendend