Skip to content

Commit

Permalink
Add additional opentelemetry configuration values (#1093)
Browse files Browse the repository at this point in the history
* Added additional OpenTelemetry configuration values to YAML

Signed-off-by: dhoard <[email protected]>
  • Loading branch information
dhoard authored Dec 9, 2024
1 parent 634a9f3 commit e4a4f45
Show file tree
Hide file tree
Showing 12 changed files with 454 additions and 94 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
package io.prometheus.jmx.test.opentelemetry;

import static org.assertj.core.api.Assertions.assertThat;

import io.prometheus.jmx.test.support.JmxExporterMode;
import io.prometheus.jmx.test.support.OpenTelemetryTestEnvironment;
import io.prometheus.jmx.test.support.TestSupport;
import io.prometheus.jmx.test.support.http.HttpClient;
import io.prometheus.jmx.test.support.http.HttpResponse;
import io.prometheus.jmx.test.support.throttle.ExponentialBackoffThrottle;
import io.prometheus.jmx.test.support.throttle.Throttle;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.testcontainers.containers.Network;
import org.verifyica.api.ArgumentContext;
import org.verifyica.api.ClassContext;
import org.verifyica.api.Trap;
import org.verifyica.api.Verifyica;
import org.yaml.snakeyaml.Yaml;

/** Class to implement BasicTest */
public class CompleteTest {

@Verifyica.ArgumentSupplier(parallelism = Integer.MAX_VALUE)
public static Stream<OpenTelemetryTestEnvironment> arguments() {
return OpenTelemetryTestEnvironment.createOpenTelemetryTestEnvironments();
}

@Verifyica.Prepare
public static void prepare(ClassContext classContext) {
TestSupport.getOrCreateNetwork(classContext);
}

@Verifyica.BeforeAll
public void beforeAll(ArgumentContext argumentContext) {
Class<?> testClass = argumentContext.classContext().testClass();
Network network = TestSupport.getOrCreateNetwork(argumentContext);
TestSupport.initializeOpenTelemetryTestEnvironment(argumentContext, network, testClass);
}

/** Method to test that Prometheus is up */
@Verifyica.Test
@Verifyica.Order(1)
public void testPrometheusIsUp(OpenTelemetryTestEnvironment openTelemetryTestEnvironment)
throws IOException {
Throttle throttle = new ExponentialBackoffThrottle(100, 5000);
boolean isUp = false;

for (int i = 0; i < 10; i++) {
HttpResponse httpResponse = sendPrometheusQuery(openTelemetryTestEnvironment, "up");

if (httpResponse.statusCode() == 200) {
assertThat(httpResponse.body()).isNotNull();
assertThat(httpResponse.body().string()).isNotNull();

Map<Object, Object> map = new Yaml().load(httpResponse.body().string());

String status = (String) map.get("status");
assertThat(status).isEqualTo("success");

isUp = true;
break;
} else {
throttle.throttle();
}
}

assertThat(isUp).withFailMessage("Prometheus is down").isTrue();
}

/** Method to test that metrics exist in Prometheus */
@Verifyica.Test
@Verifyica.Order(2)
public void testPrometheusHasMetrics(OpenTelemetryTestEnvironment openTelemetryTestEnvironment)
throws IOException {
boolean isJmxExporterModeJavaStandalone =
openTelemetryTestEnvironment.getJmxExporterMode() == JmxExporterMode.Standalone;

for (String metricName :
ExpectedMetricsNames.getMetricsNames().stream()
.filter(
metricName ->
!isJmxExporterModeJavaStandalone
|| (!metricName.startsWith("jvm_")
&& !metricName.startsWith("process_")))
.collect(Collectors.toList())) {
Double value = getPrometheusMetric(openTelemetryTestEnvironment, metricName);

assertThat(value).as("metricName [%s]", metricName).isNotNull();
assertThat(value).as("metricName [%s]", metricName).isEqualTo(1);
}
}

@Verifyica.AfterAll
public void afterAll(ArgumentContext argumentContext) throws Throwable {
List<Trap> traps = new ArrayList<>();

traps.add(new Trap(() -> TestSupport.destroyOpenTelemetryTestEnvironment(argumentContext)));
traps.add(new Trap(() -> TestSupport.destroyNetwork(argumentContext)));

Trap.assertEmpty(traps);
}

@Verifyica.Conclude
public static void conclude(ClassContext classContext) throws Throwable {
new Trap(() -> TestSupport.destroyNetwork(classContext)).assertEmpty();
}

/**
* Method to get a Prometheus metric
*
* @param openTelemetryTestEnvironment openTelemetryTestEnvironment
* @param metricName metricName
* @return the metric value, or null if it doesn't exist
*/
protected Double getPrometheusMetric(
OpenTelemetryTestEnvironment openTelemetryTestEnvironment, String metricName)
throws IOException {
Throttle throttle = new ExponentialBackoffThrottle(100, 5000);
Double value = null;

for (int i = 0; i < 10; i++) {
HttpResponse httpResponse =
sendPrometheusQuery(openTelemetryTestEnvironment, metricName);

assertThat(httpResponse.statusCode()).isEqualTo(200);
assertThat(httpResponse.body()).isNotNull();
assertThat(httpResponse.body().string()).isNotNull();

// TODO parse response and return value
if (httpResponse.body().string().contains(metricName)) {
value = 1.0;
break;
}

throttle.throttle();
}

return value;
}

/**
* Method to send a Prometheus query
*
* @param openTelemetryTestEnvironment openTelemetryTestEnvironment
* @param query query
* @return an HttpResponse
*/
protected HttpResponse sendPrometheusQuery(
OpenTelemetryTestEnvironment openTelemetryTestEnvironment, String query)
throws IOException {
return sendRequest(
openTelemetryTestEnvironment,
"/api/v1/query?query=" + URLEncoder.encode(query, StandardCharsets.UTF_8));
}

/**
* Method to send a Http GET request
*
* @param openTelemetryTestEnvironment openTelemetryTestEnvironment
* @param path path
* @return an HttpResponse
*/
protected HttpResponse sendRequest(
OpenTelemetryTestEnvironment openTelemetryTestEnvironment, String path)
throws IOException {
return HttpClient.sendRequest(openTelemetryTestEnvironment.getPrometheusUrl(path));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/bash

java \
-Xmx512M \
-javaagent:jmx_prometheus_javaagent.jar=exporter.yaml \
-jar jmx_example_application.jar
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
openTelemetry:
endpoint: http://prometheus:9090/api/v1/otlp
protocol: http/protobuf
interval: 1
timeoutSeconds: 60
serviceName: service-name
serviceInstanceId: service-instance-id
serviceNamespace: service-namespace
serviceVersion: 1
headers:
test.header: "test.value"
resourceAttributes:
deployment.environment: "test"
rules:
- pattern: ".*"
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
global:
scrape_interval: 15s # Default scrape interval, not used since there are no scrape targets

scrape_configs: [] # Empty scrape_configs means no targets to scrape
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/bin/bash

java \
-Xmx512M \
-Dcom.sun.management.jmxremote=true \
-Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.local.only=false \
-Dcom.sun.management.jmxremote.port=9999 \
-Dcom.sun.management.jmxremote.registry.ssl=false \
-Dcom.sun.management.jmxremote.rmi.port=9999 \
-Dcom.sun.management.jmxremote.ssl.need.client.auth=false \
-Dcom.sun.management.jmxremote.ssl=false \
-jar jmx_example_application.jar
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/bash

java \
-Xmx512M \
-jar jmx_prometheus_standalone.jar exporter.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
openTelemetry:
endpoint: http://prometheus:9090/api/v1/otlp
protocol: http/protobuf
interval: 1
timeoutSeconds: 60
serviceName: service-name
serviceInstanceId: service-instance-id
serviceNamespace: service-namespace
serviceVersion: 1
headers:
test.header: "test.value"
resourceAttributes:
deployment.environment: "test"
hostPort: application:9999
rules:
- pattern: ".*"
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
global:
scrape_interval: 15s # Default scrape interval, not used since there are no scrape targets

scrape_configs: [] # Empty scrape_configs means no targets to scrape
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public Map<String, String> apply(Object o) {
Map<String, String> result = new LinkedHashMap<>();
Map<Object, Object> map = (Map<Object, Object>) o;

map.forEach((o1, o2) -> result.put(o1.toString(), o2.toString()));
map.forEach((o1, o2) -> result.put(o1.toString().trim(), o2.toString().trim()));

return result;
} catch (Throwable t) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,11 @@ public String apply(Object value) {
}

try {
return (String) value;
if (value instanceof String) {
return (String) value;
} else {
return value.toString();
}
} catch (Throwable t) {
throw supplier.get();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package io.prometheus.jmx.common.configuration;

import io.prometheus.jmx.common.util.Precondition;
import java.util.Map;
import java.util.function.Function;
import java.util.function.Supplier;

/**
* Class to validate a Maps keys/values, throwing a RuntimeException from the Supplier if any
* key/value is null or empty
*/
public class ValidateMapValues implements Function<Map<String, String>, Map<String, String>> {

private final Supplier<? extends RuntimeException> supplier;

/**
* Constructor
*
* @param supplier supplier
*/
public ValidateMapValues(Supplier<? extends RuntimeException> supplier) {
Precondition.notNull(supplier);
this.supplier = supplier;
}

@Override
public Map<String, String> apply(Map<String, String> map) {
for (Map.Entry<String, String> entry : map.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();

if (key == null || key.trim().isEmpty() || value == null || value.isEmpty()) {
throw supplier.get();
}
}

return map;
}
}
Loading

0 comments on commit e4a4f45

Please sign in to comment.