class SysLogger::Formatter::RFC5424

Constants

FACILITIES
Format
SEVERITIES

Attributes

appname[RW]
msgid[R]
procid[RW]

Public Class Methods

new(appname = nil, procid = nil, msgid = nil, facility = nil) click to toggle source
Calls superclass method
# File lib/syslogger/formatter/rfc5424.rb, line 49
def initialize(appname = nil, procid = nil, msgid = nil, facility = nil)
  super()

  @counter = 0

  @hostname = Socket.gethostname
  @msgid = format_field(msgid, 32)
  @procid = procid
  @appname = appname

  self.facility = facility || :local7
end

Public Instance Methods

call(severity, datetime, progname, message) click to toggle source
# File lib/syslogger/formatter/rfc5424.rb, line 70
def call(severity, datetime, progname, message)
  severity = SEVERITIES[severity.to_s.downcase.to_sym] || SEVERITIES[:info]
  pri = (facility << 3) | severity

  # Since we're using RFC5424 format, it makes more sense to use the
  # passed in progname as the msgid rather than changing the appname when
  # a block was received to generate the message.
  message_id = progname.nil? ? msgid : format_field(progname, 32)

  structured_data = {
    "meta" => {
      "x-group" => gen_xgroup,
      "x-counter" => @counter
    }
  }

  lines = msg2str(message).split(/\r?\n/).reject(&:empty?).map do |line|
    @counter = (@counter + 1) % 65536
    structured_data["meta"]["x-counter"] = @counter
    sd = format_sdata(structured_data)
    Format % [pri, datetime.strftime("%FT%T.%6N%:z"), @hostname,
              format_field(@appname, 48), format_field(@procid || Process.pid.to_s, 128),
              message_id, sd, line]
  end
  if lines.size == 1
    lines[0]
  else
    lines
  end
end
facility() click to toggle source
# File lib/syslogger/formatter/rfc5424.rb, line 62
def facility
  @facility
end
facility=(f) click to toggle source
# File lib/syslogger/formatter/rfc5424.rb, line 66
def facility=(f)
  @facility = FACILITIES[f.to_s.downcase.to_sym] || @facility
end

Private Instance Methods

format_field(text, max_length) click to toggle source
# File lib/syslogger/formatter/rfc5424.rb, line 106
def format_field(text, max_length)
  if text
    text[0..max_length].gsub(/\s+/, '')
  else
    '-'
  end
end
format_sdata(sdata) click to toggle source
# File lib/syslogger/formatter/rfc5424.rb, line 114
def format_sdata(sdata)
  if sdata.empty?
    '-'
  end
  # TODO clean up of SD-NAMe and PARAM-VALUE is kind of brute force
  #      here, could be done better per RFC5424
  r = []
  sdata.each { |sid, hash|
    s = []
    s.push(sid.to_s.gsub(/[^-\w]/, ""))
    hash.each { |n, v|
      paramname = n.to_s.gsub(/[^-\w]/, "")
      paramvalue = v.to_s.gsub(/[\]"=]/, "")
      s.push("#{paramname}=\"#{paramvalue}\"")
    }
    r.push("["+s.join(" ")+"]")
  }
  rx = []
  r.each { |x|
    rx.push("[#{x}]")
  }
  r.join("")
end
gen_xgroup() click to toggle source
# File lib/syslogger/formatter/rfc5424.rb, line 102
def gen_xgroup
  rand(99999999)
end
msg2str(msg) click to toggle source
# File lib/syslogger/formatter/rfc5424.rb, line 138
def msg2str(msg)
  case msg
    when ::String
      msg
    when ::Exception
      "#{ msg.message } (#{ msg.class })\n" <<
        (msg.backtrace || []).join("\n")
    else
      msg.inspect
  end
end