2015-09-10 3 views
2

Предположим, у меня есть приложение scala, основанное на Futures, на scala.concurrent для обработки asyn/concurency (до сих пор не использовались актеры).Регистрация с аккой. app design

Во многих местах я использую log4j для входа в файл журнала. Так как я/О.И. полагаю, что может повысить производительность путем отправки сообщения журнала LoggingActor

что-то вроде этого:

def stuffTodo(arg:String)(implicit ex:ExecutionContext) : Future[Result] = { 

// important performant work 
// .. 
logAcrot ! LogMessage("message-1") 
// ... 
} 

где тзд: case class LogMessage(msg:String, implicit ex:ExecutionContext)

затем в ActorLog

def receive = { 
    case LogMessage(msg:String, ex:ExecutionContext) ⇒ {log.info(msg + ex)} 
} 

Я видел другие подходы, которые в основном обертываниеscala.concurent.ExecutionContext (с текущей резьбой) и используйте Mapped Diagnostic Context -magic (log4j) и выполните регистрацию, установив идентификатор потока в лог-сообщение. Но в конечном итоге он блокирует/замедляет поток/выполнение (насколько я понимаю) и делает приложение медленнее.

В этом случае с этим Актером, регистрация остается независимой/асинхронной и последовательной в одно и то же время.

Это хорошая идея пойти этим путем? Обмен опытом? плюсы/минусы/проблемы? Перед тем, как попробовать тяжелую нагрузку ..

ответ

3

У Akka уже была хорошая поддержка для регистрации, о чем документация на странице Logging - Akka Documentation. Я не думаю, что необходимо или желательно создать в вашей системе регистратора, особенно когда этот механизм уже существует.

Возможно, вы уже используете класс LoggingAdaptor, который выполняет асинхронное ведение журнала, и делает это, отправляя его на шину событий. Вы должны иметь возможность использовать этот же механизм у актера или снаружи.

Посмотрите на Logging.scala

Logging подмешать

Scala имеет подмешать для актеров, что создает логгер для актера и позволяет MDC быть установлена.Из документации:

import Logging.MDC 

final case class Req(work: String, visitorId: Int) 

    class MdcActorMixin extends Actor with akka.actor.DiagnosticActorLogging { 
     var reqId = 0 

     override def mdc(currentMessage: Any): MDC = { 
      reqId += 1 
      val always = Map("requestId" -> reqId) 
      val perMessage = currentMessage match { 
       case r: Req => Map("visitorId" -> r.visitorId) 
       case _  => Map() 
      } 
      always ++ perMessage 
     } 

     def receive: Receive = { 
      case r: Req => { 
       log.info(s"Starting new request: ${r.work}") 
      } 
     } 
} 

Logging вне актера

Есть два примера в Logging.scala файл createing в LoggingSource вне актера:

trait MyType { // as an example 
    def name: String 
} 

implicit val myLogSourceType: LogSource[MyType] = new LogSource[MyType] { 
    def genString(a: MyType) = a.name 
} 

class MyClass extends MyType { 
    val log = Logging(eventStream, this) // will use "hallo" as logSource 
    def name = "hallo" 
} 

Второй вариант используется для включения адреса действующей системы:

trait MyType { // as an example 
    def name: String 
} 

implicit val myLogSourceType: LogSource[MyType] = new LogSource[MyType] { 
    def genString(a: MyType) = a.name 
    def genString(a: MyType, s: ActorSystem) = a.name + "," + s 
} 

class MyClass extends MyType { 
    val sys = ActorSystem("sys") 
    val log = Logging(sys, this) // will use "hallo,akka://sys" as logSource 
    def name = "hallo" 
    } 

MDC может быть установлен на адаптере регистрации, если вам это нужно.

Logging резьбы и MDC

Документация также охватывает вашу точку на регистрации потока, когда ведение журнала асинхронно выполняется другим потоком.

Поскольку ведение журнала выполняется асинхронно нить, в которой была выполнена регистрация захватывается в контексте Mapped диагностики (MDC) с именем атрибута sourceThread. С помощью Logback имя потока: , доступное с спецификатором% X {sourceThread} в шаблоне шаблона .

+0

следуя вашей ссылке: Я сделал только это: https://github.com/Sergey80/scala-samples/blob/master/src/main/scala/concurrency/logging/LogSample.scala кажется работает. но все же следует выяснить, как сделать работу/работу макета: https://github.com/Sergey80/scala-samples/blob/master/src/main/scala/logback.xml – ses

+0

Ницца. Я немного обновил ответ для других, используя некоторые из примеров из файла журнала. – andygavin

1

Похоже на инженерную.

Я бы с Logback и реализовать пользовательские asynchonous Appender, если бы я сделал что-то вроде этого, так что я не должен был бы изменить свой код, если я решу не прекратить.

В противном случае протоколирование библиотек довольно неплохо, я бы постарался, возможно, настроить его для повышения производительности и полагаться на то, что другие используют эту функцию.

Смежные вопросы