diff --git a/src/main/java/de/caritas/cob/userservice/api/helper/LogstashAppender.java b/src/main/java/de/caritas/cob/userservice/api/helper/LogstashAppender.java deleted file mode 100644 index cd4c1a180..000000000 --- a/src/main/java/de/caritas/cob/userservice/api/helper/LogstashAppender.java +++ /dev/null @@ -1,143 +0,0 @@ -package de.caritas.cob.userservice.api.helper; - -import static java.util.concurrent.CompletableFuture.supplyAsync; - -import ch.qos.logback.classic.spi.ILoggingEvent; -import ch.qos.logback.core.AppenderBase; -import ch.qos.logback.core.encoder.Encoder; -import ch.qos.logback.core.spi.DeferredProcessingAware; -import com.google.common.collect.Lists; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.io.UnsupportedEncodingException; -import java.util.ArrayList; -import java.util.Collection; -import lombok.SneakyThrows; -import net.logstash.logback.encoder.StreamingEncoder; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.HttpPut; -import org.apache.http.entity.StringEntity; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClientBuilder; - -public class LogstashAppender - extends AppenderBase { - - private int connectionTimeoutMillis = 300; // default value - private int logBufferSize = 20; // default value - private String logstashHost; - private Encoder encoder; - private ArrayList bufferedJsonLogRequests = Lists.newArrayListWithCapacity(100); - - @SneakyThrows - @Override - protected void append(ILoggingEvent event) { - if (!isLogstashEnvVariableSet()) { - return; - } - - serializeEventAndAddToBuffer((T) event); - if (isBufferSizeExceeded()) { - sendRequestsAsynchronously(); - } - } - - private boolean isLogstashEnvVariableSet() { - this.logstashHost = getLogstashHost(); - if (logstashHost == null) { - logToStandardError( - "Logstash env variable (LOGSTASH_HOST) not set, skipping logging to logstash"); - return false; - } - return true; - } - - private void serializeEventAndAddToBuffer(T event) { - bufferedJsonLogRequests.add(serializeToJson(event)); - } - - private boolean isBufferSizeExceeded() { - return bufferedJsonLogRequests.size() % logBufferSize == 0; - } - - private void sendRequestsAsynchronously() { - ArrayList bufferCopy = new ArrayList<>(bufferedJsonLogRequests); - supplyAsync(() -> sendPackageToLogstash(bufferCopy)); - bufferedJsonLogRequests.clear(); - } - - private String sendPackageToLogstash(Collection logsSerializedToJson) { - try (CloseableHttpClient client = getHttpClient()) { - for (String log : logsSerializedToJson) { - client.execute(prepareHttpPutRequest(log)); - } - return "success"; - } catch (IOException e) { - handleIOException(e); - return "error"; - } - } - - CloseableHttpClient getHttpClient() { - RequestConfig config = - RequestConfig.custom() - .setConnectTimeout(connectionTimeoutMillis) - .setConnectionRequestTimeout(connectionTimeoutMillis) - .setSocketTimeout(connectionTimeoutMillis) - .build(); - return HttpClientBuilder.create().setDefaultRequestConfig(config).build(); - } - - private void handleIOException(IOException e) { - logToStandardError("IO Exception during http call to logstash endpoint"); - e.printStackTrace(); - } - - protected String getLogstashHost() { - return System.getenv("LOGSTASH_HOST"); - } - - private HttpPut prepareHttpPutRequest(String json) throws UnsupportedEncodingException { - HttpPut httpPut = new HttpPut(logstashHost); - StringEntity entity = new StringEntity(json); - httpPut.setEntity(entity); - httpPut.setHeader("Content-type", "application/json"); - return httpPut; - } - - private String serializeToJson(T event) { - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - this.encode(event, outputStream); - return outputStream.toString(); - } - - private void encode(T event, OutputStream outputStream) { - if (this.encoder instanceof StreamingEncoder) { - try { - ((StreamingEncoder) this.encoder).encode(event, outputStream); - } catch (Exception e) { - logToStandardError("Encoder exception occurred. Logs may not be delivered to logstash"); - e.printStackTrace(); - } - } else { - logToStandardError("Encoder is not an instance of streaming encoder. "); - } - } - - private void logToStandardError(String msg) { - System.err.println(msg); - } - - public void setEncoder(Encoder encoder) { - this.encoder = encoder; - } - - public void setLogBufferSize(int logBufferSize) { - this.logBufferSize = logBufferSize; - } - - public void setConnectionTimeoutMillis(int connectionTimeoutMillis) { - this.connectionTimeoutMillis = connectionTimeoutMillis; - } -} diff --git a/src/main/resources/logback-spring.xml b/src/main/resources/logback-spring.xml index b05ccb790..3d3bbc521 100644 --- a/src/main/resources/logback-spring.xml +++ b/src/main/resources/logback-spring.xml @@ -1,42 +1,6 @@ - - true - - %d{yyyy.MMM.dd HH:mm:ss.SSS} %level - %msg%n - - log/userservice.log - - - 20 - 400 - - - - - - { - "serviceName": "users", - "timestamp": "%date{yyyy-MM-dd'T'HH:mm:ss.SSS'Z',UTC}", - "request": { - "correlationId": "%mdc{CID:-null}", - "timestamp": "%date{yyyy-MM-dd'T'HH:mm:ss.SSS'Z',UTC}" - }, - "log": { - "level": "%level", - "levelValue": "#asLong{%relative}", - "logger": "%logger", - "message": "%message", - "thread": "%thread", - "stack": "%replace(%replace(%rEx){'\n','\\\\n'}){'\t','\\\\t'}" - } - } - - - - - @@ -66,8 +30,6 @@ - - diff --git a/src/test/java/de/caritas/cob/userservice/api/helper/LogstashAppenderTest.java b/src/test/java/de/caritas/cob/userservice/api/helper/LogstashAppenderTest.java deleted file mode 100644 index 932b8cf5a..000000000 --- a/src/test/java/de/caritas/cob/userservice/api/helper/LogstashAppenderTest.java +++ /dev/null @@ -1,83 +0,0 @@ -package de.caritas.cob.userservice.api.helper; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.timeout; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoInteractions; - -import ch.qos.logback.classic.spi.ILoggingEvent; -import ch.qos.logback.core.encoder.Encoder; -import java.io.IOException; -import java.io.OutputStream; -import lombok.Setter; -import net.logstash.logback.encoder.StreamingEncoder; -import org.apache.http.client.methods.HttpPut; -import org.apache.http.impl.client.CloseableHttpClient; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -@ExtendWith(MockitoExtension.class) -class LogstashAppenderTest { - - private static final int LOG_BUFFER_SIZE = 2; - - @InjectMocks TestableLogstashAppender logstashAppender = getTestableLogstashAppender(); - - private TestableLogstashAppender getTestableLogstashAppender() { - TestableLogstashAppender testableLogstashAppender = new TestableLogstashAppender(); - testableLogstashAppender.setLogBufferSize(LOG_BUFFER_SIZE); - return testableLogstashAppender; - } - - @Mock CloseableHttpClient closeableHttpClientMock; - - @Mock CustomStreamingEncoder streamingEncoder; - - @Mock ILoggingEvent loggingEvent; - - @Test - void append_Should_callLogbackEndpointIfNumberOfLogsExceedBufferSize() - throws IOException, InterruptedException { - // when - logstashAppender.append(loggingEvent); - logstashAppender.append(loggingEvent); - logstashAppender.append(loggingEvent); - // then - verify(streamingEncoder, timeout(1000).times(3)) - .encode(eq(loggingEvent), any(OutputStream.class)); - verify(closeableHttpClientMock, timeout(1000).times(2)).execute(any(HttpPut.class)); - } - - @Test - void append_Should_Not_CallLogbackEndpointIfEnvironmentVariableNotSet() throws IOException { - // given - logstashAppender = getTestableLogstashAppender(); - logstashAppender.setLogstashHost(null); - // when - logstashAppender.append(loggingEvent); - // then - verifyNoInteractions(streamingEncoder); - verifyNoInteractions(closeableHttpClientMock); - } - - @Setter - private class TestableLogstashAppender extends LogstashAppender { - - private String logstashHost = "http://logstash.default"; - - protected String getLogstashHost() { - return logstashHost; - } - - @Override - protected CloseableHttpClient getHttpClient() { - return closeableHttpClientMock; - } - } - - private interface CustomStreamingEncoder extends Encoder, StreamingEncoder {} -}