Akka学习笔记:日志

10 篇文章 0 订阅

在前面的三篇文章中《Akka学习笔记:ACTORS介绍》《Akka学习笔记:Actor消息传递(1)》《Akka学习笔记:Actor消息传递(2)》  ,我们只是简单地介绍了Actors以及消息传递如何工作。在这篇文章中我们将给TeacherActor类加一些日志和测试功能。

回顾

  之前的TeacherActor代码的片段如下:

01 class TeacherActor extends Actor {
02  
03   val quotes = List(
04     "Moderation is for cowards",
05     "Anything worth doing is worth overdoing",
06     "The trouble is you think you have time",
07     "You never gonna know if you never even try")
08  
09   def receive = {
10  
11     case QuoteRequest => {
12  
13       import util.Random
14  
15       //Get a random Quote from the list and construct a response
16       val quoteResponse=QuoteResponse(quotes(Random.nextInt(quotes.size)))
17  
18       println (quoteResponse)
19  
20     }
21   }
22 }

用SLF4J 打印Akka日志

  你可能注意到,我们直接将quoteResponse 打印到标准的输出是一个很不好的想法,让我们通过启用SLF4J Facade打印日志来修改这个。

通过日志来修复Actor类

  Akka提供了一个非常小的trait 来打印日志,称为 ActorLogging。让我们来修改一下代码:

01 class TeacherLogActor extends Actor with ActorLogging {
02  
03    val quotes = List(
04     "Moderation is for cowards",
05     "Anything worth doing is worth overdoing",
06     "The trouble is you think you have time",
07     "You never gonna know if you never even try")
08  
09   def receive = {
10  
11     case QuoteRequest => {
12  
13       import util.Random
14  
15       //get a random element (for now)
16       val quoteResponse=QuoteResponse(quotes(Random.nextInt(quotes.size)))
17       log.info(quoteResponse.toString())
18     }
19   }
20  
21   //We'll cover the purpose of this method in the Testing section
22   def quoteList=quotes
23  
24 }

  这里有点绕道。实际上,当我们以日志记下来一个message,ActorLogging 中的logging 方法已经将该消息publishes到了EventStream。那什么是EventStream?
  EventStream and Logging
  EventStream的行为其实有点像消息中介,我们可以通过它发布和接收消息。和一般的MOM的微秒区别就是,EventStream的订阅者(subscribers)只能是Actor。在logging消息的场景,所有的log message都会发布到EventStream中。默认情况下,订阅这些消息的Actor是DefaultLogger ,它只是简单的将消息打印到标准输出。代码片段如下:

1 class DefaultLogger extends Actor with StdOutLogger { 
2     override def receive: Receive = {
3         ...
4         case event: LogEvent ⇒ print(event)
5     }
6 }

  这就是为什么当我面再次启动StudentSimulatorApp程序的时候,我们看到日志消息被打印到终端。
  也就是说,EventStream不仅仅适合打日志。它是Actor世界中常用的public-subscribe机制。让我们再回到SLF4J

配置Akka来启用SLF4J

代码片段如下:

1 akka{ 
2     loggers = ["akka.event.slf4j.Slf4jLogger"]
3     loglevel = "DEBUG"
4     logging-filter = "akka.event.slf4j.Slf4jLoggingFilter"
5 }

  我们将这些配置信息存储在名为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,如下:

01 <?xml version="1.0" encoding="UTF-8"?> 
02 <configuration
03     <appender name="FILE"
04         class="ch.qos.logback.core.rolling.RollingFileAppender">
05         <encoder>
06             <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
07         </encoder>
08  
09         <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
10             <fileNamePattern>logs\akka.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
11             <timeBasedFileNamingAndTriggeringPolicy
12                       class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
13                 <maxFileSize>50MB</maxFileSize>
14             </timeBasedFileNamingAndTriggeringPolicy>
15         </rollingPolicy>
16     </appender>
17  
18     <root level="DEBUG">
19         <appender-ref ref="FILE" />
20     </root>
21 </configuration

  同样将它放到 main/resources目录下面,你得确保 main/resources目录在你的eclipse或者其他IDE的Classpath里面。同时,你得将logback 和slf4j-api加入到你的pom文件中或者build.sbt中,如下:

01 name := "AkkaNotes_Messaging"
02  
03 version := "1.0"
04  
05 organization := "com.arunma"
06  
07 scalaVersion := "2.11.2"
08  
09 resolvers ++=
10         Seq("repo" at "http://repo.typesafe.com/typesafe/releases/")
11              
12 libraryDependencies ++= {
13         val akkaVersion = "2.3.4"
14         val sprayVersion = "1.3.1"
15         Seq(
16             "com.typesafe.akka" %% "akka-actor" % akkaVersion,
17             "io.spray" %% "spray-can" % sprayVersion,
18             "io.spray" %% "spray-routing" % sprayVersion,
19             "io.spray" %% "spray-json" % "1.2.6",
20             "com.typesafe.akka" %% "akka-slf4j" % akkaVersion,
21             "ch.qos.logback" % "logback-classic" % "1.1.2",
22             "com.typesafe.akka" %% "akka-testkit" % akkaVersion,
23             "org.scalatest" %% "scalatest" % "2.2.0"
24             )
25 }

  当我们再次启动StudentSimulatorApp的时候,并且发送消息到新的TeacherLogActor中,将会生成一个名为akkaxxxxx.log的文件,内容大概如下:


如果想及时了解 Spark、Hadoop或者Hbase相关的文章,欢迎关注微信公共帐号: iteblog_hadoop

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值