mirror of
https://github.com/tiennm99/tjahzi.git
synced 2026-10-13 22:16:25 +00:00
Re #4: Added ability to pass preconfigured headers in every http call to Loki.
This commit is contained in:
1 parent
06b212f425
commit
a42a9cdbed
7 files changed
+252
-22
No files matched your search
@@ -20,11 +20,13 @@ import pl.tkowalcz.tjahzi.http.HttpClientFactory;
|
||||
import pl.tkowalcz.tjahzi.http.NettyHttpClient;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static java.util.Arrays.stream;
|
||||
|
||||
/**
|
||||
* Loki Appender.
|
||||
@@ -81,9 +83,16 @@ public class LokiAppender extends AbstractAppender {
|
||||
.withRequestTimeoutMillis(readTimeoutMillis)
|
||||
.build();
|
||||
|
||||
String[] additionalHeaders = stream(headers)
|
||||
.flatMap(header -> Stream.of(header.getName(), header.getValue()))
|
||||
.toArray(String[]::new);
|
||||
|
||||
NettyHttpClient httpClient = HttpClientFactory
|
||||
.defaultFactory()
|
||||
.getHttpClient(configurationBuilder);
|
||||
.getHttpClient(
|
||||
configurationBuilder,
|
||||
additionalHeaders
|
||||
);
|
||||
|
||||
LoggingSystem loggingSystem = new TjahziInitializer().createLoggingSystem(
|
||||
httpClient,
|
||||
@@ -92,17 +101,7 @@ public class LokiAppender extends AbstractAppender {
|
||||
);
|
||||
|
||||
HashMap<String, String> lokiLabels = Maps.newHashMap();
|
||||
Arrays.stream(labels).forEach(property -> {
|
||||
String value = getConfiguration()
|
||||
.getStrSubstitutor()
|
||||
.replace(property.getValue());
|
||||
|
||||
lokiLabels.put(
|
||||
property.getName(),
|
||||
value
|
||||
);
|
||||
}
|
||||
);
|
||||
stream(labels).forEach(__ -> lokiLabels.put(__.getName(), __.getValue()));
|
||||
|
||||
return new LokiAppender(
|
||||
getName(),
|
||||
@@ -218,7 +217,10 @@ public class LokiAppender extends AbstractAppender {
|
||||
);
|
||||
|
||||
Objects.requireNonNull(layout, "layout");
|
||||
this.appenderLogic = new AppenderLogic(loggingSystem, lokiLabels);
|
||||
this.appenderLogic = new AppenderLogic(
|
||||
loggingSystem,
|
||||
lokiLabels
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -48,6 +48,13 @@
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.github.tomakehurst</groupId>
|
||||
<artifactId>wiremock-jre8</artifactId>
|
||||
<version>2.27.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Testcontainers -->
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
|
||||
@@ -4,8 +4,13 @@ public class HttpClientFactory {
|
||||
|
||||
private static final HttpClientFactory INSTANCE = new HttpClientFactory();
|
||||
|
||||
public NettyHttpClient getHttpClient(ClientConfiguration clientConfiguration) {
|
||||
return new NettyHttpClient(clientConfiguration);
|
||||
public NettyHttpClient getHttpClient(
|
||||
ClientConfiguration clientConfiguration,
|
||||
String[] additionalHeaders) {
|
||||
return new NettyHttpClient(
|
||||
clientConfiguration,
|
||||
additionalHeaders
|
||||
);
|
||||
}
|
||||
|
||||
public static HttpClientFactory defaultFactory() {
|
||||
|
||||
@@ -15,15 +15,20 @@ import java.util.concurrent.ThreadFactory;
|
||||
|
||||
public class NettyHttpClient implements AutoCloseable {
|
||||
|
||||
public static final String PROTOBUF_MIME_TYPE = "application/x-protobuf";
|
||||
|
||||
private final EventLoopGroup group;
|
||||
private final String logEndpoint;
|
||||
|
||||
private final Channel channel;
|
||||
private final String host;
|
||||
private final HttpHeaders headers;
|
||||
|
||||
private final Snappy snappy = new Snappy();
|
||||
|
||||
public NettyHttpClient(ClientConfiguration clientConfiguration) {
|
||||
public NettyHttpClient(
|
||||
ClientConfiguration clientConfiguration,
|
||||
String[] additionalHeaders) {
|
||||
host = clientConfiguration.getHost();
|
||||
logEndpoint = clientConfiguration.getLogEndpoint();
|
||||
|
||||
@@ -46,6 +51,11 @@ public class NettyHttpClient implements AutoCloseable {
|
||||
.connect()
|
||||
.syncUninterruptibly()
|
||||
.channel();
|
||||
|
||||
headers = new ReadOnlyHttpHeaders(
|
||||
true,
|
||||
additionalHeaders
|
||||
);
|
||||
}
|
||||
|
||||
public void log(ByteBuf dataBuffer) {
|
||||
@@ -59,9 +69,11 @@ public class NettyHttpClient implements AutoCloseable {
|
||||
output
|
||||
);
|
||||
|
||||
request.headers().set(HttpHeaderNames.CONTENT_TYPE, "application/x-protobuf");
|
||||
request.headers().set(HttpHeaderNames.CONTENT_LENGTH, output.readableBytes());
|
||||
request.headers().set(HttpHeaderNames.HOST, host);
|
||||
request.headers()
|
||||
.add(headers)
|
||||
.set(HttpHeaderNames.CONTENT_TYPE, PROTOBUF_MIME_TYPE)
|
||||
.set(HttpHeaderNames.CONTENT_LENGTH, output.readableBytes())
|
||||
.set(HttpHeaderNames.HOST, host);
|
||||
|
||||
channel.writeAndFlush(request);
|
||||
}
|
||||
|
||||
@@ -54,7 +54,10 @@ class LoggingSystemSanityCheckTest {
|
||||
.build();
|
||||
|
||||
NettyHttpClient httpClient = HttpClientFactory.defaultFactory()
|
||||
.getHttpClient(clientConfiguration);
|
||||
.getHttpClient(
|
||||
clientConfiguration,
|
||||
new String[0]
|
||||
);
|
||||
|
||||
TjahziInitializer initializer = new TjahziInitializer();
|
||||
LoggingSystem loggingSystem = initializer.createLoggingSystem(
|
||||
|
||||
@@ -0,0 +1,198 @@
|
||||
package pl.tkowalcz.tjahzi;
|
||||
|
||||
import com.github.tomakehurst.wiremock.WireMockServer;
|
||||
import org.awaitility.Durations;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import pl.tkowalcz.tjahzi.http.ClientConfiguration;
|
||||
import pl.tkowalcz.tjahzi.http.HttpClientFactory;
|
||||
import pl.tkowalcz.tjahzi.http.NettyHttpClient;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static com.github.tomakehurst.wiremock.client.WireMock.*;
|
||||
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
|
||||
import static org.awaitility.Awaitility.await;
|
||||
|
||||
class HeadersTest {
|
||||
|
||||
private WireMockServer wireMockServer;
|
||||
|
||||
private TjahziInitializer initializer;
|
||||
private LoggingSystem loggingSystem;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
wireMockServer = new WireMockServer(
|
||||
wireMockConfig()
|
||||
.dynamicPort()
|
||||
.dynamicHttpsPort()
|
||||
);
|
||||
|
||||
wireMockServer.start();
|
||||
|
||||
initializer = new TjahziInitializer();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void tearDown() {
|
||||
wireMockServer.stop();
|
||||
|
||||
if (loggingSystem != null) {
|
||||
loggingSystem.close(
|
||||
(int) TimeUnit.SECONDS.toMillis(10),
|
||||
System.out::println
|
||||
);
|
||||
|
||||
loggingSystem = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldIncludeAdditionalHeaders() {
|
||||
// Given
|
||||
wireMockServer.stubFor(
|
||||
get(urlEqualTo("/loki/api/v1/push"))
|
||||
.willReturn(
|
||||
aResponse().withStatus(200)
|
||||
));
|
||||
|
||||
ClientConfiguration clientConfiguration = ClientConfiguration.builder()
|
||||
.withConnectionTimeoutMillis(10_000)
|
||||
.withHost("localhost")
|
||||
.withPort(wireMockServer.port())
|
||||
.withMaxRetries(1)
|
||||
.build();
|
||||
|
||||
NettyHttpClient httpClient = HttpClientFactory.defaultFactory()
|
||||
.getHttpClient(
|
||||
clientConfiguration,
|
||||
new String[]{
|
||||
"X-Scope-OrgID", "Circus",
|
||||
"C", "Control"
|
||||
}
|
||||
);
|
||||
|
||||
LoggingSystem loggingSystem = initializer.createLoggingSystem(
|
||||
httpClient,
|
||||
1024 * 1024,
|
||||
false
|
||||
);
|
||||
|
||||
// WHen
|
||||
TjahziLogger logger = loggingSystem.createLogger();
|
||||
logger.log(
|
||||
System.currentTimeMillis(),
|
||||
Map.of(),
|
||||
"Test"
|
||||
);
|
||||
|
||||
// Then
|
||||
await()
|
||||
.atMost(Durations.FIVE_SECONDS)
|
||||
.untilAsserted(() ->
|
||||
wireMockServer.verify(
|
||||
postRequestedFor(urlMatching("/loki/api/v1/push"))
|
||||
.withHeader("X-Scope-OrgID", equalTo("Circus"))
|
||||
));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldHandleCaseWithNoAdditionalHeaders() {
|
||||
// Given
|
||||
wireMockServer.stubFor(
|
||||
get(urlEqualTo("/loki/api/v1/push"))
|
||||
.willReturn(
|
||||
aResponse().withStatus(200)
|
||||
));
|
||||
|
||||
ClientConfiguration clientConfiguration = ClientConfiguration.builder()
|
||||
.withConnectionTimeoutMillis(10_000)
|
||||
.withHost("localhost")
|
||||
.withPort(wireMockServer.port())
|
||||
.withMaxRetries(1)
|
||||
.build();
|
||||
|
||||
NettyHttpClient httpClient = HttpClientFactory.defaultFactory()
|
||||
.getHttpClient(
|
||||
clientConfiguration,
|
||||
new String[0]
|
||||
);
|
||||
|
||||
LoggingSystem loggingSystem = initializer.createLoggingSystem(
|
||||
httpClient,
|
||||
1024 * 1024,
|
||||
false
|
||||
);
|
||||
|
||||
// WHen
|
||||
TjahziLogger logger = loggingSystem.createLogger();
|
||||
logger.log(
|
||||
System.currentTimeMillis(),
|
||||
Map.of(),
|
||||
"Test"
|
||||
);
|
||||
|
||||
// Then
|
||||
await()
|
||||
.atMost(Durations.FIVE_SECONDS)
|
||||
.untilAsserted(() ->
|
||||
wireMockServer.verify(
|
||||
postRequestedFor(urlMatching("/loki/api/v1/push"))
|
||||
));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotOverrideCrucialHeaders() {
|
||||
// Given
|
||||
wireMockServer.stubFor(
|
||||
get(urlEqualTo("/loki/api/v1/push"))
|
||||
.willReturn(
|
||||
aResponse().withStatus(200)
|
||||
));
|
||||
|
||||
ClientConfiguration clientConfiguration = ClientConfiguration.builder()
|
||||
.withConnectionTimeoutMillis(10_000)
|
||||
.withHost("localhost")
|
||||
.withPort(wireMockServer.port())
|
||||
.withMaxRetries(1)
|
||||
.build();
|
||||
|
||||
NettyHttpClient httpClient = HttpClientFactory.defaultFactory()
|
||||
.getHttpClient(
|
||||
clientConfiguration,
|
||||
new String[]{
|
||||
"content-type", "text/plain",
|
||||
"content-length", "5232423423",
|
||||
"host", "remote"
|
||||
}
|
||||
);
|
||||
|
||||
LoggingSystem loggingSystem = initializer.createLoggingSystem(
|
||||
httpClient,
|
||||
1024 * 1024,
|
||||
false
|
||||
);
|
||||
|
||||
// When
|
||||
TjahziLogger logger = loggingSystem.createLogger();
|
||||
logger.log(
|
||||
System.currentTimeMillis(),
|
||||
Map.of(),
|
||||
"Test"
|
||||
);
|
||||
|
||||
// Then
|
||||
await()
|
||||
.atMost(Durations.FIVE_SECONDS)
|
||||
.untilAsserted(() ->
|
||||
wireMockServer.verify(
|
||||
postRequestedFor(urlMatching("/loki/api/v1/push"))
|
||||
.withHeader("content-type", matching("application/x-protobuf"))
|
||||
.withHeader("content-length", matching("29|30"))
|
||||
.withHeader("host", matching("localhost"))
|
||||
));
|
||||
}
|
||||
}
|
||||
+4
-1
@@ -57,7 +57,10 @@ class LoggingSystemTest {
|
||||
.build();
|
||||
|
||||
NettyHttpClient httpClient = HttpClientFactory.defaultFactory()
|
||||
.getHttpClient(clientConfiguration);
|
||||
.getHttpClient(
|
||||
clientConfiguration,
|
||||
new String[0]
|
||||
);
|
||||
|
||||
TjahziInitializer initializer = new TjahziInitializer();
|
||||
LoggingSystem loggingSystem = initializer.createLoggingSystem(
|
||||
Reference in new issue
Block a user