Spring boot 版本
我用的 Spring boot 版本是 2.4.x,其实 2.2.x 以上都可以使用这种方法
第一种解决方案
application.properties 配置文件加上 :
logging.level.org.springframework.data.elasticsearch.client.WIRE : trace
复制代码
但必须要自定义初始化 RestHighLevelClient bean,如下:
@Bean(destroyMethod = "close")
public RestHighLevelClient restClient() {
ClientConfiguration clientConfiguration = ClientConfiguration.builder()
.connectedTo(esHost +":" + esPort).usingSsl()
.build();
RestHighLevelClient client = RestClients.create(clientConfiguration).rest();
return client;
}
复制代码
原理是方法 RestClients.create 做了http拦截,如果用默认的 RestHighLevelClient 将没有这个功能,所以会不起效果。
第二种解决方案
上述方案虽然可以解决问题,但是不能使用 ElasticsearchRestClientProperties 作为配置文件,由于不想再多弄一份elasticsearch配置,可以根据第一种方案的实现原理,自定义实现 RestClientBuilderCustomizer 来扩展 RestHighLevelClient 特性,实现类如下:
package com.example.config;
import org.apache.http.HttpEntity;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpRequest;
import org.apache.http.HttpRequestInterceptor;
import org.apache.http.HttpResponse;
import org.apache.http.HttpResponseInterceptor;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
import org.apache.http.protocol.HttpContext;
import org.elasticsearch.client.RestClientBuilder;
import org.springframework.boot.autoconfigure.elasticsearch.RestClientBuilderCustomizer;
import org.springframework.data.elasticsearch.client.ClientLogger;
import org.springframework.data.elasticsearch.client.RestClients;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
/**
* 自定义一些特性
*
* @see org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientAutoConfiguration
*/
@Component
public class CustomRestClientBuilderCustomizer implements RestClientBuilderCustomizer {
/**
* Name of whose value can be used to correlate log messages for this request.
*/
private static final String LOG_ID_ATTRIBUTE = RestClients.class.getName() + ".LOG_ID";
@Override
public void customize(RestClientBuilder builder) {
}
@Override
public void customize(HttpAsyncClientBuilder builder) {
if (ClientLogger.isEnabled()) {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
builder.addInterceptorLast((HttpRequestInterceptor) interceptor);
builder.addInterceptorLast((HttpResponseInterceptor) interceptor);
}
}
/**
* 由于自动装配 RestHighLevelClient 没有使用 spring data elasticsearch 相关的类,导致打印日志不能兼容
*
* @see RestClients.HttpLoggingInterceptor
*/
private static class HttpLoggingInterceptor implements HttpResponseInterceptor, HttpRequestInterceptor {
@Override
public void process(HttpRequest request, HttpContext context) throws IOException {
String logId = (String) context.getAttribute(LOG_ID_ATTRIBUTE);
if (logId == null) {
logId = ClientLogger.newLogId();
context.setAttribute(LOG_ID_ATTRIBUTE, logId);
}
if (request instanceof HttpEntityEnclosingRequest && ((HttpEntityEnclosingRequest) request).getEntity() != null) {
HttpEntityEnclosingRequest entityRequest = (HttpEntityEnclosingRequest) request;
HttpEntity entity = ((HttpEntityEnclosingRequest) request).getEntity();
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
entity.writeTo(buffer);
if (!entity.isRepeatable()) {
entityRequest.setEntity(new ByteArrayEntity(buffer.toByteArray()));
}
ClientLogger.logRequest(logId, request.getRequestLine().getMethod(), request.getRequestLine().getUri(), "",
buffer::toString);
} else {
ClientLogger.logRequest(logId, request.getRequestLine().getMethod(), request.getRequestLine().getUri(), "");
}
}
@Override
public void process(HttpResponse response, HttpContext context) {
String logId = (String) context.getAttribute(LOG_ID_ATTRIBUTE);
ClientLogger.logRawResponse(logId, HttpStatus.resolve(response.getStatusLine().getStatusCode()));
}
}
}
复制代码
这样使用 HttpLoggingInterceptor 对 HttpAsyncClient 做拦截,打印日志。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END