|
| 1 | +# Created by Ari Brown on 2008-02-23. |
| 2 | +# For rubinius. All pwnage reserved. |
| 3 | + |
| 4 | +# ** Syslog(Module) |
| 5 | + |
| 6 | +# Included Modules: Syslog::Constants |
| 7 | + |
| 8 | +# require 'syslog' |
| 9 | + |
| 10 | +# A Simple wrapper for the UNIX syslog system calls that might be handy |
| 11 | +# if you're writing a server in Ruby. For the details of the syslog(8) |
| 12 | +# architecture and constants, see the syslog(3) manual page of your |
| 13 | +# platform. |
| 14 | +require 'ffi' |
| 15 | + |
| 16 | +if FFI::Platform::IS_WINDOWS |
| 17 | + raise LoadError, "Syslog not supported on this platform" |
| 18 | +end |
| 19 | + |
| 20 | +module Syslog |
| 21 | + module Constants |
| 22 | + Java::jnr.constants.platform.Syslog.values.each do |const| |
| 23 | + next if const.name == '__UNKNOWN_CONSTANT__' |
| 24 | + next if !const.defined? |
| 25 | + const_set const.name, const.value |
| 26 | + end |
| 27 | + end |
| 28 | + include Constants |
| 29 | + |
| 30 | + module Level |
| 31 | + if defined? Constants::LOG_EMERG |
| 32 | + LOG_EMERG = Constants::LOG_EMERG |
| 33 | + |
| 34 | + def emerg(*args) |
| 35 | + Syslog.log(LOG_EMERG, *args) |
| 36 | + end |
| 37 | + end |
| 38 | + if defined? Constants::LOG_ALERT |
| 39 | + LOG_ALERT = Constants::LOG_ALERT |
| 40 | + |
| 41 | + def alert(*args) |
| 42 | + Syslog.log(LOG_ALERT, *args) |
| 43 | + end |
| 44 | + end |
| 45 | + if defined? Constants::LOG_CRIT |
| 46 | + LOG_CRIT = Constants::LOG_CRIT |
| 47 | + |
| 48 | + def crit(*args) |
| 49 | + Syslog.log(LOG_CRIT, *args) |
| 50 | + end |
| 51 | + end |
| 52 | + if defined? Constants::LOG_ERR |
| 53 | + LOG_ERR = Constants::LOG_ERR |
| 54 | + |
| 55 | + def err(*args) |
| 56 | + Syslog.log(LOG_ERR, *args) |
| 57 | + end |
| 58 | + end |
| 59 | + if defined? Constants::LOG_WARNING |
| 60 | + LOG_WARNING = Constants::LOG_WARNING |
| 61 | + |
| 62 | + def warning(*args) |
| 63 | + Syslog.log(LOG_WARNING, *args) |
| 64 | + end |
| 65 | + end |
| 66 | + if defined? Constants::LOG_NOTICE |
| 67 | + LOG_NOTICE = Constants::LOG_NOTICE |
| 68 | + |
| 69 | + def notice(*args) |
| 70 | + Syslog.log(LOG_NOTICE, *args) |
| 71 | + end |
| 72 | + end |
| 73 | + if defined? Constants::LOG_INFO |
| 74 | + LOG_INFO = Constants::LOG_INFO |
| 75 | + |
| 76 | + def info(*args) |
| 77 | + Syslog.log(LOG_INFO, *args) |
| 78 | + end |
| 79 | + end |
| 80 | + if defined? Constants::LOG_DEBUG |
| 81 | + LOG_DEBUG = Constants::LOG_DEBUG |
| 82 | + |
| 83 | + def debug(*args) |
| 84 | + syslog_write(LOG_DEBUG, *args) |
| 85 | + end |
| 86 | + end |
| 87 | + end |
| 88 | + |
| 89 | + module Facility |
| 90 | + if defined? Constants::LOG_AUTH |
| 91 | + LOG_AUTH = Constants::LOG_AUTH |
| 92 | + end |
| 93 | + if defined? Constants::LOG_AUTHPRIV |
| 94 | + LOG_AUTHPRIV = Constants::LOG_AUTHPRIV |
| 95 | + end |
| 96 | + if defined? Constants::LOG_CONSOLE |
| 97 | + LOG_CONSOLE = Constants::LOG_CONSOLE |
| 98 | + end |
| 99 | + if defined? Constants::LOG_CRON |
| 100 | + LOG_CRON = Constants::LOG_CRON |
| 101 | + end |
| 102 | + if defined? Constants::LOG_DAEMON |
| 103 | + LOG_DAEMON = Constants::LOG_DAEMON |
| 104 | + end |
| 105 | + if defined? Constants::LOG_FTP |
| 106 | + LOG_FTP = Constants::LOG_FTP |
| 107 | + end |
| 108 | + if defined? Constants::LOG_KERN |
| 109 | + LOG_KERN = Constants::LOG_KERN |
| 110 | + end |
| 111 | + if defined? Constants::LOG_LPR |
| 112 | + LOG_LPR = Constants::LOG_LPR |
| 113 | + end |
| 114 | + if defined? Constants::LOG_MAIL |
| 115 | + LOG_MAIL = Constants::LOG_MAIL |
| 116 | + end |
| 117 | + if defined? Constants::LOG_NEWS |
| 118 | + LOG_NEWS = Constants::LOG_NEWS |
| 119 | + end |
| 120 | + if defined? Constants::LOG_NTP |
| 121 | + LOG_NTP = Constants::LOG_NTP |
| 122 | + end |
| 123 | + if defined? Constants::LOG_SECURITY |
| 124 | + LOG_SECURITY = Constants::LOG_SECURITY |
| 125 | + end |
| 126 | + if defined? Constants::LOG_SYSLOG |
| 127 | + LOG_SYSLOG = Constants::LOG_SYSLOG |
| 128 | + end |
| 129 | + if defined? Constants::LOG_USER |
| 130 | + LOG_USER = Constants::LOG_USER |
| 131 | + end |
| 132 | + if defined? Constants::LOG_UUCP |
| 133 | + LOG_UUCP = Constants::LOG_UUCP |
| 134 | + end |
| 135 | + if defined? Constants::LOG_LOCAL0 |
| 136 | + LOG_LOCAL0 = Constants::LOG_LOCAL0 |
| 137 | + end |
| 138 | + if defined? Constants::LOG_LOCAL1 |
| 139 | + LOG_LOCAL1 = Constants::LOG_LOCAL1 |
| 140 | + end |
| 141 | + if defined? Constants::LOG_LOCAL2 |
| 142 | + LOG_LOCAL2 = Constants::LOG_LOCAL2 |
| 143 | + end |
| 144 | + if defined? Constants::LOG_LOCAL3 |
| 145 | + LOG_LOCAL3 = Constants::LOG_LOCAL3 |
| 146 | + end |
| 147 | + if defined? Constants::LOG_LOCAL4 |
| 148 | + LOG_LOCAL4 = Constants::LOG_LOCAL4 |
| 149 | + end |
| 150 | + if defined? Constants::LOG_LOCAL5 |
| 151 | + LOG_LOCAL5 = Constants::LOG_LOCAL5 |
| 152 | + end |
| 153 | + if defined? Constants::LOG_LOCAL6 |
| 154 | + LOG_LOCAL6 = Constants::LOG_LOCAL6 |
| 155 | + end |
| 156 | + if defined? Constants::LOG_LOCAL7 |
| 157 | + LOG_LOCAL7 = Constants::LOG_LOCAL7 |
| 158 | + end |
| 159 | + end |
| 160 | + |
| 161 | + module Foreign |
| 162 | + extend FFI::Library |
| 163 | + ffi_lib FFI::Platform::LIBC |
| 164 | + |
| 165 | + # methods |
| 166 | + attach_function :open, "openlog", [:pointer, :int, :int], :void |
| 167 | + attach_function :close, "closelog", [], :void |
| 168 | + attach_function :write, "syslog", [:int, :string, :varargs], :void |
| 169 | + attach_function :set_mask, "setlogmask", [:int], :int |
| 170 | + end |
| 171 | + |
| 172 | + class << self |
| 173 | + |
| 174 | + ## |
| 175 | + # returns the ident of the last open call |
| 176 | + def ident |
| 177 | + @opened ? @ident : nil |
| 178 | + end |
| 179 | + |
| 180 | + ## |
| 181 | + # returns the options of the last open call |
| 182 | + def options |
| 183 | + @opened ? @options : nil |
| 184 | + end |
| 185 | + |
| 186 | + ## |
| 187 | + # returns the facility of the last open call |
| 188 | + def facility |
| 189 | + @opened ? @facility : nil |
| 190 | + end |
| 191 | + |
| 192 | + ## |
| 193 | + # mask |
| 194 | + # mask=(mask) |
| 195 | + # |
| 196 | + # Returns or sets the log priority mask. The value of the mask |
| 197 | + # is persistent and will not be reset by Syslog::open or |
| 198 | + # Syslog::close. |
| 199 | + # |
| 200 | + # Example: |
| 201 | + # Syslog.mask = Syslog::LOG_UPTO(Syslog::LOG_ERR) |
| 202 | + def mask |
| 203 | + @mask ||= -1 |
| 204 | + @opened ? @mask : nil |
| 205 | + end |
| 206 | + attr_writer :mask |
| 207 | + |
| 208 | + ## |
| 209 | + # open(ident = $0, logopt = Syslog::LOG_PID | Syslog::LOG_CONS, facility = Syslog::LOG_USER) [{ |syslog| ... }] |
| 210 | + # |
| 211 | + # Opens syslog with the given options and returns the module |
| 212 | + # itself. If a block is given, calls it with an argument of |
| 213 | + # itself. If syslog is already opened, raises RuntimeError. |
| 214 | + # |
| 215 | + # Examples: |
| 216 | + # Syslog.open('ftpd', Syslog::LOG_PID | Syslog::LOG_NDELAY, Syslog::LOG_FTP) |
| 217 | + # open!(ident = $0, logopt = Syslog::LOG_PID | Syslog::LOG_CONS, facility = Syslog::LOG_USER) |
| 218 | + # reopen(ident = $0, logopt = Syslog::LOG_PID | Syslog::LOG_CONS, facility = Syslog::LOG_USER) |
| 219 | + def open(ident=nil, opt=nil, fac=nil) |
| 220 | + raise "Syslog already open" unless not @opened |
| 221 | + |
| 222 | + ident ||= $0 |
| 223 | + opt ||= Constants::LOG_PID | Constants::LOG_CONS |
| 224 | + fac ||= Constants::LOG_USER |
| 225 | + |
| 226 | + @ident = ident |
| 227 | + @options = opt |
| 228 | + @facility = fac |
| 229 | + @ident_memory = if ident |
| 230 | + FFI::MemoryPointer.from_string(ident) |
| 231 | + else |
| 232 | + nil |
| 233 | + end |
| 234 | + Foreign.open(@ident_memory, opt, fac) |
| 235 | + |
| 236 | + @opened = true |
| 237 | + |
| 238 | + # Calling set_mask twice is the standard way to set the 'default' mask |
| 239 | + @mask = Foreign.set_mask(0) |
| 240 | + Foreign.set_mask(@mask) |
| 241 | + |
| 242 | + if block_given? |
| 243 | + begin |
| 244 | + yield self |
| 245 | + ensure |
| 246 | + close |
| 247 | + end |
| 248 | + end |
| 249 | + |
| 250 | + self |
| 251 | + end |
| 252 | + |
| 253 | + ## |
| 254 | + # like open, but closes it first |
| 255 | + def reopen(*args, &block) |
| 256 | + close |
| 257 | + open(*args, &block) |
| 258 | + end |
| 259 | + |
| 260 | + alias_method :open!, :reopen |
| 261 | + |
| 262 | + ## |
| 263 | + # Is it open? |
| 264 | + def opened? |
| 265 | + @opened || false |
| 266 | + end |
| 267 | + |
| 268 | + ## |
| 269 | + # Close the log |
| 270 | + # close will raise an error if it is already closed |
| 271 | + def close |
| 272 | + raise "Syslog not opened" unless @opened |
| 273 | + |
| 274 | + Foreign.close |
| 275 | + @ident = nil |
| 276 | + @options = @facility = @mask = -1; |
| 277 | + @opened = false |
| 278 | + end |
| 279 | + |
| 280 | + ## |
| 281 | + # log(Syslog::LOG_CRIT, "The %s is falling!", "sky") |
| 282 | + # |
| 283 | + # Doesn't take any platform specific printf statements |
| 284 | + # logs things to $stderr |
| 285 | + # log(Syslog::LOG_CRIT, "Welcome, %s, to my %s!", "leethaxxor", "lavratory") |
| 286 | + def log(pri, *args) |
| 287 | + write(pri, *args) |
| 288 | + end |
| 289 | + |
| 290 | + ## |
| 291 | + # handy little shortcut for LOG_EMERG as the priority |
| 292 | + def emerg(*args); write(Syslog::LOG_EMERG, *args); end |
| 293 | + |
| 294 | + ## |
| 295 | + # handy little shortcut for LOG_ALERT as the priority |
| 296 | + def alert(*args); write(Syslog::LOG_ALERT, *args); end |
| 297 | + |
| 298 | + ## |
| 299 | + # handy little shortcut for LOG_ERR as the priority |
| 300 | + def err(*args); write(Syslog::LOG_ERR, *args); end |
| 301 | + |
| 302 | + ## |
| 303 | + # handy little shortcut for LOG_CRIT as the priority |
| 304 | + def crit(*args); write(Syslog::LOG_CRIT, *args); end |
| 305 | + |
| 306 | + ## |
| 307 | + # handy little shortcut for LOG_WARNING as the priority |
| 308 | + def warning(*args);write(Syslog::LOG_WARNING, *args); end |
| 309 | + |
| 310 | + ## |
| 311 | + # handy little shortcut for LOG_NOTICE as the priority |
| 312 | + def notice(*args); write(Syslog::LOG_NOTICE, *args); end |
| 313 | + |
| 314 | + ## |
| 315 | + # handy little shortcut for LOG_INFO as the priority |
| 316 | + def info(*args); write(Syslog::LOG_INFO, *args); end |
| 317 | + |
| 318 | + ## |
| 319 | + # handy little shortcut for LOG_DEBUG as the priority |
| 320 | + def debug(*args); write(Syslog::LOG_DEBUG, *args); end |
| 321 | + |
| 322 | + ## |
| 323 | + # LOG_MASK(pri) |
| 324 | + # |
| 325 | + # HACK copied from macro |
| 326 | + # Creates a mask for one priority. |
| 327 | + def LOG_MASK(pri) |
| 328 | + 1 << pri |
| 329 | + end |
| 330 | + |
| 331 | + ## |
| 332 | + # LOG_UPTO(pri) |
| 333 | + # HACK copied from macro |
| 334 | + # Creates a mask for all priorities up to pri. |
| 335 | + def LOG_UPTO(pri) |
| 336 | + (1 << ((pri)+1)) - 1 |
| 337 | + end |
| 338 | + |
| 339 | + def inspect |
| 340 | + if @opened |
| 341 | + "<#%s: opened=true, ident=\"%s\", options=%d, facility=%d, mask=%d>" % |
| 342 | + [self.name, @ident, @options, @facility, @mask] |
| 343 | + else |
| 344 | + "<##{self.name}: opened=false>" |
| 345 | + end |
| 346 | + end |
| 347 | + |
| 348 | + ## |
| 349 | + # Syslog.instance # => Syslog |
| 350 | + # Returns the Syslog module |
| 351 | + def instance |
| 352 | + self |
| 353 | + end |
| 354 | + |
| 355 | + FORMAT_STRING = '%s' |
| 356 | + def write(pri, format, *args) |
| 357 | + raise "Syslog must be opened before write" unless @opened |
| 358 | + |
| 359 | + message = format % args |
| 360 | + Foreign.write(pri, FORMAT_STRING, :string, message, :pointer, nil) |
| 361 | + end |
| 362 | + private :write |
| 363 | + end |
| 364 | +end |
0 commit comments