Page
Create the Quarkus application
Let’s start by creating a simple Quarkus application exposing some metrics.
Note: We provide a final container image with all of the code, so you can skip the application creation if you are more interested in the observability part.
Go to https://code.quarkus.io/ and generate a new Quarkus application with RESTEasy Reactive, Container Image Jib, and Micrometer Registry Prometheus. Click the link to get a pre-populated page with all dependencies. Figure 1 shows the Quarkus generator page.
Now click the Generate your application button, download the zip file locally, and unzip it. With just the Micrometer extension, some JVM-specific metrics are automatically exposed.
Let’s add some custom metrics—for example, the value of a counter that is incremented using a REST endpoint.
Modify the application code
Open the code in your IDE and edit the org.acme.GreetingResource
class with the following content:
// This is the main Micrometer class to register custom metrics
private final MeterRegistry registry;
// The data to monitor
private AtomicInteger currentMemory;
// Injects the Micrometer registry
GreetingResource(MeterRegistry registry) {
this.registry = registry;
// Registers this metric under current.memory name, initializing the counter to 0
currentMemory = this.registry.gauge("current.memory", Tags.empty(), new AtomicInteger(0));
}
// Creates an endpoint to modify the observed variable
@GET
@Path("/consume/{amount}")
@Produces(MediaType.TEXT_PLAIN)
public Integer consume(@PathParam("amount") int mem) {
this.currentMemory.addAndGet(mem);
return this.currentMemory.get();
}
Of course, you need to import these classes too:
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Tags;
import jakarta.ws.rs.PathParam;
Configure Jib
The final step is configuring Jib to push the container image to the registry. In this case, I used my quay.io account, but you should add your own configuration values.
Open the application.properties file and add the following values:
# Change with your values
quarkus.container-image.group=lordofthejars
quarkus.container-image.registry=quay.io
quarkus.container-image.tag=1.0.0
By default, Quarkus maps the extra endpoints, like the metrics one, to the /q subpath, so to get the metrics, you should query the /q/metrics endpoint. Because Prometheus expects the metrics published in /metrics by default, let’s reconfigure Quarkus not to use the subpath:
quarkus.http.non-application-root-path=/
Now you can build, containerize, and publish the application. Again, you can skip this step if you like, as an image is available at https://quay.io/lordofthejars/quarkus-monitor:1.0.0.
Kubernitize
It’s time to create a Kubernetes deployment file for this application. Create a deployment.yaml
file with the following content:
---
apiVersion: v1
kind: Service
metadata:
annotations:
app.quarkus.io/build-timestamp: 2023-06-30 - 12:45:38 +0000
prometheus.io/scrape: "true"
prometheus.io/path: /metrics
prometheus.io/port: "8080"
prometheus.io/scheme: http
labels:
app: monitor
app.kubernetes.io/name: quarkus-monitor
name: quarkus-monitor
spec:
ports:
- name: http
port: 8080
protocol: TCP
targetPort: 8080
selector:
app: monitor
app.kubernetes.io/name: quarkus-monitor
type: ClusterIP
---
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
app.quarkus.io/build-timestamp: 2023-06-30 - 12:45:38 +0000
prometheus.io/scrape: "true"
prometheus.io/path: /metrics
prometheus.io/port: "8080"
prometheus.io/scheme: http
labels:
app.kubernetes.io/name: quarkus-monitor
app: monitor
name: quarkus-monitor
spec:
replicas: 1
selector:
matchLabels:
app: monitor
app.kubernetes.io/name: quarkus-monitor
template:
metadata:
annotations:
app.quarkus.io/build-timestamp: 2023-06-30 - 12:45:38 +0000
prometheus.io/scrape: "true"
prometheus.io/path: /metrics
prometheus.io/port: "8080"
prometheus.io/scheme: http
labels:
app.kubernetes.io/name: quarkus-monitor
app: monitor
spec:
containers:
- env:
- name: KUBERNETES_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
image: quay.io/lordofthejars/quarkus-monitor:1.0.0
imagePullPolicy: Always
name: quarkus-monitor
ports:
- containerPort: 8080
name: http
protocol: TCP
It has nothing special except for the labels. As you’ll see later, we use labels to configure Prometheus, specify which services it should target, and expose the metrics in the /metrics
endpoint. In this case, the app=monitor
label is essential because every service containing this label will be targeted.
Congratulations. You have created your Quarkus application and configured it. Now it's time to work in the Developer Sandbox and deploy a Prometheus instance.