Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#1411: Add more practical example for module micrometer-quickstart #1412

Draft
wants to merge 1 commit into
base: development
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public class ExampleResource {

private final MeterRegistry registry;

LinkedList<Long> list = new LinkedList<>();
private final LinkedList<Long> list = new LinkedList<>();

// Update the constructor to create the gauge
ExampleResource(MeterRegistry registry) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
package org.acme.micrometer;

import java.util.LinkedList;

import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.PathParam;

import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Tags;
import io.micrometer.core.instrument.Timer;
import io.micrometer.core.instrument.DistributionSummary;

/**
* REST API for monitoring and recording temperature readings.
*/
@Path("/temperature")
@Produces("text/plain")
public class TemperatureResource {

private final MeterRegistry registry;
private LinkedList<Double> temperatures = new LinkedList<>();

DistributionSummary temperatureSummary;

/**
* Constructs a TemperatureResource.
* Initializes the monitoring tools for temperatures.
*
* @param registry MeterRegistry for recording metrics.
*/
public TemperatureResource(MeterRegistry registry) {
this.registry = registry;
// Summary to record temperature readings and their distribution.
temperatureSummary = registry.summary("temperature.readings", Tags.of("unit", "celsius"));
// Gauge to monitor the size of the temperature list in real-time.
registry.gaugeCollectionSize("temperature.list.size", Tags.empty(), temperatures);
}

/**
* Adds a temperature reading to the recorded list and updates the summary metric.
*
* @param temp The temperature to add.
* @return A message confirming the addition of the temperature.
*/
@GET
@Path("/add/{temp}")
public String addTemperature(@PathParam("temp") double temp) {
temperatures.add(temp);
temperatureSummary.record(temp);
return "Temperature added: " + temp;
}

/**
* Calculates the average of all recorded temperatures.
* Uses a timer to measure the time taken to perform this calculation.
*
* @return The average temperature or a message if no temperatures are recorded.
*/
@GET
@Path("/average")
public String calculateAverage() {
Timer timer = registry.timer("temperature.calculation.average");
return timer.record(() -> {
if (temperatures.isEmpty()) {
return "No temperatures recorded.";
}
double sum = 0;
for (Double t : temperatures) {
sum += t;
}
double average = sum / temperatures.size();
return "Average temperature: " + average + " Celsius";
});
}

/**
* Finds the maximum temperature from the recorded list.
* Measurement is timed for performance analysis.
*
* @return The maximum temperature or a message if no temperatures are recorded.
*/
@GET
@Path("/max")
public String findMaxTemperature() {
Timer timer = registry.timer("temperature.calculation.max");
return timer.record(() -> {
return temperatures.stream()
.max(Double::compare)
.map(maxTemp -> "Maximum temperature: " + maxTemp + " Celsius")
.orElse("No temperatures recorded.");
});
}

/**
* Finds the minimum temperature from the recorded list.
* Measurement is timed for performance analysis.
*
* @return The minimum temperature or a message if no temperatures are recorded.
*/
@GET
@Path("/min")
public String findMinTemperature() {
Timer timer = registry.timer("temperature.calculation.min");
return timer.record(() -> {
return temperatures.stream()
.min(Double::compare)
.map(minTemp -> "Minimum temperature: " + minTemp + " Celsius")
.orElse("No temperatures recorded.");
});
}

// New endpoint to reset the temperatures list
@GET
@Path("/reset")
public String resetTemperatures() {
temperatures.clear();
return "Temperatures reset successfully.";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package org.acme.micrometer;

import static io.restassured.RestAssured.get;
import static io.restassured.RestAssured.when;
import static org.hamcrest.CoreMatchers.containsString;

import org.junit.jupiter.api.Test;

import io.quarkus.test.junit.QuarkusTest;
import io.restassured.http.Header;

/**
* Test class for TemperatureResource using REST-assured.
*/
@QuarkusTest
public class TemperatureResourceTest {

@BeforeEach
void resetTemperatures() {
get("/temperature/reset").then().assertThat().statusCode(200);
}

@Test
void testAddTemperature() {
when().get("/temperature/add/20.5").then().statusCode(200)
.body(containsString("Temperature added: 20.5"));
when().get("/temperature/add/22.3").then().statusCode(200)
.body(containsString("Temperature added: 22.3"));
}

@Test
void testAverageTemperature() {
// Add temperatures first
get("/temperature/add/20.5");
get("/temperature/add/22.3");
get("/temperature/add/25.1");

// Check the average calculation
when().get("/temperature/average").then().statusCode(200)
.body(containsString("Average temperature: 22.633333333333333 Celsius"));
}

@Test
void testMaxTemperature() {
// Add temperatures first
get("/temperature/add/20.5");
get("/temperature/add/22.3");
get("/temperature/add/25.1");

// Check the maximum temperature calculation
when().get("/temperature/max").then().statusCode(200)
.body(containsString("Maximum temperature: 25.1 Celsius"));
}

@Test
void testMinTemperature() {
// Add temperatures first
get("/temperature/add/20.5");
get("/temperature/add/22.3");
get("/temperature/add/25.1");

// Check the minimum temperature calculation
when().get("/temperature/min").then().statusCode(200)
.body(containsString("Minimum temperature: 20.5 Celsius"));
}

@Test
void testTemperatureMetrics() {
// Trigger endpoints to populate metrics
get("/temperature/add/20.5");
get("/temperature/add/22.3");
get("/temperature/add/25.1");
get("/temperature/average");
get("/temperature/max");
get("/temperature/min");

// Check metrics for recorded operations
when().get("/q/metrics").then().statusCode(200)
.body(containsString("temperature_readings_sum"))
.body(containsString("temperature_readings_count 3.0"))
.body(containsString("temperature_calculation_average_seconds_count 1.0"))
.body(containsString("temperature_calculation_max_seconds_count 1.0"))
.body(containsString("temperature_calculation_min_seconds_count 1.0"));
}
}