1. Overview
1.概述
In this tutorial, we’ll show how to enable logging in Apache’s HttpClient. Additionally, we’ll explain how logging is implemented inside the library. Afterward, we’ll show how to enable different levels of logging.
在本教程中,我们将展示如何在Apache的HttpClient中启用日志。此外,我们将解释在库内如何实现日志记录。之后,我们将展示如何启用不同级别的日志。
2. Logging Implementation
2.记录的实施
The HttpClient library provides efficient, up-to-date, and feature-rich implementation client site of the HTTP protocol.
HttpClient库提供了高效的、最新的、功能丰富的HTTP协议的实现客户端站点。
Indeed as a library, HttpClient doesn’t force logging implementation. With this intention, version 4.5, provides logs with Commons Logging. Similarly, the latest version, 5.1, uses a logging facade provided by SLF4J. Both versions use a hierarchy schema to match loggers with their configurations.
作为一个库,HttpClient并不强制实现日志记录。本着这样的意图,4.5版本,用Commons Logging提供日志。同样,最新的版本,即5.1,使用了由SLF4J提供的日志界面。这两个版本都使用一个层次结构模式来匹配记录器与它们的配置。
Thanks to that, it is possible to set up loggers for single classes or for all classes related to the same functionality.
得益于此,它可以为单个类或与同一功能相关的所有类设置记录器。
3. Log Types
3.日志类型
Let’s have a look at log levels defined by the library. We can distinguish 3 types of logs:
让我们来看看库中定义的日志级别。我们可以区分3种类型的日志。
- context logging – logs information about all internal operations of HttpClient. It contains wire and header logs as well.
- wire logging – logs only data transmitted to and from the server
- header logging – logs HTTP headers only
In version 4.5 the corresponding packages are org.apache.http.impl.client and org.apache.http.wire, org.apache.http.headers.
在4.5版本中,相应的包是org.apache.http.impl.client和org.apache.http.wire,org.apache.http.headers。
Acordingly in version 5.1 the are packages org.apache.hc.client5.http, org.apache.hc.client5.http.wire and org.apache.hc.client5.http.headers.
因此,在5.1版本中,有几个软件包org.apache.hc.client5.http,org.apache.hc.client5.http.wire和org.apache.hc.client5.http.headers.。
4. Log4j Configuration
4.Log4j配置
Let’s have a look at how to enable logging in to both versions. Our aim is to achieve the same flexibility in both versions. In version 4.1, we’ll redirect logs to SLF4j. Thanks to that, different logging frameworks can be used.
让我们来看看如何启用两个版本的登录功能。 我们的目的是在两个版本中实现同样的灵活性。在4.1版本中,我们将把日志重定向到SLF4j。得益于此,可以使用不同的日志框架。
4.1. Version 4.5 Configuration
4.1.4.5版配置
Let’s add the httpclient dependency:
让我们添加httpclient依赖性。
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.8</version>
<exclusions>
<exclusion>
<artifactId>commons-logging</artifactId>
<groupId>commons-logging</groupId>
</exclusion>
</exclusions>
</dependency>
We’ll use jul-to-slf4j to redirect logs to SLF4J. Therefore we excluded commons-logging. Let’s then add a dependency to the bridge between JUL and SLF4J:
我们将使用jul-to-slf4j来重定向日志到SLF4J。因此我们排除了commons-logging。然后让我们为JUL和SLF4J之间的桥梁添加一个依赖关系。
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jul-to-slf4j</artifactId>
<version>1.7.26</version>
</dependency>
Because SLF4J is just a facade, we need a binding. In our example, we’ll use logback:
因为SLF4J只是一个facade,我们需要一个绑定。在我们的例子中,我们将使用logback>。
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.6</version>
</dependency>
Let’s now create the ApacheHttpClientUnitTest class:
现在让我们来创建ApacheHttpClientUnitTest类。
public class ApacheHttpClientUnitTest {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
public static final String DUMMY_URL = "https://postman-echo.com/get";
@Test
public void whenUseApacheHttpClient_thenCorrect() throws IOException {
HttpGet request = new HttpGet(DUMMY_URL);
try (CloseableHttpClient client = HttpClients.createDefault(); CloseableHttpResponse response = client.execute(request)) {
HttpEntity entity = response.getEntity();
logger.debug("Response -> {}", EntityUtils.toString(entity));
}
}
}
The test fetches a dummy web page and prints the contents to the log.
该测试获取了一个假的网页,并将内容打印到日志中。
Let’s now define a logger configuration with our logback.xml file:
现在让我们用我们的logback.xml文件定义一个记录器配置。
<configuration debug="false">
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%date [%level] %logger - %msg %n</pattern>
</encoder>
</appender>
<logger name="com.baeldung.httpclient.readresponsebodystring" level="debug"/>
<logger name="org.apache.http" level="debug"/>
<root level="WARN">
<appender-ref ref="stdout"/>
</root>
</configuration>
After running our test, all HttpClient’s logs can be found in the console:
在运行我们的测试之后,所有HttpClient的日志都可以在控制台中找到。
...
2021-06-19 22:24:45,378 [DEBUG] org.apache.http.impl.execchain.MainClientExec - Executing request GET /get HTTP/1.1
2021-06-19 22:24:45,378 [DEBUG] org.apache.http.impl.execchain.MainClientExec - Target auth state: UNCHALLENGED
2021-06-19 22:24:45,379 [DEBUG] org.apache.http.impl.execchain.MainClientExec - Proxy auth state: UNCHALLENGED
2021-06-19 22:24:45,382 [DEBUG] org.apache.http.headers - http-outgoing-0 >> GET /get HTTP/1.1
...
4.2. Version 5.1 Configuration
4.2.5.1版配置
Let’s have a look now at the higher version. It contains redesigned logging. Therefore, instead of Commons Logging, it utilizes SLF4J. As a result, a binding for the logger facade is the only additional dependency. Therefore we’ll use logback-classic as in the first example.
现在让我们来看看更高的版本。它包含重新设计的日志。因此,它利用 SLF4J 而不是 Commons Logging。因此,对日志器界面的绑定是唯一的额外依赖。因此,我们将使用logback-classic作为第一个例子。
Let’s add the httpclient5 dependency:
让我们添加httpclient5依赖性。
<dependency>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
<version>5.1</version>
</dependency>
Let’s add a similar test as in the previous example:
让我们添加一个与前面例子类似的测试。
public class ApacheHttpClient5UnitTest {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
public static final String DUMMY_URL = "https://postman-echo.com/get";
@Test
public void whenUseApacheHttpClient_thenCorrect() throws IOException, ParseException {
HttpGet request = new HttpGet(DUMMY_URL);
try (CloseableHttpClient client = HttpClients.createDefault(); CloseableHttpResponse response = client.execute(request)) {
HttpEntity entity = response.getEntity();
logger.debug("Response -> {}", EntityUtils.toString(entity));
}
}
}
Next, we need to add a logger to the logback.xml file:
接下来,我们需要在 logback.xml文件中添加一个记录器。
<configuration debug="false">
...
<logger name="org.apache.hc.client5.http" level="debug"/>
...
</configuration>
Let’s run the test class ApacheHttpClient5UnitTest and check the output. It is similar to the old version:
让我们运行测试类ApacheHttpClient5UnitTest并检查输出。它与旧版本相似。
...
2021-06-19 22:27:16,944 [DEBUG] org.apache.hc.client5.http.impl.classic.InternalHttpClient - ep-0000000000 endpoint connected
2021-06-19 22:27:16,944 [DEBUG] org.apache.hc.client5.http.impl.classic.MainClientExec - ex-0000000001 executing GET /get HTTP/1.1
2021-06-19 22:27:16,944 [DEBUG] org.apache.hc.client5.http.impl.classic.InternalHttpClient - ep-0000000000 start execution ex-0000000001
2021-06-19 22:27:16,944 [DEBUG] org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager - ep-0000000000 executing exchange ex-0000000001 over http-outgoing-0
2021-06-19 22:27:16,960 [DEBUG] org.apache.hc.client5.http.headers - http-outgoing-0 >> GET /get HTTP/1.1
...
5. Conclusion
5.总结
That concludes this short tutorial on how to configure logging for Apache’s HttpClient. Firstly, we explained how logging is implemented in the library. Secondly, we configured logging in two versions and executed simple test cases to show the output.
这个关于如何为Apache的HttpClient配置日志的简短教程到此结束。首先,我们解释了日志是如何在库中实现的。其次,我们在两个版本中配置了日志,并执行了简单的测试案例来显示输出。
As always, the source code of the example is available over on GitHub.
一如既往,该示例的源代码可在GitHub上获得over。