Red Hat Quarkus native applications monitoring

Red Hat Quarkus is an open source Java framework optimized for GraalVM Native Images to make Java a valuable citizen in the world of microservices. Quarkus belongs to the family of full-stack frameworks tailored for Kubernetes. It includes modern Java libraries and follows the latest Java standards.

Learn how Dynatrace can trace native Java applications and monitor metrics and logs of a Quarkus application compiled as a native image.

Prerequisites

  • Your GraalVM version is supported by Dynatrace.

  • GraalVM is configured to build native images. For details, see the Building a native executable Quarkus guide.

  • OneAgent or Dynatrace Operator is installed on the machine where the application is about to be executed.

    The required installation depends on your application:

    If your application is running
    See the instruction for
    on a virtual machine or bare-metal
    as workload in Kubernetes or OpenShift

Traces

Dynatrace can automatically trace just-in-time (JIT) compiled Quarkus applications executed on OpenJDK HotSpot JVM and GraalVM.

For ahead-of-time (AOT) compiled Quarkus applications executed on GraalVM, see GraalVM Native Image to get started.

OpenTelemetry

You can export Quarkus tracing information using OpenTelemetry. To do so, use the Quarkus-specific configuration parameters to configure the exporter to send trace data to one of the two available endpoints, ActiveGate or OneAgent.

The following example shows how to configure application.properties to export to a Dynatrace SaaS endpoint. It specifies the API URL and the necessary, percent-encoded Authorization header with the API token.

quarkus.application.name=myservice
quarkus.otel.exporter.otlp.traces.endpoint=https://{your-environment-id}.live.dynatrace.com/api/v2/otlp
quarkus.otel.exporter.otlp.traces.headers=authorization=Api-Token%20dt.....
quarkus.log.console.format=%d{HH:mm:ss} %-5p traceId=%X{traceId}, parentId=%X{parentId}, spanId=%X{spanId}, sampled=%X{sampled} [%c{2.}] (%t) %s%e%n

Metrics

Red Hat recommends that you obtain metrics from Quarkus via the quarkus-micrometer-registry-prometheus library.

To learn how to utilize Micrometer metrics in your Quarkus application, see the Micrometer metrics Quarkus guide.

Dynatrace offers two approaches for obtaining Micrometer metrics from Prometheus: via API or via an extension.

Ingest Micrometer metrics via Dynatrace API

Use the Dynatrace API to ingest metrics obtained from the quarkus-micrometer-registry-prometheus library.

To learn more about the ingestion procedure, see Send Micrometer metrics to Dynatrace.

For natively built applications, be sure to follow the Directly in Micrometer approach.

Ingest Micrometer metrics via an extension

Use the Dynatrace Extension 2.0 Framework to ingest Micrometer metrics obtained from the Prometheus data source—you need to create a custom extension for that.

As a starting point, you can use the custom extension example below. It's tailored to the quarkus-micrometer-registry-prometheus library. Be sure to use the correct metrics endpoint in your configuration. The default endpoint is localhost:8080/q/metrics.

