Scala Akka actor日志中关于PinnedDispatcher的线程名称
我正在用Akka v2.5.23编写一个应用程序。该应用程序涉及以下参与者:Scala Akka actor日志中关于PinnedDispatcher的线程名称,scala,logging,akka,Scala,Logging,Akka,我正在用Akka v2.5.23编写一个应用程序。该应用程序涉及以下参与者: 名为CalculatorRouter的路由器参与者类 名为Calculator的routee actor类 我在创建Calculator actor时配置了PinnedDispatcher,并将log.info放在这个actor类的receive方法中。我希望在日志文件中看到thread name字段包含pinted。但是,线程名称字段是默认调度程序。我在日志文件中进行了搜索,发现与此log.info相关的所有线程
- 名为CalculatorRouter的路由器参与者类
- 名为Calculator的routee actor类
log.info
放在这个actor类的receive方法中。我希望在日志文件中看到thread name字段包含pinted
。但是,线程名称字段是默认调度程序
。我在日志文件中进行了搜索,发现与此log.info
相关的所有线程名称都是defaultdispatcher
。我的代码有问题吗
日志文件片段:
09:49:25.116 [server-akka.actor.default-dispatcher-14] INFO handler.Calculator $anonfun$applyOrElse$3 92 - akka://server/user/device/$a/$a Total calc received
以下是代码片段:
class CalculatorRouter extends Actor with ActorLogging {
var router = {
val routees = Vector.fill(5) {
val r = context.actorOf(Props[Calculator].withDispatcher("calc.my-pinned-dispatcher"))
context.watch(r)
ActorRefRoutee(r)
}
Router(SmallestMailboxRoutingLogic(), routees)
}
def receive = {
case w: Calc => router.route(w, sender)
case Terminated(a) =>
router.removeRoutee(a)
val r = context.actorOf(Props[Calculator].withDispatcher("calc.my-pinned-dispatcher"))
context.watch(r)
router = router.addRoutee(r)
}
}
calc.my-pinned-dispatcher的配置如下:
calc.my-pinned-dispatcher {
executor="thread-pool-executor"
type=PinnedDispatcher
}
class Calculator extends Actor with ActorLogging {
val w = new UdanRemoteCalculateTotalBalanceTime
def receive = {
case TotalCalc(fn, ocvFilepath, ratedCapacity, battCount) ⇒
log.info(s"${self.path} Total calc received")
Try{
w.CalculateTotalBalanceTime(1, fn, ocvFilepath, ratedCapacity)
} match {
case Success(t) ⇒
val v = t.getIntData
sender.!(Calculated(v))(context.parent)
case Failure(e) ⇒ log.error(e.getMessage)
}
}
}
object Calculator {
sealed trait Calc
final case class TotalCalc(filename: String, ocvFilepath: String, ratedCapacity: String, batteryCount: Int) extends Calc
}
类计算器的源代码如下:
calc.my-pinned-dispatcher {
executor="thread-pool-executor"
type=PinnedDispatcher
}
class Calculator extends Actor with ActorLogging {
val w = new UdanRemoteCalculateTotalBalanceTime
def receive = {
case TotalCalc(fn, ocvFilepath, ratedCapacity, battCount) ⇒
log.info(s"${self.path} Total calc received")
Try{
w.CalculateTotalBalanceTime(1, fn, ocvFilepath, ratedCapacity)
} match {
case Success(t) ⇒
val v = t.getIntData
sender.!(Calculated(v))(context.parent)
case Failure(e) ⇒ log.error(e.getMessage)
}
}
}
object Calculator {
sealed trait Calc
final case class TotalCalc(filename: String, ocvFilepath: String, ratedCapacity: String, batteryCount: Int) extends Calc
}
logback.xml
<configuration debug="true">
<contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator">
<!-- reset all previous level configurations of all j.u.l. loggers -->
<resetJUL>true</resetJUL>
</contextListener>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>/var/log/app.log</file>
<append>true</append>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- daily rollover -->
<fileNamePattern>/var/log/app.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- keep 30 days' worth of history capped at 3GB total size -->
<maxHistory>100</maxHistory>
<totalSizeCap>30000MB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} %M %L - %msg%n</pattern>
</encoder>
</appender>
<appender name="ASYNCFILE" class="ch.qos.logback.classic.AsyncAppender">
<appender-ref ref="FILE" />
<queueSize>500</queueSize>
<includeCallerData>true</includeCallerData>
</appender>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} %M %L - %msg%n</pattern>
</encoder>
</appender>
<logger name="application" level="DEBUG"/>
<root level="INFo">
<appender-ref ref="ASYNCFILE"/>
</root>
</configuration>
真的
/var/log/app.log
真的
/var/log/app.%d{yyyy-MM-dd}.log
100
30000MB
%d{HH:mm:ss.SSS}[%thread]-5级别%logger{36}%M%L-%msg%n
500
真的
%d{HH:mm:ss.SSS}[%thread]-5级别%logger{36}%M%L-%msg%n
'3月20日4更新
谢谢@anand sai。在conf文件中放入
akka.loggers-dispatcher=“calc.my-pinted-dispatcher”
之后,我将my pinted dispatcher xx
作为日志文件每一行中的线程名称。我认为线程名称应该指示actor Calculator的receive
方法正在执行的线程,在本例中,类似于'pinted-dispatcher-xx'
,因为线程是由pinted dispatcher根据我的配置获得的。现在,它证明它指示记录器的调度程序获得的线程。如果是这种情况,如何记录参与者消息处理程序代码的线程名称?我认为解决方案是在应用程序.conf中添加akka.loggers dispatcher
calc.my-pinned-dispatcher {
executor="thread-pool-executor"
type=PinnedDispatcher
}
akka.loggers-dispatcher = "calc.my-pinned-dispatcher"
如果在akka中搜索logger dispatcher
,您将发现值为“akka.actor.default dispatcher`,我们需要覆盖此配置,如上所示
编辑
ActorLogging是异步的。当您使用ActorLogging进行日志记录时,它会向日志参与者发送一条消息,默认情况下,日志参与者在默认调度程序上运行。Logback会记录调用它的线程,它将是ActorLogging参与者的线程,而不是参与者的线程。为了实现此目标,有一个所谓的映射诊断控制ext(MDC),它捕获akka源代码(执行日志记录的参与者的路径)
,源线程(执行日志记录的线程)
,以及执行日志记录的更多线程
如下表所示:
由于日志记录是异步完成的,因此
使用属性名在MDC中捕获已执行的日志记录
sourceThread
执行日志记录的参与者的路径可用
在属性名为akkaSource的MDC中
执行日志记录的参与者系统名称可用
在属性名为sourceActorSystem的MDC中,但这是
通常也包括在akkaSource
属性中
参与者系统的地址,包含主机和端口(如果
系统正在使用群集,可通过akkaAddress
访问
对于类型化的参与者,日志事件时间戳是在日志调用时获取的
这部电影是为了阿卡的内部记录和经典演员而制作的
日志记录是异步的,这意味着日志项的时间戳
从调用底层记录器实现时获取,
一开始可能会让人惊讶,如果你想更准确
输出此类记录器的时间戳,使用MDC属性
akkaTimestamp
。请注意,MDC键对于
打字演员
如果有帮助,请告诉我!!放置akka.loggers-dispatcher=“calc.my-pinted-dispatcher”后“在conf文件中,我在日志文件的每一行中都有
my pinted dispatcher xx
作为线程名称。感谢您的编辑和参考文档。我已将sourceThread放在配置文件中,它的工作方式与我预期的一样。日志文件现在具有PinnedDispatcher xx
作为与PinnedDispatcher关联的参与者中日志调用的线程名。