class ActiveSupport::BroadcastLogger

logger.loggable? # [true, true]
puts logger.broadcasts # => [MyLogger, MyLogger]
logger.broadcast_to(MyLogger.new(STDOUT))
logger.loggable? # => true
logger.broadcast_to(MyLogger.new(STDOUT))
logger.loggable? # => A NoMethodError exception is raised because no loggers in the broadcasts could respond.
logger = BroadcastLogger.new
end
end
true
def loggable?
class MyLogger < ::Logger
the method:
of raw values, depending on how many loggers in the broadcasts responded to
the ‘BroadcastLogger` will proxy them and return the raw value, or an array
If you are adding a custom logger with custom methods to the broadcast,
broadcast.info(“Hello world”) # The log message will appear nowhere.
broadcast = BroadcastLogger.new
be written anywhere. For instance:
At least one sink has to be part of the broadcast. Otherwise, your logs will not
broadcast.info(“Hello world!”) # Writes the log only to STDOUT.
broadcast.stop_broadcasting_to(file_logger)
broadcast.info(“Hello world!”) # Writes the log to STDOUT and the development.log file.
broadcast = BroadcastLogger.new(stdout_logger, file_logger)
file_logger = Logger.new(“development.log”)
stdout_logger = Logger.new(STDOUT)
Stop broadcasting log to a sink.
broadcast.level = Logger::FATAL # Modify the log level for the whole broadcast.
broadcast = BroadcastLogger.new(stdout_logger, file_logger)
file_logger = Logger.new(“development.log”)
stdout_logger = Logger.new(STDOUT)
Modifying the log level for all broadcasted loggers.
broadcast.info(“Hello world!”) # Writes the log to STDOUT and the development.log file.
broadcast.broadcast_to(file_logger)
file_logger = Logger.new(“development.log”)
broadcast = BroadcastLogger.new(stdout_logger)
stdout_logger = Logger.new(STDOUT)
Add a logger to the broadcast.
broadcast.info(“Hello world!”) # Writes the log to STDOUT and the development.log file.
broadcast = BroadcastLogger.new(stdout_logger, file_logger)
file_logger = Logger.new(“development.log”)
stdout_logger = Logger.new(STDOUT)
Broadcasting your logs.
that are part of the broadcast.
However, all the methods on this logger will propagate and be delegated to the other loggers
The BroadcastLogger acts as a standard logger and all methods you are used to are available.
With the Broadcast logger, you can broadcast your logs to a unlimited number of sinks.
in development to display messages on STDOUT and also write them to a file (development.log).
The Broadcast logger is a logger used to write messages to multiple IO. It is commonly used
= Active Support Broadcast Logger

def <<(message)

def <<(message)
  dispatch { |logger| logger.<<(message) }
end

def add(*args, &block)

def add(*args, &block)
  dispatch { |logger| logger.add(*args, &block) }
end

def broadcast_to(*loggers)

broadcast_logger.broadcast_to(Logger.new(STDOUT), Logger.new(STDERR))
broadcast_logger = ActiveSupport::BroadcastLogger.new

Add logger(s) to the broadcast.
def broadcast_to(*loggers)
  @broadcasts.concat(loggers)
end

def close

def close
  dispatch { |logger| logger.close }
end

def debug(*args, &block)

def debug(*args, &block)
  dispatch { |logger| logger.debug(*args, &block) }
end

def debug!

Sets the log level to Logger::DEBUG for the whole broadcast.
def debug!
  dispatch { |logger| logger.debug! }
end

def debug?

to at least one broadcast. +False+ otherwise.
+True+ if the log level allows entries with severity Logger::DEBUG to be written
def debug?
  @broadcasts.any? { |logger| logger.debug? }
end

def dispatch(&block)

def dispatch(&block)
  @broadcasts.each { |logger| block.call(logger) }
end

def error(*args, &block)

def error(*args, &block)
  dispatch { |logger| logger.error(*args, &block) }
end

def error!

Sets the log level to Logger::ERROR for the whole broadcast.
def error!
  dispatch { |logger| logger.error! }
end

def error?

to at least one broadcast. +False+ otherwise.
+True+ if the log level allows entries with severity Logger::ERROR to be written
def error?
  @broadcasts.any? { |logger| logger.error? }
end

def fatal(*args, &block)

def fatal(*args, &block)
  dispatch { |logger| logger.fatal(*args, &block) }
end

def fatal!

Sets the log level to Logger::FATAL for the whole broadcast.
def fatal!
  dispatch { |logger| logger.fatal! }
end

def fatal?

to at least one broadcast. +False+ otherwise.
+True+ if the log level allows entries with severity Logger::FATAL to be written
def fatal?
  @broadcasts.any? { |logger| logger.fatal? }
end

def formatter=(formatter)

def formatter=(formatter)
  dispatch { |logger| logger.formatter = formatter }
  @formatter = formatter
end

def info(*args, &block)

def info(*args, &block)
  dispatch { |logger| logger.info(*args, &block) }
end

def info!

Sets the log level to Logger::INFO for the whole broadcast.
def info!
  dispatch { |logger| logger.info! }
end

def info?

to at least one broadcast. +False+ otherwise.
+True+ if the log level allows entries with severity Logger::INFO to be written
def info?
  @broadcasts.any? { |logger| logger.info? }
end

def initialize(*loggers)

def initialize(*loggers)
  @broadcasts = []
  @progname = "Broadcast"
  broadcast_to(*loggers)
end

def initialize_copy(other)

def initialize_copy(other)
  @broadcasts = []
  @progname = other.progname.dup
  @formatter = other.formatter.dup
  broadcast_to(*other.broadcasts.map(&:dup))
end

def level

def level
  @broadcasts.map(&:level).min
end

def level=(level)

def level=(level)
  dispatch { |logger| logger.level = level }
end

def local_level=(level)

def local_level=(level)
  dispatch do |logger|
    logger.local_level = level if logger.respond_to?(:local_level=)
  end
end

def method_missing(name, *args, **kwargs, &block)

def method_missing(name, *args, **kwargs, &block)
  loggers = @broadcasts.select { |logger| logger.respond_to?(name) }
  if loggers.none?
    super(name, *args, **kwargs, &block)
  elsif loggers.one?
    loggers.first.send(name, *args, **kwargs, &block)
  else
    loggers.map { |logger| logger.send(name, *args, **kwargs, &block) }
  end
end

def respond_to_missing?(method, include_all)

def respond_to_missing?(method, include_all)
  @broadcasts.any? { |logger| logger.respond_to?(method, include_all) }
end

def stop_broadcasting_to(logger)

broadcast_logger.stop_broadcasting_to(sink)

broadcast_logger = ActiveSupport::BroadcastLogger.new
sink = Logger.new(STDOUT)

the broadcast will no longer be written to its sink.
Remove a logger from the broadcast. When a logger is removed, messages sent to
def stop_broadcasting_to(logger)
  @broadcasts.delete(logger)
end

def unknown(*args, &block)

def unknown(*args, &block)
  dispatch { |logger| logger.unknown(*args, &block) }
end

def warn(*args, &block)

def warn(*args, &block)
  dispatch { |logger| logger.warn(*args, &block) }
end

def warn!

Sets the log level to Logger::WARN for the whole broadcast.
def warn!
  dispatch { |logger| logger.warn! }
end

def warn?

to at least one broadcast. +False+ otherwise.
+True+ if the log level allows entries with severity Logger::WARN to be written
def warn?
  @broadcasts.any? { |logger| logger.warn? }
end