class Zlogger::Daemon

Constants

FLUSH_TIMER

Attributes

log_date[RW]
options[R]
output_file[RW]

Public Class Methods

new(options={}) click to toggle source
# File lib/zlogger/daemon.rb, line 14
def initialize(options={})
  @options = options
  if options[:output]
    @log_date = Date.today
    @output_file = File.new(output_filepath, 'a+')
  end
end

Public Instance Methods

bind_address() click to toggle source
# File lib/zlogger/daemon.rb, line 64
def bind_address
  options[:bind_address] ||= "0.0.0.0"
end
context() click to toggle source
# File lib/zlogger/daemon.rb, line 56
def context
  @context ||= (ZMQ.context || ZMQ::Context.new)
end
flush() click to toggle source

flush the output file only if enough elapsed time has occurred since the last flush. We want the log capture to be responsive, and reduce the amount of time waiting for synchronous disk i/o.

# File lib/zlogger/daemon.rb, line 114
def flush
  if output
    now = Time.now
    if @last_flush.nil? || (now - @last_flush > FLUSH_TIMER)
      output.flush
      @last_flush = now
    end
  end
end
log(prefix, line) click to toggle source
# File lib/zlogger/daemon.rb, line 105
def log(prefix, line)
  formatted = "#{Time.now.strftime("%Y%m%d %I:%M:%S.%L")}\t#{prefix}:\t#{line}"
  output.puts(formatted)
  $stdout.puts(formatted) if options[:stdout] && options[:output]
  pub_socket.send(formatted)
end
output() click to toggle source
# File lib/zlogger/daemon.rb, line 68
def output
  output_file || $stdout
end
output_filepath() click to toggle source
# File lib/zlogger/daemon.rb, line 72
def output_filepath
  filename = options[:output]
  file_extension = File.extname(filename)
  filename = filename.gsub(file_extension, "") unless file_extension == ""
  if options[:rotate]
    filename = "#{ filename }_#{ log_date.to_s }.log"
  else
    filename = "#{ filename }.log"
  end
  Pathname.new(filename).to_s
end
port() click to toggle source
# File lib/zlogger/daemon.rb, line 60
def port
  options[:port] ||= DEFAULT_PORT
end
pub_socket() click to toggle source
# File lib/zlogger/daemon.rb, line 97
def pub_socket
  @pub_socket ||= begin
    socket = context.socket :PUB
    socket.bind("tcp://#{bind_address}:#{port.to_i + 1}")
    socket
  end
end
rotate_file() click to toggle source
# File lib/zlogger/daemon.rb, line 84
def rotate_file
  if self.log_date < Date.today

    self.log_date = Date.today

    # closes previous day file
    self.output_file.close if output_file # just a fail safe in case that for some reason the output file is nil

    # assigns file for the new day to output_file attribute
    self.output_file = File.new(output_filepath, 'a+')
  end
end
run() click to toggle source
# File lib/zlogger/daemon.rb, line 22
def run
  socket = context.socket :SUB
  socket.subscribe ""
  socket.bind("tcp://#{bind_address}:#{port}")

  poll_item = ZMQ::Pollitem(socket, ZMQ::POLLIN)
  poller = ZMQ::Poller.new
  poller.register(poll_item)

  loop do
    begin
      rotate_file if options[:rotate]

      poller.poll(FLUSH_TIMER)
      if poller.readables.include?(socket)
        message = socket.recv_message
        prefix = message.pop.to_s
        buffer = message.pop.to_s
        buffer.gsub("\r\n", "\n")
        buffer.split("\n").each do |line|
          log(prefix, line)
        end
      end

      flush

    rescue Interrupt
      break
    rescue StandardError => e
      log("ZLOGGER::DAEMON", e.to_s)
    end
  end
end