问题描述
在使用Azure Event Hub的SDK时候,常规情况下,发现示例代码中并没有SDK内部的日志输出。因为在Java项目中,没有添加 SLF4J 依赖,已致于在启动时候有如下提示:
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
那么,有什么方便的办法,能把SDK中,内部处理Event Hub的日志打印出来,并且保存在日志文件中呢?
问题解答
是的,如提示所说,使用 SLF4J 就可以了。因为Azure Event Hub SDK中使用 (com.azure.core.util.logging.ClientLogger) 对日志进行输出,所以在最外层(应用代码级)就需要有一个接收日志的Provider,那就是SLF4J。
下面的步骤,就是展示如何添加SLF4J依赖,如何添加输出到文件,输出到Console的配置,最后查看输出结果。
前提要求:根据官方示例代码,已经成功运行消费端应用:https://docs.azure.cn/zh-cn/event-hubs/event-hubs-java-get-started-send (文末附带本文的示例代码)
第一步:在 pom.xml 中添加 SLF4J 的3个依赖项
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
第二步:在 .\src\main\resources 目录中添加 log4j.properties 文件,并设置最关键的 日志输出级别,路径 和 格式
# Root logger option
log4j.rootLogger=INFO, stdout, FILE
# Direct log messages to stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1} - %m%n
# Direct log messages to file
# Define the file appender
log4j.appender.FILE=org.apache.log4j.FileAppender
# Set the name of the file
log4j.appender.FILE.File=Logs/log.out
# Set the immediate flush to true (default)
log4j.appender.FILE.ImmediateFlush=true
# Set the threshold to debug mode
log4j.appender.FILE.Threshold=debug
# Set the append to false, overwrite
log4j.appender.FILE.Append=false
# Define the layout for file appender
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.conversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1} - %m%n
第三步: 检查输出结果
1)实验项目的文件结构
2)pom.xml 中添加的 slf4j 依赖
3)为日志输出到文件和控制台配置属性
4)查看文件日志输出
5)查看控制台日志输出
附录一:本文实验中的全部代码
1:POM.XML 文件内容
<?xml versinotallow="1.0" encoding="UTF-8"?>
<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.example</groupId>
<artifactId>ConsumeMessageAbort</artifactId>
<version>1.0-SNAPSHOT</version>
<name>ConsumeMessageAbort</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-messaging-eventhubs</artifactId>
<version>5.12.2</version>
</dependency>
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-messaging-eventhubs-checkpointstore-blob</artifactId>
<version>1.14.0</version>
</dependency>
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-identity</artifactId>
<version>1.5.3</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.5.5</version>
<configuration>
<archive>
<manifest>
<mainClass>com.example.App</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
</plugins>
</build>
</project>
2:src\main\resources\log4j.properties 文件内容
# Root logger option
log4j.rootLogger=INFO, stdout, FILE
# Direct log messages to stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1} - %m%n
# Direct log messages to file
# Define the file appender
log4j.appender.FILE=org.apache.log4j.FileAppender
# Set the name of the file
log4j.appender.FILE.File=Logs/log.out
# Set the immediate flush to true (default)
log4j.appender.FILE.ImmediateFlush=true
# Set the threshold to debug mode
log4j.appender.FILE.Threshold=debug
# Set the append to false, overwrite
log4j.appender.FILE.Append=false
# Define the layout for file appender
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.conversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1} - %m%n
3:src\main\java\com\example\App.java 文件内容
package com.example;
import com.azure.messaging.eventhubs.EventData;
import com.azure.messaging.eventhubs.EventHubClientBuilder;
import com.azure.messaging.eventhubs.EventHubConsumerAsyncClient;
import com.azure.messaging.eventhubs.EventProcessorClientBuilder;
import java.io.IOException;
import java.sql.Date;
import java.time.Instant;
import java.time.temporal.TemporalUnit;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Consumer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Hello world!
*
*/
public class App {
final static Logger logger = LoggerFactory.getLogger(App.class);
private static final String azureEventHubConnectionString = "event hub namespace connection string";
private static final String azureEventHubHostName = "event hub name";
public static void main(String[] args) throws IOException {
System.out.println("Hello World!");
EventHubConsumerAsyncClient consumer = new EventHubClientBuilder()
.connectionString(azureEventHubConnectionString, azureEventHubHostName)
.consumerGroup(EventHubClientBuilder.DEFAULT_CONSUMER_GROUP_NAME)
.buildAsyncConsumerClient();
try {
consumer.receive(true).subscribe(
event -> {
EventData data = event.getData();
String message = "SequenceNumber is" + data.getSequenceNumber().toString()
+ " The eventData is "
+ data.getBodyAsString();
System.out.println(message);
logger.info(message);
},
error -> logger.error("The iot hub failed to listen for messages, error is {}" + error.toString()));
} catch (Exception e) {
consumer = new EventHubClientBuilder()
.connectionString(azureEventHubConnectionString, azureEventHubHostName)
.consumerGroup(EventHubClientBuilder.DEFAULT_CONSUMER_GROUP_NAME)
.buildAsyncConsumerClient();
System.out.println("recollect consumer");
logger.warn("recollect consumer");
}
System.out.println("Press enter to stop.");
logger.info("Press enter to stop.");
System.in.read();
System.out.println("...End...");
}
}
4:文件结构
参考资料
开启 Apache Flink 制造者 Producer 示例代码中的日志输出 : https://www.cnblogs.com/lulight/p/15789878.html
使用 Java 向/从 Azure 事件中心 (azure-messaging-eventhubs) 发送/接收事件 : https://docs.azure.cn/zh-cn/event-hubs/event-hubs-java-get-started-send
当在复杂的环境中面临问题,格物之道需:浊而静之徐清,安以动之徐生。 云中,恰是如此!
分类: 【Azure 事件中心】
标签: Azure 环境, Azure Event Hub Java SDK, 日志输出为文件格式, org.slf4j.Logger 收集 Event Hub SDK(Java) 输出日志, log4j.appender.FILE