diff --git a/src/main/scala/net/lag/logging/Syslog.scala b/src/main/scala/net/lag/logging/Syslog.scala index 88b38a5..b9800f7 100644 --- a/src/main/scala/net/lag/logging/Syslog.scala +++ b/src/main/scala/net/lag/logging/Syslog.scala @@ -16,6 +16,9 @@ package net.lag.logging +import scala.actors.Actor._ +import scala.actors._ + import java.util.{logging => javalog} import java.net.{DatagramPacket, DatagramSocket, InetAddress, InetSocketAddress, SocketAddress} import java.text.SimpleDateFormat @@ -129,14 +132,24 @@ class SyslogHandler(useIsoDateFormat: Boolean, server: String) extends Handler(n def clearServerName = formatter.clearServerName - def publish(record: javalog.LogRecord) = synchronized { - try { - val data = getFormatter.format(record).getBytes - val packet = new DatagramPacket(data, data.length, dest) - socket.send(packet) - } catch { - case e => - System.err.println(Formatter.formatStackTrace(e, 30).mkString("\n")) + def publish(record: javalog.LogRecord) = { + val data = formatter.format(record).getBytes + val packet = new DatagramPacket(data, data.length, dest) + NonBlockingSyslog.send (() => socket.send(packet)) + } +} + +object NonBlockingSyslog { + def send (action: () => Unit) = writer ! action + def block = writer !? Wait + + private case object Wait + + private lazy val writer = actor { + while (true) receive { + case Wait => reply (()) + case action: (() => Unit) => try {action ()} + catch {case e => System.err.println(Formatter.formatStackTrace(e, 30).mkString("\n"))} } } } diff --git a/src/test/scala/net/lag/logging/LoggingSpec.scala b/src/test/scala/net/lag/logging/LoggingSpec.scala index d92e44b..c54785d 100644 --- a/src/test/scala/net/lag/logging/LoggingSpec.scala +++ b/src/test/scala/net/lag/logging/LoggingSpec.scala @@ -345,6 +345,8 @@ object LoggingSpec extends Specification with TestHelper { syslog.clearServerName log.debug("and debug!") + NonBlockingSyslog.block + val p = new DatagramPacket(new Array[Byte](1024), 1024) serverSocket.receive(p) new String(p.getData, 0, p.getLength) mustEqual "<9>2008-03-29T05:53:16 raccoon.local whiskey: fatal message!" @@ -360,6 +362,7 @@ object LoggingSpec extends Specification with TestHelper { log.addHandler(syslog) log.info("here's an info message with BSD time.") serverSocket.receive(p) + NonBlockingSyslog.block new String(p.getData, 0, p.getLength) mustEqual "<14>Mar 29 05:53:16 raccoon.local whiskey: here's an info message with BSD time." }