R7. PromQL Integration Reference
Diátaxis: Reference · Audience: operators / administrators (with PromQL or Grafana experience) ← Back to contents
If you are already comfortable with Grafana dashboards or PromQL, the WAS, JVM, system, WEB, and DBMS metrics OPENMARU APM collects can be queried directly with standard PromQL-compatible queries. Collection, storage, querying, and visualization all happen in APM alone, with no separate Prometheus server, exporter, or scrape configuration, and existing Grafana dashboard assets can be reused.
- APM's fine-grained metrics as they are -- reach JVM, GC, thread, DB connection pool, and transaction metrics with standard PromQL
- Rich labels -- filter and aggregate precisely with APM context such as
instance_id,ip_addr, andagent_type - rate/increase are fast and accurate -- stored as a delta at collection time, so a query only sums
- Relative time expressions -- intuitive forms such as
nowandnow-1hare supported (a convenience standard Prometheus does not have)
For what each metric means, see R2. Chart Metric Reference and E3. What the Metrics Mean. To gather charts inside the console, H3. My Dashboard is enough -- PromQL is the tool for external integration and automation.
How to open it -- in a browser, http://{apm-server}/monitoring/api/v1/metric-explorer
(the Metric Explorer UI). Sign in with an API access key -- go to the left menu ▸ Settings ▸
Users, press the edit user button, and create and copy the key.
Getting Started in 5 Minutes
The simplest query -- one line gives the JVM heap usage (current value) of every WAS instance.
jvm_heap_heapUsed
To see only a particular instance, or only a particular IP range (regular expression):
jvm_heap_heapUsed{instance_id="apm-was-01"}
jvm_heap_heapUsed{ip_addr=~"192\\.168\\.80\\..*"}
Apply time functions to get the maximum over the last hour and the 5-minute average GC frequency:
max_over_time(jvm_heap_heapUsed[1h])
rate(jvm_gc_gcCount[5m])
Note Choose the exact metric name from the Metric Explorer dropdown, or check it with
GET /api/v1/label/__name__/values(about 250 of them).
Querying a Specified Period
A range query (/api/v1/query_range) takes the start and end times and a step (the data interval).
Four time formats are supported.
| Format | Example | Note |
|---|---|---|
| Relative time | now, now-1h, now-30m, now-1d | The most convenient -- units s/m/h/d |
| Unix epoch (seconds) | 1704067200 | shell date +%s |
| Unix epoch with a fraction | 1704067200.123 | Millisecond precision |
| RFC3339 | 2026-05-10T09:00:00+09:00 | Can include a time zone |
Frequently used call examples:
# The last hour -- the most common case (step automatically 15s)
curl -G "http://{apm-server}/monitoring/api/v1/query_range" \
--data-urlencode "query=jvm_heap_heapUsed" \
--data-urlencode "start=now-1h" \
--data-urlencode "end=now"
# The weekly trend over the last 7 days (step automatically 5m)
curl -G "http://{apm-server}/monitoring/api/v1/query_range" \
--data-urlencode "query=max_over_time(cpu_usage_cpuUsage[1h])" \
--data-urlencode "start=now-7d" \
--data-urlencode "end=now"
# Specifying the step directly (15-second interval)
curl -G "http://{apm-server}/monitoring/api/v1/query_range" \
--data-urlencode "query=rate(jvm_gc_gcCount[5m])" \
--data-urlencode "start=now-30m" \
--data-urlencode "end=now" \
--data-urlencode "step=15s"
# A particular date range (KST)
curl -G "http://{apm-server}/monitoring/api/v1/query_range" \
--data-urlencode "query=jvm_heap_heapUsed{agent_type=\"WAS\"}" \
--data-urlencode "start=2026-05-10T09:00:00+09:00" \
--data-urlencode "end=2026-05-11T18:00:00+09:00"
Without a step, it is calculated automatically from the query range:
| Query range | Automatic step | Data points (example) | Suggested use |
|---|---|---|---|
| 12 hours or less | 15s | 1 hour ≈ 240 | Real time · standard dashboards |
| 12 hours to 2 days | 1m | 24 hours ≈ 1,440 | Day-to-day comparison |
| 2 to 8 days | 5m | 7 days ≈ 2,016 | Weekly trend |
| 8 to 21 days | 10m | Fortnightly trend | |
| 21 days or more | 30m | 30 days ≈ 1,440 | Monthly comparison |
Note The raw data is stored every 2 seconds. A smaller step is denser but loads the server more -- start with a large step and reduce it when you need to.
If you need only one value at a single point in time, use an instant query (/api/v1/query):
# The heap usage now / one hour ago
curl -G "http://{apm-server}/monitoring/api/v1/query" \
--data-urlencode "query=jvm_heap_heapUsed"
curl -G "http://{apm-server}/monitoring/api/v1/query" \
--data-urlencode "query=jvm_heap_heapUsed" \
--data-urlencode "time=now-1h"
Metric Names and Labels
APM metrics are distinguished by five label dimensions. They are used directly in query filters and aggregation.
| Label | Meaning | Example values |
|---|---|---|
__name__ | The metric name -- in the form {nameSpace}_{metricName}_{field} | jvm_heap_heapUsed, cpu_usage_cpuUsage |
ip_addr | The IP of the host the agent is installed on | 192.168.80.190 |
agent_type | The agent type | WAS, SYS, DBMS, WEB |
instance_id | The instance identifier (unique within the host) | apm-was-01, nginx-1 |
namespace | The metric group | jvm, transaction, cpu, memory |
Prometheus-standard labels are generated automatically as well -- instance
(= {ip_addr}:{instance_id}) and job (= agent_type).
For metric names, only one form has to be known: {nameSpace}_{metricName}_{field} (the
trailing _field may be omitted -- omitting it selects the default field).
| Example | Meaning |
|---|---|
jvm_heap_heapUsed | The used field of the JVM heap |
jvm_heap_heapMax | The maximum field of the same metric |
cpu_usage_cpuUsage | CPU utilization |
cpu_usage_systemCpuUsage | System-wide CPU utilization |
All four standard label matchers are supported, and several conditions are combined with commas:
metric{label="value"} # equal
metric{label!="value"} # not equal
metric{label=~"regex"} # regular expression match
metric{label!~"regex"} # regular expression non-match
jvm_heap_heapUsed{ip_addr="192.168.80.190", instance_id=~"apm-was-.*", agent_type="WAS"}
How It Differs from Prometheus
Almost all the syntax is identical; one thing differs -- how counters are stored.
| Aspect | Prometheus | OPENMARU APM |
|---|---|---|
| Stored counter value | A monotonically increasing cumulative value (total requests 1, 2, 3 …) | The delta per unit time (17 in 2 seconds) |
rate() calculation | (last value − first value) ÷ period | sum of deltas ÷ period |
increase() calculation | last value − first value | sum of deltas |
| Counter reset correction | Required | Not required (a delta has no reset concept) |
What the user sees is the same -- rate(jvm_gc_gcCount[5m]) is "the average GC count per second"
on both. Only the internal calculation differs, and storing deltas up front makes it faster and more
accurate.
The following are 100% compatible -- label matchers, aggregation operators (sum by and so on) with
topk/bottomk/quantile, rate/irate/increase, the *_over_time function family, the maths
functions, arithmetic and comparison operations, and the HTTP API specification.
Unsupported items and limitations:
| Item | State |
|---|---|
histogram_quantile() | Not supported -- APM stores quantiles directly, so use fields such as avgRT, minRT, and maxRT straight away |
| Recording / alerting rules | Not supported |
Subquery (<expr>[<range>:<step>]) | Limited support |
predict_linear(), holt_winters() | Not supported |
| Automatic rollup for long-range queries | Not applied -- for queries over several weeks, specifying a large step is recommended |
Note Querying
metric{...}without a function returns the last sample in the step window. If you need an exact sum or average over the window, writesum_over_time(...)oravg_over_time(...)explicitly.
Supported Functions
All four standard data types (instant vector, range vector, scalar, string) are supported.
Rate / counter functions -- range vector → instant vector:
rate(metric[5m]) # average rate of change per second
irate(metric[5m]) # instantaneous rate from the last two samples
increase(metric[5m]) # the total increase over the window
The over_time family -- window statistics:
avg_over_time(metric[1h]) min_over_time(metric[1h]) max_over_time(metric[1h])
sum_over_time(metric[1h]) count_over_time(metric[1h]) last_over_time(metric[1h])
Aggregation operators -- sum, avg, min, max, count, stddev, stdvar,
topk(N, …), bottomk(N, …), quantile(0.95, …), count_values, group.
Group with a by or without clause:
avg by (instance) (jvm_heap_heapUsed) # average per instance
sum without (user_key) (jvm_heap_heapUsed) # group by everything except user_key
topk(5, rate(jvm_gc_gcCount[5m])) # the top 5 instances by GC frequency
Maths, arithmetic, and comparison:
abs(metric) ceil(metric) floor(metric) round(metric)
metric_a + metric_b
rate(metric[5m]) / 60
jvm_heap_heapUsed > 1024 * 1024 * 1024 # returns only the series over 1 GB
Metric Explorer
A UI for running PromQL interactively in a browser -- reach it at the address in How to open it above.
| Area | Function |
|---|---|
| Metric selection dropdown | Automatic discovery of registered metrics (by __name__) |
| PromQL query input | Type it directly -- choosing from the dropdown fills it in automatically |
| Label filter panel | Dropdowns per ip_addr, agent_type, instance_id, and namespace |
| Aggregate function selection | sum, avg, topk, quantile, and others |
| Time range | Quick buttons from the last 5m to 7d, plus a custom range |
| Step | Auto / 15s / 1m / 5m / 10m / 30m / 1h |
| Result visualization | Line, area, and bar charts plus a table of raw values |
| Copy API URL | Copies the current query as an /api/v1/query_range URL -- for external integration such as Grafana |
Making your first chart in 30 seconds:
- Select
jvm_heap_heapUsedin the metric dropdown - Select
agent_type=WASin the label filter - Click the 1h time range and leave Step at Auto
- Click Run → a graph of one hour of heap usage across the WAS instances appears
Note Auto is usually enough for Step. A small step with a long range loads the server heavily.
Grafana integration -- the same API can be connected as a Prometheus data source in Grafana:
URL: http://{apm-server}/monitoring
Access: Server (default)
Grafana calls /api/v1/query, /api/v1/query_range, /api/v1/labels, and the rest automatically --
reuse existing dashboard and alerting assets as they are.
HTTP API Summary
| Method | Path | Purpose |
|---|---|---|
| GET / POST | /api/v1/query | Instant (single point in time) query |
| GET / POST | /api/v1/query_range | Range (time range) query |
| GET | /api/v1/series | Series metadata |
| GET | /api/v1/labels | The list of label names |
| GET | /api/v1/label/{name}/values | The list of values for a particular label |
| GET | /api/v1/metadata | Metric metadata |
| GET | /api/v1/metric-explorer | The Metric Explorer UI |
Parameters -- query (required), time for instant, and start, end, and step for range
(calculated automatically when omitted). Exploratory calls:
# The full list of available metrics (~250)
curl "http://{apm-server}/monitoring/api/v1/label/__name__/values"
# The list of label names / the values of a particular label
curl "http://{apm-server}/monitoring/api/v1/labels"
curl "http://{apm-server}/monitoring/api/v1/label/agent_type/values"
A Collection of Frequently Used Queries
The metric names are examples following the general pattern -- check the exact names for your environment in the Metric Explorer.
JVM / WAS:
jvm_heap_heapUsed{agent_type="WAS"} # current heap usage across all WAS
avg_over_time(jvm_heap_heapUsed[5m]) # 5-minute average heap usage
topk(5, jvm_heap_heapUsed) # the top 5 instances by heap usage
(jvm_heap_heapUsed / jvm_heap_heapMax) > 0.8 # heap utilization over 80%
sum_over_time(jvm_gc_gcTime[1h]) # total GC time (1 hour)
rate(jvm_gc_gcCount[5m]) # GC count per second
datasource_pool_active{agent_type="WAS"} # DataSource connections in use
System:
topk(10, cpu_usage_cpuUsage{agent_type="SYS"}) # the top 10 hosts by CPU
cpu_usage_systemCpuUsage # system-wide CPU
avg_over_time(cpu_usage_cpuUsage[1h]) # 1-hour average CPU per instance
Aggregating per host:
avg by (ip_addr) (jvm_heap_heapUsed) # average heap per host
count by (agent_type) (jvm_heap_heapUsed) # instance count per agent_type
{ip_addr="192.168.80.190"} # every series for a particular IP
When It Does Not Work
| Symptom | What to check |
|---|---|
| You do not know the metric name | Check the actual name in the Metric Explorer dropdown or at /api/v1/label/__name__/values |
| The result is empty | A typo in a label value -- check the possible values at /api/v1/label/{name}/values, and check the case of agent_type |
| Metric Explorer sign-in fails | An API access key is required -- create and copy the key under Settings ▸ Users |
A rate() value is not what you expect | APM stores deltas, so there is no reset correction -- check you have not confused it with a query without a function |
| The sum or average does not match | A query without a function gives the last sample -- write sum_over_time or avg_over_time explicitly |
histogram_quantile does not work | Not supported -- query quantile fields such as avgRT and maxRT directly |
| A long-range query is slow | Specify a large step (30m to 1h) -- a small step over a long range is heavy |
Related Documents
- R2. Chart Metric Reference -- what each metric means, the signals of trouble, and thresholds
- E3. What the Metrics Mean -- the concepts of APDEX, response time, and throughput
- H3. My Dashboard -- gathering charts inside the console (no PromQL needed)
- H18. Managing Users, Groups, and Permissions -- where the API access key is issued
This chapter also appears with the same content as chapter 7 of the OPENMARU APM API Integration Guide. To read it alongside the JSON APIs that use a session cookie (graph data, configuration, user management), see that guide.