欢迎关注Hadoop、Spark、Flink、Hive、Hbase、Flume等大数据资料分享微信公共账号:iteblog_hadoop
  1. 文章总数:961
  2. 浏览总数:11,480,990
  3. 评论:3873
  4. 分类目录:103 个
  5. 注册用户数:5841
  6. 最后更新:2018年10月17日
过往记忆博客公众号iteblog_hadoop
欢迎关注微信公众号:
iteblog_hadoop
大数据技术博客公众号bigdata_ai
大数据猿:
bigdata_ai

Akka学习笔记:日志

  在前面的三篇文章中《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的文件,内容大概如下:


如果想及时了解Spark、Hadoop或者Hbase相关的文章,欢迎关注微信公共帐号:iteblog_hadoop
本博客文章除特别声明,全部都是原创!
转载本文请加上:转载自过往记忆(https://www.iteblog.com/)
本文链接: 【Akka学习笔记:日志】(https://www.iteblog.com/archives/1156.html)
喜欢 (10)
分享 (0)
发表我的评论
取消评论

表情
本博客评论系统带有自动识别垃圾评论功能,请写一些有意义的评论,谢谢!
(5)个小伙伴在吐槽
  1. 好文,期待下篇!
    terry2014-10-15 10:05 回复