Skip to content

Commit 376cb71

Browse files
committed
Add JRuby's syslog
This syslog is defined using the FFI gem and JRuby's jnr-constants library for the syslog constants. The makefile is stubbed out on JRuby since it is not needed and the existing syslog.rb loads either the JRuby version or the standard C extension. Fixes #1
1 parent 4e7b12d commit 376cb71

4 files changed

Lines changed: 376 additions & 7 deletions

File tree

ext/syslog/extconf.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ def windows?
1414
RbConfig::CONFIG["host_os"] =~ /mswin|mingw/
1515
end
1616

17-
if windows?
17+
if windows? || RUBY_ENGINE == 'jruby'
1818
generate_dummy_makefile
1919
else
2020
have_library("log") # for Android

lib/syslog.rb

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
begin
2-
require 'syslog_ext'
2+
if RUBY_ENGINE == 'jruby'
3+
require 'syslog/jruby'
4+
else
5+
require 'syslog_ext'
6+
end
37
rescue LoadError
48
raise LoadError.new(<<-EOS)
5-
Can't load Syslog!
6-
7-
Syslog is not supported on your system. For Windows
8-
we recommend using the win32-eventlog gem.
9-
EOS
9+
Can't load Syslog!
10+
11+
Syslog is not supported on your system. For Windows
12+
we recommend using the win32-eventlog gem.
13+
EOS
1014
end

lib/syslog/jruby.rb

Lines changed: 364 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,364 @@
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

Comments
 (0)