《Akka学习笔记:ACTORS介绍》
《Akka学习笔记:Actor消息传递(1)》
《Akka学习笔记:Actor消息传递(2)》
《Akka学习笔记:日志》
《Akka学习笔记:测试Actors》
《Akka学习笔记:Actor消息处理-请求和响应(1) 》
《Akka学习笔记:Actor消息处理-请求和响应(2) 》
《Akka学习笔记:ActorSystem(配置)》
《Akka学习笔记:ActorSystem(调度)》
在前面的三篇文章中《Akka学习笔记:ACTORS介绍》《Akka学习笔记:Actor消息传递(1)》和《Akka学习笔记:Actor消息传递(2)》 ,我们只是简单地介绍了Actors以及消息传递如何工作。在这篇文章中我们将给TeacherActor类加一些日志和测试功能。
回顾
之前的TeacherActor代码的片段如下:
class TeacherActor extends Actor { val quotes = List( "Moderation is for cowards", "Anything worth doing is worth overdoing", "The trouble is you think you have time", "You never gonna know if you never even try") def receive = { case QuoteRequest => { import util.Random //Get a random Quote from the list and construct a response val quoteResponse=QuoteResponse(quotes(Random.nextInt(quotes.size))) println (quoteResponse) } } }
用SLF4J 打印Akka日志
你可能注意到,我们直接将quoteResponse 打印到标准的输出是一个很不好的想法,让我们通过启用SLF4J Facade打印日志来修改这个。
通过日志来修复Actor类
Akka提供了一个非常小的trait 来打印日志,称为 ActorLogging。让我们来修改一下代码:
class TeacherLogActor extends Actor with ActorLogging { val quotes = List( "Moderation is for cowards", "Anything worth doing is worth overdoing", "The trouble is you think you have time", "You never gonna know if you never even try") def receive = { case QuoteRequest => { import util.Random //get a random element (for now) val quoteResponse=QuoteResponse(quotes(Random.nextInt(quotes.size))) log.info(quoteResponse.toString()) } } //We'll cover the purpose of this method in the Testing section def quoteList=quotes }
这里有点绕道。实际上,当我们以日志记下来一个message,ActorLogging 中的logging 方法已经将该消息publishes到了EventStream。那什么是EventStream?
EventStream and Logging
EventStream的行为其实有点像消息中介,我们可以通过它发布和接收消息。和一般的MOM的微秒区别就是,EventStream的订阅者(subscribers)只能是Actor。在logging消息的场景,所有的log message都会发布到EventStream中。默认情况下,订阅这些消息的Actor是DefaultLogger ,它只是简单的将消息打印到标准输出。代码片段如下:
class DefaultLogger extends Actor with StdOutLogger { override def receive: Receive = { ... case event: LogEvent ⇒ print(event) } }
这就是为什么当我面再次启动StudentSimulatorApp程序的时候,我们看到日志消息被打印到终端。
也就是说,EventStream不仅仅适合打日志。它是Actor世界中常用的public-subscribe机制。让我们再回到SLF4J
配置Akka来启用SLF4J
代码片段如下:
akka{ loggers = ["akka.event.slf4j.Slf4jLogger"] loglevel = "DEBUG" logging-filter = "akka.event.slf4j.Slf4jLoggingFilter" }
我们将这些配置信息存储在名为application.conf文件中,这个文件需要配置在你的classpath里面。在我们的工程目录下,可以放在main/resources目录下面。
从这个配置中,我们可以
1、loggers属性表明,Actor将消息订阅到log Event中。 Slf4jLogger所做的仅仅是消费 log messages并将它放到SLF4J Logger facade里。
2、loglevel 属性表明,日志的输出级别。
3、logging-filter和loglevel 结合,传入日志消息的输出级别并将符合的消息publishing到EventStream中。
你可能会说,在之前的例子里怎么就没有application.conf文件呢?那是因为Akka提供了一些默认的配置属性。
THROW IN A logback.xml
我们将通过logback.xml文件来配置SLF4J logger backed,如下:
<?xml version="1.0" encoding="UTF-8"?> <configuration> <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <encoder> <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> </encoder> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>logs\akka.%d{yyyy-MM-dd}.%i.log</fileNamePattern> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>50MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> </rollingPolicy> </appender> <root level="DEBUG"> <appender-ref ref="FILE" /> </root> </configuration>
同样将它放到 main/resources目录下面,你得确保 main/resources目录在你的eclipse或者其他IDE的Classpath里面。同时,你得将logback 和slf4j-api加入到你的pom文件中或者build.sbt中,如下:
name := "AkkaNotes_Messaging" version := "1.0" organization := "com.arunma" scalaVersion := "2.11.2" resolvers ++= Seq("repo" at "http://repo.typesafe.com/typesafe/releases/") libraryDependencies ++= { val akkaVersion = "2.3.4" val sprayVersion = "1.3.1" Seq( "com.typesafe.akka" %% "akka-actor" % akkaVersion, "io.spray" %% "spray-can" % sprayVersion, "io.spray" %% "spray-routing" % sprayVersion, "io.spray" %% "spray-json" % "1.2.6", "com.typesafe.akka" %% "akka-slf4j" % akkaVersion, "ch.qos.logback" % "logback-classic" % "1.1.2", "com.typesafe.akka" %% "akka-testkit" % akkaVersion, "org.scalatest" %% "scalatest" % "2.2.0" ) }
当我们再次启动StudentSimulatorApp的时候,并且发送消息到新的TeacherLogActor中,将会生成一个名为akkaxxxxx.log的文件,内容大概如下:
本博客文章除特别声明,全部都是原创!原创文章版权归过往记忆大数据(过往记忆)所有,未经许可不得转载。
本文链接: 【Akka学习笔记:日志】(https://www.iteblog.com/archives/1156.html)
好文,期待下篇!