Ruby 2.0.0p247(2013-06-27revision41674)

- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

syslog.c
Go to the documentation of this file.
1 /*
2 * UNIX Syslog extension for Ruby
3 * Amos Gouaux, University of Texas at Dallas
4 * <amos+ruby@utdallas.edu>
5 * Documented by mathew <meta@pobox.com>
6 *
7 * $RoughId: syslog.c,v 1.21 2002/02/25 12:21:17 knu Exp $
8 * $Id: syslog.c 35739 2012-05-21 07:18:49Z knu $
9 */
10
11 #include "ruby/ruby.h"
12 #include "ruby/util.h"
13 #include <syslog.h>
14
15 /* Syslog class */
16 static VALUE mSyslog;
17 /*
18 * Module holding all Syslog constants. See Syslog::log and
19 * Syslog::open for constant descriptions.
20 */
21 static VALUE mSyslogConstants;
22 /* Module holding Syslog option constants */
23 static VALUE mSyslogOption;
24 /* Module holding Syslog facility constants */
25 static VALUE mSyslogFacility;
26 /* Module holding Syslog level constants */
27 static VALUE mSyslogLevel;
28 /* Module holding Syslog utility macros */
29 static VALUE mSyslogMacros;
30
31 static const char *syslog_ident = NULL;
32 static int syslog_options = -1, syslog_facility = -1, syslog_mask = -1;
33 static int syslog_opened = 0;
34
35 /* Package helper routines */
36 static void syslog_write(int pri, int argc, VALUE *argv)
37 {
38 VALUE str;
39
40 rb_secure(4);
41 if (argc < 1) {
42 rb_raise(rb_eArgError, "no log message supplied");
43 }
44
45 if (!syslog_opened) {
46 rb_raise(rb_eRuntimeError, "must open syslog before write");
47 }
48
49 str = rb_f_sprintf(argc, argv);
50
51 syslog(pri, "%s", RSTRING_PTR(str));
52 }
53
54 /* Closes the syslog facility.
55 * Raises a runtime exception if it is not open.
56 */
57 static VALUE mSyslog_close(VALUE self)
58 {
59 rb_secure(4);
60 if (!syslog_opened) {
61 rb_raise(rb_eRuntimeError, "syslog not opened");
62 }
63
64 closelog();
65
66 xfree((void *)syslog_ident);
67 syslog_ident = NULL;
68 syslog_options = syslog_facility = syslog_mask = -1;
69 syslog_opened = 0;
70
71 return Qnil;
72 }
73
74 /* call-seq:
75 * open(ident, options, facility) => syslog
76 *
77 * :yields: syslog
78 *
79 * Open the syslog facility.
80 * Raises a runtime exception if it is already open.
81 *
82 * Can be called with or without a code block. If called with a block, the
83 * Syslog object created is passed to the block.
84 *
85 * If the syslog is already open, raises a RuntimeError.
86 *
87 * +ident+ is a String which identifies the calling program.
88 *
89 * +options+ is the logical OR of any of the following:
90 *
91 * LOG_CONS:: If there is an error while sending to the system logger,
92 * write directly to the console instead.
93 *
94 * LOG_NDELAY:: Open the connection now, rather than waiting for the first
95 * message to be written.
96 *
97 * LOG_NOWAIT:: Don't wait for any child processes created while logging
98 * messages. (Has no effect on Linux.)
99 *
100 * LOG_ODELAY:: Opposite of LOG_NDELAY; wait until a message is sent before
101 * opening the connection. (This is the default.)
102 *
103 * LOG_PERROR:: Print the message to stderr as well as sending it to syslog.
104 * (Not in POSIX.1-2001.)
105 *
106 * LOG_PID:: Include the current process ID with each message.
107 *
108 * +facility+ describes the type of program opening the syslog, and is
109 * the logical OR of any of the following which are defined for the host OS:
110 *
111 * LOG_AUTH:: Security or authorization. Deprecated, use LOG_AUTHPRIV
112 * instead.
113 *
114 * LOG_AUTHPRIV:: Security or authorization messages which should be kept
115 * private.
116 *
117 * LOG_CONSOLE:: System console message.
118 *
119 * LOG_CRON:: System task scheduler (cron or at).
120 *
121 * LOG_DAEMON:: A system daemon which has no facility value of its own.
122 *
123 * LOG_FTP:: An FTP server.
124 *
125 * LOG_KERN:: A kernel message (not sendable by user processes, so not of
126 * much use to Ruby, but listed here for completeness).
127 *
128 * LOG_LPR:: Line printer subsystem.
129 *
130 * LOG_MAIL:: Mail delivery or transport subsystem.
131 *
132 * LOG_NEWS:: Usenet news system.
133 *
134 * LOG_NTP:: Network Time Protocol server.
135 *
136 * LOG_SECURITY:: General security message.
137 *
138 * LOG_SYSLOG:: Messages generated internally by syslog.
139 *
140 * LOG_USER:: Generic user-level message.
141 *
142 * LOG_UUCP:: UUCP subsystem.
143 *
144 * LOG_LOCAL0 to LOG_LOCAL7:: Locally-defined facilities.
145 *
146 * Example:
147 *
148 * Syslog.open("webrick", Syslog::LOG_PID,
149 * Syslog::LOG_DAEMON | Syslog::LOG_LOCAL3)
150 *
151 */
152 static VALUE mSyslog_open(int argc, VALUE *argv, VALUE self)
153 {
154 VALUE ident, opt, fac;
155
156 if (syslog_opened) {
157 rb_raise(rb_eRuntimeError, "syslog already open");
158 }
159
160 rb_scan_args(argc, argv, "03", &ident, &opt, &fac);
161
162 if (NIL_P(ident)) {
163 ident = rb_gv_get("$0");
164 }
165 SafeStringValue(ident);
166 syslog_ident = strdup(RSTRING_PTR(ident));
167
168 if (NIL_P(opt)) {
169 syslog_options = LOG_PID | LOG_CONS;
170 } else {
171 syslog_options = NUM2INT(opt);
172 }
173
174 if (NIL_P(fac)) {
175 syslog_facility = LOG_USER;
176 } else {
177 syslog_facility = NUM2INT(fac);
178 }
179
180 openlog(syslog_ident, syslog_options, syslog_facility);
181
182 syslog_opened = 1;
183
184 setlogmask(syslog_mask = setlogmask(0));
185
186 /* be like File.new.open {...} */
187 if (rb_block_given_p()) {
188 rb_ensure(rb_yield, self, mSyslog_close, self);
189 }
190
191 return self;
192 }
193
194 /* call-seq:
195 * reopen(ident, options, facility) => syslog
196 *
197 * :yields: syslog
198 *
199 * Closes and then reopens the syslog.
200 *
201 * Arguments are the same as for open().
202 */
203 static VALUE mSyslog_reopen(int argc, VALUE *argv, VALUE self)
204 {
205 mSyslog_close(self);
206
207 return mSyslog_open(argc, argv, self);
208 }
209
210 /* call-seq:
211 * opened?
212 *
213 * Returns true if the syslog is open.
214 */
215 static VALUE mSyslog_isopen(VALUE self)
216 {
217 return syslog_opened ? Qtrue : Qfalse;
218 }
219
220 /* Returns the identity string used in the last call to open()
221 */
222 static VALUE mSyslog_ident(VALUE self)
223 {
224 return syslog_opened ? rb_str_new2(syslog_ident) : Qnil;
225 }
226
227 /* Returns the options bitmask used in the last call to open()
228 */
229 static VALUE mSyslog_options(VALUE self)
230 {
231 return syslog_opened ? INT2NUM(syslog_options) : Qnil;
232 }
233
234 /* Returns the facility number used in the last call to open()
235 */
236 static VALUE mSyslog_facility(VALUE self)
237 {
238 return syslog_opened ? INT2NUM(syslog_facility) : Qnil;
239 }
240
241 /* Returns the log priority mask in effect. The mask is not reset by opening
242 * or closing syslog.
243 */
244 static VALUE mSyslog_get_mask(VALUE self)
245 {
246 return syslog_opened ? INT2NUM(syslog_mask) : Qnil;
247 }
248
249 /* call-seq:
250 * mask=(priority_mask)
251 *
252 * Sets the log priority mask. A method LOG_UPTO is defined to make it easier
253 * to set mask values. Example:
254 *
255 * Syslog.mask = Syslog::LOG_UPTO(Syslog::LOG_ERR)
256 *
257 * Alternatively, specific priorities can be selected and added together using
258 * binary OR. Example:
259 *
260 * Syslog.mask = Syslog::LOG_MASK(Syslog::LOG_ERR) | Syslog::LOG_MASK(Syslog::LOG_CRIT)
261 *
262 * The priority mask persists through calls to open() and close().
263 */
264 static VALUE mSyslog_set_mask(VALUE self, VALUE mask)
265 {
266 rb_secure(4);
267 if (!syslog_opened) {
268 rb_raise(rb_eRuntimeError, "must open syslog before setting log mask");
269 }
270
271 setlogmask(syslog_mask = NUM2INT(mask));
272
273 return mask;
274 }
275
276 /* call-seq:
277 * log(priority, format_string, *format_args)
278 *
279 * Log a message with the specified priority. Example:
280 *
281 * Syslog.log(Syslog::LOG_CRIT, "Out of disk space")
282 * Syslog.log(Syslog::LOG_CRIT, "User %s logged in", ENV['USER'])
283 *
284 * The priority levels, in descending order, are:
285 *
286 * LOG_EMERG:: System is unusable
287 * LOG_ALERT:: Action needs to be taken immediately
288 * LOG_CRIT:: A critical condition has occurred
289 * LOG_ERR:: An error occurred
290 * LOG_WARNING:: Warning of a possible problem
291 * LOG_NOTICE:: A normal but significant condition occurred
292 * LOG_INFO:: Informational message
293 * LOG_DEBUG:: Debugging information
294 *
295 * Each priority level also has a shortcut method that logs with it's named priority.
296 * As an example, the two following statements would produce the same result:
297 *
298 * Syslog.log(Syslog::LOG_ALERT, "Out of memory")
299 * Syslog.alert("Out of memory")
300 *
301 * Format strings are as for printf/sprintf, except that in addition %m is
302 * replaced with the error message string that would be returned by
303 * strerror(errno).
304 *
305 */
306 static VALUE mSyslog_log(int argc, VALUE *argv, VALUE self)
307 {
308 VALUE pri;
309
310 if (argc < 2) {
311 rb_raise(rb_eArgError, "wrong number of arguments (%d for 2+)", argc);
312 }
313
314 argc--;
315 pri = *argv++;
316
317 if (!FIXNUM_P(pri)) {
318 rb_raise(rb_eTypeError, "type mismatch: %s given", rb_class2name(CLASS_OF(pri)));
319 }
320
321 syslog_write(FIX2INT(pri), argc, argv);
322
323 return self;
324 }
325
326 /* Returns an inspect() string summarizing the object state.
327 */
328 static VALUE mSyslog_inspect(VALUE self)
329 {
330 Check_Type(self, T_MODULE);
331
332 if (!syslog_opened)
333 return rb_sprintf("<#%s: opened=false>", rb_class2name(self));
334
335 return rb_sprintf("<#%s: opened=true, ident=\"%s\", options=%d, facility=%d, mask=%d>",
336 rb_class2name(self),
337 syslog_ident,
338 syslog_options,
339 syslog_facility,
340 syslog_mask);
341 }
342
343 /* Returns self, for backward compatibility.
344 */
345 static VALUE mSyslog_instance(VALUE self)
346 {
347 return self;
348 }
349
350 #define define_syslog_shortcut_method(pri, name) \
351 static VALUE mSyslog_##name(int argc, VALUE *argv, VALUE self) \
352 { \
353 syslog_write((pri), argc, argv); \
354 \
355 return self; \
356 }
357
358 #ifdef LOG_EMERG
359 define_syslog_shortcut_method(LOG_EMERG, emerg)
360 #endif
361 #ifdef LOG_ALERT
362 define_syslog_shortcut_method(LOG_ALERT, alert)
363 #endif
364 #ifdef LOG_CRIT
365 define_syslog_shortcut_method(LOG_CRIT, crit)
366 #endif
367 #ifdef LOG_ERR
368 define_syslog_shortcut_method(LOG_ERR, err)
369 #endif
370 #ifdef LOG_WARNING
371 define_syslog_shortcut_method(LOG_WARNING, warning)
372 #endif
373 #ifdef LOG_NOTICE
374 define_syslog_shortcut_method(LOG_NOTICE, notice)
375 #endif
376 #ifdef LOG_INFO
377 define_syslog_shortcut_method(LOG_INFO, info)
378 #endif
379 #ifdef LOG_DEBUG
380 define_syslog_shortcut_method(LOG_DEBUG, debug)
381 #endif
382
383 /* call-seq:
384 * LOG_MASK(priority_level) => priority_mask
385 *
386 * Generates a mask bit for a priority level. See #mask=
387 */
388 static VALUE mSyslogMacros_LOG_MASK(VALUE mod, VALUE pri)
389 {
390 return INT2FIX(LOG_MASK(NUM2INT(pri)));
391 }
392
393 /* call-seq:
394 * LOG_UPTO(priority_level) => priority_mask
395 *
396 * Generates a mask value for priority levels at or below the level specified.
397 * See #mask=
398 */
399 static VALUE mSyslogMacros_LOG_UPTO(VALUE mod, VALUE pri)
400 {
401 return INT2FIX(LOG_UPTO(NUM2INT(pri)));
402 }
403
404 static VALUE mSyslogMacros_included(VALUE mod, VALUE target)
405 {
406 rb_extend_object(target, mSyslogMacros);
407 return mod;
408 }
409
410 /* The syslog package provides a Ruby interface to the POSIX system logging
411 * facility.
412 *
413 * Syslog messages are typically passed to a central logging daemon.
414 * The daemon may filter them; route them into different files (usually
415 * found under /var/log); place them in SQL databases; forward
416 * them to centralized logging servers via TCP or UDP; or even alert the
417 * system administrator via email, pager or text message.
418 *
419 * Unlike application-level logging via Logger or Log4r, syslog is designed
420 * to allow secure tamper-proof logging.
421 *
422 * The syslog protocol is standardized in RFC 5424.
423 */
424 void Init_syslog()
425 {
426 mSyslog = rb_define_module("Syslog");
427
428 mSyslogConstants = rb_define_module_under(mSyslog, "Constants");
429
430 mSyslogOption = rb_define_module_under(mSyslog, "Option");
431 mSyslogFacility = rb_define_module_under(mSyslog, "Facility");
432 mSyslogLevel = rb_define_module_under(mSyslog, "Level");
433 mSyslogMacros = rb_define_module_under(mSyslog, "Macros");
434
435 rb_define_module_function(mSyslog, "open", mSyslog_open, -1);
436 rb_define_module_function(mSyslog, "reopen", mSyslog_reopen, -1);
437 rb_define_module_function(mSyslog, "open!", mSyslog_reopen, -1);
438 rb_define_module_function(mSyslog, "opened?", mSyslog_isopen, 0);
439
440 rb_define_module_function(mSyslog, "ident", mSyslog_ident, 0);
441 rb_define_module_function(mSyslog, "options", mSyslog_options, 0);
442 rb_define_module_function(mSyslog, "facility", mSyslog_facility, 0);
443
444 rb_define_module_function(mSyslog, "log", mSyslog_log, -1);
445 rb_define_module_function(mSyslog, "close", mSyslog_close, 0);
446 rb_define_module_function(mSyslog, "mask", mSyslog_get_mask, 0);
447 rb_define_module_function(mSyslog, "mask=", mSyslog_set_mask, 1);
448
449 rb_define_module_function(mSyslog, "inspect", mSyslog_inspect, 0);
450 rb_define_module_function(mSyslog, "instance", mSyslog_instance, 0);
451
452 /* Syslog options */
453
454 #define rb_define_syslog_option(c) \
455 rb_define_const(mSyslogOption, #c, INT2NUM(c))
456
457 #ifdef LOG_PID
458 rb_define_syslog_option(LOG_PID);
459 #endif
460 #ifdef LOG_CONS
461 rb_define_syslog_option(LOG_CONS);
462 #endif
463 #ifdef LOG_ODELAY
464 rb_define_syslog_option(LOG_ODELAY); /* deprecated */
465 #endif
466 #ifdef LOG_NDELAY
467 rb_define_syslog_option(LOG_NDELAY);
468 #endif
469 #ifdef LOG_NOWAIT
470 rb_define_syslog_option(LOG_NOWAIT); /* deprecated */
471 #endif
472 #ifdef LOG_PERROR
473 rb_define_syslog_option(LOG_PERROR);
474 #endif
475
476 /* Syslog facilities */
477
478 #define rb_define_syslog_facility(c) \
479 rb_define_const(mSyslogFacility, #c, INT2NUM(c))
480
481 #ifdef LOG_AUTH
482 rb_define_syslog_facility(LOG_AUTH);
483 #endif
484 #ifdef LOG_AUTHPRIV
485 rb_define_syslog_facility(LOG_AUTHPRIV);
486 #endif
487 #ifdef LOG_CONSOLE
488 rb_define_syslog_facility(LOG_CONSOLE);
489 #endif
490 #ifdef LOG_CRON
491 rb_define_syslog_facility(LOG_CRON);
492 #endif
493 #ifdef LOG_DAEMON
494 rb_define_syslog_facility(LOG_DAEMON);
495 #endif
496 #ifdef LOG_FTP
497 rb_define_syslog_facility(LOG_FTP);
498 #endif
499 #ifdef LOG_KERN
500 rb_define_syslog_facility(LOG_KERN);
501 #endif
502 #ifdef LOG_LPR
503 rb_define_syslog_facility(LOG_LPR);
504 #endif
505 #ifdef LOG_MAIL
506 rb_define_syslog_facility(LOG_MAIL);
507 #endif
508 #ifdef LOG_NEWS
509 rb_define_syslog_facility(LOG_NEWS);
510 #endif
511 #ifdef LOG_NTP
512 rb_define_syslog_facility(LOG_NTP);
513 #endif
514 #ifdef LOG_SECURITY
515 rb_define_syslog_facility(LOG_SECURITY);
516 #endif
517 #ifdef LOG_SYSLOG
518 rb_define_syslog_facility(LOG_SYSLOG);
519 #endif
520 #ifdef LOG_USER
521 rb_define_syslog_facility(LOG_USER);
522 #endif
523 #ifdef LOG_UUCP
524 rb_define_syslog_facility(LOG_UUCP);
525 #endif
526 #ifdef LOG_LOCAL0
527 rb_define_syslog_facility(LOG_LOCAL0);
528 #endif
529 #ifdef LOG_LOCAL1
530 rb_define_syslog_facility(LOG_LOCAL1);
531 #endif
532 #ifdef LOG_LOCAL2
533 rb_define_syslog_facility(LOG_LOCAL2);
534 #endif
535 #ifdef LOG_LOCAL3
536 rb_define_syslog_facility(LOG_LOCAL3);
537 #endif
538 #ifdef LOG_LOCAL4
539 rb_define_syslog_facility(LOG_LOCAL4);
540 #endif
541 #ifdef LOG_LOCAL5
542 rb_define_syslog_facility(LOG_LOCAL5);
543 #endif
544 #ifdef LOG_LOCAL6
545 rb_define_syslog_facility(LOG_LOCAL6);
546 #endif
547 #ifdef LOG_LOCAL7
548 rb_define_syslog_facility(LOG_LOCAL7);
549 #endif
550
551 /* Syslog levels and the shortcut methods */
552
553 #define rb_define_syslog_level(c, m) \
554 rb_define_const(mSyslogLevel, #c, INT2NUM(c)); \
555 rb_define_module_function(mSyslog, #m, mSyslog_##m, -1)
556
557 #ifdef LOG_EMERG
558 rb_define_syslog_level(LOG_EMERG, emerg);
559 #endif
560 #ifdef LOG_ALERT
561 rb_define_syslog_level(LOG_ALERT, alert);
562 #endif
563 #ifdef LOG_CRIT
564 rb_define_syslog_level(LOG_CRIT, crit);
565 #endif
566 #ifdef LOG_ERR
567 rb_define_syslog_level(LOG_ERR, err);
568 #endif
569 #ifdef LOG_WARNING
570 rb_define_syslog_level(LOG_WARNING, warning);
571 #endif
572 #ifdef LOG_NOTICE
573 rb_define_syslog_level(LOG_NOTICE, notice);
574 #endif
575 #ifdef LOG_INFO
576 rb_define_syslog_level(LOG_INFO, info);
577 #endif
578 #ifdef LOG_DEBUG
579 rb_define_syslog_level(LOG_DEBUG, debug);
580 #endif
581
582 /* Syslog macros */
583
584 rb_define_method(mSyslogMacros, "LOG_MASK", mSyslogMacros_LOG_MASK, 1);
585 rb_define_method(mSyslogMacros, "LOG_UPTO", mSyslogMacros_LOG_UPTO, 1);
586 rb_define_singleton_method(mSyslogMacros, "included", mSyslogMacros_included, 1);
587
588 rb_include_module(mSyslogConstants, mSyslogOption);
589 rb_include_module(mSyslogConstants, mSyslogFacility);
590 rb_include_module(mSyslogConstants, mSyslogLevel);
591 rb_funcall(mSyslogConstants, rb_intern("include"), 1, mSyslogMacros);
592
593 rb_define_singleton_method(mSyslogConstants, "included", mSyslogMacros_included, 1);
594 rb_funcall(mSyslog, rb_intern("include"), 1, mSyslogConstants);
595 }
596