首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >和阿克卡一起伐木。app设计

和阿克卡一起伐木。app设计
EN

Stack Overflow用户
提问于 2015-09-10 01:50:15
回答 2查看 187关注 0票数 2

假设我有一个基于Futures、基于scala.concurrent的scala应用程序来处理asyn /一致性(到目前为止还没有使用任何参与者)。

在许多地方,我使用log4j将内容记录到日志文件中。由于是I/O,我想我可以通过向LoggingActor发送日志消息来提高性能

就像这样:

代码语言:javascript
复制
def stuffTodo(arg:String)(implicit ex:ExecutionContext) : Future[Result] = {

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

其中msg:case class LogMessage(msg:String, implicit ex:ExecutionContext)

然后在ActorLog

代码语言:javascript
复制
def receive = {
    case LogMessage(msg:String, ex:ExecutionContext) ⇒ {log.info(msg + ex)}
}

我看到了其他方法,基本上是包装 scala.concurent.ExecutionContext (用当前线程),使用映射诊断上下文-magic (log4j),并通过将线程id附加到日志消息来进行日志记录。但最终它会阻塞/减缓线程/执行(据我理解),并使应用程序变慢。

在本例中,使用此Actor,日志记录保持独立/异步并同时保持顺序。

走这条路好吗?分享经验故事?赞成/反对/关切?在重负荷试验之前询问..。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-09-10 13:37:02

Akka已经很好地支持日志记录,日志记录在页面伐木- Akka文档上。我不认为在您的系统中创建记录器参与者是必要或可取的,特别是在这种机制已经存在的情况下。

您可能已经使用了异步执行日志记录的LoggingAdaptor类,它通过将其发送到事件总线来实现这一点。您应该能够在参与者或外部使用相同的机制。

看看Logging.scala

测井Mixin

Scala为参与者提供了一个混合器,它为参与者创建了记录器,并允许设置MDC。来自文件:

代码语言:javascript
复制
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.scala文件中有两个示例用于在参与者之外创建一个LoggingSource:

代码语言:javascript
复制
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"
}

第二个变体用于包括参与者系统的地址:

代码语言:javascript
复制
 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。

日志线程和MDC

当日志记录由另一个线程异步执行时,文档还介绍了日志记录线程上的要点。

由于日志记录是异步完成的,因此执行日志记录的线程将在属性名为sourceThread的映射诊断上下文(MDC)中捕获。使用Logback,在模式布局配置中%X{sourceThread}说明符中可以使用线程名。

票数 3
EN

Stack Overflow用户

发布于 2015-09-10 03:58:08

看起来就像在工程上。

如果我要这样做,我将使用logback,并实现自定义异步Appender,因此如果我决定不停止,就不必更改代码。

否则,日志库是不错的选择,我可能会尝试调优它以获得更好的性能,并在实现此特性时依赖其他人的经验。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32491795

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档