name: custom:com.dynatrace.extension.micrometer-quarkus
version: 1.0.0
minDynatraceVersion: "1.247"
author:
name: Dynatrace
#dashboards:
# - path: "dashboards/dashboard_exporter.json"
#alerts:
# - path: "alerts/alert_socket_usage.json"
prometheus:
- group: quarkus metrics
interval:
minutes: 1
featureSet: all
dimensions:
- key: quarkus
value: const:quarkus
subgroups:
# global counters
- subgroup: quarkus global counter
dimensions:
- key: global_counters
value: const:global_counters
metrics:
# HELP process_uptime_seconds The uptime of the Java virtual machine
# TYPE process_uptime_seconds gauge
- key: com.dynatrace.process.global.uptime.seconds
value: metric:process_uptime_seconds
type: gauge
featureSet: global
# HELP process_cpu_usage The "recent cpu usage" for the Java Virtual Machine process
# TYPE process_cpu_usage gauge
- key: com.dynatrace.process.global.cpu.usage
value: metric:process_cpu_usage
type: gauge
featureSet: global
# HELP system_cpu_usage The "recent cpu usage" of the system the application is running in
# TYPE system_cpu_usage gauge
- key: com.dynatrace.system.global.cpu.usage
value: metric:system_cpu_usage
type: gauge
featureSet: global
# HELP jvm_classes_unloaded_classes_total The total number of classes unloaded since the Java virtual machine has started execution
# TYPE jvm_classes_unloaded_classes_total counter
- key: com.dynatrace.jvm.classes.global.uploaded.total
value: metric:jvm_classes_unloaded_classes_total
type: count
featureSet: global
# HELP jvm_info_total JVM version info
# TYPE jvm_info_total counter
- key: com.dynatrace.jvm.global.info.total
value: metric:jvm_info_total
type: count
featureSet: global
# HELP http_server_connections_seconds_max
# TYPE http_server_connections_seconds_max gauge
- key: com.dynatrace.http.server.connections.seconds.global.max
value: metric:http_server_connections_seconds_max
type: gauge
featureSet: global
# HELP http_server_connections_seconds
# TYPE http_server_connections_seconds summary
- key: com.dynatrace.http.server.connections.seconds.active.global.count
value: metric:http_server_connections_seconds_active_count
type: count
featureSet: global
- key: com.dynatrace.http.server.connections.seconds.active.global.duration.summary
value: metric:http_server_connections_seconds_duration_sum
type: gauge
featureSet: global
# HELP process_files_max_files The maximum file descriptor count
# TYPE process_files_max_files gauge
- key: com.dynatrace.process.files.global.max
value: metric:process_files_max_files
type: gauge
featureSet: global
# HELP http_server_bytes_written_max
# TYPE http_server_bytes_written_max gauge
- key: com.dynatrace.http.server.bytes.wrriten.global.max
value: metric:http_server_bytes_written_max
type: gauge
featureSet: global
# HELP http_server_bytes_written
# TYPE http_server_bytes_written summary
- key: com.dynatrace.http.server.bytes.written.global.count
value: metric:http_server_bytes_written_count
type: count
featureSet: global
- key: com.dynatrace.http.server.bytes.written.global.summary
value: metric:http_server_bytes_written_sum
type: gauge
featureSet: global
# HELP system_load_average_1m The sum of the number of runnable entities queued to available processors and the number of runnable entities running on the available processors averaged over a period of time
# TYPE system_load_average_1m gauge
- key: com.dynatrace.system.load.average.global.lm
value: metric:system_load_average_1m
type: gauge
featureSet: global
# HELP jvm_gc_overhead_percent An approximation of the percent of CPU time used by GC activities over the last lookback period or since monitoring began, whichever is shorter, in the range [0..1]
# TYPE jvm_gc_overhead_percent gauge
- key: com.dynatrace.jvm.gc.overhead.global.percent
value: metric:jvm_gc_overhead_percent
type: gauge
featureSet: global
# HELP jvm_threads_daemon_threads The current number of live daemon threads
# TYPE jvm_threads_daemon_threads gauge
- key: com.dynatrace.jvm.threads.daemon.global.threads
value: metric:jvm_threads_daemon_threads
type: gauge
featureSet: global
# HELP jvm_threads_live_threads The current number of live threads including both daemon and non-daemon threads
# TYPE jvm_threads_live_threads gauge
- key: com.dynatrace.jvm.threads.live.global.threads
value: metric:jvm_threads_live_threads
type: gauge
featureSet: global
# HELP http_server_requests_seconds
# TYPE http_server_requests_seconds summary
- key: com.dynatrace.http.server.bytes.written.global.count
value: metric:http_server_requests_seconds_count
type: count
featureSet: global
- key: com.dynatrace.http.server.bytes.written.global.summary
value: metric:http_server_requests_seconds_sum
type: gauge
featureSet: global
# HELP http_server_requests_seconds_max
# TYPE http_server_requests_seconds_max gauge
- key: com.dynatrace.http.server.requests.seconds.max
value: metric:http_server_requests_seconds_max
type: gauge
featureSet: global
# HELP process_start_time_seconds Start time of the process since unix epoch.
# TYPE process_start_time_seconds gauge
- key: com.dynatrace.process.start.time.global.seconds
value: metric:process_start_time_seconds
type: gauge
featureSet: global
# HELP jvm_classes_loaded_classes The number of classes that are currently loaded in the Java virtual machine
# TYPE jvm_classes_loaded_classes gauge
- key: com.dynatrace.jvm.classes.loaded.global.max
value: metric:jvm_classes_loaded_classes
type: gauge
featureSet: global
# HELP jvm_threads_peak_threads The peak live thread count since the Java virtual machine started or peak was reset
# TYPE jvm_threads_peak_threads gauge
- key: com.dynatrace.jvm.threads.peak.global.threads
value: metric:jvm_threads_peak_threads
type: gauge
featureSet: global
# HELP system_cpu_count The number of processors available to the Java virtual machine
# TYPE system_cpu_count gauge
- key: com.dynatrace.system.cpu.global.counter
value: metric:system_cpu_count
type: gauge
featureSet: global
# HELP process_files_open_files The open file descriptor count
# TYPE process_files_open_files gauge
- key: com.dynatrace.process.files.open.global.files
value: metric:process_files_open_files
type: gauge
featureSet: global

Logs

Dynatrace offers various options for collecting logs from your applications and environments.

To learn how to set up logging in your Quarkus application, see the Configuring logging Quarkus guide.

For the procedure below, we assume your application writes logs to the /var/log/quarkus-app.log file.

  1. Start your Quarkus native application.
  2. Go to Hosts or Hosts Classic (latest Dynatrace) and select your host.
  3. Scroll down to the Process analysis section and, in the list of processes, select the process of your Quarkus native application.
  4. On the right side of the Process panel, select More > Settings.
  5. In the process group settings, select Log monitoring > Add new log for monitoring.
  6. Enter the full path of your log file. Be sure to follow the log path requirements.
  7. Select Save changes.
  8. Include the added log files in your log storage.