如何使用登录Akka演员?

时间:2017-04-26 06:14:31

标签: scala akka

我可以通过隐式设置Akka actor中的Logging吗?我想登录演员。我的代码如下:

object EmployeeRouterActor {
  final case class Employee(id: Long, name: String)
  final case object StopChild
  final case class ChildResponse(id: Long, name: String)
}

final class EmployeeRouterActor extends Actor with akka.actor.ActorLogging {

  import EmployeeRouterActor._

  private var children = Map.empty[Long, ActorRef]

  override def receive: Receive = {
    case e @ Employee(id, _)  => {
      getChild(id) ! e
    }
    case r @ ChildResponse(id, _) => {
      stopChild(id)
      val idItem = r.id
      val nameItem = r.name
      sender ! s"Employee {$idItem} is $nameItem."
    }
  }

  private def getChild(id: Long): ActorRef =
    context.child(id.toString).getOrElse {
      val child = context.actorOf(EmployeeEchoActor.apply(), id.toString)
      children += (id -> child)
      child
    }

  private def stopChild(id: Long) = {
    children(id) ! StopChild
    children -= id
  }

}

但是,在这种情况下,我不能做这样的事情:

class EmployeeRouterActor (implicit logger: LoggingAdapter) { ... }

我遇到以下错误:

Error:(10, 30) could not find implicit value for parameter logger: akka.event.LoggingAdapter
  def apply(): Props = Props(new EmployeeEchoActor)

Error:(10, 30) not enough arguments for constructor EmployeeEchoActor: (implicit logger: akka.event.LoggingAdapter)actors.EmployeeEchoActor.
Unspecified value parameter logger.
  def apply(): Props = Props(new EmployeeEchoActor)

是否可以在演员内部使用Akka的记录?

EmployeeEchoActor(子actor)的定义如下:

object EmployeeEchoActor {
  def apply(): Props = Props(new EmployeeEchoActor)
}

class EmployeeEchoActor(implicit logger: LoggingAdapter) extends Actor {

  override def receive = {

    case employee: EmployeeRouterActor.Employee => {
      logger.info("Message received!")
      val idItem = employee.id
      val nameItem = employee.name
      context.parent ! EmployeeRouterActor.ChildResponse( idItem, nameItem )

    }
    case EmployeeRouterActor.StopChild => {
      logger.info("Stopping :(!")
      context.stop(self)
    }
    case _ => sender ! "Internal Error!"
  }

}

1 个答案:

答案 0 :(得分:2)

解决方案是:

final class EmployeeRouterActor extends Actor with akka.actor.ActorLogging {

实现ActorLogging并在代码中使用日志,例如:

override def receive: Receive = {
    case e @ Employee(id, _)  => {
      log.info("Message received!")
      getChild(id) ! e
    }
    case r @ ChildResponse(id, _) => {
      log.info("Response received from child!")
      stopChild(id)
      log.info("Child has been stopped!")
      val idItem = r.id
      val nameItem = r.name
      sender ! s"Employee {$idItem} is $nameItem."
    }

  }