From 49e73f2fb731d7b232cc437970561858c0cb4c61 Mon Sep 17 00:00:00 2001 From: Christophe Pache Date: Mon, 28 Jan 2013 16:02:47 +0100 Subject: [PATCH] EventHandler using the OSGi LogService NB1: the EventHandler needs to be specified in the configuration NB2: there are some logs that appear in the OSGi prompt at starting and stopping of the Bundle messages are stored in Buffer become used in DefaultOSGiLogger cleanings thanks to patriknw Conflicts: project/AkkaBuild.scala --- .../akka/osgi/ActorSystemActivator.scala | 15 +++++++ .../akka/osgi/impl/DefaultOSGiLogger.scala | 45 +++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 akka-osgi/src/main/scala/akka/osgi/impl/DefaultOSGiLogger.scala diff --git a/akka-osgi/src/main/scala/akka/osgi/ActorSystemActivator.scala b/akka-osgi/src/main/scala/akka/osgi/ActorSystemActivator.scala index 7e33467c32..b3a1bbe43c 100644 --- a/akka-osgi/src/main/scala/akka/osgi/ActorSystemActivator.scala +++ b/akka-osgi/src/main/scala/akka/osgi/ActorSystemActivator.scala @@ -6,6 +6,8 @@ package akka.osgi import akka.actor.ActorSystem import java.util.{ Dictionary, Properties } import org.osgi.framework.{ ServiceRegistration, BundleContext, BundleActivator } +import org.osgi.service.log.LogService +import org.osgi.util.tracker.ServiceTracker /** * Abstract bundle activator implementation to bootstrap and configure an actor system in an @@ -38,9 +40,22 @@ abstract class ActorSystemActivator extends BundleActivator { */ def start(context: BundleContext): Unit = { system = Some(OsgiActorSystemFactory(context).createActorSystem(Option(getActorSystemName(context)))) + findLogService(context) foreach (log ⇒ system.foreach(sys ⇒ sys.eventStream.publish(log))) system foreach (configure(context, _)) } + /** + * Finds a LogService in the BundleContext in any + * + * @param context the BundleContext + * @return An option of the LogService in the BundleContext + */ + def findLogService(context: BundleContext): Option[LogService] = { + val logServiceTracker = new ServiceTracker(context, classOf[LogService].getName, null) + logServiceTracker.open() + Option(logServiceTracker.getService.asInstanceOf[LogService]) + } + /** * Shuts down the ActorSystem when the bundle is stopped and, if necessary, unregisters a service registration. * diff --git a/akka-osgi/src/main/scala/akka/osgi/impl/DefaultOSGiLogger.scala b/akka-osgi/src/main/scala/akka/osgi/impl/DefaultOSGiLogger.scala new file mode 100644 index 0000000000..2533c19cd9 --- /dev/null +++ b/akka-osgi/src/main/scala/akka/osgi/impl/DefaultOSGiLogger.scala @@ -0,0 +1,45 @@ +/** + * Copyright (C) 2009-2012 Typesafe Inc. + */ +package akka.osgi.impl + +import akka.event.Logging.{ LogEvent, DefaultLogger } +import org.osgi.service.log.LogService +import akka.event.Logging +import collection.mutable.Buffer + +/** + * EventHandler for OSGi environment. + * Stands for an interface between akka and the OSGi LogService + * It uses the OSGi LogService to log the received LogEvents + */ +class DefaultOSGiLogger extends DefaultLogger { + + //the Default Logger needs to be aware of the LogService which is published on the EventStream + context.system.eventStream.subscribe(self, classOf[LogService]) + + val messageFormat = "[%s] %s" + + var messagesToLog: Vector[LogEvent] = Vector() + + override def receive: Receive = { + //register the log service to use + case logService: LogService ⇒ setLogService(logService) + case logEvent: LogEvent ⇒ messagesToLog = messagesToLog :+ logEvent + } + + def setLogService(logService: LogService) { + messagesToLog.foreach(logMessage(logService, _)) + context.become(receiveEvent(logService)) + } + + def receiveEvent(logService: LogService): Receive = { case logEvent: LogEvent ⇒ logMessage(logService, logEvent) } + + def logMessage(logService: LogService, event: LogEvent) { + event match { + case error: Logging.Error ⇒ logService.log(event.level.asInt, Logging.stackTraceFor(error.cause)) + case _ => logService.log(event.level.asInt, messageFormat.format(event.logSource, event.message)) + } + } + +} \ No newline at end of file