Akka提供的默认日志系统只输出到控制台,这种日志系统不可以用到产品环境,当然你可以整合SLF4J这样的日志系统,下面介绍如何在Akka中使用Logback记录日志。
1. 创建Maven工程引入相关依赖。
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.shindler.ioee.test</groupId>
<artifactId>akka</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>akka</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/com.typesafe.akka/akka-actor_2.11 -->
<dependency>
<groupId>com.typesafe.akka</groupId>
<artifactId>akka-actor_2.11</artifactId>
<version>2.4.10</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.typesafe.akka/akka-slf4j_2.11 -->
<dependency>
<groupId>com.typesafe.akka</groupId>
<artifactId>akka-slf4j_2.11</artifactId>
<version>2.4.10</version>
</dependency>
<!-- https://mvnrepository.com/artifact/ch.qos.logback/logback-classic -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.7</version>
</dependency>
</dependencies>
</project>
2. 添加akka配置文件,指定使用SLF4J日志系统。
# In this file you can override any option defined in the reference files.
# Copy in parts of the reference files and modify as you please.
akka {
# Loggers to register at boot time (akka.event.Logging$DefaultLogger logs
# to STDOUT)
loggers = ["akka.event.slf4j.Slf4jLogger"]
# Log level used by the configured loggers (see "loggers") as soon
# as they have been started; before that, see "stdout-loglevel"
# Options: OFF, ERROR, WARNING, INFO, DEBUG
loglevel = "ERROR"
# Log level for the very basic logger activated during ActorSystem startup.
# This logger prints the log messages to stdout (System.out).
# Options: OFF, ERROR, WARNING, INFO, DEBUG
stdout-loglevel = "ERROR"
# Filter of log events that is used by the LoggingAdapter before
# publishing log events to the eventStream.
logging-filter = "akka.event.slf4j.Slf4jLoggingFilter"
}
3. 创建Logback.xml配置文件,产品环境中,会单独记录错误日志,配置如下:
<configuration> <!--ERROR与其他日志分开--> <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>ERROR</level> <onMatch>DENY</onMatch> <onMismatch>ACCEPT</onMismatch> </filter> <encoder> <pattern> <pattern>CONSOLE -- [%-5level] %d{HH:mm:ss} - %msg%n</pattern> </pattern> </encoder> </appender> <!--ERROR与其他日志分开--> <appender name="ERROR" class="ch.qos.logback.core.ConsoleAppender"> <target>System.err</target> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>ERROR</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> <encoder> <pattern> <pattern>ERROR -- [%-5level] %d{HH:mm:ss} - %msg%n</pattern> </pattern> </encoder> </appender> <root level="DEBUG"> <appender-ref ref="CONSOLE" /> <appender-ref ref="ERROR" /> </root> </configuration>
4. 创建LoggerActor类,代码如下:
package com.shindler.ioee.test;
import akka.actor.UntypedActor;
import akka.event.Logging;
import akka.event.LoggingAdapter;
import scala.Option;
/**
* Created by zengsam on 2016/9/29.
*/
public class LoggerActor2 extends UntypedActor {
LoggingAdapter log = Logging.getLogger(getContext().system(), this);
@Override
public void onReceive(Object message) throws Throwable {
log.error("Received message: {}", message);
log.info("Received message: {}", message);
log.debug("Received message: {}", message);
}
@Override
public void preStart() {
log.info("Starting");
}
@Override
public void preRestart(Throwable reason, Option<Object> message) {
log.error(reason, "Restarting due to [{}] when processing [{}]",
reason.getMessage(), message.isDefined() ? message.get() : "");
}
}
5. 创建测试程序,代码如下:
package com.shindler.ioee.test;
import akka.actor.ActorRef;
import akka.actor.ActorSystem;
import akka.actor.Props;
import java.util.Date;
/**
* Hello world!
*/
public class App {
public static void main(String[] args) {
System.out.println("Hello World!");
ActorSystem system = ActorSystem.apply("testActorSystem");
ActorRef loggerActor = system.actorOf(Props.create(LoggerActor.class), "loggerActor");
ActorRef loggerActor2 = system.actorOf(Props.create(LoggerActor2.class), "loggerActor2");
while (true) {
try {
loggerActor.tell(new Date().toString(), ActorRef.noSender());
loggerActor2.tell(new Date().toString(), ActorRef.noSender());
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
运行程序,可以看到Actor使用了Logback来记录日志,并且单独记录了ERROR日志。