A guide on how to provide system and application metrics from a microservice with MicroProfile Metrics: https://openliberty.io/guides/microprofile-metrics.html
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
finish
start
.gitignore
.travis.yml
LICENSE
README.adoc

README.adoc

Providing metrics from a microservice

Note
This repository contains the guide documentation source. To view the guide in published form, view it on the Open Liberty website.

You’ll explore how to provide system and application metrics from a microservice with MicroProfile Metrics.

What you’ll learn

You will learn how to use MicroProfile Metrics to provide metrics from a microservice. You can monitor metrics to determine the performance and health of a service. You can also use them to pinpoint issues, collect data for capacity planning, or to decide when to scale a service to run with more or fewer resources.

The application that you will work with is an inventory service that stores information about various systems. The inventory service communicates with the system service on a particular host to retrieve its system properties when necessary.

You will use annotations provided by MicroProfile Metrics to instrument the inventory service to provide application-level metrics data. You will add counter, gauge, and timer metrics to the service.

You will also check well-known REST endpoints that are defined by MicroProfile Metrics to review the metrics data collected. Monitoring agents can access these endpoints to collect metrics.

Try what you’ll build

The finish directory contains the finished implementation for the application. You can try it out before you build your own.

To try the application, navigate to the finish directory and run the following command:

mvn install liberty:start-server

Maven builds the application and runs it inside Open Liberty.

Point your browser to the http://localhost:9080/inventory/systems URL to access the inventory service. Because you just started the application, the inventory is currently empty. Then, access the http://localhost:9080/inventory/systems/localhost URL to add the localhost into the inventory.

Access the inventory service at the http://localhost:9080/inventory/systems URL at least once for application metrics to be collected. Otherwise, the metrics will not appear.

Next, point your browser to the https://localhost:9443/metrics MicroProfile Metrics endpoint. Log in as the admin user with adminpwd as the password. You can see both the system and application metrics in a text format.

To see only the application metrics, point your browser to https://localhost:9443/metrics/application.

See the following sample outputs for the @Timed, @Gauge, and @Counted metrics:

# TYPE application:inventory_properties_request_time_rate_per_second gauge
application:inventory_properties_request_time_rate_per_second 0.012564862395324394
# HELP application:inventory_properties_request_time_seconds Time needed to get the properties of a system from the given hostname
# TYPE application:inventory_size_guage gauge
# HELP application:inventory_size_guage Number of systems in the inventory
application:inventory_size_guage 1
# TYPE application:inventory_access_count counter
# HELP application:inventory_access_count Number of times the list of systems method is requested
application:inventory_access_count 1

To see only the system metrics, point your browser to https://localhost:9443/metrics/base.

See the following sample output for the @Gauge and @Counted metrics:

# TYPE base:jvm_uptime_seconds gauge
# HELP base:jvm_uptime_seconds Displays the start time of the Java virtual machine in milliseconds. This attribute displays the approximate time when the Java virtual machine started.
base:jvm_uptime_seconds 39.025
# TYPE base:classloader_current_loaded_class_count counter
# HELP base:classloader_current_loaded_class_count Displays the number of classes that are currently loaded in the Java virtual machine.
base:classloader_current_loaded_class_count 9144

When you’re done with the application, stop the Open Liberty server with the following command:

mvn liberty:stop-server

Adding MicroProfile Metrics to the inventory service

Navigate to the start directory to begin.

The MicroProfile Metrics API was added as a dependency to your pom.xml file. Look for the dependency with the mpMetrics artifact ID. Add this dependency to use MicroProfile Metrics API in your code to provide metrics from your microservices.

Next, create a src/main/liberty/config/server.xml file:

link:finish/src/main/liberty/config/server.xml[]

The mpMetrics feature enables MicroProfile Metrics support in Open Liberty. Note that this feature requires SSL and the configuration has been provided for you.

The quickStartSecurity and keyStore configuration elements provide basic security to secure the server. When you visit the /metrics endpoint, use the credentials defined in the server configuration to log in to view the data.

Adding the annotations

Create the InventoryManager class in the src/main/java/io/openliberty/guides/inventory/InventoryManager.java file:

link:finish/src/main/java/io/openliberty/guides/inventory/InventoryManager.java[]

Apply the @Timed annotation to the get() method to track how frequently the method is invoked and also how long it takes for the invocation to complete. This annotation has these metadata fields:

