One of the new features in Payara Server and Payara Micro 18.104.22.168 and 5.181 is full compatibility with MicroProfile 1.2. In this blog, I will introduce Metrics 1.0, a new API of MicroProfile 1.2 to use with Payara Micro (and Payara Server).
Needless to say, monitoring the underlying runtime and system, as well as your own application, is important to keep them reliable. There is already JMX as a Java standard to monitor and expose metrics, but remote JMX is not easy to deal with. In addition, JMX is specific to Java so it can be even more difficult to use in the case that both Java and non-Java environments are mixed. MicroProfile Metrics is simple, easy to use and suitable for polyglot environment API to expose system and application metrics.
MicroProfile Metrics is fairly simple to use, and it is even enabled by default in both Payara Server and Payara Micro. To understand the inner workings of the specification, there are three key features you need to know:
- REST endpoints
Prometheus is configured to collect metrics from HTTP endpoints on
/metricsby default, so there is no complicated configuration needed.
Metric values are stored in a registry with three scopes:
- Base (JVM metrics, common to every implementation)
- Vendor (Vendor specific metrics)
- Application (User metrics)
Both JSON and Prometheus text format are available. Prometheus text format is the default, but requesting application/json in the request header will return JSON formatted metrics.
First Steps with Metrics on Payara Micro
In this section, I'll show you the basics to get started with Metrics and view Base and Vendor scoped metrics with any existing application. There is no need to deploy any application to Payara Micro at this stage; both base and vendor metrics will be available by default.
For example, using
curl command is as follows;
You may see such an output as follows. This is the default output, which is Prometheus text format.
Metrics can also be retrieved with another output format - JSON. Simply access the URL with an "Accept" HTTP header. Metrics formatted as JSON can be retrieved using cURL as follows;
curl -H "Accept: application/json" http://localhost:8080/metrics
You may see such a JSON format output as follows. (This is formatted for ease to see.)
Here, we have seen metrics in the scopes of Base and Vendor. Base metrics are required by the specification, thus all MicroProfile vendors have to implement these. These are also mainly exposing JVM statistics. Vendor metrics are additional metirics provided by each vendor, so will vary between implementations of the Metrics specification. Both of these scopes are used for reporting on the status of the container.
There are several types of Metrics. Some of these can be seen in the example output above, and all can be used to provide data from your own applications in the application scope.
- Gauge - simple metric type for continuous value, e.g. memory.usedHeap, memory.committedHeap, memory.maxHeap
- Counter - simple metric type for discrete value, e.g. thread.count, thread.daemon.count
- Meter - complex metric type comprised of multiple key/values; values are count, meatRate, oneMinRate, fiveMinRate, fifteenMinRate
- Histogram - complex metric type comprised of multiple key/values; values are count, min, max, mean, stddev, p50, p75, p95, p98, p99, p999
- Timer - complex metric type comprised of multiple key/values; values are count, meanRate, oneMinRate, fiveMinRate, fifteenMinRate, min, max, mean, stddev, p50, p75, p95, p98, p99, p999
In the previous section, we see Base and Vendor metrics. Metrics are also implemented on your applications. You may provide the way of health check for each applications. It's called Application metrics.
First, add the following dependency to the pom.xml of your application.
Next, we can create our simple example using @Counter and @Meter. It exposes "employeeCount" as Counter, and both "createEmployee", "deleteEmployee" as Meter.
The counter "employeeCount" is an example of a Field level annotation which will always show the current count of employees who registered. At first, it's four ("John", "Paul", "George" and "Ringo"). Since a counter always initialises at 0, we need to increment it by 4 in our example to keep the number at the correct level. Every time the HTTP DELETE or POST is used, the counter is manually incremented.
The meter "createEmployee" and "deleteEmployee" are examples of Method level annotations which are changed by every method call. We do not need to manually set any values here, since the meters are showing the number of times that each endpoint has been hit. This kind of monitoring can be very useful in collecting data about how users make use of an application.
Before you obtain Application metrics, you should call the application once at least. Otherwise, you cannot obtain any metrics from the application and only base and vendor metrics will be shown.
Before the API, we had to struggle with remote JMX to monitor the system properly, and would often have to create complicated configurations to get good data. There is the option of a JMX-HTTP bridge such as Jolokia but that still required additional set up. Metrics is REST based, simple and flexible monitoring API that's fully configured out-of-the box. Because it's Prometheus compatible, it's also well placed to use in a Kubenetes environment. See also https://github.com/payara/Payara-Examples/tree/master/microprofile to check more example of Metrics.
You can download the spec from https://github.com/eclipse/microprofile-metrics/releases/tag/1.0 for a more comprehensive overview.