Class: Daemons::SyslogIO

Inherits:
Object
  • Object
show all
Defined in:
lib/daemons/syslogio.rb

Overview

This is a simple class meant to allow using syslog through an IO-like object. Code borrowed from github.com/phemmer/ruby-syslogio

The usage is simple:

require 'syslogio'
$stdout = SyslogIO.new("myapp", :local0, :info, $stdout)
$stderr = SyslogIO.new("myapp", :local0, :err, $stderr)
$stdout.puts "This is a message"
$stderr.puts "This is an error"
raise StandardError, 'This will get written through the SyslogIO for $stderr'

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*options) ⇒ SyslogIO

Creates a new object. You can have as many SyslogIO objects as you like. However because they all share the same syslog connection, some parameters are shared. The identifier shared among all SyslogIO objects, and is set to the value of the last one created. The Syslog options are merged together as a combination of all objects. The facility and level are distinct between each though. If an IO object is provided as an argument, any text written to the SyslogIO object will also be passed through to that IO object.

Parameters:

  • identifier (String)

    Identifier

  • facility (Fixnum<Syslog::Facility>)

    Syslog facility

  • level (Fixnum<Syslog::Level>)

    Syslog level

  • option (Fixnum<Syslog::Options>)

    Syslog option

  • passthrough (IO)

    IO passthrough


58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/daemons/syslogio.rb', line 58

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

Instance Attribute Details

#syncBoolean

Indicates whether synchonous IO is enabled.

Returns:

  • (Boolean)

18
19
20
# File 'lib/daemons/syslogio.rb', line 18

def sync
  @sync
end

Instance Method Details

#crit(text) ⇒ Object Also known as: fatal

Log at the critical level

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


195
196
197
# File 'lib/daemons/syslogio.rb', line 195

def crit(text)
  log(text, Syslog::LOG_CRIT)
end

#debug(text) ⇒ Object

Log at the debug level

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


159
160
161
# File 'lib/daemons/syslogio.rb', line 159

def debug(text)
  log(text, Syslog::LOG_DEBUG)
end

#emerg(text) ⇒ Object

Log at the emergency level

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


203
204
205
# File 'lib/daemons/syslogio.rb', line 203

def emerg(text)
  log(text, Syslog::LOG_EMERG)
end

#error(text) ⇒ Object

Log at the error level

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


188
189
190
# File 'lib/daemons/syslogio.rb', line 188

def error(text)
  log(text, Syslog::LOG_ERR)
end

#flushObject

Immediately flush any buffered data


151
152
153
154
# File 'lib/daemons/syslogio.rb', line 151

def flush
  syswrite(@buffer)
  @buffer = ''
end

#info(text) ⇒ Object

Log at the info level

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


166
167
168
# File 'lib/daemons/syslogio.rb', line 166

def info(text)
  log(text, Syslog::LOG_INFO)
end

#isattyObject

false


237
238
239
# File 'lib/daemons/syslogio.rb', line 237

def isatty
  false
end

#log(text, level = nil) ⇒ Object

Write a complete line at the specified log level

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


219
220
221
222
223
224
225
226
227
228
229
# File 'lib/daemons/syslogio.rb', line 219

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

#notice(text) ⇒ Object Also known as: notify

Log at the notice level

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


173
174
175
# File 'lib/daemons/syslogio.rb', line 173

def notice(text)
  log(text, Syslog::LOG_NOTICE)
end

#puts(*texts) ⇒ Object

Log a complete line

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


210
211
212
213
214
# File 'lib/daemons/syslogio.rb', line 210

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

#sub_add(regex, replacement) ⇒ Object

Add a substitution rule

These substitutions will be applied to each line before it is logged. This can be useful if some other gem is generating log content and you want to change the formatting.

Parameters:

  • regex (Regex)

99
100
101
# File 'lib/daemons/syslogio.rb', line 99

def sub_add(regex, replacement)
  @subs << [regex, replacement]
end

#syswrite(text) ⇒ Object

Write to syslog directly, bypassing buffering if enabled.


132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/daemons/syslogio.rb', line 132

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

#warn(text) ⇒ Object

Log at the warning level

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


181
182
183
# File 'lib/daemons/syslogio.rb', line 181

def warn(text)
  log(text, Syslog::LOG_WARNING)
end

#write(text) ⇒ Object Also known as: <<

Write to syslog respecting the behavior of the #sync setting.


117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/daemons/syslogio.rb', line 117

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