name

Optional. Use this field to name of the metric.

description

Optional. Use this field to describe the purpose of the metric.

absolute

Optional. Use this field to determine whether the metric name is the exact name that is specified in the name field or that is specified with the package prefix.

Apply the @Counted annotation to the list() method to count how many times the http://localhost:9080/inventory/systems URL is accessed. Note the additional metadata field:

monotonic

Set this annotation to true to count the total number of invocations of the annotated method, which is the total number of times the inventory is accessed.

Apply the @Gauge annotation to the getTotal() method to track the number of systems that are stored in the inventory. Note that when the value of the gauge is retrieved, the underlying getTotal() method is called to return the size of the inventory. Note the additional metadata field:

unit

Set the unit of the metric. If it is MetricUnits.NONE, the metric name is used as is without appending the unit name, and no scaling is applied.

Additional information about these annotations, relevant metadata fields, and more are available at the MicroProfile website.

Point your browser to the https://localhost:9443/metrics URL to review the all available metrics that have been enabled through MicroProfile Metrics. Log in with admin as your username and adminpwd as your password. You see only the system metrics because the server just started, and the inventory service has not been accessed.

Next, point your browser to the http://localhost:9080/inventory/systems URL. Reload the https://localhost:9443/metrics URL, or access only the application metrics at the https://localhost:9443/metrics/application URL.

Testing the metrics

You can test your application manually, but automated tests ensure code quality because they trigger a failure whenever a code change introduces a defect. JUnit and the JAX-RS Client API provide a simple environment for you to write tests.

First, create a test class in the src/test/java/it/io/openliberty/guides/metrics/MetricsTest.java file:

link:finish/src/test/java/it/io/openliberty/guides/metrics/MetricsTest.java[]
  • The testPropertiesRequestTimeMetric() test case validates the @Timed metric. It sends a request to the http://localhost:9080/inventory/systems/localhost URL to access the inventory service, which adds the localhost host to the inventory. Next, the test case makes a connection to the https://localhost:9443/metrics/application URL to retrieve application metrics as plain text. Then, it asserts whether the time that is needed to retrieve the system properties for localhost is less than 4 seconds.

  • The testInventoryAccessCountMetric() test case validates the @Counted metric. The test case sends a request to the http://localhost:9080/inventory/systems URL to retrieve the whole inventory, and then it asserts that this endpoint is accessed only once.

  • The testInventorySizeGaugeMetric() test case validates the @Gauge metric. The test case first ensures that the localhost is in the inventory. It then looks for the @Gauge metric and asserts that the inventory size is equal to 1.

The oneTimeSetup() method retrieves the port number for the server and builds a base URL string to set up the tests. Apply the @BeforeClass annotation to this method to execute it before any of the test cases.

The setup() method creates a JAX-RS client that makes HTTP requests to the inventory service. Register this client with a JsrJsonpProvider JSON-P provider to process JSON resources. The teardown() method destroys this client instance. Apply the @Before annotation so that a method executes before a test case, and apply the @After annotation so that a method executes after a test case. Apply these annotations to methods that are generally used to perform any setup and teardown tasks before and after a test.

To execute the test cases in a particular order, put them in a testSuite() method. Label the method with the @Test annotation, which automatically executes when your test class runs.

In addition, a few endpoint tests src/test/java/it/io/openliberty/guides/inventory/InventoryEndpointTest.java and src/test/java/it/io/openliberty/guides/system/SystemEndpointTest.java are provided for you to test the basic functionality of the inventory and system services. If a test failure occurs, then you might have introduced a bug into the code.

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running it.io.openliberty.guides.system.SystemEndpointTest
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.4 sec - in it.io.openliberty.guides.system.SystemEndpointTest
Running it.io.openliberty.guides.metrics.MetricsTest
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.697 sec - in it.io.openliberty.guides.metrics.MetricsTest
Running it.io.openliberty.guides.inventory.InventoryEndpointTest
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.264 sec - in it.io.openliberty.guides.inventory.InventoryEndpointTest

Results :

Tests run: 3, Failures: 0, Errors: 0, Skipped: 0

To see whether the tests detect a failure, go to the MetricsTest.java file and change any of the assertions in the validateMetric() method. Rerun the Maven build. A test failure occurs.

Great work! You’re done!

You learned how to enable system and application metrics for microservices by using MicroProfile Metrics and wrote tests to validate them.