Akka执行元日志中有关PinnedDispatcher的线程名称

sshcrbum  于 2022-11-06  发布在  其他
关注(0)|答案(1)|浏览(107)

我正在用Akka v2.5.23编写一个应用程序。该应用程序涉及以下参与者:

  • 名为CalculatorRouter的路由器执行元类
  • 名为Calculator的被路由者执行元类

我在创建Calculator actor时配置了一个PinnedDispatcher,并将log.info放在这个actor类的receive方法中。我希望在日志文件中看到线程名称字段包含pinned。但是,线程名称字段是default-dispatcher。我在日志文件中搜索了一下,发现与此log.info相关的所有线程名称都是default-dispatcher。我的代码有什么问题吗?
日志文件片段:

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
}

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>

'20 3月4日更新
在我把akka.loggers-dispatcher = "calc.my-pinned-dispatcher"放到conf文件中之后,我在日志文件的每一行都得到了my-pinned-dispatcher-xx作为线程名。我认为线程名应该指示actor Calculator的receive方法正在执行的线程,在本例中,类似于'pinned-dispatcher-xx'的东西,因为线程是根据我的配置由固定的调度程序获得的。现在它证明了它指示了由记录器的调度程序获得的线程。如果是这种情况,如何为参与者的消息处理程序代码记录线程名称?

f5emj3cl

f5emj3cl1#

我认为解决方案是在application.conf中添加akka.loggers-dispatcher

calc.my-pinned-dispatcher {
    executor="thread-pool-executor"
    type=PinnedDispatcher
  }
akka.loggers-dispatcher = "calc.my-pinned-dispatcher"

如果你在akka的default configuration中搜索logger-dispatcher,你会发现值是“akka.actor.default-dispatcher”,我们需要如上所示覆盖这个配置。

编辑

ActorLogging是异步的。当您使用ActorLogging进行记录时,它会将消息传送至记录执行元,而该执行元预设会在预设分派程式上执行。Logback会记录呼叫它的执行绪,而该执行绪将是ActorLogging执行元的执行绪,而不是您的执行元的执行绪。为了达成此目的,有一个所谓的Map诊断上下文(MDC),可撷取akka source(执行日志记录的执行元的路径)、**source thread(执行日志记录的线程)**以及执行日志记录的更多内容。
如文档中所示:
由于日志记录是异步完成的,因此在MDC中使用属性名称sourceThread捕获执行日志记录的线程。
执行日志记录的参与者的路径在MDC中可用,属性名为akkaSource
执行日志记录的执行元系统名称在MDC中可用,其属性名称为sourceActorSystem,但通常也包含在akkaSource属性中。
执行元系统的地址(如果系统使用集群,则包含主机和端口)可通过akkaAddress获得。
对于类型化的参与者,日志事件时间戳是在进行日志调用时获取的,但是对于Akka的内部日志记录以及经典的参与者日志记录是异步的,这意味着日志条目的时间戳是在调用底层日志记录器实现时获取的,这一点一开始可能会令人惊讶。如果您想更准确地输出此类日志记录器的时间戳,请使用MDC属性akkaTimestamp。请注意,MDC键对于类型化的参与者将没有任何值。
如果有帮助的话,让我知道!!

相关问题