class Daemons::SyslogIO

def self.syslog_constant(option)

@!visibility private
def self.syslog_constant(option)
  return unless option = syslog_constant_sym(option)
  return Syslog.constants.include?(option) ? Syslog.const_get(option) : nil
end

def self.syslog_constant_sym(option)

@!visibility private
def self.syslog_constant_sym(option)
  return unless option.is_a?(Symbol) or option.is_a?(String)
  option = option.to_s.upcase
  option = "LOG_#{option}" unless option[0..4] == 'LOG_'
  option = option.to_sym
  option
end

def self.syslog_facility(option)

@!visibility private
def self.syslog_facility(option)
  return unless option = syslog_constant_sym(option)
  return Syslog::Facility.constants.include?(option) ? Syslog.const_get(option) : nil
end

def self.syslog_level(option)

@!visibility private
def self.syslog_level(option)
  return unless option = syslog_constant_sym(option)
  return Syslog::Level.constants.include?(option) ? Syslog.const_get(option) : nil
end

def self.syslog_option(option)

@!visibility private
def self.syslog_option(option)
  return unless option = syslog_constant_sym(option)
  return Syslog::Option.constants.include?(option) ? Syslog.const_get(option) : nil
end

def crit(text)

Shorthand for {#log}(text, Syslog::LOG_CRIT)

Log at the critical level
def crit(text)
  log(text, Syslog::LOG_CRIT)
end

def debug(text)

Shorthand for {#log}(text, Syslog::LOG_DEBUG)

Log at the debug level
def debug(text)
  log(text, Syslog::LOG_DEBUG)
end

def emerg(text)

Shorthand for {#log}(text, Syslog::LOG_EMERG)

Log at the emergency level
def emerg(text)
  log(text, Syslog::LOG_EMERG)
end

def error(text)

Shorthand for {#log}(text, Syslog::LOG_ERR)

Log at the error level
def error(text)
  log(text, Syslog::LOG_ERR)
end

def flush

Immediately flush any buffered data
def flush
  syswrite(@buffer)
  @buffer = ''
end

def info(text)

Shorthand for {#log}(text, Syslog::LOG_INFO)

Log at the info level
def info(text)
  log(text, Syslog::LOG_INFO)
end

def initialize(*options)

Parameters:
  • passthrough (IO) -- IO passthrough
  • option (Fixnum) -- Syslog option
  • level (Fixnum) -- Syslog level
  • facility (Fixnum) -- Syslog facility
  • identifier (String) -- Identifier
def initialize(*options)
  options.each do |option|
    if option.is_a?(String)
      @ident = option
    elsif value = self.class.syslog_facility(option)
      @facility = value
    elsif value = self.class.syslog_level(option)
      @level = value
    elsif value = self.class.syslog_option(option)
      @options = 0 if @options.nil?
      @options |= value
    elsif option.is_a?(IO)
      @out = option
    else
      raise ArgumentError, "Unknown argument #{option.inspect}"
    end
  end
  @options ||= 0
  @ident ||= $0.sub(/.*\//, '')
  @facility ||= Syslog::LOG_USER
  @level ||= Syslog::LOG_INFO
  if Syslog.opened? then
    options = Syslog.options | @options
    @syslog = Syslog.reopen(@ident, options, @facility)
  else
    @syslog = Syslog.open(@ident, @options, @facility)
  end
  @subs = []
  @sync = false
  @buffer = ''
  at_exit { flush }
end

def isatty

false
def isatty
  false
end

def log(text, level = nil)

Similar to {#puts} but allows changing the log level for just this one message

Write a complete line at the specified log level
def log(text, level = nil)
  if priority.nil? then
    write(text.chomp + "\n")
  else
    priority_bkup = @priority
    #TODO fix this to be less ugly. Temporarily setting an instance variable is evil
    @priority = priority
    write(text.chomp + "\n")
    @priority = priority_bkup
  end
end

def noop(*args)

@!visibility private
def noop(*args)
end

def notice(text)

Shorthand for {#log}(text, Syslog::LOG_NOTICE)

Log at the notice level
def notice(text)
  log(text, Syslog::LOG_NOTICE)
end

def puts(*texts)

Similar to {#write} but appends a newline if not present.

Log a complete line
def puts(*texts)
  texts.each do |text|
    write(text.chomp + "\n")
  end
end

def sub_add(regex, replacement)

Parameters:
  • regex (Regex) --
def sub_add(regex, replacement)
  @subs << [regex, replacement]
end

def sync=(sync)

When false (default), output will be line buffered. For syslog this is optimal so the log entries are complete lines.

Enable or disable synchronous IO (buffering).
def sync=(sync)
  if sync != true and sync != false then
    raise ArgumentError, "sync must be true or false"
  end
  @sync = sync
  if sync == true then
    flush
  end
end

def syswrite(text)

Write to syslog directly, bypassing buffering if enabled.
def syswrite(text)
  begin
    @out.syswrite(text) if @out and !@out.closed?
  rescue SystemCallError => e
  end
  text.split(/\n/).each do |line|
    @subs.each do |sub|
      line.sub!(sub[0], sub[1])
    end
    if line == '' or line.match(/^\s*$/) then
      next
    end
    Syslog.log(@facility | @level, line)
  end
  nil
end

def warn(text)

Shorthand for {#log}(text, Syslog::LOG_WARNING)

Log at the warning level
def warn(text)
  log(text, Syslog::LOG_WARNING)
end

def write(text)

Write to syslog respecting the behavior of the {#sync} setting.
def write(text)
  if @sync then
    syswrite(text)
  else
    text.split(/(\n)/).each do |line|
      @buffer = @buffer + line.to_s
      if line == "\n" then
        flush
      end
    end
  end
end