Skip to content

Commit

Permalink
Add Prometheus annotations when smallrye metrics in enabled
Browse files Browse the repository at this point in the history
Fixes: #10301
  • Loading branch information
geoand committed Jun 29, 2020
1 parent 8bbf90c commit 8d50e38
Show file tree
Hide file tree
Showing 7 changed files with 166 additions and 7 deletions.
4 changes: 4 additions & 0 deletions extensions/kubernetes/vanilla/deployment/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@
<groupId>io.quarkus</groupId>
<artifactId>quarkus-kubernetes-client-deployment-internal</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-smallrye-metrics-spi</artifactId>
</dependency>
<dependency>
<groupId>io.dekorate</groupId>
<artifactId>kubernetes-annotations</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package io.quarkus.kubernetes.deployment;

final class Annotations {

private Annotations() {
}

static class Prometheus {

private Prometheus() {
}

private static final String PREFIX = "prometheus.io/";

static final String SCRAPE = PREFIX + "scrape";
static final String PATH = PREFIX + "path";
static final String PORT = PREFIX + "port";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,17 @@
import io.quarkus.deployment.pkg.PackageConfig;
import io.quarkus.deployment.pkg.builditem.OutputTargetBuildItem;
import io.quarkus.deployment.util.FileUtil;
import io.quarkus.kubernetes.spi.*;
import io.quarkus.kubernetes.deployment.Annotations.Prometheus;
import io.quarkus.kubernetes.spi.KubernetesAnnotationBuildItem;
import io.quarkus.kubernetes.spi.KubernetesCommandBuildItem;
import io.quarkus.kubernetes.spi.KubernetesDeploymentTargetBuildItem;
import io.quarkus.kubernetes.spi.KubernetesEnvBuildItem;
import io.quarkus.kubernetes.spi.KubernetesHealthLivenessPathBuildItem;
import io.quarkus.kubernetes.spi.KubernetesHealthReadinessPathBuildItem;
import io.quarkus.kubernetes.spi.KubernetesLabelBuildItem;
import io.quarkus.kubernetes.spi.KubernetesPortBuildItem;
import io.quarkus.kubernetes.spi.KubernetesRoleBuildItem;
import io.quarkus.smallrye.metrics.deployment.spi.MetricsConfigurationBuildItem;

class KubernetesProcessor {

Expand Down Expand Up @@ -118,12 +128,28 @@ public EnabledKubernetesDeploymentTargetsBuildItem enabledKubernetesDeploymentTa

@BuildStep
public List<KubernetesAnnotationBuildItem> createAnnotations(KubernetesConfig kubernetesConfig,
OpenshiftConfig openshiftConfig, KnativeConfig knativeConfig) {
List<KubernetesAnnotationBuildItem> items = new ArrayList<KubernetesAnnotationBuildItem>();
kubernetesConfig.annotations.forEach((k, v) -> items.add(new KubernetesAnnotationBuildItem(k, v, KUBERNETES)));
openshiftConfig.annotations.forEach((k, v) -> items.add(new KubernetesAnnotationBuildItem(k, v, OPENSHIFT)));
knativeConfig.annotations.forEach((k, v) -> items.add(new KubernetesAnnotationBuildItem(k, v, KNATIVE)));
return items;
OpenshiftConfig openshiftConfig, KnativeConfig knativeConfig,
Optional<MetricsConfigurationBuildItem> metricsConfiguration, List<KubernetesPortBuildItem> kubernetesPorts) {
List<KubernetesAnnotationBuildItem> result = new ArrayList<KubernetesAnnotationBuildItem>();
addAnnotations(kubernetesConfig, KUBERNETES, metricsConfiguration, kubernetesPorts, result);
addAnnotations(openshiftConfig, OPENSHIFT, metricsConfiguration, kubernetesPorts, result);
addAnnotations(knativeConfig, KNATIVE, metricsConfiguration, kubernetesPorts, result);
return result;
}

private void addAnnotations(PlatformConfiguration config, String target,
Optional<MetricsConfigurationBuildItem> metricsConfigurationBuildItem,
List<KubernetesPortBuildItem> kubernetesPorts,
List<KubernetesAnnotationBuildItem> result) {
for (Map.Entry<String, String> entry : config.getAnnotations().entrySet()) {
result.add(new KubernetesAnnotationBuildItem(entry.getKey(), entry.getValue(), target));
}
if (metricsConfigurationBuildItem.isPresent() && !kubernetesPorts.isEmpty()) {
result.add(new KubernetesAnnotationBuildItem(Prometheus.SCRAPE, "true", target));
result.add(new KubernetesAnnotationBuildItem(Prometheus.PATH, metricsConfigurationBuildItem.get().getPath(),
target));
result.add(new KubernetesAnnotationBuildItem(Prometheus.PORT, "" + kubernetesPorts.get(0).getPort(), target));
}
}

@BuildStep
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
import io.quarkus.smallrye.metrics.deployment.jandex.JandexBeanInfoAdapter;
import io.quarkus.smallrye.metrics.deployment.jandex.JandexMemberInfoAdapter;
import io.quarkus.smallrye.metrics.deployment.spi.MetricBuildItem;
import io.quarkus.smallrye.metrics.deployment.spi.MetricsConfigurationBuildItem;
import io.quarkus.smallrye.metrics.runtime.MetadataHolder;
import io.quarkus.smallrye.metrics.runtime.SmallRyeMetricsRecorder;
import io.quarkus.smallrye.metrics.runtime.TagHolder;
Expand Down Expand Up @@ -123,6 +124,11 @@ static final class SmallRyeMetricsConfig {

SmallRyeMetricsConfig metrics;

@BuildStep
MetricsConfigurationBuildItem metricsConfigurationBuildItem() {
return new MetricsConfigurationBuildItem(metrics.path);
}

@BuildStep
@Record(STATIC_INIT)
void createRoute(BuildProducer<RouteBuildItem> routes,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package io.quarkus.smallrye.metrics.deployment.spi;

import io.quarkus.builder.item.SimpleBuildItem;

/**
* A build item that can be used by build steps that need to know the metrics configuration
*/
public final class MetricsConfigurationBuildItem extends SimpleBuildItem {

private final String path;

public MetricsConfigurationBuildItem(String path) {
this.path = path;
}

public String getPath() {
return path;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package io.quarkus.it.kubernetes;

import static io.restassured.RestAssured.given;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.entry;
import static org.hamcrest.Matchers.is;

import java.io.IOException;
import java.nio.file.Path;
import java.util.Collections;
import java.util.List;

import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.fabric8.kubernetes.api.model.HasMetadata;
import io.fabric8.kubernetes.api.model.apps.Deployment;
import io.quarkus.bootstrap.model.AppArtifact;
import io.quarkus.builder.Version;
import io.quarkus.test.LogFile;
import io.quarkus.test.ProdBuildResults;
import io.quarkus.test.ProdModeTestResults;
import io.quarkus.test.QuarkusProdModeTest;

public class KubernetesWithMetricsTest {

@RegisterExtension
static final QuarkusProdModeTest config = new QuarkusProdModeTest()
.setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class).addClasses(GreetingResource.class))
.setApplicationName("health")
.setApplicationVersion("0.1-SNAPSHOT")
.setRun(true)
.setLogFileName("k8s.log")
.withConfigurationResource("kubernetes-with-metrics.properties")
.setForcedDependencies(
Collections.singletonList(
new AppArtifact("io.quarkus", "quarkus-smallrye-metrics", Version.getVersion())));

@ProdBuildResults
private ProdModeTestResults prodModeTestResults;

@LogFile
private Path logfile;

@Test
public void assertApplicationRuns() {
assertThat(logfile).isRegularFile().hasFileName("k8s.log");
TestUtil.assertLogFileContents(logfile, "kubernetes", "metrics");

given()
.when().get("/greeting")
.then()
.statusCode(200)
.body(is("hello"));
}

@Test
public void assertGeneratedResources() throws IOException {
final Path kubernetesDir = prodModeTestResults.getBuildDir().resolve("kubernetes");
assertThat(kubernetesDir)
.isDirectoryContaining(p -> p.getFileName().endsWith("kubernetes.json"))
.isDirectoryContaining(p -> p.getFileName().endsWith("kubernetes.yml"));
List<HasMetadata> kubernetesList = DeserializationUtil
.deserializeAsList(kubernetesDir.resolve("kubernetes.yml"));
assertThat(kubernetesList.get(0)).isInstanceOfSatisfying(Deployment.class, d -> {
assertThat(d.getMetadata()).satisfies(m -> {
assertThat(m.getName()).isEqualTo("health");
});

assertThat(d.getSpec()).satisfies(deploymentSpec -> {
assertThat(deploymentSpec.getTemplate()).satisfies(t -> {
assertThat(t.getMetadata()).satisfies(meta -> {
assertThat(meta.getAnnotations()).contains(entry("prometheus.io/scrape", "true"),
entry("prometheus.io/path", "/met"), entry("prometheus.io/port", "9090"));
});
});
});
});
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
quarkus.http.port=9090
quarkus.smallrye-metrics.path=/met

0 comments on commit 8d50e38

Please sign in to comment.