Akka中使用Logback日志框架
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日志。