Ruby & Syslog & custom facility

fguillen picture fguillen · Oct 28, 2010 · Viewed 11.4k times · Source

I am very new playing with syslog.

We have decided to use syslog to track some special events in our Rails application.

The problem is that I don't want to use the default /var/log/system.log file but use a custom one like /var/log/myapp_events.log.

I see that for that I have to define my own facility in /etc/syslog.conf like this:

myapp_events.* /var/log/myapp_events.log

After restarting syslogd I see that I can play with it directly into the bash console:

syslog -s -k Facility myapp_events Message "this is my message"

The message appears into the /var/log/myapp_events.log as expected, but I cannot reproduce this behavior using the syslog ruby gem. I have tried:

require 'syslog'
Syslog.open('myapp_events', Syslog::LOG_PID | Syslog::LOG_CONS) { |s| s.warning 'this is my message' }  # sends the message to system.log
Syslog.open('myapp_events', Syslog::LOG_PID | Syslog::LOG_CONS, 'myapp_events') { |s| s.warning 'this is my message' }  # error because 'myapp_event' can't be converted to int.

I see that Syslog.open has a third argument which is the facility but it has to be an integer and what I have is a string.

Any suggestion?

Answer

fguillen picture fguillen · Oct 29, 2010

Definitely the syslog ruby implementation doesn't allow us to use custom facilities.

The syslog ruby implementation is using the syslog [C implementation] (http://github.com/ruby/ruby/blob/trunk/ext/syslog/syslog.c#L36).

The syslog C implementation only allows us to use a very short list of facility names: LOG_USER, LOG_MAIL, LOG_DAEMON, LOG_AUTH, LOG_SYSLOG, LOG_LPR, LOG_NEWS, LOG_UUCP, UUCP , LOG_CRON, LOG_AUTHPRIV, LOG_FTP, LOG_LOCAL0, LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4, LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7.

So in the end what I did was to use one of the LOG_LOCALX facilities that are already there for personal use.

Now I can configure syslog like this:

# /etc/syslog.conf
local5.*    /var/log/myapp_events.log

And in Ruby do this:

Syslog.open('myapp', Syslog::LOG_PID, Syslog::LOG_LOCAL5) { |s| s.info 'this is my message' }

I think is the way that syslog wants you to define custom facilities.