我们有一个Elastic Search appender
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.AppenderBase;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.net.InetAddress;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.apache.commons.codec.binary.Base64;
import org.apache.http.HttpHost;
import org.apache.http.impl.nio.reactor.IOReactorConfig;
import org.elasticsearch.ElasticsearchStatusException;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.common.xcontent.XContentType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ElasticSearchAppender extends AppenderBase<ILoggingEvent> {
private static final Logger log = LoggerFactory.getLogger(ElasticSearchAppender.class);
private static ObjectMapper mapper = new ObjectMapper();
private static RestHighLevelClient elastic;
private ExecutorService executorService = Executors.newFixedThreadPool(10);
private static RequestOptions COMMON_OPTIONS;
private String hostname;
private Integer port;
private String index;
private String application;
private String login;
private String password;
public ElasticSearchAppender() {
}
public String getLogin() {
return this.login;
}
public void setLogin(String login) {
this.login = login;
}
public String getPassword() {
return this.password;
}
public void setPassword(String password) {
this.password = password;
}
public String getApplication() {
return this.application;
}
public void setApplication(String application) {
this.application = application;
}
public String getHostname() {
return this.hostname;
}
public void setHostname(String hostname) {
this.hostname = hostname;
}
public Integer getPort() {
return this.port;
}
public void setPort(Integer port) {
this.port = port;
}
public String getIndex() {
return this.index;
}
public void setIndex(String index) {
this.index = index;
}
protected void append(ILoggingEvent event) {
if (elastic == null) {
this.createElasticConnection(this.hostname, this.port);
try {
CreateIndexRequest createIndexRequest = new CreateIndexRequest(this.index);
createIndexRequest.source(mapper.writeValueAsString(new Message(InetAddress.getLocalHost().getHostName(), LocalDateTime.ofInstant(Instant.ofEpochMilli(event.getTimeStamp()), ZoneOffset.UTC).toString(), event.getLevel().toString(), event.getLoggerName(), event.getMDCPropertyMap(), event.getFormattedMessage(), this.application)), XContentType.JSON);
elastic.indices().create(createIndexRequest, COMMON_OPTIONS);
} catch (ElasticsearchStatusException var3) {
log.error(var3.getMessage(), var3);
} catch (IOException var4) {
}
} else {
this.executorService.submit(() -> {
try {
IndexRequest indexRequest = new IndexRequest(this.index);
indexRequest.source(mapper.writeValueAsString(new Message(InetAddress.getLocalHost().getHostName(), LocalDateTime.ofInstant(Instant.ofEpochMilli(event.getTimeStamp()), ZoneOffset.UTC).toString(), event.getLevel().toString(), event.getLoggerName(), event.getMDCPropertyMap(), event.getFormattedMessage(), this.application)), XContentType.JSON);
elastic.index(indexRequest, COMMON_OPTIONS);
} catch (IOException var3) {
}
});
}
}
private void createElasticConnection(String hostname, int port) {
elastic = new RestHighLevelClient(RestClient.builder(new HttpHost[]{new HttpHost(hostname, port, "http")}).setRequestConfigCallback((requestConfigBuilder) -> {
return requestConfigBuilder.setConnectTimeout(5000).setSocketTimeout(60000);
}).setHttpClientConfigCallback((httpClientBuilder) -> {
return httpClientBuilder.setDefaultIOReactorConfig(IOReactorConfig.custom().setIoThreadCount(200).build());
}));
RequestOptions.Builder builder = RequestOptions.DEFAULT.toBuilder();
builder.addHeader("Authorization", "Basic " + Base64.encodeBase64String((this.login + ":" + this.password).getBytes()));
COMMON_OPTIONS = builder.build();
}
private class Message {
private String hostname;
private String time;
private String level;
private String loggerName;
private Map<String, String> mdcProperty;
private String msg;
private String applicationName;
public String getHostname() {
return this.hostname;
}
public String getTime() {
return this.time;
}
public String getLevel() {
return this.level;
}
public String getLoggerName() {
return this.loggerName;
}
public Map<String, String> getMdcProperty() {
return this.mdcProperty;
}
public String getMsg() {
return this.msg;
}
public String getApplicationName() {
return this.applicationName;
}
public void setHostname(String hostname) {
this.hostname = hostname;
}
public void setTime(String time) {
this.time = time;
}
public void setLevel(String level) {
this.level = level;
}
public void setLoggerName(String loggerName) {
this.loggerName = loggerName;
}
public void setMdcProperty(Map<String, String> mdcProperty) {
this.mdcProperty = mdcProperty;
}
public void setMsg(String msg) {
this.msg = msg;
}
public void setApplicationName(String applicationName) {
this.applicationName = applicationName;
}
public Message() {
}
public Message(String hostname, String time, String level, String loggerName, Map<String, String> mdcProperty, String msg, String applicationName) {
this.hostname = hostname;
this.time = time;
this.level = level;
this.loggerName = loggerName;
this.mdcProperty = mdcProperty;
this.msg = msg;
this.applicationName = applicationName;
}
}
}
当我们把它放在logback.xml
中时
<appender name="Elastic" class="***.log.appender.ElasticSearchAppender">
<hostname>${elkHostname}</hostname>
<port>${elkPort}</port>
<index>${elkIndex}</index>
<application>${applicationName}</application>
<login>${login}</login>
<password>${password}</password>
</appender>
如果我们能够
<logger name="org.apache.http" level="debug" additivity="false">
<appender-ref ref="STDOUT"/>
<appender-ref ref="Elastic"/>
</logger>
然后,根据我们的日志,我们的应用程序在第一个http调用caomint时挂起,或者由应用程序启动
1条答案
按热度按时间jdgnovmf1#
事实证明,由于
org.apache.http
logger,Elastic发起的调用本身应该由Elastic appender记录,因为Elastic执行http调用。因此,它变成了递归和堆栈溢出。但在日志中,它看起来就像什么也没发生。
要解决这个问题,就要避免对
org.apache.http
logger使用Elastic appender。