diff --git a/lib/log4r/outputter/syslogoutputter.rb b/lib/log4r/outputter/syslogoutputter.rb index 280db75..bea80af 100644 --- a/lib/log4r/outputter/syslogoutputter.rb +++ b/lib/log4r/outputter/syslogoutputter.rb @@ -15,6 +15,8 @@ module Log4r class SyslogOutputter < Outputter include Syslog::Constants + + SEMAPHOR = Mutex.new() # maps default log4r levels to syslog priorities (logevents never see ALL and OFF) # SYSLOG Levels are: @@ -118,8 +120,16 @@ def canonical_log(logevent) msg = o.inspect end - Syslog.open(@ident, @logopt, @facility) do |s| - s.log(pri, '%s', msg) + #Block globally, since the Syslog gets opened for the process + SEMAPHOR.synchronize do + Syslog.open(@ident, @logopt, @facility) do |s| + s.mask = begin + Syslog::LOG_UPTO(SYSLOG_LEVELS_MAP[@levels_map[Log4r::LNAMES[@level]]]) + rescue + Syslog::LOG_UPTO(LOG_INFO) + end + s.log(pri, '%s', msg) + end end end end diff --git a/tests/testsyslogoutputter.rb b/tests/testsyslogoutputter.rb new file mode 100644 index 0000000..a6172fd --- /dev/null +++ b/tests/testsyslogoutputter.rb @@ -0,0 +1,32 @@ +require 'test_helper' +require 'log4r/outputter/syslogoutputter' + +class TestSyslogOutputter < TestCase + def test_concurrency + threads = [] + (1..20).each do + threads << Thread.new do + #Create log and add syslog outputter + id = Thread.current.__id__ + id = id.to_s() + log = Log4r::Logger.new(id) + log.add(Log4r::SyslogOutputter.new(id)) + + (1..200).each do + log.debug "debugging" + log.info "a piece of info" + log.warn "Danger, Will Robinson, danger!" + log.error "I dropped my Wookie! :(" + log.fatal "kaboom!" + Thread.pass() + end + end + end + + threads.each do |thread| + assert_nothing_raised(Exception) do + thread.join() + end + end + end +end \ No newline at end of file