This page documents how to interact with the Catalyst Cloud Metrics Service using the OpenStack CLI, the Python Client for Gnocchi, or via direct metrics API requests using cURL.
You should reference the Metrics Service Overview while going through this page to understand some of the concepts and terminology used. Information on the resource and metric types we offer is available in the Resource/Metric Reference.
Note
The Metrics Service has no user interface on the Catalyst Cloud dashboard at this time.
Catalyst Cloud users with one of the following user roles can use the Metrics Service (for more information, see Access Control):
First, follow the instructions for setting up the CLI Tools and SDKs.
Make sure you have sourced the OpenRC file for your project in an open terminal.
Check that the openstack metric series of commands are available.
If not, make sure the gnocchiclient package is installed.
$ openstack metric --help
Command "metric" matches:
metric aggregates
metric archive-policy create
metric archive-policy delete
metric archive-policy list
metric archive-policy show
metric archive-policy update
metric archive-policy-rule create
metric archive-policy-rule delete
metric archive-policy-rule list
metric archive-policy-rule show
metric benchmark measures add
metric benchmark measures show
metric benchmark metric create
metric benchmark metric show
metric capabilities list
metric create
metric delete
metric list
metric measures add
metric measures aggregation
metric measures batch-metrics
metric measures batch-resources-metrics
metric measures show
metric resource batch delete
metric resource create
metric resource delete
metric resource history
metric resource list
metric resource search
metric resource show
metric resource update
metric resource-type create
metric resource-type delete
metric resource-type list
metric resource-type show
metric resource-type update
metric server version
metric show
metric status
Here we will show you how to get a working Gnocchi client object in an interactive Python shell.
First, open an interactive Python shell in the environment where
the gnocchiclient package is installed:
python3 -i
Next, copy and paste the following code into the shell to create and configure a Gnocchi client object from the authentication credentials configured in your terminal.
We will use gnocchi_client as the variable to access the
Python Client for Gnocchi in examples throughout this page.
import datetime
import os
from pprint import pprint
from keystoneauth1.identity.generic import Token
from keystoneauth1.session import Session
from gnocchiclient.client import Client
session = Session(auth=Token(os.environ["OS_AUTH_URL"], os.environ["OS_TOKEN"], project_id=os.environ["OS_PROJECT_ID"]))
gnocchi_client = Client("1", session=session, adapter_options=dict(region_name=os.environ["OS_REGION_NAME"]))
If you get the following error:
Traceback (most recent call last):
File "<stdin>", line 6, in <module>
ModuleNotFoundError: No module named 'gnocchiclient'
Make sure the gnocchiclient package is installed in your Python environment.
For more information on how to use the gnocchiclient library,
read the Python Client for Gnocchi documentation.
Install the curl system package if it is not installed already.
sudo apt update && sudo apt install -y curl
sudo dnf install -y curl
Here are instructions for performing a number of tasks regularly done when interacting with the Metrics Service.
This example shows how to get the metadata for a resource
of a certain type (e.g. instance), and the list of metrics
associated with the resource.
Run the following command:
openstack metric resource show --type ${resource_type} ${resource_id}
Example output:
$ openstack metric resource show --type instance af6b97d9-d172-4e06-b565-db1e97097340
+-----------------------+---------------------------------------------------------------------+
| Field | Value |
+-----------------------+---------------------------------------------------------------------+
| id | af6b97d9-d172-4e06-b565-db1e97097340 |
| creator | 42dcfd23b04a4006b9e2b08c0a835aeb:70d50fbf0c2148689aa2c319351e634d |
| started_at | 2025-03-18T02:16:55.790609+00:00 |
| revision_start | 2025-03-18T22:00:58.683260+00:00 |
| ended_at | None |
| user_id | 517bcd700274432d96f43616ac1e37ea |
| project_id | 9864e20f92ef47238becfe06b869d2ac |
| original_resource_id | af6b97d9-d172-4e06-b565-db1e97097340 |
| type | instance |
| display_name | test-instance |
| image_ref | None |
| flavor_id | 28153197-6690-4485-9dbc-fc24489b0683 |
| server_group | None |
| flavor_name | c1.c1r1 |
| os_distro | ubuntu |
| os_type | linux |
| host | None |
| revision_end | None |
| metrics | compute.instance.booting.time: c418003f-5115-4bd3-a56e-270d90e26b2f |
| | cpu: 6febda4a-4a3f-485f-b6e2-5f94d55e39b0 |
| | disk.ephemeral.size: d0add36c-6208-40d3-a8d0-2f5ab3a550bd |
| | disk.root.size: b4e3d818-444b-46a9-b874-c82fd78e3a66 |
| | instance: 53c46abc-5336-49a8-ac76-fc5aed5e5154 |
| | memory: 1e87f21e-2238-41f0-80fd-950e3e2f9bcf |
| | vcpus: 9d60abe7-b1d7-425d-8d89-6c0eecd38c47 |
| created_by_user_id | 42dcfd23b04a4006b9e2b08c0a835aeb |
| created_by_project_id | 70d50fbf0c2148689aa2c319351e634d |
+-----------------------+---------------------------------------------------------------------+
Call the following method:
gnocchi_client.resource.get("{resource_type}", "{resource_id}")
Example output:
>>> pprint(gnocchi_client.resource.get("instance", "af6b97d9-d172-4e06-b565-db1e97097340"))
{'created_by_project_id': '70d50fbf0c2148689aa2c319351e634d',
'created_by_user_id': '42dcfd23b04a4006b9e2b08c0a835aeb',
'creator': '42dcfd23b04a4006b9e2b08c0a835aeb:70d50fbf0c2148689aa2c319351e634d',
'display_name': 'test-instance',
'ended_at': None,
'flavor_id': '28153197-6690-4485-9dbc-fc24489b0683',
'flavor_name': 'c1.c1r1',
'host': None,
'id': 'af6b97d9-d172-4e06-b565-db1e97097340',
'image_ref': None,
'metrics': {'compute.instance.booting.time': 'c418003f-5115-4bd3-a56e-270d90e26b2f',
'cpu': '6febda4a-4a3f-485f-b6e2-5f94d55e39b0',
'disk.ephemeral.size': 'd0add36c-6208-40d3-a8d0-2f5ab3a550bd',
'disk.root.size': 'b4e3d818-444b-46a9-b874-c82fd78e3a66',
'instance': '53c46abc-5336-49a8-ac76-fc5aed5e5154',
'memory': '1e87f21e-2238-41f0-80fd-950e3e2f9bcf',
'vcpus': '9d60abe7-b1d7-425d-8d89-6c0eecd38c47'},
'original_resource_id': 'af6b97d9-d172-4e06-b565-db1e97097340',
'os_distro': 'ubuntu',
'os_type': 'linux',
'project_id': '9864e20f92ef47238becfe06b869d2ac',
'revision_end': None,
'revision_start': '2025-03-18T22:00:58.683260+00:00',
'server_group': None,
'started_at': '2025-03-18T02:16:55.790609+00:00',
'type': 'instance',
'user_id': '517bcd700274432d96f43616ac1e37ea'}
Make the following request:
curl -s \
-H "X-Auth-Token: ${OS_TOKEN}" \
-H "Accept: application/json" \
https://api.$(echo "${OS_REGION_NAME}" | tr '_' '-').catalystcloud.nz:8041/v1/resource/${resource_type}/${resource_id}
Example output:
$ curl -s -H "X-Auth-Token: ${OS_TOKEN}" -H "Accept: application/json" https://api.$(echo "${OS_REGION_NAME}" | tr '_' '-').catalystcloud.nz:8041/v1/resource/instance/af6b97d9-d172-4e06-b565-db1e97097340 | jq
{
"id": "af6b97d9-d172-4e06-b565-db1e97097340",
"creator": "42dcfd23b04a4006b9e2b08c0a835aeb:70d50fbf0c2148689aa2c319351e634d",
"started_at": "2025-03-18T02:16:55.790609+00:00",
"revision_start": "2025-03-18T22:00:58.683260+00:00",
"ended_at": null,
"user_id": "517bcd700274432d96f43616ac1e37ea",
"project_id": "9864e20f92ef47238becfe06b869d2ac",
"original_resource_id": "af6b97d9-d172-4e06-b565-db1e97097340",
"type": "instance",
"display_name": "test-instance",
"image_ref": null,
"flavor_id": "28153197-6690-4485-9dbc-fc24489b0683",
"server_group": null,
"flavor_name": "c1.c1r1",
"os_distro": "ubuntu",
"os_type": "linux",
"host": null,
"revision_end": null,
"metrics": {
"compute.instance.booting.time": "c418003f-5115-4bd3-a56e-270d90e26b2f",
"cpu": "6febda4a-4a3f-485f-b6e2-5f94d55e39b0",
"disk.ephemeral.size": "d0add36c-6208-40d3-a8d0-2f5ab3a550bd",
"disk.root.size": "b4e3d818-444b-46a9-b874-c82fd78e3a66",
"instance": "53c46abc-5336-49a8-ac76-fc5aed5e5154",
"memory": "1e87f21e-2238-41f0-80fd-950e3e2f9bcf",
"vcpus": "9d60abe7-b1d7-425d-8d89-6c0eecd38c47"
},
"created_by_user_id": "42dcfd23b04a4006b9e2b08c0a835aeb",
"created_by_project_id": "70d50fbf0c2148689aa2c319351e634d"
}
Object Storage containers, unlike other resource types, do not have a UUID associated with them in the Object Storage service. The Metrics Service, however, always uses UUIDs for accessing resources.
To resolve this, the Metrics Service generates a custom UUID based on the project ID and the name of the container.
A reference to the project ID and the container name is stored inside the resource as the original_resource_id
field, in the format {project_id}_{container}.
Note
For more information, see the documentation for the container resource type.
Here is how to get object storage container resources in the Metrics Service without knowing the UUID.
Run the following command (substituting {container} for the name of the container to find):
openstack metric resource search --type swift_account "original_resource_id='${OS_PROJECT_ID}_{container}'"
Example output:
$ openstack metric resource search --type swift_account "original_resource_id='${OS_PROJECT_ID}_test-container'"
+--------------------------------------+---------------+----------------------------------+---------+-------------------------------------------------+----------------------------------+----------+----------------------------------+--------------+-------------------------------------------------------------------+----------------+
| id | type | project_id | user_id | original_resource_id | started_at | ended_at | revision_start | revision_end | creator | storage_policy |
+--------------------------------------+---------------+----------------------------------+---------+-------------------------------------------------+----------------------------------+----------+----------------------------------+--------------+-------------------------------------------------------------------+----------------+
| cc5d7d7c-c9c0-5b02-b7d1-cd6cc432358a | swift_account | 9864e20f92ef47238becfe06b869d2ac | None | 9864e20f92ef47238becfe06b869d2ac_test-container | 2025-05-19T03:14:58.321610+00:00 | None | 2025-05-19T03:14:58.321619+00:00 | None | 42dcfd23b04a4006b9e2b08c0a835aeb:ceecc421f7994cc397380fae5e495179 | nz--o1--mr-r3 |
+--------------------------------------+---------------+----------------------------------+---------+-------------------------------------------------+----------------------------------+----------+----------------------------------+--------------+-------------------------------------------------------------------+----------------+
To get just the resource’s UUID, you can add -c id -f value to the end of the command.
$ openstack metric resource search --type swift_account "original_resource_id='${OS_PROJECT_ID}_test-container'" -c id -f value
cc5d7d7c-c9c0-5b02-b7d1-cd6cc432358a
Call the following method (substituting {project_id} for your project ID, and {container} for the name of the container to find):
gnocchi_client.resource.search(
resource_type="swift_account",
query={"=": {"original_resource_id": "{project_id}_{container}"}},
)
Example output:
>>> pprint(gnocchi_client.resource.search(resource_type="swift_account", query={"=": {"original_resource_id": "9864e20f92ef47238becfe06b869d2ac_test-container"}}))
[{'created_by_project_id': 'ceecc421f7994cc397380fae5e495179',
'created_by_user_id': '42dcfd23b04a4006b9e2b08c0a835aeb',
'creator': '42dcfd23b04a4006b9e2b08c0a835aeb:ceecc421f7994cc397380fae5e495179',
'ended_at': None,
'id': 'cc5d7d7c-c9c0-5b02-b7d1-cd6cc432358a',
'metrics': {'storage.containers.objects.size': 'f226f01f-fd2f-4ff8-9848-2fb7b4f1d7dc',
'storage.objects.download.size.internet': '22956258-cbe1-40a8-aace-5c954995b4af',
'storage.objects.upload.size.internet': 'b364abff-4c95-4c2d-8d05-59ea955c2c01'},
'original_resource_id': '9864e20f92ef47238becfe06b869d2ac_test-container',
'project_id': '9864e20f92ef47238becfe06b869d2ac',
'revision_end': None,
'revision_start': '2025-05-19T03:14:58.321619+00:00',
'started_at': '2025-05-19T03:14:58.321610+00:00',
'storage_policy': 'nz--o1--mr-r3',
'type': 'swift_account',
'user_id': None}]
Make the following request (substituting {project_id} for your project ID, and {container} for the name of the container to find):
curl -s \
-X POST \
-H "X-Auth-Token: ${OS_TOKEN}" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
https://api.$(echo "${OS_REGION_NAME}" | tr '_' '-').catalystcloud.nz:8041/v1/search/resource/swift_account \
-d '{"=": {"original_resource_id": "{project_id}_{container}"}}'
Example output:
$ curl -s -X POST -H "X-Auth-Token: ${OS_TOKEN}" -H "Content-Type: application/json" -H "Accept: application/json" https://api.$(echo "${OS_REGION_NAME}" | tr '_' '-').catalystcloud.nz:8041/v1/search/resource/swift_account -d '{"=": {"original_resource_id": "9864e20f92ef47238becfe06b869d2ac_test-container"}}' | jq
[
{
"id": "cc5d7d7c-c9c0-5b02-b7d1-cd6cc432358a",
"creator": "42dcfd23b04a4006b9e2b08c0a835aeb:ceecc421f7994cc397380fae5e495179",
"started_at": "2025-05-19T03:14:58.321610+00:00",
"revision_start": "2025-05-19T03:14:58.321619+00:00",
"ended_at": null,
"user_id": null,
"project_id": "9864e20f92ef47238becfe06b869d2ac",
"original_resource_id": "9864e20f92ef47238becfe06b869d2ac_test-container",
"type": "swift_account",
"storage_policy": "nz--o1--mr-r3",
"revision_end": null,
"metrics": {
"storage.containers.objects.size": "f226f01f-fd2f-4ff8-9848-2fb7b4f1d7dc",
"storage.objects.download.size.internet": "22956258-cbe1-40a8-aace-5c954995b4af",
"storage.objects.upload.size.internet": "b364abff-4c95-4c2d-8d05-59ea955c2c01"
},
"created_by_user_id": "42dcfd23b04a4006b9e2b08c0a835aeb",
"created_by_project_id": "ceecc421f7994cc397380fae5e495179"
}
]
This example shows how to get a list of all resources
of a certain type for a project (e.g. instance).
Run the following command:
openstack metric resource list --type ${resource_type}
Example output:
$ openstack metric resource list --type instance
+--------------------------------------+----------+----------------------------------+----------------------------------+--------------------------------------+----------------------------------+----------+----------------------------------+--------------+-------------------------------------------------------------------+-----------------------+-----------+--------------------------------------+--------------+-------------+-----------+---------+------+
| id | type | project_id | user_id | original_resource_id | started_at | ended_at | revision_start | revision_end | creator | display_name | image_ref | flavor_id | server_group | flavor_name | os_distro | os_type | host |
+--------------------------------------+----------+----------------------------------+----------------------------------+--------------------------------------+----------------------------------+----------+----------------------------------+--------------+-------------------------------------------------------------------+-----------------------+-----------+--------------------------------------+--------------+-------------+-----------+---------+------+
| af6b97d9-d172-4e06-b565-db1e97097340 | instance | 9864e20f92ef47238becfe06b869d2ac | 517bcd700274432d96f43616ac1e37ea | af6b97d9-d172-4e06-b565-db1e97097340 | 2025-03-18T02:16:55.790609+00:00 | None | 2025-03-18T22:00:58.683260+00:00 | None | 42dcfd23b04a4006b9e2b08c0a835aeb:70d50fbf0c2148689aa2c319351e634d | test-instance | None | 28153197-6690-4485-9dbc-fc24489b0683 | None | c1.c1r1 | ubuntu | linux | None |
+--------------------------------------+----------+----------------------------------+----------------------------------+--------------------------------------+----------------------------------+----------+----------------------------------+--------------+-------------------------------------------------------------------+-----------------------+-----------+--------------------------------------+--------------+-------------+-----------+---------+------+
Call the following method:
gnocchi_client.resource.list(resource_type="{resource_type}")
Example output:
>>> pprint(gnocchi_client.resource.list(resource_type="instance"))
[{'created_by_project_id': '70d50fbf0c2148689aa2c319351e634d',
'created_by_user_id': '42dcfd23b04a4006b9e2b08c0a835aeb',
'creator': '42dcfd23b04a4006b9e2b08c0a835aeb:70d50fbf0c2148689aa2c319351e634d',
'display_name': 'test-instance',
'ended_at': None,
'flavor_id': '28153197-6690-4485-9dbc-fc24489b0683',
'flavor_name': 'c1.c1r1',
'host': None,
'id': 'af6b97d9-d172-4e06-b565-db1e97097340',
'image_ref': None,
'metrics': {'compute.instance.booting.time': 'c418003f-5115-4bd3-a56e-270d90e26b2f',
'cpu': '6febda4a-4a3f-485f-b6e2-5f94d55e39b0',
'disk.ephemeral.size': 'd0add36c-6208-40d3-a8d0-2f5ab3a550bd',
'disk.root.size': 'b4e3d818-444b-46a9-b874-c82fd78e3a66',
'instance': '53c46abc-5336-49a8-ac76-fc5aed5e5154',
'memory': '1e87f21e-2238-41f0-80fd-950e3e2f9bcf',
'vcpus': '9d60abe7-b1d7-425d-8d89-6c0eecd38c47'},
'original_resource_id': 'af6b97d9-d172-4e06-b565-db1e97097340',
'os_distro': 'ubuntu',
'os_type': 'linux',
'project_id': '9864e20f92ef47238becfe06b869d2ac',
'revision_end': None,
'revision_start': '2025-03-18T22:00:58.683260+00:00',
'server_group': None,
'started_at': '2025-03-18T02:16:55.790609+00:00',
'type': 'instance',
'user_id': '517bcd700274432d96f43616ac1e37ea'}]
Make the following request:
curl -s \
-H "X-Auth-Token: ${OS_TOKEN}" \
-H "Accept: application/json" \
https://api.$(echo "${OS_REGION_NAME}" | tr '_' '-').catalystcloud.nz:8041/v1/resource/${resource_type}
Example output:
$ curl -s -H "X-Auth-Token: ${OS_TOKEN}" -H "Accept: application/json" https://api.$(echo "${OS_REGION_NAME}" | tr '_' '-').catalystcloud.nz:8041/v1/resource/instance | jq
[
{
"id": "af6b97d9-d172-4e06-b565-db1e97097340",
"creator": "42dcfd23b04a4006b9e2b08c0a835aeb:70d50fbf0c2148689aa2c319351e634d",
"started_at": "2025-03-18T02:16:55.790609+00:00",
"revision_start": "2025-03-18T22:00:58.683260+00:00",
"ended_at": null,
"user_id": "517bcd700274432d96f43616ac1e37ea",
"project_id": "9864e20f92ef47238becfe06b869d2ac",
"original_resource_id": "af6b97d9-d172-4e06-b565-db1e97097340",
"type": "instance",
"display_name": "test-instance",
"image_ref": null,
"flavor_id": "28153197-6690-4485-9dbc-fc24489b0683",
"server_group": null,
"flavor_name": "c1.c1r1",
"os_distro": "ubuntu",
"os_type": "linux",
"host": null,
"revision_end": null,
"metrics": {
"compute.instance.booting.time": "c418003f-5115-4bd3-a56e-270d90e26b2f",
"cpu": "6febda4a-4a3f-485f-b6e2-5f94d55e39b0",
"disk.ephemeral.size": "d0add36c-6208-40d3-a8d0-2f5ab3a550bd",
"disk.root.size": "b4e3d818-444b-46a9-b874-c82fd78e3a66",
"instance": "53c46abc-5336-49a8-ac76-fc5aed5e5154",
"memory": "1e87f21e-2238-41f0-80fd-950e3e2f9bcf",
"vcpus": "9d60abe7-b1d7-425d-8d89-6c0eecd38c47"
},
"created_by_user_id": "42dcfd23b04a4006b9e2b08c0a835aeb",
"created_by_project_id": "70d50fbf0c2148689aa2c319351e634d"
}
]
This example shows how to get more details for a resource metric by name.
Note
Metrics can only be fetched using their own unique ID, or by name in combination with a resource ID.
Fetching metrics only by name is not supported.
Run the following command:
openstack metric show --resource-id ${resource_id} ${metric_name}
Example output:
$ openstack metric show --resource-id af6b97d9-d172-4e06-b565-db1e97097340 cpu
+--------------------------------+-------------------------------------------------------------------+
| Field | Value |
+--------------------------------+-------------------------------------------------------------------+
| id | 6febda4a-4a3f-485f-b6e2-5f94d55e39b0 |
| creator | 42dcfd23b04a4006b9e2b08c0a835aeb:70d50fbf0c2148689aa2c319351e634d |
| name | cpu |
| unit | ns |
| archive_policy/name | met1.telemetry-high-rate |
| resource/id | af6b97d9-d172-4e06-b565-db1e97097340 |
| resource/creator | 42dcfd23b04a4006b9e2b08c0a835aeb:70d50fbf0c2148689aa2c319351e634d |
| resource/started_at | 2025-03-18T02:16:55.790609+00:00 |
| resource/revision_start | 2025-03-18T22:00:58.683260+00:00 |
| resource/ended_at | None |
| resource/user_id | 517bcd700274432d96f43616ac1e37ea |
| resource/project_id | 9864e20f92ef47238becfe06b869d2ac |
| resource/original_resource_id | af6b97d9-d172-4e06-b565-db1e97097340 |
| resource/type | instance |
| resource/revision_end | None |
| resource/created_by_user_id | 42dcfd23b04a4006b9e2b08c0a835aeb |
| resource/created_by_project_id | 70d50fbf0c2148689aa2c319351e634d |
+--------------------------------+-------------------------------------------------------------------+
Call the following method:
gnocchi_client.metric.get("{metric_name}", resource_id="{resource_id}")
Example output:
>>> pprint(gnocchi_client.metric.get("cpu", resource_id="af6b97d9-d172-4e06-b565-db1e97097340"))
{'archive_policy': {'aggregation_methods': ['rate:mean', 'mean'],
'back_window': 0,
'definition': [{'granularity': '0:01:00',
'points': 7200,
'timespan': '5 days, 0:00:00'},
{'granularity': '0:10:00',
'points': 4320,
'timespan': '30 days, 0:00:00'},
{'granularity': '1:00:00',
'points': 2160,
'timespan': '90 days, 0:00:00'}],
'name': 'met1.telemetry-high-rate'},
'created_by_project_id': '70d50fbf0c2148689aa2c319351e634d',
'created_by_user_id': '42dcfd23b04a4006b9e2b08c0a835aeb',
'creator': '42dcfd23b04a4006b9e2b08c0a835aeb:70d50fbf0c2148689aa2c319351e634d',
'id': '6febda4a-4a3f-485f-b6e2-5f94d55e39b0',
'name': 'cpu',
'resource': {'created_by_project_id': '70d50fbf0c2148689aa2c319351e634d',
'created_by_user_id': '42dcfd23b04a4006b9e2b08c0a835aeb',
'creator': '42dcfd23b04a4006b9e2b08c0a835aeb:70d50fbf0c2148689aa2c319351e634d',
'ended_at': None,
'id': 'af6b97d9-d172-4e06-b565-db1e97097340',
'original_resource_id': 'af6b97d9-d172-4e06-b565-db1e97097340',
'project_id': '9864e20f92ef47238becfe06b869d2ac',
'revision_end': None,
'revision_start': '2025-03-18T22:00:58.683260+00:00',
'started_at': '2025-03-18T02:16:55.790609+00:00',
'type': 'instance',
'user_id': '517bcd700274432d96f43616ac1e37ea'},
'unit': 'ns'}
Make the following request:
curl -s \
-H "X-Auth-Token: ${OS_TOKEN}" \
-H "Accept: application/json" \
https://api.$(echo "${OS_REGION_NAME}" | tr '_' '-').catalystcloud.nz:8041/v1/resource/${resource_type}/${resource_id}/metric/${metric_name}
Example output:
$ curl -s -H "X-Auth-Token: ${OS_TOKEN}" -H "Accept: application/json" https://api.$(echo "${OS_REGION_NAME}" | tr '_' '-').catalystcloud.nz:8041/v1/resource/instance/af6b97d9-d172-4e06-b565-db1e97097340/metric/cpu | jq
{
"id": "6febda4a-4a3f-485f-b6e2-5f94d55e39b0",
"creator": "42dcfd23b04a4006b9e2b08c0a835aeb:70d50fbf0c2148689aa2c319351e634d",
"name": "cpu",
"unit": "ns",
"resource": {
"id": "af6b97d9-d172-4e06-b565-db1e97097340",
"creator": "42dcfd23b04a4006b9e2b08c0a835aeb:70d50fbf0c2148689aa2c319351e634d",
"started_at": "2025-03-18T02:16:55.790609+00:00",
"revision_start": "2025-03-18T22:00:58.683260+00:00",
"ended_at": null,
"user_id": "517bcd700274432d96f43616ac1e37ea",
"project_id": "9864e20f92ef47238becfe06b869d2ac",
"original_resource_id": "af6b97d9-d172-4e06-b565-db1e97097340",
"type": "instance",
"revision_end": null,
"created_by_user_id": "42dcfd23b04a4006b9e2b08c0a835aeb",
"created_by_project_id": "70d50fbf0c2148689aa2c319351e634d"
},
"archive_policy": {
"name": "met1.telemetry-high-rate",
"back_window": 0,
"definition": [
{
"timespan": "5 days, 0:00:00",
"granularity": "0:01:00",
"points": 7200
},
{
"timespan": "30 days, 0:00:00",
"granularity": "0:10:00",
"points": 4320
},
{
"timespan": "90 days, 0:00:00",
"granularity": "1:00:00",
"points": 2160
}
],
"aggregation_methods": [
"rate:mean",
"mean"
]
},
"created_by_user_id": "42dcfd23b04a4006b9e2b08c0a835aeb",
"created_by_project_id": "70d50fbf0c2148689aa2c319351e634d"
}
This example shows how to get more details for a metric using its unique ID.
Note
Metrics can only be fetched using their own unique ID, or by name in combination with a resource ID.
Fetching metrics only by name is not supported.
Run the following command:
openstack metric show ${metric_id}
Example output:
$ openstack metric show 6febda4a-4a3f-485f-b6e2-5f94d55e39b0
+--------------------------------+-------------------------------------------------------------------+
| Field | Value |
+--------------------------------+-------------------------------------------------------------------+
| id | 6febda4a-4a3f-485f-b6e2-5f94d55e39b0 |
| creator | 42dcfd23b04a4006b9e2b08c0a835aeb:70d50fbf0c2148689aa2c319351e634d |
| name | cpu |
| unit | ns |
| archive_policy/name | met1.telemetry-high-rate |
| resource/id | af6b97d9-d172-4e06-b565-db1e97097340 |
| resource/creator | 42dcfd23b04a4006b9e2b08c0a835aeb:70d50fbf0c2148689aa2c319351e634d |
| resource/started_at | 2025-03-18T02:16:55.790609+00:00 |
| resource/revision_start | 2025-03-18T22:00:58.683260+00:00 |
| resource/ended_at | None |
| resource/user_id | 517bcd700274432d96f43616ac1e37ea |
| resource/project_id | 9864e20f92ef47238becfe06b869d2ac |
| resource/original_resource_id | af6b97d9-d172-4e06-b565-db1e97097340 |
| resource/type | instance |
| resource/revision_end | None |
| resource/created_by_user_id | 42dcfd23b04a4006b9e2b08c0a835aeb |
| resource/created_by_project_id | 70d50fbf0c2148689aa2c319351e634d |
+--------------------------------+-------------------------------------------------------------------+
Call the following method:
gnocchi_client.metric.get("{metric_id}")
Example output:
>>> pprint(gnocchi_client.metric.get("6febda4a-4a3f-485f-b6e2-5f94d55e39b0"))
{'archive_policy': {'aggregation_methods': ['rate:mean', 'mean'],
'back_window': 0,
'definition': [{'granularity': '0:01:00',
'points': 7200,
'timespan': '5 days, 0:00:00'},
{'granularity': '0:10:00',
'points': 4320,
'timespan': '30 days, 0:00:00'},
{'granularity': '1:00:00',
'points': 2160,
'timespan': '90 days, 0:00:00'}],
'name': 'met1.telemetry-high-rate'},
'created_by_project_id': '70d50fbf0c2148689aa2c319351e634d',
'created_by_user_id': '42dcfd23b04a4006b9e2b08c0a835aeb',
'creator': '42dcfd23b04a4006b9e2b08c0a835aeb:70d50fbf0c2148689aa2c319351e634d',
'id': '6febda4a-4a3f-485f-b6e2-5f94d55e39b0',
'name': 'cpu',
'resource': {'created_by_project_id': '70d50fbf0c2148689aa2c319351e634d',
'created_by_user_id': '42dcfd23b04a4006b9e2b08c0a835aeb',
'creator': '42dcfd23b04a4006b9e2b08c0a835aeb:70d50fbf0c2148689aa2c319351e634d',
'ended_at': None,
'id': 'af6b97d9-d172-4e06-b565-db1e97097340',
'original_resource_id': 'af6b97d9-d172-4e06-b565-db1e97097340',
'project_id': '9864e20f92ef47238becfe06b869d2ac',
'revision_end': None,
'revision_start': '2025-03-18T22:00:58.683260+00:00',
'started_at': '2025-03-18T02:16:55.790609+00:00',
'type': 'instance',
'user_id': '517bcd700274432d96f43616ac1e37ea'},
'unit': 'ns'}
Make the following request:
curl -s \
-H "X-Auth-Token: ${OS_TOKEN}" \
-H "Accept: application/json" \
https://api.$(echo "${OS_REGION_NAME}" | tr '_' '-').catalystcloud.nz:8041/v1/metric/${metric_id}
Example output:
$ curl -s -H "X-Auth-Token: ${OS_TOKEN}" -H "Accept: application/json" https://api.$(echo "${OS_REGION_NAME}" | tr '_' '-').catalystcloud.nz:8041/v1/metric/6febda4a-4a3f-485f-b6e2-5f94d55e39b0 | jq
{
"id": "6febda4a-4a3f-485f-b6e2-5f94d55e39b0",
"creator": "42dcfd23b04a4006b9e2b08c0a835aeb:70d50fbf0c2148689aa2c319351e634d",
"name": "cpu",
"unit": "ns",
"resource": {
"id": "af6b97d9-d172-4e06-b565-db1e97097340",
"creator": "42dcfd23b04a4006b9e2b08c0a835aeb:70d50fbf0c2148689aa2c319351e634d",
"started_at": "2025-03-18T02:16:55.790609+00:00",
"revision_start": "2025-03-18T22:00:58.683260+00:00",
"ended_at": null,
"user_id": "517bcd700274432d96f43616ac1e37ea",
"project_id": "9864e20f92ef47238becfe06b869d2ac",
"original_resource_id": "af6b97d9-d172-4e06-b565-db1e97097340",
"type": "instance",
"revision_end": null,
"created_by_user_id": "42dcfd23b04a4006b9e2b08c0a835aeb",
"created_by_project_id": "70d50fbf0c2148689aa2c319351e634d"
},
"archive_policy": {
"name": "met1.telemetry-high-rate",
"back_window": 0,
"definition": [
{
"timespan": "5 days, 0:00:00",
"granularity": "0:01:00",
"points": 7200
},
{
"timespan": "30 days, 0:00:00",
"granularity": "0:10:00",
"points": 4320
},
{
"timespan": "90 days, 0:00:00",
"granularity": "1:00:00",
"points": 2160
}
],
"aggregation_methods": [
"rate:mean",
"mean"
]
},
"created_by_user_id": "42dcfd23b04a4006b9e2b08c0a835aeb",
"created_by_project_id": "70d50fbf0c2148689aa2c319351e634d"
}
This shows how you can query measures from resource metrics for a given aggregation method and granularity.
This is a simple way of getting a sample of pre-aggregated measures as we store them without going through the complexity of the Aggregates API, but no additional processing on the measures is supported.
Below is an example of getting cpu metric measures of an instance
for the hour of 2025-08-09 00:00-01:00 UTC, using the rate:mean
aggregation method and a granularity of 600 seconds.
Run the following command:
openstack metric measures show --resource-id ${resource_id} \
${metric_name}
--aggregation ${aggregation} \
--granularity ${granularity} \
--start ${start} \
--stop ${stop} \
--utc
Note
If no timezone offset (e.g. +12:00) is specified on your
--start and --stop timestamps, this command will automatically
change the timestamps to UTC relative to your computer’s system timezone.
To prevent this behaviour, make sure that your --start
and --stop values have the correct timezone offset.
Likewise, by default the timestamps returned by this command will be in your
computer’s system timezone. If you’d like to receive measure timestamps in UTC,
set the --utc flag.
Warning
You should always set --start and --stop for your measure queries.
Not doing so will result in an unbounded query being performed, causing more metrics to be retrieved than intended or a timeout.
Example command with populated values:
openstack metric measures show --resource-id af6b97d9-d172-4e06-b565-db1e97097340 \
cpu
--aggregation rate:mean \
--granularity 600 \
--start "2025-08-09T00:00:00+00:00" \
--stop "2025-08-09T01:00:00+00:00" \
--utc
Example output:
$ openstack metric measures show --resource-id af6b97d9-d172-4e06-b565-db1e97097340 cpu --aggregation rate:mean --granularity 600 --start "2025-08-09T00:00:00+00:00" --stop "2025-08-09T01:00:00+00:00" --utc
+---------------------------+-------------+--------------+
| timestamp | granularity | value |
+---------------------------+-------------+--------------+
| 2025-08-09T00:00:00+00:00 | 600.0 | 1100000000.0 |
| 2025-08-09T00:10:00+00:00 | 600.0 | 840000000.0 |
| 2025-08-09T00:20:00+00:00 | 600.0 | 880000000.0 |
| 2025-08-09T00:30:00+00:00 | 600.0 | 880000000.0 |
| 2025-08-09T00:40:00+00:00 | 600.0 | 830000000.0 |
| 2025-08-09T00:50:00+00:00 | 600.0 | 860000000.0 |
+---------------------------+-------------+--------------+
Measures can be fetched directly using the gnocchi_client.metric.get_measures method.
gnocchi_client.metric.get_measures(
"{metric_name}",
resource_id="{resource_id}",
start="{start}",
stop="{stop}",
aggregation="{aggregation}",
granularity=granularity,
)
Warning
You should always set start and stop for your measure queries.
Not doing so will result in an unbounded query being performed, causing more metrics to be retrieved than intended or a timeout.
Example method call with populated values:
gnocchi_client.metric.get_measures(
"cpu",
resource_id="af6b97d9-d172-4e06-b565-db1e97097340",
start="2025-08-09T00:00:00+00:00",
stop="2025-08-09T01:00:00+00:00",
aggregation="rate:mean",
granularity=600,
)
Example output:
>>> gnocchi_client.metric.get_measures("cpu", resource_id="af6b97d9-d172-4e06-b565-db1e97097340", start="2025-08-09T00:00:00+00:00", stop="2025-08-09T01:00:00+00:00", aggregation="rate:mean", granularity=600)
[(datetime.datetime(2025, 8, 9, 0, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
600.0,
1100000000.0),
(datetime.datetime(2025, 8, 9, 0, 10, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
600.0,
840000000.0),
(datetime.datetime(2025, 8, 9, 0, 20, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
600.0,
880000000.0),
(datetime.datetime(2025, 8, 9, 0, 30, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
600.0,
880000000.0),
(datetime.datetime(2025, 8, 9, 0, 40, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
600.0,
830000000.0),
(datetime.datetime(2025, 8, 9, 0, 50, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
600.0,
860000000.0)]
Note that the returned timestamps are timezone-aware datetime.datetime objects in UTC.
Make the following request:
curl -s \
-H "X-Auth-Token: ${OS_TOKEN}" \
-H "Accept: application/json" \
"https://api.$(echo "${OS_REGION_NAME}" | tr '_' '-').catalystcloud.nz:8041/v1/resource/${resource_type}/${resource_id}/metric/${metric_name}/measures?start=${start}&stop=${stop}&aggregation=${aggregation}&granularity=${granularity}"
Warning
You should always set start and stop for your measure queries.
Not doing so will result in an unbounded query being performed, causing more metrics to be retrieved than intended or a timeout.
Example request with populated values (and required values URL-encoded):
curl -s \
-H "X-Auth-Token: ${OS_TOKEN}" \
-H "Accept: application/json" \
"https://api.$(echo "${OS_REGION_NAME}" | tr '_' '-').catalystcloud.nz:8041/v1/resource/instance/af6b97d9-d172-4e06-b565-db1e97097340/metric/cpu/measures?start=2025-08-09T00%3A00%3A00%2B00%3A00&stop=2025-08-09T01%3A00%3A00%2B00%3A00&aggregation=rate%3Amean&granularity=600"
Example output:
$ curl -s -H "X-Auth-Token: ${OS_TOKEN}" -H "Accept: application/json" "https://api.$(echo "${OS_REGION_NAME}" | tr '_' '-').catalystcloud.nz:8041/v1/resource/instance/af6b97d9-d172-4e06-b565-db1e97097340/metric/cpu/measures?start=2025-08-09T00%3A00%3A00%2B00%3A00&stop=2025-08-09T01%3A00%3A00%2B00%3A00&aggregation=rate%3Amean&granularity=600" | jq
[
[
"2025-08-09T00:00:00+00:00",
600.0,
1100000000.0
],
[
"2025-08-09T00:10:00+00:00",
600.0,
840000000.0
],
[
"2025-08-09T00:20:00+00:00",
600.0,
880000000.0
],
[
"2025-08-09T00:30:00+00:00",
600.0,
880000000.0
],
[
"2025-08-09T00:40:00+00:00",
600.0,
830000000.0
],
[
"2025-08-09T00:50:00+00:00",
600.0,
860000000.0
]
]
Returned timestamps are in UTC.
The Metrics Service allows you to perform searches on resources within a project to return only resources that match the defined search filters.
The same filter syntax is used by the Aggregates API when performing queries against resource metrics.
Here we provide a few examples of how to use the resource search API to do some common tasks. For more details on the available search filters and options, see the Gnocchi search API documentation.
Note
One major consideration when making search filters is that by default all resources that match the filters will be returned, including resources that no longer exist (but still have metrics recorded in the Metrics Service).
If you want to exclude deleted resources, add a filter
checking that ended_at is set to null.
In addition, please be aware that metrics and resource metadata expire after 90 days, so any deleted resources older than that are no longer available.
In this example, we are going to search for all instances
that have used the c1.c1r1 compute flavour.
Run the following command:
openstack metric resource search --type instance "flavor_name='c1.c1r1'"
Example output:
$ openstack metric resource search --type instance "flavor_name='c1.c1r1'"
+--------------------------------------+----------+----------------------------------+----------------------------------+--------------------------------------+----------------------------------+----------+----------------------------------+--------------+-------------------------------------------------------------------+------------------------+--------------------------------------+--------------------------------------+--------------+-------------+-----------+---------+------+
| id | type | project_id | user_id | original_resource_id | started_at | ended_at | revision_start | revision_end | creator | display_name | image_ref | flavor_id | server_group | flavor_name | os_distro | os_type | host |
+--------------------------------------+----------+----------------------------------+----------------------------------+--------------------------------------+----------------------------------+----------+----------------------------------+--------------+-------------------------------------------------------------------+------------------------+--------------------------------------+--------------------------------------+--------------+-------------+-----------+---------+------+
| af6b97d9-d172-4e06-b565-db1e97097340 | instance | 9864e20f92ef47238becfe06b869d2ac | 517bcd700274432d96f43616ac1e37ea | af6b97d9-d172-4e06-b565-db1e97097340 | 2025-03-18T02:16:55.790609+00:00 | None | 2025-03-18T22:00:58.683260+00:00 | None | 42dcfd23b04a4006b9e2b08c0a835aeb:70d50fbf0c2148689aa2c319351e634d | test-instance | None | 28153197-6690-4485-9dbc-fc24489b0683 | None | c1.c1r1 | ubuntu | linux | None |
| 2a50f066-8e1e-44b1-b355-091d88fdac7f | instance | 9864e20f92ef47238becfe06b869d2ac | 517bcd700274432d96f43616ac1e37ea | 2a50f066-8e1e-44b1-b355-091d88fdac7f | 2025-07-23T04:30:10.527292+00:00 | None | 2025-07-23T04:30:10.527296+00:00 | None | 42dcfd23b04a4006b9e2b08c0a835aeb:ceecc421f7994cc397380fae5e495179 | test-instance-20250723 | ec8c7806-19d2-4791-b503-d6cdd2414187 | 28153197-6690-4485-9dbc-fc24489b0683 | None | c1.c1r1 | ubuntu | linux | None |
+--------------------------------------+----------+----------------------------------+----------------------------------+--------------------------------------+----------------------------------+----------+----------------------------------+--------------+-------------------------------------------------------------------+------------------------+--------------------------------------+--------------------------------------+--------------+-------------+-----------+---------+------+
Call the following method:
gnocchi_client.resource.search(
resource_type="instance",
query={"=": {"flavor_name": "c1.c1r1"}}, # 'eq' can also be used.
)
Example output:
>>> pprint(gnocchi_client.resource.search(resource_type="instance", query={"=": {"flavor_name": "c1.c1r1"}}))
[{'created_by_project_id': '70d50fbf0c2148689aa2c319351e634d',
'created_by_user_id': '42dcfd23b04a4006b9e2b08c0a835aeb',
'creator': '42dcfd23b04a4006b9e2b08c0a835aeb:70d50fbf0c2148689aa2c319351e634d',
'display_name': 'test-instance',
'ended_at': None,
'flavor_id': '28153197-6690-4485-9dbc-fc24489b0683',
'flavor_name': 'c1.c1r1',
'host': None,
'id': 'af6b97d9-d172-4e06-b565-db1e97097340',
'image_ref': None,
'metrics': {'compute.instance.booting.time': 'c418003f-5115-4bd3-a56e-270d90e26b2f',
'cpu': '6febda4a-4a3f-485f-b6e2-5f94d55e39b0',
'disk.ephemeral.size': 'd0add36c-6208-40d3-a8d0-2f5ab3a550bd',
'disk.root.size': 'b4e3d818-444b-46a9-b874-c82fd78e3a66',
'instance': '53c46abc-5336-49a8-ac76-fc5aed5e5154',
'memory': '1e87f21e-2238-41f0-80fd-950e3e2f9bcf',
'vcpus': '9d60abe7-b1d7-425d-8d89-6c0eecd38c47'},
'original_resource_id': 'af6b97d9-d172-4e06-b565-db1e97097340',
'os_distro': 'ubuntu',
'os_type': 'linux',
'project_id': '9864e20f92ef47238becfe06b869d2ac',
'revision_end': None,
'revision_start': '2025-03-18T22:00:58.683260+00:00',
'server_group': None,
'started_at': '2025-03-18T02:16:55.790609+00:00',
'type': 'instance',
'user_id': '517bcd700274432d96f43616ac1e37ea'},
{'created_by_project_id': 'ceecc421f7994cc397380fae5e495179',
'created_by_user_id': '42dcfd23b04a4006b9e2b08c0a835aeb',
'creator': '42dcfd23b04a4006b9e2b08c0a835aeb:ceecc421f7994cc397380fae5e495179',
'display_name': 'test-instance-20250723',
'ended_at': None,
'flavor_id': '28153197-6690-4485-9dbc-fc24489b0683',
'flavor_name': 'c1.c1r1',
'host': None,
'id': '2a50f066-8e1e-44b1-b355-091d88fdac7f',
'image_ref': 'ec8c7806-19d2-4791-b503-d6cdd2414187',
'metrics': {'compute.instance.booting.time': '2f3fc7d3-60f9-41cb-93b8-4d08d2a9bdd1',
'cpu': 'afa729d2-3877-4589-88d7-f5da9debad46',
'disk.ephemeral.size': '4cdb7ab7-7799-46fe-b317-efa892a8b2a1',
'disk.root.size': '4e01f69c-ed8a-4ffc-9675-20f9c8538088',
'instance': '4cf621c4-bc18-47ea-a580-e33fcc94ce49',
'memory': '5a13e69e-e79e-4a69-b1e2-9f1f2075e279',
'vcpus': '44576b05-786e-421a-ae42-98de5872327f'},
'original_resource_id': '2a50f066-8e1e-44b1-b355-091d88fdac7f',
'os_distro': 'ubuntu',
'os_type': 'linux',
'project_id': '9864e20f92ef47238becfe06b869d2ac',
'revision_end': None,
'revision_start': '2025-07-23T04:30:10.527296+00:00',
'server_group': None,
'started_at': '2025-07-23T04:30:10.527292+00:00',
'type': 'instance',
'user_id': '517bcd700274432d96f43616ac1e37ea'}]
Example JSON payload (save this as payload.json):
{"=": {"flavor_name": "c1.c1r1"}}
Make the following request:
curl -s \
-X POST \
-H "X-Auth-Token: ${OS_TOKEN}" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
https://api.$(echo "${OS_REGION_NAME}" | tr '_' '-').catalystcloud.nz:8041/v1/search/resource/instance \
--data-binary "@payload.json"
Example output:
$ curl -s -X POST -H "X-Auth-Token: ${OS_TOKEN}" -H "Content-Type: application/json" -H "Accept: application/json" https://api.$(echo "${OS_REGION_NAME}" | tr '_' '-').catalystcloud.nz:8041/v1/search/resource/instance --data-binary "@payload.json" | jq
[
{
"id": "af6b97d9-d172-4e06-b565-db1e97097340",
"creator": "42dcfd23b04a4006b9e2b08c0a835aeb:70d50fbf0c2148689aa2c319351e634d",
"started_at": "2025-03-18T02:16:55.790609+00:00",
"revision_start": "2025-03-18T22:00:58.683260+00:00",
"ended_at": null,
"user_id": "517bcd700274432d96f43616ac1e37ea",
"project_id": "9864e20f92ef47238becfe06b869d2ac",
"original_resource_id": "af6b97d9-d172-4e06-b565-db1e97097340",
"type": "instance",
"display_name": "test-instance",
"image_ref": null,
"flavor_id": "28153197-6690-4485-9dbc-fc24489b0683",
"server_group": null,
"flavor_name": "c1.c1r1",
"os_distro": "ubuntu",
"os_type": "linux",
"host": null,
"revision_end": null,
"metrics": {
"compute.instance.booting.time": "c418003f-5115-4bd3-a56e-270d90e26b2f",
"cpu": "6febda4a-4a3f-485f-b6e2-5f94d55e39b0",
"disk.ephemeral.size": "d0add36c-6208-40d3-a8d0-2f5ab3a550bd",
"disk.root.size": "b4e3d818-444b-46a9-b874-c82fd78e3a66",
"instance": "53c46abc-5336-49a8-ac76-fc5aed5e5154",
"memory": "1e87f21e-2238-41f0-80fd-950e3e2f9bcf",
"vcpus": "9d60abe7-b1d7-425d-8d89-6c0eecd38c47"
},
"created_by_user_id": "42dcfd23b04a4006b9e2b08c0a835aeb",
"created_by_project_id": "70d50fbf0c2148689aa2c319351e634d"
},
{
"id": "2a50f066-8e1e-44b1-b355-091d88fdac7f",
"creator": "42dcfd23b04a4006b9e2b08c0a835aeb:ceecc421f7994cc397380fae5e495179",
"started_at": "2025-07-23T04:30:10.527292+00:00",
"revision_start": "2025-07-23T04:30:10.527296+00:00",
"ended_at": null,
"user_id": "517bcd700274432d96f43616ac1e37ea",
"project_id": "9864e20f92ef47238becfe06b869d2ac",
"original_resource_id": "2a50f066-8e1e-44b1-b355-091d88fdac7f",
"type": "instance",
"display_name": "test-instance-20250723",
"image_ref": "ec8c7806-19d2-4791-b503-d6cdd2414187",
"flavor_id": "28153197-6690-4485-9dbc-fc24489b0683",
"server_group": null,
"flavor_name": "c1.c1r1",
"os_distro": "ubuntu",
"os_type": "linux",
"host": null,
"revision_end": null,
"metrics": {
"compute.instance.booting.time": "2f3fc7d3-60f9-41cb-93b8-4d08d2a9bdd1",
"cpu": "afa729d2-3877-4589-88d7-f5da9debad46",
"disk.ephemeral.size": "4cdb7ab7-7799-46fe-b317-efa892a8b2a1",
"disk.root.size": "4e01f69c-ed8a-4ffc-9675-20f9c8538088",
"instance": "4cf621c4-bc18-47ea-a580-e33fcc94ce49",
"memory": "5a13e69e-e79e-4a69-b1e2-9f1f2075e279",
"vcpus": "44576b05-786e-421a-ae42-98de5872327f"
},
"created_by_user_id": "42dcfd23b04a4006b9e2b08c0a835aeb",
"created_by_project_id": "ceecc421f7994cc397380fae5e495179"
}
]
You can search for all resources that have an attribute that does not equal the provided value.
In this example, we are going to search for all instances that have been deleted.
Run the following command:
openstack metric resource search --type instance "ended_at!=null"
Example output:
$ openstack metric resource search --type instance "ended_at!=null"
+--------------------------------------+----------+----------------------------------+----------------------------------+--------------------------------------+----------------------------------+----------------------------------+----------------------------------+--------------+-------------------------------------------------------------------+------------------------+-----------+--------------------------------------+--------------+-------------+-----------+---------+------+
| id | type | project_id | user_id | original_resource_id | started_at | ended_at | revision_start | revision_end | creator | display_name | image_ref | flavor_id | server_group | flavor_name | os_distro | os_type | host |
+--------------------------------------+----------+----------------------------------+----------------------------------+--------------------------------------+----------------------------------+----------------------------------+----------------------------------+--------------+-------------------------------------------------------------------+------------------------+-----------+--------------------------------------+--------------+-------------+-----------+---------+------+
| f6ebbaef-33da-40bf-a339-ce7dd051a38d | instance | 9864e20f92ef47238becfe06b869d2ac | 517bcd700274432d96f43616ac1e37ea | f6ebbaef-33da-40bf-a339-ce7dd051a38d | 2025-02-13T23:38:53.690143+00:00 | 2025-06-17T03:05:34.743285+00:00 | 2025-06-17T03:05:42.873501+00:00 | None | 42dcfd23b04a4006b9e2b08c0a835aeb:70d50fbf0c2148689aa2c319351e634d | test-instance-20250214 | None | c093745c-a6c7-4792-9f3d-085e7782eca6 | None | c1.c2r4 | None | None | None |
+--------------------------------------+----------+----------------------------------+----------------------------------+--------------------------------------+----------------------------------+----------------------------------+----------------------------------+--------------+-------------------------------------------------------------------+------------------------+-----------+--------------------------------------+--------------+-------------+-----------+---------+------+
Call the following method:
gnocchi_client.resource.search(
resource_type="instance",
query={"!=": {"ended_at": None}}, # 'ne' can also be used.
)
Example output:
>>> pprint(gnocchi_client.resource.search(resource_type="instance", query={"!=": {"ended_at": None}}))
[{'created_by_project_id': '70d50fbf0c2148689aa2c319351e634d',
'created_by_user_id': '42dcfd23b04a4006b9e2b08c0a835aeb',
'creator': '42dcfd23b04a4006b9e2b08c0a835aeb:70d50fbf0c2148689aa2c319351e634d',
'display_name': 'test-instance-20250214',
'ended_at': '2025-06-17T03:05:34.743285+00:00',
'flavor_id': 'c093745c-a6c7-4792-9f3d-085e7782eca6',
'flavor_name': 'c1.c2r4',
'host': None,
'id': 'f6ebbaef-33da-40bf-a339-ce7dd051a38d',
'image_ref': None,
'metrics': {'compute.instance.booting.time': 'aea2e871-570e-4c14-9695-9b045578f2dd',
'cpu': 'f3a01650-a493-4700-b326-e4ab4f913931',
'disk.ephemeral.size': '0e03a783-ff6d-430a-b643-01be72932301',
'disk.root.size': '5e1068b4-fe1b-4568-8458-9358d4fe1fdf',
'instance': '03c55595-35fd-42e6-ac49-65979af7e52e',
'memory': 'f459aadc-cf54-48e5-b7b7-a7d72a740a10',
'vcpus': '54312c05-af08-4aaf-9194-13427ba5d31d'},
'original_resource_id': 'f6ebbaef-33da-40bf-a339-ce7dd051a38d',
'os_distro': None,
'os_type': None,
'project_id': '9864e20f92ef47238becfe06b869d2ac',
'revision_end': None,
'revision_start': '2025-06-17T03:05:42.873501+00:00',
'server_group': None,
'started_at': '2025-02-13T23:38:53.690143+00:00',
'type': 'instance',
'user_id': '517bcd700274432d96f43616ac1e37ea'}]
Example JSON payload (save this as payload.json):
{"!=": {"ended_at": null}}
Make the following request:
curl -s \
-X POST \
-H "X-Auth-Token: ${OS_TOKEN}" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
https://api.$(echo "${OS_REGION_NAME}" | tr '_' '-').catalystcloud.nz:8041/v1/search/resource/instance \
--data-binary "@payload.json"
Example output:
$ curl -s -X POST -H "X-Auth-Token: ${OS_TOKEN}" -H "Content-Type: application/json" -H "Accept: application/json" https://api.$(echo "${OS_REGION_NAME}" | tr '_' '-').catalystcloud.nz:8041/v1/search/resource/instance --data-binary "@payload.json" | jq
[
{
"id": "f6ebbaef-33da-40bf-a339-ce7dd051a38d",
"creator": "42dcfd23b04a4006b9e2b08c0a835aeb:70d50fbf0c2148689aa2c319351e634d",
"started_at": "2025-02-13T23:38:53.690143+00:00",
"revision_start": "2025-06-17T03:05:42.873501+00:00",
"ended_at": "2025-06-17T03:05:34.743285+00:00",
"user_id": "517bcd700274432d96f43616ac1e37ea",
"project_id": "9864e20f92ef47238becfe06b869d2ac",
"original_resource_id": "f6ebbaef-33da-40bf-a339-ce7dd051a38d",
"type": "instance",
"display_name": "test-instance-20250214",
"image_ref": null,
"flavor_id": "c093745c-a6c7-4792-9f3d-085e7782eca6",
"server_group": null,
"flavor_name": "c1.c2r4",
"os_distro": null,
"os_type": null,
"host": null,
"revision_end": null,
"metrics": {
"compute.instance.booting.time": "aea2e871-570e-4c14-9695-9b045578f2dd",
"cpu": "f3a01650-a493-4700-b326-e4ab4f913931",
"disk.ephemeral.size": "0e03a783-ff6d-430a-b643-01be72932301",
"disk.root.size": "5e1068b4-fe1b-4568-8458-9358d4fe1fdf",
"instance": "03c55595-35fd-42e6-ac49-65979af7e52e",
"memory": "f459aadc-cf54-48e5-b7b7-a7d72a740a10",
"vcpus": "54312c05-af08-4aaf-9194-13427ba5d31d"
},
"created_by_user_id": "42dcfd23b04a4006b9e2b08c0a835aeb",
"created_by_project_id": "70d50fbf0c2148689aa2c319351e634d"
}
]
String-type attributes can be filtered for partial matches using the like operator.
Wildcards can be placed using the special character %.
In this example, we are going to search for all instances
that have test-instance in their name.
Run the following command:
openstack metric resource search --type instance "display_name like '%test-instance%'"
Example output:
$ openstack metric resource search --type instance "display_name like '%test-instance%'"
+--------------------------------------+----------+----------------------------------+----------------------------------+--------------------------------------+----------------------------------+----------+----------------------------------+--------------+-------------------------------------------------------------------+------------------------+--------------------------------------+--------------------------------------+--------------+-------------+-----------+---------+------+
| id | type | project_id | user_id | original_resource_id | started_at | ended_at | revision_start | revision_end | creator | display_name | image_ref | flavor_id | server_group | flavor_name | os_distro | os_type | host |
+--------------------------------------+----------+----------------------------------+----------------------------------+--------------------------------------+----------------------------------+----------+----------------------------------+--------------+-------------------------------------------------------------------+------------------------+--------------------------------------+--------------------------------------+--------------+-------------+-----------+---------+------+
| af6b97d9-d172-4e06-b565-db1e97097340 | instance | 9864e20f92ef47238becfe06b869d2ac | 517bcd700274432d96f43616ac1e37ea | af6b97d9-d172-4e06-b565-db1e97097340 | 2025-03-18T02:16:55.790609+00:00 | None | 2025-03-18T22:00:58.683260+00:00 | None | 42dcfd23b04a4006b9e2b08c0a835aeb:70d50fbf0c2148689aa2c319351e634d | test-instance | None | 28153197-6690-4485-9dbc-fc24489b0683 | None | c1.c1r1 | ubuntu | linux | None |
| 2a50f066-8e1e-44b1-b355-091d88fdac7f | instance | 9864e20f92ef47238becfe06b869d2ac | 517bcd700274432d96f43616ac1e37ea | 2a50f066-8e1e-44b1-b355-091d88fdac7f | 2025-07-23T04:30:10.527292+00:00 | None | 2025-07-23T04:30:10.527296+00:00 | None | 42dcfd23b04a4006b9e2b08c0a835aeb:ceecc421f7994cc397380fae5e495179 | test-instance-20250723 | ec8c7806-19d2-4791-b503-d6cdd2414187 | 28153197-6690-4485-9dbc-fc24489b0683 | None | c1.c1r1 | ubuntu | linux | None |
+--------------------------------------+----------+----------------------------------+----------------------------------+--------------------------------------+----------------------------------+----------+----------------------------------+--------------+-------------------------------------------------------------------+------------------------+--------------------------------------+--------------------------------------+--------------+-------------+-----------+---------+------+
Call the following method:
gnocchi_client.resource.search(
resource_type="instance",
query={"like": {"display_name": "%test-instance%"}},
)
Example output:
>>> pprint(gnocchi_client.resource.search(resource_type="instance", query={"like": {"display_name": "%test-instance%"}}))
[{'created_by_project_id': '70d50fbf0c2148689aa2c319351e634d',
'created_by_user_id': '42dcfd23b04a4006b9e2b08c0a835aeb',
'creator': '42dcfd23b04a4006b9e2b08c0a835aeb:70d50fbf0c2148689aa2c319351e634d',
'display_name': 'test-instance',
'ended_at': None,
'flavor_id': '28153197-6690-4485-9dbc-fc24489b0683',
'flavor_name': 'c1.c1r1',
'host': None,
'id': 'af6b97d9-d172-4e06-b565-db1e97097340',
'image_ref': None,
'metrics': {'compute.instance.booting.time': 'c418003f-5115-4bd3-a56e-270d90e26b2f',
'cpu': '6febda4a-4a3f-485f-b6e2-5f94d55e39b0',
'disk.ephemeral.size': 'd0add36c-6208-40d3-a8d0-2f5ab3a550bd',
'disk.root.size': 'b4e3d818-444b-46a9-b874-c82fd78e3a66',
'instance': '53c46abc-5336-49a8-ac76-fc5aed5e5154',
'memory': '1e87f21e-2238-41f0-80fd-950e3e2f9bcf',
'vcpus': '9d60abe7-b1d7-425d-8d89-6c0eecd38c47'},
'original_resource_id': 'af6b97d9-d172-4e06-b565-db1e97097340',
'os_distro': 'ubuntu',
'os_type': 'linux',
'project_id': '9864e20f92ef47238becfe06b869d2ac',
'revision_end': None,
'revision_start': '2025-03-18T22:00:58.683260+00:00',
'server_group': None,
'started_at': '2025-03-18T02:16:55.790609+00:00',
'type': 'instance',
'user_id': '517bcd700274432d96f43616ac1e37ea'},
{'created_by_project_id': 'ceecc421f7994cc397380fae5e495179',
'created_by_user_id': '42dcfd23b04a4006b9e2b08c0a835aeb',
'creator': '42dcfd23b04a4006b9e2b08c0a835aeb:ceecc421f7994cc397380fae5e495179',
'display_name': 'test-instance-20250723',
'ended_at': None,
'flavor_id': '28153197-6690-4485-9dbc-fc24489b0683',
'flavor_name': 'c1.c1r1',
'host': None,
'id': '2a50f066-8e1e-44b1-b355-091d88fdac7f',
'image_ref': 'ec8c7806-19d2-4791-b503-d6cdd2414187',
'metrics': {'compute.instance.booting.time': '2f3fc7d3-60f9-41cb-93b8-4d08d2a9bdd1',
'cpu': 'afa729d2-3877-4589-88d7-f5da9debad46',
'disk.ephemeral.size': '4cdb7ab7-7799-46fe-b317-efa892a8b2a1',
'disk.root.size': '4e01f69c-ed8a-4ffc-9675-20f9c8538088',
'instance': '4cf621c4-bc18-47ea-a580-e33fcc94ce49',
'memory': '5a13e69e-e79e-4a69-b1e2-9f1f2075e279',
'vcpus': '44576b05-786e-421a-ae42-98de5872327f'},
'original_resource_id': '2a50f066-8e1e-44b1-b355-091d88fdac7f',
'os_distro': 'ubuntu',
'os_type': 'linux',
'project_id': '9864e20f92ef47238becfe06b869d2ac',
'revision_end': None,
'revision_start': '2025-07-23T04:30:10.527296+00:00',
'server_group': None,
'started_at': '2025-07-23T04:30:10.527292+00:00',
'type': 'instance',
'user_id': '517bcd700274432d96f43616ac1e37ea'}]
Example JSON payload (save this as payload.json):
{"like": {"display_name": "%test-instance%"}}
Make the following request:
curl -s \
-X POST \
-H "X-Auth-Token: ${OS_TOKEN}" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
https://api.$(echo "${OS_REGION_NAME}" | tr '_' '-').catalystcloud.nz:8041/v1/search/resource/instance \
--data-binary "@payload.json"
Example output:
$ curl -s -X POST -H "X-Auth-Token: ${OS_TOKEN}" -H "Content-Type: application/json" -H "Accept: application/json" https://api.$(echo "${OS_REGION_NAME}" | tr '_' '-').catalystcloud.nz:8041/v1/search/resource/instance --data-binary "@payload.json" | jq
[
{
"id": "af6b97d9-d172-4e06-b565-db1e97097340",
"creator": "42dcfd23b04a4006b9e2b08c0a835aeb:70d50fbf0c2148689aa2c319351e634d",
"started_at": "2025-03-18T02:16:55.790609+00:00",
"revision_start": "2025-03-18T22:00:58.683260+00:00",
"ended_at": null,
"user_id": "517bcd700274432d96f43616ac1e37ea",
"project_id": "9864e20f92ef47238becfe06b869d2ac",
"original_resource_id": "af6b97d9-d172-4e06-b565-db1e97097340",
"type": "instance",
"display_name": "test-instance",
"image_ref": null,
"flavor_id": "28153197-6690-4485-9dbc-fc24489b0683",
"server_group": null,
"flavor_name": "c1.c1r1",
"os_distro": "ubuntu",
"os_type": "linux",
"host": null,
"revision_end": null,
"metrics": {
"compute.instance.booting.time": "c418003f-5115-4bd3-a56e-270d90e26b2f",
"cpu": "6febda4a-4a3f-485f-b6e2-5f94d55e39b0",
"disk.ephemeral.size": "d0add36c-6208-40d3-a8d0-2f5ab3a550bd",
"disk.root.size": "b4e3d818-444b-46a9-b874-c82fd78e3a66",
"instance": "53c46abc-5336-49a8-ac76-fc5aed5e5154",
"memory": "1e87f21e-2238-41f0-80fd-950e3e2f9bcf",
"vcpus": "9d60abe7-b1d7-425d-8d89-6c0eecd38c47"
},
"created_by_user_id": "42dcfd23b04a4006b9e2b08c0a835aeb",
"created_by_project_id": "70d50fbf0c2148689aa2c319351e634d"
},
{
"id": "2a50f066-8e1e-44b1-b355-091d88fdac7f",
"creator": "42dcfd23b04a4006b9e2b08c0a835aeb:ceecc421f7994cc397380fae5e495179",
"started_at": "2025-07-23T04:30:10.527292+00:00",
"revision_start": "2025-07-23T04:30:10.527296+00:00",
"ended_at": null,
"user_id": "517bcd700274432d96f43616ac1e37ea",
"project_id": "9864e20f92ef47238becfe06b869d2ac",
"original_resource_id": "2a50f066-8e1e-44b1-b355-091d88fdac7f",
"type": "instance",
"display_name": "test-instance-20250723",
"image_ref": "ec8c7806-19d2-4791-b503-d6cdd2414187",
"flavor_id": "28153197-6690-4485-9dbc-fc24489b0683",
"server_group": null,
"flavor_name": "c1.c1r1",
"os_distro": "ubuntu",
"os_type": "linux",
"host": null,
"revision_end": null,
"metrics": {
"compute.instance.booting.time": "2f3fc7d3-60f9-41cb-93b8-4d08d2a9bdd1",
"cpu": "afa729d2-3877-4589-88d7-f5da9debad46",
"disk.ephemeral.size": "4cdb7ab7-7799-46fe-b317-efa892a8b2a1",
"disk.root.size": "4e01f69c-ed8a-4ffc-9675-20f9c8538088",
"instance": "4cf621c4-bc18-47ea-a580-e33fcc94ce49",
"memory": "5a13e69e-e79e-4a69-b1e2-9f1f2075e279",
"vcpus": "44576b05-786e-421a-ae42-98de5872327f"
},
"created_by_user_id": "42dcfd23b04a4006b9e2b08c0a835aeb",
"created_by_project_id": "ceecc421f7994cc397380fae5e495179"
}
]
Any condition can be negated using the not operator.
In this example, we are going to search for all instances
that do not have test-instance in their name.
Run the following command:
openstack metric resource search --type instance "not display_name like '%test-instance%'"
Example output:
$ openstack metric resource search --type instance "not display_name like '%test-instance%'"
+--------------------------------------+----------+----------------------------------+----------------------------------+--------------------------------------+----------------------------------+----------+----------------------------------+--------------+-------------------------------------------------------------------+---------------------------------------------------------+-----------+--------------------------------------+--------------+-------------+-----------+---------+------+
| id | type | project_id | user_id | original_resource_id | started_at | ended_at | revision_start | revision_end | creator | display_name | image_ref | flavor_id | server_group | flavor_name | os_distro | os_type | host |
+--------------------------------------+----------+----------------------------------+----------------------------------+--------------------------------------+----------------------------------+----------+----------------------------------+--------------+-------------------------------------------------------------------+---------------------------------------------------------+-----------+--------------------------------------+--------------+-------------+-----------+---------+------+
| d2fa2bc2-184a-4694-85f1-4db10ad37cf3 | instance | 9864e20f92ef47238becfe06b869d2ac | 517bcd700274432d96f43616ac1e37ea | d2fa2bc2-184a-4694-85f1-4db10ad37cf3 | 2025-01-09T23:19:14.518004+00:00 | None | 2025-05-23T00:42:36.409828+00:00 | None | 42dcfd23b04a4006b9e2b08c0a835aeb:70d50fbf0c2148689aa2c319351e634d | test-cluster-4uexlwoysna4-default-worker-d1fbf004-p67wm | None | c093745c-a6c7-4792-9f3d-085e7782eca6 | None | c1.c2r4 | flatcar | linux | None |
| 6040b4a8-b951-485b-88a6-422eb3f278dd | instance | 9864e20f92ef47238becfe06b869d2ac | 517bcd700274432d96f43616ac1e37ea | 6040b4a8-b951-485b-88a6-422eb3f278dd | 2025-01-09T23:19:14.090443+00:00 | None | 2025-05-26T01:31:44.486588+00:00 | None | 42dcfd23b04a4006b9e2b08c0a835aeb:70d50fbf0c2148689aa2c319351e634d | test-cluster-4uexlwoysna4-control-plane-2b817ab5-hlxnd | None | c093745c-a6c7-4792-9f3d-085e7782eca6 | None | c1.c2r4 | flatcar | linux | None |
+--------------------------------------+----------+----------------------------------+----------------------------------+--------------------------------------+----------------------------------+----------+----------------------------------+--------------+-------------------------------------------------------------------+---------------------------------------------------------+-----------+--------------------------------------+--------------+-------------+-----------+---------+------+
Call the following method:
gnocchi_client.resource.search(
resource_type="instance",
query={"not": {"like": {"display_name": "%test-instance%"}}},
)
Example output:
>>> pprint(gnocchi_client.resource.search(resource_type="instance", query={"not": {"like": {"display_name": "%test-instance%"}}}))
[{'created_by_project_id': '70d50fbf0c2148689aa2c319351e634d',
'created_by_user_id': '42dcfd23b04a4006b9e2b08c0a835aeb',
'creator': '42dcfd23b04a4006b9e2b08c0a835aeb:70d50fbf0c2148689aa2c319351e634d',
'display_name': 'test-cluster-4uexlwoysna4-default-worker-d1fbf004-p67wm',
'ended_at': None,
'flavor_id': 'c093745c-a6c7-4792-9f3d-085e7782eca6',
'flavor_name': 'c1.c2r4',
'host': None,
'id': 'd2fa2bc2-184a-4694-85f1-4db10ad37cf3',
'image_ref': None,
'metrics': {'compute.instance.booting.time': '4bcfb861-79a5-447c-acb2-ad412fbfb9b5',
'cpu': 'dd42ae93-402c-4df2-8ecb-c649fdf33c77',
'disk.ephemeral.size': '77497629-cace-4224-86ca-1b56c437d341',
'disk.root.size': '3fd2aa67-cd4c-4720-91b6-26c8b5ff1316',
'instance': '375d6e09-083d-439a-b038-88bae7af1259',
'memory': 'a02af497-3bbe-421c-9ac0-32e323c26b57',
'vcpus': '6b91d233-ec0b-496a-9870-a0d8a33f6bb0'},
'original_resource_id': 'd2fa2bc2-184a-4694-85f1-4db10ad37cf3',
'os_distro': 'flatcar',
'os_type': 'linux',
'project_id': '9864e20f92ef47238becfe06b869d2ac',
'revision_end': None,
'revision_start': '2025-05-23T00:42:36.409828+00:00',
'server_group': None,
'started_at': '2025-01-09T23:19:14.518004+00:00',
'type': 'instance',
'user_id': '517bcd700274432d96f43616ac1e37ea'},
{'created_by_project_id': '70d50fbf0c2148689aa2c319351e634d',
'created_by_user_id': '42dcfd23b04a4006b9e2b08c0a835aeb',
'creator': '42dcfd23b04a4006b9e2b08c0a835aeb:70d50fbf0c2148689aa2c319351e634d',
'display_name': 'test-cluster-4uexlwoysna4-control-plane-2b817ab5-hlxnd',
'ended_at': None,
'flavor_id': 'c093745c-a6c7-4792-9f3d-085e7782eca6',
'flavor_name': 'c1.c2r4',
'host': None,
'id': '6040b4a8-b951-485b-88a6-422eb3f278dd',
'image_ref': None,
'metrics': {'compute.instance.booting.time': 'c7730e2a-b536-45d4-85a8-46d74fa40bbf',
'cpu': '54166b0a-7a93-4e26-acfd-3939578a937c',
'disk.ephemeral.size': '567748b2-9507-4faa-bf6c-dc22b3431ca1',
'disk.root.size': '2c2d9da6-16fc-44a6-ad0c-b9dbf0e7c278',
'instance': '2b00d300-459c-49c5-9a22-8bbe546c1326',
'memory': '1ab76159-718a-45c8-9fab-3f4cbf189671',
'vcpus': '9a1f3735-03c3-4d81-9f31-2f09bd1009d2'},
'original_resource_id': '6040b4a8-b951-485b-88a6-422eb3f278dd',
'os_distro': 'flatcar',
'os_type': 'linux',
'project_id': '9864e20f92ef47238becfe06b869d2ac',
'revision_end': None,
'revision_start': '2025-05-26T01:31:44.486588+00:00',
'server_group': None,
'started_at': '2025-01-09T23:19:14.090443+00:00',
'type': 'instance',
'user_id': '517bcd700274432d96f43616ac1e37ea'}]
Example JSON payload (save this as payload.json):
{"not": {"like": {"display_name": "%test-instance%"}}}
Make the following request:
curl -s \
-X POST \
-H "X-Auth-Token: ${OS_TOKEN}" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
https://api.$(echo "${OS_REGION_NAME}" | tr '_' '-').catalystcloud.nz:8041/v1/search/resource/instance \
--data-binary "@payload.json"
Example output:
$ curl -s -X POST -H "X-Auth-Token: ${OS_TOKEN}" -H "Content-Type: application/json" -H "Accept: application/json" https://api.$(echo "${OS_REGION_NAME}" | tr '_' '-').catalystcloud.nz:8041/v1/search/resource/instance --data-binary "@payload.json" | jq
[
{
"id": "d2fa2bc2-184a-4694-85f1-4db10ad37cf3",
"creator": "42dcfd23b04a4006b9e2b08c0a835aeb:70d50fbf0c2148689aa2c319351e634d",
"started_at": "2025-01-09T23:19:14.518004+00:00",
"revision_start": "2025-05-23T00:42:36.409828+00:00",
"ended_at": null,
"user_id": "517bcd700274432d96f43616ac1e37ea",
"project_id": "9864e20f92ef47238becfe06b869d2ac",
"original_resource_id": "d2fa2bc2-184a-4694-85f1-4db10ad37cf3",
"type": "instance",
"display_name": "test-cluster-4uexlwoysna4-default-worker-d1fbf004-p67wm",
"image_ref": null,
"flavor_id": "c093745c-a6c7-4792-9f3d-085e7782eca6",
"server_group": null,
"flavor_name": "c1.c2r4",
"os_distro": "flatcar",
"os_type": "linux",
"host": null,
"revision_end": null,
"metrics": {
"compute.instance.booting.time": "4bcfb861-79a5-447c-acb2-ad412fbfb9b5",
"cpu": "dd42ae93-402c-4df2-8ecb-c649fdf33c77",
"disk.ephemeral.size": "77497629-cace-4224-86ca-1b56c437d341",
"disk.root.size": "3fd2aa67-cd4c-4720-91b6-26c8b5ff1316",
"instance": "375d6e09-083d-439a-b038-88bae7af1259",
"memory": "a02af497-3bbe-421c-9ac0-32e323c26b57",
"vcpus": "6b91d233-ec0b-496a-9870-a0d8a33f6bb0"
},
"created_by_user_id": "42dcfd23b04a4006b9e2b08c0a835aeb",
"created_by_project_id": "70d50fbf0c2148689aa2c319351e634d"
},
{
"id": "6040b4a8-b951-485b-88a6-422eb3f278dd",
"creator": "42dcfd23b04a4006b9e2b08c0a835aeb:70d50fbf0c2148689aa2c319351e634d",
"started_at": "2025-01-09T23:19:14.090443+00:00",
"revision_start": "2025-05-26T01:31:44.486588+00:00",
"ended_at": null,
"user_id": "517bcd700274432d96f43616ac1e37ea",
"project_id": "9864e20f92ef47238becfe06b869d2ac",
"original_resource_id": "6040b4a8-b951-485b-88a6-422eb3f278dd",
"type": "instance",
"display_name": "test-cluster-4uexlwoysna4-control-plane-2b817ab5-hlxnd",
"image_ref": null,
"flavor_id": "c093745c-a6c7-4792-9f3d-085e7782eca6",
"server_group": null,
"flavor_name": "c1.c2r4",
"os_distro": "flatcar",
"os_type": "linux",
"host": null,
"revision_end": null,
"metrics": {
"compute.instance.booting.time": "c7730e2a-b536-45d4-85a8-46d74fa40bbf",
"cpu": "54166b0a-7a93-4e26-acfd-3939578a937c",
"disk.ephemeral.size": "567748b2-9507-4faa-bf6c-dc22b3431ca1",
"disk.root.size": "2c2d9da6-16fc-44a6-ad0c-b9dbf0e7c278",
"instance": "2b00d300-459c-49c5-9a22-8bbe546c1326",
"memory": "1ab76159-718a-45c8-9fab-3f4cbf189671",
"vcpus": "9a1f3735-03c3-4d81-9f31-2f09bd1009d2"
},
"created_by_user_id": "42dcfd23b04a4006b9e2b08c0a835aeb",
"created_by_project_id": "70d50fbf0c2148689aa2c319351e634d"
}
]
Number and datetime-type attributes allow filtering based on whether or not the attribute is greater than or less than the provided value (with optional “or equal to”).
In this example, we are going to search for all instances created within the month of July.
Run the following command:
openstack metric resource search --type instance "started_at>='2025-07-01T00:00:00+00:00' and started_at<'2025-08-01T00:00:00+00:00'"
Example output:
$ openstack metric resource search --type instance "started_at>='2025-07-01T00:00:00+00:00' and started_at<'2025-08-01T00:00:00+00:00'"
+--------------------------------------+----------+----------------------------------+----------------------------------+--------------------------------------+----------------------------------+----------+----------------------------------+--------------+-------------------------------------------------------------------+------------------------+--------------------------------------+--------------------------------------+--------------+-------------+-----------+---------+------+
| id | type | project_id | user_id | original_resource_id | started_at | ended_at | revision_start | revision_end | creator | display_name | image_ref | flavor_id | server_group | flavor_name | os_distro | os_type | host |
+--------------------------------------+----------+----------------------------------+----------------------------------+--------------------------------------+----------------------------------+----------+----------------------------------+--------------+-------------------------------------------------------------------+------------------------+--------------------------------------+--------------------------------------+--------------+-------------+-----------+---------+------+
| 2a50f066-8e1e-44b1-b355-091d88fdac7f | instance | 9864e20f92ef47238becfe06b869d2ac | 517bcd700274432d96f43616ac1e37ea | 2a50f066-8e1e-44b1-b355-091d88fdac7f | 2025-07-23T04:30:10.527292+00:00 | None | 2025-07-23T04:30:10.527296+00:00 | None | 42dcfd23b04a4006b9e2b08c0a835aeb:ceecc421f7994cc397380fae5e495179 | test-instance-20250723 | ec8c7806-19d2-4791-b503-d6cdd2414187 | 28153197-6690-4485-9dbc-fc24489b0683 | None | c1.c1r1 | ubuntu | linux | None |
+--------------------------------------+----------+----------------------------------+----------------------------------+--------------------------------------+----------------------------------+----------+----------------------------------+--------------+-------------------------------------------------------------------+------------------------+--------------------------------------+--------------------------------------+--------------+-------------+-----------+---------+------+
Call the following method:
gnocchi_client.resource.search(
resource_type="instance",
query={
"and": [
{">=": {"started_at": "2025-07-01T00:00:00+00:00"}}, # 'ge' can also be used.
{"<": {"started_at": "2025-08-01T00:00:00+00:00"}}, # 'lt' can also be used.
],
},
)
Example output:
>>> pprint(gnocchi_client.resource.search(resource_type="instance", query={"and": [{">=": {"started_at": "2025-07-01T00:00:00+00:00"}}, {"<": {"started_at": "2025-08-01T00:00:00+00:00"}}]}))
[{'created_by_project_id': 'ceecc421f7994cc397380fae5e495179',
'created_by_user_id': '42dcfd23b04a4006b9e2b08c0a835aeb',
'creator': '42dcfd23b04a4006b9e2b08c0a835aeb:ceecc421f7994cc397380fae5e495179',
'display_name': 'test-instance-20250723',
'ended_at': None,
'flavor_id': '28153197-6690-4485-9dbc-fc24489b0683',
'flavor_name': 'c1.c1r1',
'host': None,
'id': '2a50f066-8e1e-44b1-b355-091d88fdac7f',
'image_ref': 'ec8c7806-19d2-4791-b503-d6cdd2414187',
'metrics': {'compute.instance.booting.time': '2f3fc7d3-60f9-41cb-93b8-4d08d2a9bdd1',
'cpu': 'afa729d2-3877-4589-88d7-f5da9debad46',
'disk.ephemeral.size': '4cdb7ab7-7799-46fe-b317-efa892a8b2a1',
'disk.root.size': '4e01f69c-ed8a-4ffc-9675-20f9c8538088',
'instance': '4cf621c4-bc18-47ea-a580-e33fcc94ce49',
'memory': '5a13e69e-e79e-4a69-b1e2-9f1f2075e279',
'vcpus': '44576b05-786e-421a-ae42-98de5872327f'},
'original_resource_id': '2a50f066-8e1e-44b1-b355-091d88fdac7f',
'os_distro': 'ubuntu',
'os_type': 'linux',
'project_id': '9864e20f92ef47238becfe06b869d2ac',
'revision_end': None,
'revision_start': '2025-07-23T04:30:10.527296+00:00',
'server_group': None,
'started_at': '2025-07-23T04:30:10.527292+00:00',
'type': 'instance',
'user_id': '517bcd700274432d96f43616ac1e37ea'}]
Example JSON payload (save this as payload.json):
{
"and": [
{">=": {"started_at": "2025-07-01T00:00:00+00:00"}},
{"<": {"started_at": "2025-08-01T00:00:00+00:00"}}
]
}
Make the following request:
curl -s \
-X POST \
-H "X-Auth-Token: ${OS_TOKEN}" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
https://api.$(echo "${OS_REGION_NAME}" | tr '_' '-').catalystcloud.nz:8041/v1/search/resource/instance \
--data-binary "@payload.json"
Example output:
$ curl -s -X POST -H "X-Auth-Token: ${OS_TOKEN}" -H "Content-Type: application/json" -H "Accept: application/json" https://api.$(echo "${OS_REGION_NAME}" | tr '_' '-').catalystcloud.nz:8041/v1/search/resource/instance ---data-binary "@payload.json" | jq
[
{
"id": "2a50f066-8e1e-44b1-b355-091d88fdac7f",
"creator": "42dcfd23b04a4006b9e2b08c0a835aeb:ceecc421f7994cc397380fae5e495179",
"started_at": "2025-07-23T04:30:10.527292+00:00",
"revision_start": "2025-07-23T04:30:10.527296+00:00",
"ended_at": null,
"user_id": "517bcd700274432d96f43616ac1e37ea",
"project_id": "9864e20f92ef47238becfe06b869d2ac",
"original_resource_id": "2a50f066-8e1e-44b1-b355-091d88fdac7f",
"type": "instance",
"display_name": "test-instance-20250723",
"image_ref": "ec8c7806-19d2-4791-b503-d6cdd2414187",
"flavor_id": "28153197-6690-4485-9dbc-fc24489b0683",
"server_group": null,
"flavor_name": "c1.c1r1",
"os_distro": "ubuntu",
"os_type": "linux",
"host": null,
"revision_end": null,
"metrics": {
"compute.instance.booting.time": "2f3fc7d3-60f9-41cb-93b8-4d08d2a9bdd1",
"cpu": "afa729d2-3877-4589-88d7-f5da9debad46",
"disk.ephemeral.size": "4cdb7ab7-7799-46fe-b317-efa892a8b2a1",
"disk.root.size": "4e01f69c-ed8a-4ffc-9675-20f9c8538088",
"instance": "4cf621c4-bc18-47ea-a580-e33fcc94ce49",
"memory": "5a13e69e-e79e-4a69-b1e2-9f1f2075e279",
"vcpus": "44576b05-786e-421a-ae42-98de5872327f"
},
"created_by_user_id": "42dcfd23b04a4006b9e2b08c0a835aeb",
"created_by_project_id": "ceecc421f7994cc397380fae5e495179"
}
]
Nested and/or conditions can be defined in filters to perform more complex queries.
In this example, we are going to search for all instances
that have test-instance in their name that were started
in March 2025 or July 2025.
Run the following command:
openstack metric resource search --type instance "display_name like '%test-instance%' and ((started_at>='2025-03-01T00:00:00+00:00' and started_at<'2025-04-01T00:00:00+00:00') or (started_at>='2025-07-01T00:00:00+00:00' and started_at<'2025-08-01T00:00:00+00:00'))"
Example output:
$ openstack metric resource search --type instance "display_name like '%test-instance%' and ((started_at>='2025-03-01T00:00:00+00:00' and started_at<'2025-04-01T00:00:00+00:00') or (started_at>='2025-07-01T00:00:00+00:00' and started_at<'2025-08-01T00:00:00+00:00'))"
+--------------------------------------+----------+----------------------------------+----------------------------------+--------------------------------------+----------------------------------+----------+----------------------------------+--------------+-------------------------------------------------------------------+------------------------+--------------------------------------+--------------------------------------+--------------+-------------+-----------+---------+------+
| id | type | project_id | user_id | original_resource_id | started_at | ended_at | revision_start | revision_end | creator | display_name | image_ref | flavor_id | server_group | flavor_name | os_distro | os_type | host |
+--------------------------------------+----------+----------------------------------+----------------------------------+--------------------------------------+----------------------------------+----------+----------------------------------+--------------+-------------------------------------------------------------------+------------------------+--------------------------------------+--------------------------------------+--------------+-------------+-----------+---------+------+
| af6b97d9-d172-4e06-b565-db1e97097340 | instance | 9864e20f92ef47238becfe06b869d2ac | 517bcd700274432d96f43616ac1e37ea | af6b97d9-d172-4e06-b565-db1e97097340 | 2025-03-18T02:16:55.790609+00:00 | None | 2025-03-18T22:00:58.683260+00:00 | None | 42dcfd23b04a4006b9e2b08c0a835aeb:70d50fbf0c2148689aa2c319351e634d | test-instance | None | 28153197-6690-4485-9dbc-fc24489b0683 | None | c1.c1r1 | ubuntu | linux | None |
| 2a50f066-8e1e-44b1-b355-091d88fdac7f | instance | 9864e20f92ef47238becfe06b869d2ac | 517bcd700274432d96f43616ac1e37ea | 2a50f066-8e1e-44b1-b355-091d88fdac7f | 2025-07-23T04:30:10.527292+00:00 | None | 2025-07-23T04:30:10.527296+00:00 | None | 42dcfd23b04a4006b9e2b08c0a835aeb:ceecc421f7994cc397380fae5e495179 | test-instance-20250723 | ec8c7806-19d2-4791-b503-d6cdd2414187 | 28153197-6690-4485-9dbc-fc24489b0683 | None | c1.c1r1 | ubuntu | linux | None |
+--------------------------------------+----------+----------------------------------+----------------------------------+--------------------------------------+----------------------------------+----------+----------------------------------+--------------+-------------------------------------------------------------------+------------------------+--------------------------------------+--------------------------------------+--------------+-------------+-----------+---------+------+
Call the following method:
gnocchi_client.resource.search(
resource_type="instance",
query={
"and": [
{"like": {"display_name": "%test-instance%"}},
{
"or": [
{
"and": [
{">=": {"started_at": "2025-03-01T00:00:00+00:00"}},
{"<": {"started_at": "2025-04-01T00:00:00+00:00"}},
],
},
{
"and": [
{">=": {"started_at": "2025-07-01T00:00:00+00:00"}},
{"<": {"started_at": "2025-08-01T00:00:00+00:00"}},
],
},
],
},
],
},
)
Example output:
>>> pprint(gnocchi_client.resource.search(resource_type="instance", query={"and": [{"like": {"display_name": "%test-instance%"}}, {"or": [{"and": [{">=": {"started_at": "2025-03-01T00:00:00+00:00"}}, {"<": {"started_at": "2025-04-01T00:00:00+00:00"}}]}, {"and": [{">=": {"started_at": "2025-07-01T00:00:00+00:00"}}, {"<": {"started_at": "2025-08-01T00:00:00+00:00"}}]}]}]}))
[{'created_by_project_id': '70d50fbf0c2148689aa2c319351e634d',
'created_by_user_id': '42dcfd23b04a4006b9e2b08c0a835aeb',
'creator': '42dcfd23b04a4006b9e2b08c0a835aeb:70d50fbf0c2148689aa2c319351e634d',
'display_name': 'test-instance',
'ended_at': None,
'flavor_id': '28153197-6690-4485-9dbc-fc24489b0683',
'flavor_name': 'c1.c1r1',
'host': None,
'id': 'af6b97d9-d172-4e06-b565-db1e97097340',
'image_ref': None,
'metrics': {'compute.instance.booting.time': 'c418003f-5115-4bd3-a56e-270d90e26b2f',
'cpu': '6febda4a-4a3f-485f-b6e2-5f94d55e39b0',
'disk.ephemeral.size': 'd0add36c-6208-40d3-a8d0-2f5ab3a550bd',
'disk.root.size': 'b4e3d818-444b-46a9-b874-c82fd78e3a66',
'instance': '53c46abc-5336-49a8-ac76-fc5aed5e5154',
'memory': '1e87f21e-2238-41f0-80fd-950e3e2f9bcf',
'vcpus': '9d60abe7-b1d7-425d-8d89-6c0eecd38c47'},
'original_resource_id': 'af6b97d9-d172-4e06-b565-db1e97097340',
'os_distro': 'ubuntu',
'os_type': 'linux',
'project_id': '9864e20f92ef47238becfe06b869d2ac',
'revision_end': None,
'revision_start': '2025-03-18T22:00:58.683260+00:00',
'server_group': None,
'started_at': '2025-03-18T02:16:55.790609+00:00',
'type': 'instance',
'user_id': '517bcd700274432d96f43616ac1e37ea'},
{'created_by_project_id': 'ceecc421f7994cc397380fae5e495179',
'created_by_user_id': '42dcfd23b04a4006b9e2b08c0a835aeb',
'creator': '42dcfd23b04a4006b9e2b08c0a835aeb:ceecc421f7994cc397380fae5e495179',
'display_name': 'test-instance-20250723',
'ended_at': None,
'flavor_id': '28153197-6690-4485-9dbc-fc24489b0683',
'flavor_name': 'c1.c1r1',
'host': None,
'id': '2a50f066-8e1e-44b1-b355-091d88fdac7f',
'image_ref': 'ec8c7806-19d2-4791-b503-d6cdd2414187',
'metrics': {'compute.instance.booting.time': '2f3fc7d3-60f9-41cb-93b8-4d08d2a9bdd1',
'cpu': 'afa729d2-3877-4589-88d7-f5da9debad46',
'disk.ephemeral.size': '4cdb7ab7-7799-46fe-b317-efa892a8b2a1',
'disk.root.size': '4e01f69c-ed8a-4ffc-9675-20f9c8538088',
'instance': '4cf621c4-bc18-47ea-a580-e33fcc94ce49',
'memory': '5a13e69e-e79e-4a69-b1e2-9f1f2075e279',
'vcpus': '44576b05-786e-421a-ae42-98de5872327f'},
'original_resource_id': '2a50f066-8e1e-44b1-b355-091d88fdac7f',
'os_distro': 'ubuntu',
'os_type': 'linux',
'project_id': '9864e20f92ef47238becfe06b869d2ac',
'revision_end': None,
'revision_start': '2025-07-23T04:30:10.527296+00:00',
'server_group': None,
'started_at': '2025-07-23T04:30:10.527292+00:00',
'type': 'instance',
'user_id': '517bcd700274432d96f43616ac1e37ea'}]
Example JSON payload (save this as payload.json):
{
"and": [
{"like": {"display_name": "%test-instance%"}},
{
"or": [
{
"and": [
{">=": {"started_at": "2025-03-01T00:00:00+00:00"}},
{"<": {"started_at": "2025-04-01T00:00:00+00:00"}}
]
},
{
"and": [
{">=": {"started_at": "2025-07-01T00:00:00+00:00"}},
{"<": {"started_at": "2025-08-01T00:00:00+00:00"}}
]
}
]
}
]
}
Make the following request:
curl -s \
-X POST \
-H "X-Auth-Token: ${OS_TOKEN}" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
https://api.$(echo "${OS_REGION_NAME}" | tr '_' '-').catalystcloud.nz:8041/v1/search/resource/instance \
--data-binary "@payload.json"
Example output:
$ curl -s -X POST -H "X-Auth-Token: ${OS_TOKEN}" -H "Content-Type: application/json" -H "Accept: application/json" https://api.$(echo "${OS_REGION_NAME}" | tr '_' '-').catalystcloud.nz:8041/v1/search/resource/instance --data-binary "@payload.json" | jq
[
{
"id": "af6b97d9-d172-4e06-b565-db1e97097340",
"creator": "42dcfd23b04a4006b9e2b08c0a835aeb:70d50fbf0c2148689aa2c319351e634d",
"started_at": "2025-03-18T02:16:55.790609+00:00",
"revision_start": "2025-03-18T22:00:58.683260+00:00",
"ended_at": null,
"user_id": "517bcd700274432d96f43616ac1e37ea",
"project_id": "9864e20f92ef47238becfe06b869d2ac",
"original_resource_id": "af6b97d9-d172-4e06-b565-db1e97097340",
"type": "instance",
"display_name": "test-instance",
"image_ref": null,
"flavor_id": "28153197-6690-4485-9dbc-fc24489b0683",
"server_group": null,
"flavor_name": "c1.c1r1",
"os_distro": "ubuntu",
"os_type": "linux",
"host": null,
"revision_end": null,
"metrics": {
"compute.instance.booting.time": "c418003f-5115-4bd3-a56e-270d90e26b2f",
"cpu": "6febda4a-4a3f-485f-b6e2-5f94d55e39b0",
"disk.ephemeral.size": "d0add36c-6208-40d3-a8d0-2f5ab3a550bd",
"disk.root.size": "b4e3d818-444b-46a9-b874-c82fd78e3a66",
"instance": "53c46abc-5336-49a8-ac76-fc5aed5e5154",
"memory": "1e87f21e-2238-41f0-80fd-950e3e2f9bcf",
"vcpus": "9d60abe7-b1d7-425d-8d89-6c0eecd38c47"
},
"created_by_user_id": "42dcfd23b04a4006b9e2b08c0a835aeb",
"created_by_project_id": "70d50fbf0c2148689aa2c319351e634d"
},
{
"id": "2a50f066-8e1e-44b1-b355-091d88fdac7f",
"creator": "42dcfd23b04a4006b9e2b08c0a835aeb:ceecc421f7994cc397380fae5e495179",
"started_at": "2025-07-23T04:30:10.527292+00:00",
"revision_start": "2025-07-23T04:30:10.527296+00:00",
"ended_at": null,
"user_id": "517bcd700274432d96f43616ac1e37ea",
"project_id": "9864e20f92ef47238becfe06b869d2ac",
"original_resource_id": "2a50f066-8e1e-44b1-b355-091d88fdac7f",
"type": "instance",
"display_name": "test-instance-20250723",
"image_ref": "ec8c7806-19d2-4791-b503-d6cdd2414187",
"flavor_id": "28153197-6690-4485-9dbc-fc24489b0683",
"server_group": null,
"flavor_name": "c1.c1r1",
"os_distro": "ubuntu",
"os_type": "linux",
"host": null,
"revision_end": null,
"metrics": {
"compute.instance.booting.time": "2f3fc7d3-60f9-41cb-93b8-4d08d2a9bdd1",
"cpu": "afa729d2-3877-4589-88d7-f5da9debad46",
"disk.ephemeral.size": "4cdb7ab7-7799-46fe-b317-efa892a8b2a1",
"disk.root.size": "4e01f69c-ed8a-4ffc-9675-20f9c8538088",
"instance": "4cf621c4-bc18-47ea-a580-e33fcc94ce49",
"memory": "5a13e69e-e79e-4a69-b1e2-9f1f2075e279",
"vcpus": "44576b05-786e-421a-ae42-98de5872327f"
},
"created_by_user_id": "42dcfd23b04a4006b9e2b08c0a835aeb",
"created_by_project_id": "ceecc421f7994cc397380fae5e495179"
}
]
In many of the examples on this page, we use this search filter pattern:
started_at<'${stop}' and (ended_at>='${start}' or ended_at=null)
{
"and": [
{"<": {"started_at": stop}},
{
"or": [
{">=": {"ended_at": start}},
{"=": {"ended_at": None}},
],
},
],
}
{
"and": [
{"<": {"started_at": "{stop}"}},
{
"or": [
{">=": {"ended_at": "{start}"}},
{"=": {"ended_at": null}}
]
}
]
}
This filter sets two major conditions:
Select resources that were started before the specified stop time.
Select resources that are either still active, or were deleted after the specified start time.
The effect of this is that only resources that were known to be active during the queried time period will have results returned.
This is important because during Aggregates API queries, if they satisfy the search conditions, resources that exist in the Metrics Service will still be evaluated for measures during the search period even if they did not exist yet, or no longer existed.
This causes the response to contain references to those resources, along with empty data structures signifying they have no aggregates for the query (which can sometimes be useful information to know, but not for most use cases).
The bigger issue with this, however, is performance. Aggregate queries that match with resources that don’t need to be searched take much longer to complete, so to ensure resource searches and aggregate queries are lightweight it is highly recommended you make search filters as specific as possible.
The Metrics Service not only keeps track of the state of a resource, it also keeps a history of all state and metadata changes made to a resource and when those changes were made.
Using the resource history API you are able to query the revisions of a resource’s state, either over its entire lifetime or for a specific time period.
Note
Previous resource history revisions are guaranteed to be available for up to 90 days.
To get the history of a resource’s metadata, run the following command:
openstack metric resource history --type ${resource_type} ${resource_id}
Example output:
$ openstack metric resource history --type instance af6b97d9-d172-4e06-b565-db1e97097340
+--------------------------------------+----------+----------------------------------+----------------------------------+--------------------------------------+----------------------------------+----------+----------------------------------+----------------------------------+-------------------------------------------------------------------+---------------+-----------+--------------------------------------+--------------+-------------+-----------+---------+------+---------------------------------------------------------------------+
| id | type | project_id | user_id | original_resource_id | started_at | ended_at | revision_start | revision_end | creator | display_name | image_ref | flavor_id | server_group | flavor_name | os_distro | os_type | host | metrics |
+--------------------------------------+----------+----------------------------------+----------------------------------+--------------------------------------+----------------------------------+----------+----------------------------------+----------------------------------+-------------------------------------------------------------------+---------------+-----------+--------------------------------------+--------------+-------------+-----------+---------+------+---------------------------------------------------------------------+
| af6b97d9-d172-4e06-b565-db1e97097340 | instance | 9864e20f92ef47238becfe06b869d2ac | 517bcd700274432d96f43616ac1e37ea | af6b97d9-d172-4e06-b565-db1e97097340 | 2025-03-18T02:16:55.790609+00:00 | None | 2025-03-18T02:16:55.790617+00:00 | 2025-03-18T22:00:58.683260+00:00 | 42dcfd23b04a4006b9e2b08c0a835aeb:70d50fbf0c2148689aa2c319351e634d | test-instance | None | 28153197-6690-4485-9dbc-fc24489b0683 | None | c1.c1r1 | None | None | None | compute.instance.booting.time: c418003f-5115-4bd3-a56e-270d90e26b2f |
| | | | | | | | | | | | | | | | | | | cpu: 6febda4a-4a3f-485f-b6e2-5f94d55e39b0 |
| | | | | | | | | | | | | | | | | | | disk.ephemeral.size: d0add36c-6208-40d3-a8d0-2f5ab3a550bd |
| | | | | | | | | | | | | | | | | | | disk.root.size: b4e3d818-444b-46a9-b874-c82fd78e3a66 |
| | | | | | | | | | | | | | | | | | | instance: 53c46abc-5336-49a8-ac76-fc5aed5e5154 |
| | | | | | | | | | | | | | | | | | | memory: 1e87f21e-2238-41f0-80fd-950e3e2f9bcf |
| | | | | | | | | | | | | | | | | | | vcpus: 9d60abe7-b1d7-425d-8d89-6c0eecd38c47 |
| af6b97d9-d172-4e06-b565-db1e97097340 | instance | 9864e20f92ef47238becfe06b869d2ac | 517bcd700274432d96f43616ac1e37ea | af6b97d9-d172-4e06-b565-db1e97097340 | 2025-03-18T02:16:55.790609+00:00 | None | 2025-03-18T22:00:58.683260+00:00 | None | 42dcfd23b04a4006b9e2b08c0a835aeb:70d50fbf0c2148689aa2c319351e634d | test-instance | None | 28153197-6690-4485-9dbc-fc24489b0683 | None | c1.c1r1 | ubuntu | linux | None | compute.instance.booting.time: c418003f-5115-4bd3-a56e-270d90e26b2f |
| | | | | | | | | | | | | | | | | | | cpu: 6febda4a-4a3f-485f-b6e2-5f94d55e39b0 |
| | | | | | | | | | | | | | | | | | | disk.ephemeral.size: d0add36c-6208-40d3-a8d0-2f5ab3a550bd |
| | | | | | | | | | | | | | | | | | | disk.root.size: b4e3d818-444b-46a9-b874-c82fd78e3a66 |
| | | | | | | | | | | | | | | | | | | instance: 53c46abc-5336-49a8-ac76-fc5aed5e5154 |
| | | | | | | | | | | | | | | | | | | memory: 1e87f21e-2238-41f0-80fd-950e3e2f9bcf |
| | | | | | | | | | | | | | | | | | | vcpus: 9d60abe7-b1d7-425d-8d89-6c0eecd38c47 |
+--------------------------------------+----------+----------------------------------+----------------------------------+--------------------------------------+----------------------------------+----------+----------------------------------+----------------------------------+-------------------------------------------------------------------+---------------+-----------+--------------------------------------+--------------+-------------+-----------+---------+------+---------------------------------------------------------------------+
Add -f json to output the response as JSON:
$ openstack metric resource history --type instance af6b97d9-d172-4e06-b565-db1e97097340 -f json
[
{
"id": "af6b97d9-d172-4e06-b565-db1e97097340",
"type": "instance",
"project_id": "9864e20f92ef47238becfe06b869d2ac",
"user_id": "517bcd700274432d96f43616ac1e37ea",
"original_resource_id": "af6b97d9-d172-4e06-b565-db1e97097340",
"started_at": "2025-03-18T02:16:55.790609+00:00",
"ended_at": null,
"revision_start": "2025-03-18T02:16:55.790617+00:00",
"revision_end": "2025-03-18T22:00:58.683260+00:00",
"creator": "42dcfd23b04a4006b9e2b08c0a835aeb:70d50fbf0c2148689aa2c319351e634d",
"display_name": "test-instance",
"image_ref": null,
"flavor_id": "28153197-6690-4485-9dbc-fc24489b0683",
"server_group": null,
"flavor_name": "c1.c1r1",
"os_distro": null,
"os_type": null,
"host": null,
"metrics": {
"compute.instance.booting.time": "c418003f-5115-4bd3-a56e-270d90e26b2f",
"cpu": "6febda4a-4a3f-485f-b6e2-5f94d55e39b0",
"disk.ephemeral.size": "d0add36c-6208-40d3-a8d0-2f5ab3a550bd",
"disk.root.size": "b4e3d818-444b-46a9-b874-c82fd78e3a66",
"instance": "53c46abc-5336-49a8-ac76-fc5aed5e5154",
"memory": "1e87f21e-2238-41f0-80fd-950e3e2f9bcf",
"vcpus": "9d60abe7-b1d7-425d-8d89-6c0eecd38c47"
}
},
{
"id": "af6b97d9-d172-4e06-b565-db1e97097340",
"type": "instance",
"project_id": "9864e20f92ef47238becfe06b869d2ac",
"user_id": "517bcd700274432d96f43616ac1e37ea",
"original_resource_id": "af6b97d9-d172-4e06-b565-db1e97097340",
"started_at": "2025-03-18T02:16:55.790609+00:00",
"ended_at": null,
"revision_start": "2025-03-18T22:00:58.683260+00:00",
"revision_end": null,
"creator": "42dcfd23b04a4006b9e2b08c0a835aeb:70d50fbf0c2148689aa2c319351e634d",
"display_name": "test-instance",
"image_ref": null,
"flavor_id": "28153197-6690-4485-9dbc-fc24489b0683",
"server_group": null,
"flavor_name": "c1.c1r1",
"os_distro": "ubuntu",
"os_type": "linux",
"host": null,
"metrics": {
"compute.instance.booting.time": "c418003f-5115-4bd3-a56e-270d90e26b2f",
"cpu": "6febda4a-4a3f-485f-b6e2-5f94d55e39b0",
"disk.ephemeral.size": "d0add36c-6208-40d3-a8d0-2f5ab3a550bd",
"disk.root.size": "b4e3d818-444b-46a9-b874-c82fd78e3a66",
"instance": "53c46abc-5336-49a8-ac76-fc5aed5e5154",
"memory": "1e87f21e-2238-41f0-80fd-950e3e2f9bcf",
"vcpus": "9d60abe7-b1d7-425d-8d89-6c0eecd38c47"
}
}
]
Call the following method:
gnocchi_client.resource.history("{resource_type}", "{resource_id}")
Example output:
>>> pprint(gnocchi_client.resource.history("instance", "af6b97d9-d172-4e06-b565-db1e97097340"))
[{'created_by_project_id': '70d50fbf0c2148689aa2c319351e634d',
'created_by_user_id': '42dcfd23b04a4006b9e2b08c0a835aeb',
'creator': '42dcfd23b04a4006b9e2b08c0a835aeb:70d50fbf0c2148689aa2c319351e634d',
'display_name': 'test-instance',
'ended_at': None,
'flavor_id': '28153197-6690-4485-9dbc-fc24489b0683',
'flavor_name': 'c1.c1r1',
'host': None,
'id': 'af6b97d9-d172-4e06-b565-db1e97097340',
'image_ref': None,
'metrics': {'compute.instance.booting.time': 'c418003f-5115-4bd3-a56e-270d90e26b2f',
'cpu': '6febda4a-4a3f-485f-b6e2-5f94d55e39b0',
'disk.ephemeral.size': 'd0add36c-6208-40d3-a8d0-2f5ab3a550bd',
'disk.root.size': 'b4e3d818-444b-46a9-b874-c82fd78e3a66',
'instance': '53c46abc-5336-49a8-ac76-fc5aed5e5154',
'memory': '1e87f21e-2238-41f0-80fd-950e3e2f9bcf',
'vcpus': '9d60abe7-b1d7-425d-8d89-6c0eecd38c47'},
'original_resource_id': 'af6b97d9-d172-4e06-b565-db1e97097340',
'os_distro': None,
'os_type': None,
'project_id': '9864e20f92ef47238becfe06b869d2ac',
'revision_end': '2025-03-18T22:00:58.683260+00:00',
'revision_start': '2025-03-18T02:16:55.790617+00:00',
'server_group': None,
'started_at': '2025-03-18T02:16:55.790609+00:00',
'type': 'instance',
'user_id': '517bcd700274432d96f43616ac1e37ea'},
{'created_by_project_id': '70d50fbf0c2148689aa2c319351e634d',
'created_by_user_id': '42dcfd23b04a4006b9e2b08c0a835aeb',
'creator': '42dcfd23b04a4006b9e2b08c0a835aeb:70d50fbf0c2148689aa2c319351e634d',
'display_name': 'test-instance',
'ended_at': None,
'flavor_id': '28153197-6690-4485-9dbc-fc24489b0683',
'flavor_name': 'c1.c1r1',
'host': None,
'id': 'af6b97d9-d172-4e06-b565-db1e97097340',
'image_ref': None,
'metrics': {'compute.instance.booting.time': 'c418003f-5115-4bd3-a56e-270d90e26b2f',
'cpu': '6febda4a-4a3f-485f-b6e2-5f94d55e39b0',
'disk.ephemeral.size': 'd0add36c-6208-40d3-a8d0-2f5ab3a550bd',
'disk.root.size': 'b4e3d818-444b-46a9-b874-c82fd78e3a66',
'instance': '53c46abc-5336-49a8-ac76-fc5aed5e5154',
'memory': '1e87f21e-2238-41f0-80fd-950e3e2f9bcf',
'vcpus': '9d60abe7-b1d7-425d-8d89-6c0eecd38c47'},
'original_resource_id': 'af6b97d9-d172-4e06-b565-db1e97097340',
'os_distro': 'ubuntu',
'os_type': 'linux',
'project_id': '9864e20f92ef47238becfe06b869d2ac',
'revision_end': None,
'revision_start': '2025-03-18T22:00:58.683260+00:00',
'server_group': None,
'started_at': '2025-03-18T02:16:55.790609+00:00',
'type': 'instance',
'user_id': '517bcd700274432d96f43616ac1e37ea'}]
Make the following request:
curl -s \
-H "X-Auth-Token: ${OS_TOKEN}" \
-H "Accept: application/json" \
https://api.$(echo "${OS_REGION_NAME}" | tr '_' '-').catalystcloud.nz:8041/v1/resource/${resource_type}/${resource_id}/history
Example output:
$ curl -s -H "X-Auth-Token: ${OS_TOKEN}" -H "Accept: application/json" https://api.$(echo "${OS_REGION_NAME}" | tr '_' '-').catalystcloud.nz:8041/v1/resource/instance/af6b97d9-d172-4e06-b565-db1e97097340/history | jq
[
{
"id": "af6b97d9-d172-4e06-b565-db1e97097340",
"revision_end": "2025-03-18T22:00:58.683260+00:00",
"creator": "42dcfd23b04a4006b9e2b08c0a835aeb:70d50fbf0c2148689aa2c319351e634d",
"started_at": "2025-03-18T02:16:55.790609+00:00",
"revision_start": "2025-03-18T02:16:55.790617+00:00",
"ended_at": null,
"user_id": "517bcd700274432d96f43616ac1e37ea",
"project_id": "9864e20f92ef47238becfe06b869d2ac",
"original_resource_id": "af6b97d9-d172-4e06-b565-db1e97097340",
"type": "instance",
"display_name": "test-instance",
"image_ref": null,
"flavor_id": "28153197-6690-4485-9dbc-fc24489b0683",
"server_group": null,
"flavor_name": "c1.c1r1",
"os_distro": null,
"os_type": null,
"host": null,
"metrics": {
"compute.instance.booting.time": "c418003f-5115-4bd3-a56e-270d90e26b2f",
"cpu": "6febda4a-4a3f-485f-b6e2-5f94d55e39b0",
"disk.ephemeral.size": "d0add36c-6208-40d3-a8d0-2f5ab3a550bd",
"disk.root.size": "b4e3d818-444b-46a9-b874-c82fd78e3a66",
"instance": "53c46abc-5336-49a8-ac76-fc5aed5e5154",
"memory": "1e87f21e-2238-41f0-80fd-950e3e2f9bcf",
"vcpus": "9d60abe7-b1d7-425d-8d89-6c0eecd38c47"
},
"created_by_user_id": "42dcfd23b04a4006b9e2b08c0a835aeb",
"created_by_project_id": "70d50fbf0c2148689aa2c319351e634d"
},
{
"id": "af6b97d9-d172-4e06-b565-db1e97097340",
"revision_end": null,
"creator": "42dcfd23b04a4006b9e2b08c0a835aeb:70d50fbf0c2148689aa2c319351e634d",
"started_at": "2025-03-18T02:16:55.790609+00:00",
"revision_start": "2025-03-18T22:00:58.683260+00:00",
"ended_at": null,
"user_id": "517bcd700274432d96f43616ac1e37ea",
"project_id": "9864e20f92ef47238becfe06b869d2ac",
"original_resource_id": "af6b97d9-d172-4e06-b565-db1e97097340",
"type": "instance",
"display_name": "test-instance",
"image_ref": null,
"flavor_id": "28153197-6690-4485-9dbc-fc24489b0683",
"server_group": null,
"flavor_name": "c1.c1r1",
"os_distro": "ubuntu",
"os_type": "linux",
"host": null,
"metrics": {
"compute.instance.booting.time": "c418003f-5115-4bd3-a56e-270d90e26b2f",
"cpu": "6febda4a-4a3f-485f-b6e2-5f94d55e39b0",
"disk.ephemeral.size": "d0add36c-6208-40d3-a8d0-2f5ab3a550bd",
"disk.root.size": "b4e3d818-444b-46a9-b874-c82fd78e3a66",
"instance": "53c46abc-5336-49a8-ac76-fc5aed5e5154",
"memory": "1e87f21e-2238-41f0-80fd-950e3e2f9bcf",
"vcpus": "9d60abe7-b1d7-425d-8d89-6c0eecd38c47"
},
"created_by_user_id": "42dcfd23b04a4006b9e2b08c0a835aeb",
"created_by_project_id": "70d50fbf0c2148689aa2c319351e634d"
}
]
In the above example, we can see that there are two revisions - the first revision
from when the resource was initially created, and a second revision modifying some
metadata values (in this case, setting os_type and os_distro).
When performing resource history queries, revisions are returned in chronological
order by default. Revisions are also delineated using the revision_start and
revision_end attributes, with revision_end on the previous revision always
matching revision_start on the next revision. The latest (current) revision
has a revision_end value of null.
It is possible to retrieve a list of metadata changes (revisions) for a resource over a given time period.
In the below example, we retrieve all revisions that applied to a resource within the specified time period. The first listed revision is the initial state of that resource at the start of the time period, and all changes are listed until the last one, which is the state the resource was in at the end of the time period (sometimes, but not always, the current revision).
Run the following command:
openstack metric resource search --type ${resource_type} "id='${resource_id}' and revision_start<'${stop}' and (revision_end>='${start}' or revision_end=null)" --history
Example output:
$ openstack metric resource search --type instance "id='af6b97d9-d172-4e06-b565-db1e97097340' and revision_start<'2025-03-18T12:00:00+00:00' and (revision_end>='2025-03-18T00:00:00+00:00' or revision_end=null)" --history
+--------------------------------------+----------+----------------------------------+----------------------------------+--------------------------------------+----------------------------------+----------+----------------------------------+----------------------------------+-------------------------------------------------------------------+---------------+-----------+--------------------------------------+--------------+-------------+-----------+---------+------+
| id | type | project_id | user_id | original_resource_id | started_at | ended_at | revision_start | revision_end | creator | display_name | image_ref | flavor_id | server_group | flavor_name | os_distro | os_type | host |
+--------------------------------------+----------+----------------------------------+----------------------------------+--------------------------------------+----------------------------------+----------+----------------------------------+----------------------------------+-------------------------------------------------------------------+---------------+-----------+--------------------------------------+--------------+-------------+-----------+---------+------+
| af6b97d9-d172-4e06-b565-db1e97097340 | instance | 9864e20f92ef47238becfe06b869d2ac | 517bcd700274432d96f43616ac1e37ea | af6b97d9-d172-4e06-b565-db1e97097340 | 2025-03-18T02:16:55.790609+00:00 | None | 2025-03-18T02:16:55.790617+00:00 | 2025-03-18T22:00:58.683260+00:00 | 42dcfd23b04a4006b9e2b08c0a835aeb:70d50fbf0c2148689aa2c319351e634d | test-instance | None | 28153197-6690-4485-9dbc-fc24489b0683 | None | c1.c1r1 | None | None | None |
+--------------------------------------+----------+----------------------------------+----------------------------------+--------------------------------------+----------------------------------+----------+----------------------------------+----------------------------------+-------------------------------------------------------------------+---------------+-----------+--------------------------------------+--------------+-------------+-----------+---------+------+
Add -f json to output the response as JSON:
$ openstack metric resource search --type instance "id='af6b97d9-d172-4e06-b565-db1e97097340' and revision_start<'2025-03-18T12:00:00+00:00' and (revision_end>='2025-03-18T00:00:00+00:00' or revision_end=null)" --history -f json
[
{
"id": "af6b97d9-d172-4e06-b565-db1e97097340",
"type": "instance",
"project_id": "9864e20f92ef47238becfe06b869d2ac",
"user_id": "517bcd700274432d96f43616ac1e37ea",
"original_resource_id": "af6b97d9-d172-4e06-b565-db1e97097340",
"started_at": "2025-03-18T02:16:55.790609+00:00",
"ended_at": null,
"revision_start": "2025-03-18T02:16:55.790617+00:00",
"revision_end": "2025-03-18T22:00:58.683260+00:00",
"creator": "42dcfd23b04a4006b9e2b08c0a835aeb:70d50fbf0c2148689aa2c319351e634d",
"display_name": "test-instance",
"image_ref": null,
"flavor_id": "28153197-6690-4485-9dbc-fc24489b0683",
"server_group": null,
"flavor_name": "c1.c1r1",
"os_distro": null,
"os_type": null,
"host": null
}
]
Call the following method:
gnocchi_client.resource.search(
resource_type="{resource_type}",
query={
"and": [
{"=": {"id": "{resource_id}"}},
# Filter revisions created after the end of the window.
{"<": {"revision_start": "{stop}"}},
{
"or": [
# Filter revisions ended before the start of the window.
{">=": {"revision_end": "{start}"}},
# Include the latest revision, if started before the end of the window.
{"=": {"revision_end": None}},
],
},
],
},
history=True,
)
Example output:
>>> pprint(gnocchi_client.resource.search(
... resource_type="instance",
... query={
... "and": [
... {"=": {"id": "af6b97d9-d172-4e06-b565-db1e97097340"}},
... # Filter revisions created after the end of the window.
... {"<": {"revision_start": "2025-03-18T12:00:00+00:00"}},
... {
... "or": [
... # Filter revisions ended before the start of the window.
... {">=": {"revision_end": "2025-03-18T00:00:00+00:00"}},
... # Include the latest revision, if started before the end of the window.
... {"=": {"revision_end": None}},
... ],
... },
... ],
... },
... history=True,
... ))
[{'created_by_project_id': '70d50fbf0c2148689aa2c319351e634d',
'created_by_user_id': '42dcfd23b04a4006b9e2b08c0a835aeb',
'creator': '42dcfd23b04a4006b9e2b08c0a835aeb:70d50fbf0c2148689aa2c319351e634d',
'display_name': 'test-instance',
'ended_at': None,
'flavor_id': '28153197-6690-4485-9dbc-fc24489b0683',
'flavor_name': 'c1.c1r1',
'host': None,
'id': 'af6b97d9-d172-4e06-b565-db1e97097340',
'image_ref': None,
'metrics': {'compute.instance.booting.time': 'c418003f-5115-4bd3-a56e-270d90e26b2f',
'cpu': '6febda4a-4a3f-485f-b6e2-5f94d55e39b0',
'disk.ephemeral.size': 'd0add36c-6208-40d3-a8d0-2f5ab3a550bd',
'disk.root.size': 'b4e3d818-444b-46a9-b874-c82fd78e3a66',
'instance': '53c46abc-5336-49a8-ac76-fc5aed5e5154',
'memory': '1e87f21e-2238-41f0-80fd-950e3e2f9bcf',
'vcpus': '9d60abe7-b1d7-425d-8d89-6c0eecd38c47'},
'original_resource_id': 'af6b97d9-d172-4e06-b565-db1e97097340',
'os_distro': None,
'os_type': None,
'project_id': '9864e20f92ef47238becfe06b869d2ac',
'revision_end': '2025-03-18T22:00:58.683260+00:00',
'revision_start': '2025-03-18T02:16:55.790617+00:00',
'server_group': None,
'started_at': '2025-03-18T02:16:55.790609+00:00',
'type': 'instance',
'user_id': '517bcd700274432d96f43616ac1e37ea'}]
First, save a file containing the request payload.
Example JSON payload:
{
"and": [
{"=": {"id": "{resource_id}"}},
{"<": {"revision_start": "{stop}"}},
{
"or": [
{">=": {"revision_end": "{start}"}},
{"=": {"revision_end": null}}
]
}
]
}
Populated with values (save as payload.json):
{
"and": [
{"=": {"id": "af6b97d9-d172-4e06-b565-db1e97097340"}},
{"<": {"revision_start": "2025-03-18T12:00:00+00:00"}},
{
"or": [
{">=": {"revision_end": "2025-03-18T00:00:00+00:00"}},
{"=": {"revision_end": null}}
]
}
]
}
Make the following request:
curl -s \
-X POST \
-H "X-Auth-Token: ${OS_TOKEN}" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
"https://api.$(echo "${OS_REGION_NAME}" | tr '_' '-').catalystcloud.nz:8041/v1/search/resource/instance?history=true" \
--data-binary "@payload.json"
Example output:
$ curl -s -X POST -H "X-Auth-Token: ${OS_TOKEN}" -H "Content-Type: application/json" -H "Accept: application/json" "https://api.$(echo "${OS_REGION_NAME}" | tr '_' '-').catalystcloud.nz:8041/v1/search/resource/instance?history=true" --data-binary "@payload.json" | jq
[
{
"id": "af6b97d9-d172-4e06-b565-db1e97097340",
"revision_end": "2025-03-18T22:00:58.683260+00:00",
"creator": "42dcfd23b04a4006b9e2b08c0a835aeb:70d50fbf0c2148689aa2c319351e634d",
"started_at": "2025-03-18T02:16:55.790609+00:00",
"revision_start": "2025-03-18T02:16:55.790617+00:00",
"ended_at": null,
"user_id": "517bcd700274432d96f43616ac1e37ea",
"project_id": "9864e20f92ef47238becfe06b869d2ac",
"original_resource_id": "af6b97d9-d172-4e06-b565-db1e97097340",
"type": "instance",
"display_name": "test-instance",
"image_ref": null,
"flavor_id": "28153197-6690-4485-9dbc-fc24489b0683",
"server_group": null,
"flavor_name": "c1.c1r1",
"os_distro": null,
"os_type": null,
"host": null,
"metrics": {
"compute.instance.booting.time": "c418003f-5115-4bd3-a56e-270d90e26b2f",
"cpu": "6febda4a-4a3f-485f-b6e2-5f94d55e39b0",
"disk.ephemeral.size": "d0add36c-6208-40d3-a8d0-2f5ab3a550bd",
"disk.root.size": "b4e3d818-444b-46a9-b874-c82fd78e3a66",
"instance": "53c46abc-5336-49a8-ac76-fc5aed5e5154",
"memory": "1e87f21e-2238-41f0-80fd-950e3e2f9bcf",
"vcpus": "9d60abe7-b1d7-425d-8d89-6c0eecd38c47"
},
"created_by_user_id": "42dcfd23b04a4006b9e2b08c0a835aeb",
"created_by_project_id": "70d50fbf0c2148689aa2c319351e634d"
}
]
The Aggregates API is the main method of retrieving, processing and reaggregating data in the Metrics Service.
Clients provide, among others, two major parameters that tell the Metrics Service how data should be handled:
A series of operations, which not only select the desired metrics but also define a pipeline of actions to be performed on them to transform the output to the desired format.
Search filters that define the resources that should be evaluated, using the same format as when searching resources.
This allows for very flexible queries, from a single metric on a specific resource to a composite query reaggregating multiple metrics from many resource types into highly consolidated measures.
This section demonstrates many of the most common ways the Aggregates API is expected to be used by customers. For additional reading on the Aggregates API’s capabilities, refer to the Gnocchi documentation on Dynamic Aggregates.
This section demonstrates how to use the Aggregates API to perform a simple query.
Note
For more detailed explanations on what kind of queries can be done using the Aggregates API, see Examples.
The Aggregates API is available using the openstack metric aggregates command.
openstack metric aggregates --start "${start}" \
--stop "${stop}" \
--resource-type ${resource_type} \
--granularity ${granularity} \
"${operations}" \
"${search}"
The following basic parameters should be set for every query:
--start DATETIME - Start time of the period for which to query aggregates, as an ISO 8601 datetime (recommended) or Unix timestamp.
--stop DATETIME - End time of the period for which to query aggregates, as an ISO 8601 datetime (recommended) or Unix timestamp.
--resource-type TYPE - The resource type to query aggregates from.
--granularity SECONDS - The granularity of the aggregates to query.
operations - The aggregate operations to perform to get the desired data, in string format (not JSON).
We have examples defined below for common use cases, but if you’d like more information on what is
possible using the Aggregates API, refer to the Gnocchi documentation on Dynamic Aggregates.
search - Search filters to limit the output to desired resources only, in string format (not JSON).
For more information, see Searching Resources.
Warning
You should always set --start and --stop for your aggregate queries.
Not doing so will result in an unbounded query being performed, causing more metrics to be retrieved than intended or a timeout.
Here is a basic example of an aggregate query command against a single resource:
openstack metric aggregates --start "2025-08-09T00:00:00+00:00" \
--stop "2025-08-09T01:00:00+00:00" \
--resource-type instance \
--granularity 600 \
"(/ (/ (metric cpu rate:mean) (metric vcpus mean)) 600000000000)" \
"id=af6b97d9-d172-4e06-b565-db1e97097340"
All resources with matching metrics get measures returned in a table format.
$ openstack metric aggregates --start "2025-08-09T00:00:00+00:00" --stop "2025-08-09T01:00:00+00:00" --resource-type instance --granularity 600 "(/ (/ (metric cpu rate:mean) (metric vcpus mean)) 600000000000)" "id=af6b97d9-d172-4e06-b565-db1e97097340"
+------------+---------------------------+-------------+-----------------------+
| name | timestamp | granularity | value |
+------------+---------------------------+-------------+-----------------------+
| aggregated | 2025-08-09T00:00:00+00:00 | 600.0 | 0.0018333333333333333 |
| aggregated | 2025-08-09T00:10:00+00:00 | 600.0 | 0.0014 |
| aggregated | 2025-08-09T00:20:00+00:00 | 600.0 | 0.0014666666666666667 |
| aggregated | 2025-08-09T00:30:00+00:00 | 600.0 | 0.0014666666666666667 |
| aggregated | 2025-08-09T00:40:00+00:00 | 600.0 | 0.0013833333333333334 |
| aggregated | 2025-08-09T00:50:00+00:00 | 600.0 | 0.0014333333333333333 |
+------------+---------------------------+-------------+-----------------------+
-f json can be used to change the output format to JSON.
$ openstack metric aggregates --start "2025-08-09T00:00:00+00:00" --stop "2025-08-09T01:00:00+00:00" --resource-type instance --granularity 600 "(/ (/ (metric cpu rate:mean) (metric vcpus mean)) 600000000000)" "id=af6b97d9-d172-4e06-b565-db1e97097340" -f json
[
{
"name": "aggregated",
"timestamp": "2025-08-09T00:00:00+00:00",
"granularity": 600.0,
"value": 0.0018333333333333333
},
{
"name": "aggregated",
"timestamp": "2025-08-09T00:10:00+00:00",
"granularity": 600.0,
"value": 0.0014
},
{
"name": "aggregated",
"timestamp": "2025-08-09T00:20:00+00:00",
"granularity": 600.0,
"value": 0.0014666666666666667
},
{
"name": "aggregated",
"timestamp": "2025-08-09T00:30:00+00:00",
"granularity": 600.0,
"value": 0.0014666666666666667
},
{
"name": "aggregated",
"timestamp": "2025-08-09T00:40:00+00:00",
"granularity": 600.0,
"value": 0.0013833333333333334
},
{
"name": "aggregated",
"timestamp": "2025-08-09T00:50:00+00:00",
"granularity": 600.0,
"value": 0.0014333333333333333
}
]
Returned timestamps are in UTC.
Note
If no timezone offset (e.g. +12:00) is specified on your
--start and --stop timestamps, the CLI command for the
Aggregates API will automatically change the timestamps to UTC
relative to your computer’s system timezone.
To prevent this behaviour, make sure that your --start
and --stop values have the correct timezone offset.
Other options are also available. For reference, here is the full output of --help:
$ openstack metric aggregates --help
usage: openstack metric aggregates [-h] [-f {csv,json,table,value,yaml}] [-c COLUMN] [--quote {all,minimal,none,nonnumeric}] [--noindent] [--max-width <integer>] [--fit-width] [--print-empty]
[--sort-column SORT_COLUMN] [--sort-ascending | --sort-descending] [--resource-type RESOURCE_TYPE] [--start START] [--stop STOP] [--granularity GRANULARITY]
[--needed-overlap NEEDED_OVERLAP] [--groupby GROUPBY] [--fill FILL] [--use-history USE_HISTORY]
operations [search]
Get measurements of aggregated metrics.
positional arguments:
operations Operations to apply to time series
search A query to filter resource. The syntax is a combination of attribute, operator and value. For example: id=90d58eea-70d7-4294-a49a-170dcdf44c3c would filter resource with a certain id. More complex queries can be built,
e.g.: not (flavor_id!="1" and memory>=24). Use "" to force data to be interpreted as string. Supported operators are: not, and, ∧ or, ∨, >=, <=, !=, >, <, =, ==, eq, ne, lt, gt, ge, le, in, like, ≠, ≥, ≤, like, in.
options:
-h, --help show this help message and exit
--resource-type RESOURCE_TYPE
Resource type to query
--start START
beginning of the period
--stop STOP end of the period
--granularity GRANULARITY
granularity to retrieve
--needed-overlap NEEDED_OVERLAP
percentage of overlap across datapoints
--groupby GROUPBY
Attribute to use to group resources
--fill FILL Value to use when backfilling timestamps with missing values in a subset of series. Value should be a float or 'null'.
--use-history USE_HISTORY
Indicates if Gnocchi server should respond with the resource tags history for the aggregation query. If set to `False`, only the latest tag values will be returned. Otherwise, the measures will be split proportionally if a
tag has been changed in the `granularity` requested.
output formatters:
output formatter options
-f {csv,json,table,value,yaml}, --format {csv,json,table,value,yaml}
the output format, defaults to table
-c COLUMN, --column COLUMN
specify the column(s) to include, can be repeated to show multiple columns
--sort-column SORT_COLUMN
specify the column(s) to sort the data (columns specified first have a priority, non-existing columns are ignored), can be repeated
--sort-ascending sort the column(s) in ascending order
--sort-descending sort the column(s) in descending order
CSV Formatter:
--quote {all,minimal,none,nonnumeric}
when to include quotes, defaults to nonnumeric
json formatter:
--noindent whether to disable indenting the JSON
table formatter:
--max-width <integer>
Maximum display width, <1 to disable. You can also use the CLIFF_MAX_TERM_WIDTH environment variable, but the parameter takes precedence.
--fit-width Fit the table to the display width. Implied if --max-width greater than 0. Set the environment variable CLIFF_FIT_WIDTH=1 to always enable
--print-empty Print empty table if there is no data to show.
This command is provided by the gnocchiclient plugin.
The Aggregates API is available using the gnocchi_client.aggregates.fetch method.
def fetch(
operations: str | list[Operation],
search: str | dict[str, SearchFilter] | None = None,
resource_type: str = "generic",
start: int | str | datetime.datetime | None = None,
stop: int | str | datetime.datetime | None = None,
granularity: int | None = None,
needed_overlap: float | None = None,
groupby: list[str] | None = None,
details: bool = False,
use_history: bool = False,
) -> dict[str, Any] | list[dict[str, Any]]
The following basic parameters should be set for every query:
start - Start time of the period for which to query aggregates, as a datetime.datetime object (recommended), ISO 8601 datetime or Unix timestamp.
stop - End time of the period for which to query aggregates, as a datetime.datetime object (recommended), ISO 8601 datetime or Unix timestamp.
resource_type - The resource type to query aggregates from.
granularity - The granularity of the aggregates to query.
operations - The aggregate operations to perform to get the desired data, in string or object format.
We have examples defined below for common use cases, but if you’d like more information on what is
possible using the Aggregates API, refer to the Gnocchi documentation on Dynamic Aggregates.
search - Search filters to limit the output to desired resources only, in string or object format.
For more information, see Searching Resources.
Warning
You should always set start and stop for your aggregate queries.
Not doing so will result in an unbounded query being performed, causing more metrics to be retrieved than intended or a timeout.
Here is a basic example of an aggregate query command against a single resource:
gnocchi_client.aggregates.fetch(
operations=[
"/",
[
"/",
["metric", "cpu", "rate:mean"],
["metric", "vcpus", "mean"],
],
6000000000,
],
search={"=": {"id": "af6b97d9-d172-4e06-b565-db1e97097340"}},
resource_type="instance",
start="2025-08-09T00:00:00+00:00",
stop="2025-08-09T01:00:00+00:00",
granularity=600,
)
All resources with matching metrics usually get returned in the following format (this can change depending on the type of query).
>>> pprint(gnocchi_client.aggregates.fetch(
... operations=[
... "/",
... [
... "/",
... ["metric", "cpu", "rate:mean"],
... ["metric", "vcpus", "mean"],
... ],
... 6000000000,
... ],
... search={"=": {"id": "af6b97d9-d172-4e06-b565-db1e97097340"}},
... resource_type="instance",
... start="2025-08-09T00:00:00+00:00",
... stop="2025-08-09T01:00:00+00:00",
... granularity=600,
... ))
{'measures': {'aggregated': [(datetime.datetime(2025, 8, 9, 0, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
600.0,
0.18333333333333332),
(datetime.datetime(2025, 8, 9, 0, 10, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
600.0,
0.14),
(datetime.datetime(2025, 8, 9, 0, 20, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
600.0,
0.14666666666666667),
(datetime.datetime(2025, 8, 9, 0, 30, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
600.0,
0.14666666666666667),
(datetime.datetime(2025, 8, 9, 0, 40, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
600.0,
0.13833333333333334),
(datetime.datetime(2025, 8, 9, 0, 50, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
600.0,
0.14333333333333334)]}}}}
Note that the returned timestamps are timezone-aware datetime.datetime objects in UTC.
The Aggregates API is available using the /v1/aggregates endpoint.
Here is a basic example of an aggregate query command against a single resource:
curl -s \
-X POST \
-H "X-Auth-Token: ${OS_TOKEN}" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
https://api.$(echo "${OS_REGION_NAME}" | tr '_' '-').catalystcloud.nz:8041/v1/aggregates \
--url-query "start=${start}" \
--url-query "stop=${stop}" \
--url-query "granularity=${granularity}" \
--data-binary "@payload.json"
Example JSON payload (save this as payload.json):
{
"operations": [
"/",
[
"/",
["metric", "cpu", "rate:mean"],
["metric", "vcpus", "mean"]
],
600000000000
],
"search": {"=": {"id": "af6b97d9-d172-4e06-b565-db1e97097340"}},
"resource_type": "instance"
}
The following basic parameters should be set for every query:
start - Start time of the period for which to query aggregates, as an ISO 8601 datetime (recommended) or Unix timestamp.
stop - End time of the period for which to query aggregates, as an ISO 8601 datetime (recommended) or Unix timestamp.
resource_type - The resource type to query aggregates from.
granularity - The granularity of the aggregates to query.
operations - The aggregate operations to perform to get the desired data, in string or object format.
We have examples defined below for common use cases, but if you’d like more information on what is
possible using the Aggregates API, refer to the Gnocchi documentation on Dynamic Aggregates.
search - Search filters to limit the output to desired resources only, in string or object format.
For more information, see Searching Resources.
Warning
You should always set start and stop for your aggregate queries.
Not doing so will result in an unbounded query being performed, causing more metrics to be retrieved than intended or a timeout.
All resources with matching metrics usually get returned in the following format (this can change depending on the type of query).
$ curl -s -X POST -H "X-Auth-Token: ${OS_TOKEN}" -H "Content-Type: application/json" -H "Accept: application/json" https://api.$(echo "${OS_REGION_NAME}" | tr '_' '-').catalystcloud.nz:8041/v1/aggregates --url-query "start=${start}" --url-query "stop=${stop}" --url-query "granularity=${granularity}" --data-binary "@payload.json" | jq
{
"measures": {
"aggregated": [
[
"2025-08-09T00:00:00+00:00",
600.0,
0.0018333333333333333
],
[
"2025-08-09T00:10:00+00:00",
600.0,
0.0014
],
[
"2025-08-09T00:20:00+00:00",
600.0,
0.0014666666666666667
],
[
"2025-08-09T00:30:00+00:00",
600.0,
0.0014666666666666667
],
[
"2025-08-09T00:40:00+00:00",
600.0,
0.0013833333333333334
],
[
"2025-08-09T00:50:00+00:00",
600.0,
0.0014333333333333333
]
]
}
}
Returned timestamps are in UTC.
You can append the current metadata of matching resources to any aggregate query using the details option.
This allows you to get both resource details and aggregations in a single query, saving potentially multiple additional requests to get the metadata of found resources.
This functionality is not available using the OpenStack CLI.
Run the following code:
start = "2025-08-09T00:00:00+00:00"
stop = "2025-08-09T01:00:00+00:00"
granularity = 600
gnocchi_client.aggregates.fetch(
operations=[
"/",
[
"/",
["metric", "cpu", "rate:mean"],
["metric", "vcpus", "mean"],
],
1000000000 * granularity,
],
search={"=": {"id": "af6b97d9-d172-4e06-b565-db1e97097340"}},
resource_type="instance",
start=start,
stop=stop,
granularity=granularity,
details=True,
)
Example output:
>>> start = "2025-08-09T00:00:00+00:00"
>>> stop = "2025-08-09T01:00:00+00:00"
>>> granularity = 600
>>> pprint(gnocchi_client.aggregates.fetch(
... operations=[
... "/",
... [
... "/",
... ["metric", "cpu", "rate:mean"],
... ["metric", "vcpus", "mean"],
... ],
... 1000000000 * granularity,
... ],
... search={"=": {"id": "af6b97d9-d172-4e06-b565-db1e97097340"}},
... resource_type="instance",
... start=start,
... stop=stop,
... granularity=granularity,
... details=True,
... ))
{'measures': {'aggregated': [(datetime.datetime(2025, 8, 9, 0, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
600.0,
0.18333333333333332),
(datetime.datetime(2025, 8, 9, 0, 10, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
600.0,
0.14),
(datetime.datetime(2025, 8, 9, 0, 20, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
600.0,
0.14666666666666667),
(datetime.datetime(2025, 8, 9, 0, 30, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
600.0,
0.14666666666666667),
(datetime.datetime(2025, 8, 9, 0, 40, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
600.0,
0.13833333333333334),
(datetime.datetime(2025, 8, 9, 0, 50, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
600.0,
0.14333333333333334)]}}}},
'references': [{'created_by_project_id': '70d50fbf0c2148689aa2c319351e634d',
'created_by_user_id': '42dcfd23b04a4006b9e2b08c0a835aeb',
'creator': '42dcfd23b04a4006b9e2b08c0a835aeb:70d50fbf0c2148689aa2c319351e634d',
'display_name': 'test-instance',
'ended_at': None,
'flavor_id': '28153197-6690-4485-9dbc-fc24489b0683',
'flavor_name': 'c1.c1r1',
'host': None,
'id': 'af6b97d9-d172-4e06-b565-db1e97097340',
'image_ref': None,
'metrics': {'compute.instance.booting.time': 'c418003f-5115-4bd3-a56e-270d90e26b2f',
'cpu': '6febda4a-4a3f-485f-b6e2-5f94d55e39b0',
'disk.ephemeral.size': 'd0add36c-6208-40d3-a8d0-2f5ab3a550bd',
'disk.root.size': 'b4e3d818-444b-46a9-b874-c82fd78e3a66',
'instance': '53c46abc-5336-49a8-ac76-fc5aed5e5154',
'memory': '1e87f21e-2238-41f0-80fd-950e3e2f9bcf',
'vcpus': '9d60abe7-b1d7-425d-8d89-6c0eecd38c47'},
'original_resource_id': 'af6b97d9-d172-4e06-b565-db1e97097340',
'os_distro': 'ubuntu',
'os_type': 'linux',
'project_id': '9864e20f92ef47238becfe06b869d2ac',
'revision_end': None,
'revision_start': '2025-03-18T22:00:58.683260+00:00',
'server_group': None,
'started_at': '2025-03-18T02:16:55.790609+00:00',
'type': 'instance',
'user_id': '517bcd700274432d96f43616ac1e37ea'}]}
First, save a file containing the request payload.
start="2025-08-09T00:00:00+00:00"
stop="2025-08-09T01:00:00+00:00"
granularity=600
cat > payload.json << EOF
{
"operations": [
"/",
[
"/",
["metric", "cpu", "rate:mean"],
["metric", "vcpus", "mean"]
],
$(echo "1000000000 * $granularity" | bc)
],
"search": {"=": {"id": "af6b97d9-d172-4e06-b565-db1e97097340"}},
"resource_type": "instance"
}
EOF
Here is what the payload should look like:
{
"operations": [
"/",
[
"/",
["metric", "cpu", "rate:mean"],
["metric", "vcpus", "mean"]
],
600000000000
],
"search": {"=": {"id": "af6b97d9-d172-4e06-b565-db1e97097340"}},
"resource_type": "instance"
}
Now, run the command to make the request.
curl -s \
-X POST \
-H "X-Auth-Token: ${OS_TOKEN}" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
https://api.$(echo "${OS_REGION_NAME}" | tr '_' '-').catalystcloud.nz:8041/v1/aggregates \
--url-query "start=${start}" \
--url-query "stop=${stop}" \
--url-query "granularity=${granularity}" \
--url-query "details=true" \
--data-binary "@payload.json"
Example output:
$ curl -s -X POST -H "X-Auth-Token: ${OS_TOKEN}" -H "Content-Type: application/json" -H "Accept: application/json" https://api.$(echo "${OS_REGION_NAME}" | tr '_' '-').catalystcloud.nz:8041/v1/aggregates --url-query "start=${start}" --url-query "stop=${stop}" --url-query "granularity=${granularity}" --url-query "details=true" --data-binary "@payload.json" | jq
{
"measures": {
"aggregated": [
[
"2025-08-09T00:00:00+00:00",
600.0,
0.0018333333333333333
],
[
"2025-08-09T00:10:00+00:00",
600.0,
0.0014
],
[
"2025-08-09T00:20:00+00:00",
600.0,
0.0014666666666666667
],
[
"2025-08-09T00:30:00+00:00",
600.0,
0.0014666666666666667
],
[
"2025-08-09T00:40:00+00:00",
600.0,
0.0013833333333333334
],
[
"2025-08-09T00:50:00+00:00",
600.0,
0.0014333333333333333
]
]
},
"references": [
{
"id": "af6b97d9-d172-4e06-b565-db1e97097340",
"creator": "42dcfd23b04a4006b9e2b08c0a835aeb:70d50fbf0c2148689aa2c319351e634d",
"started_at": "2025-03-18T02:16:55.790609+00:00",
"revision_start": "2025-03-18T22:00:58.683260+00:00",
"ended_at": null,
"user_id": "517bcd700274432d96f43616ac1e37ea",
"project_id": "9864e20f92ef47238becfe06b869d2ac",
"original_resource_id": "af6b97d9-d172-4e06-b565-db1e97097340",
"type": "instance",
"display_name": "test-instance",
"image_ref": null,
"flavor_id": "28153197-6690-4485-9dbc-fc24489b0683",
"server_group": null,
"flavor_name": "c1.c1r1",
"os_distro": "ubuntu",
"os_type": "linux",
"host": None,
"revision_end": null,
"metrics": {
"compute.instance.booting.time": "c418003f-5115-4bd3-a56e-270d90e26b2f",
"cpu": "6febda4a-4a3f-485f-b6e2-5f94d55e39b0",
"disk.ephemeral.size": "d0add36c-6208-40d3-a8d0-2f5ab3a550bd",
"disk.root.size": "b4e3d818-444b-46a9-b874-c82fd78e3a66",
"instance": "53c46abc-5336-49a8-ac76-fc5aed5e5154",
"memory": "1e87f21e-2238-41f0-80fd-950e3e2f9bcf",
"vcpus": "9d60abe7-b1d7-425d-8d89-6c0eecd38c47"
},
"created_by_user_id": "42dcfd23b04a4006b9e2b08c0a835aeb",
"created_by_project_id": "70d50fbf0c2148689aa2c319351e634d"
}
]
}
In this example we show how to get the 10 minute mean CPU usage of an instance as a decimal percentage (0-1).
The query takes into account the mean number of vCPUs the instance ran with in each aggregated datapoint, to allow instance resizes to be handled gracefully.
Here are the commands we will run:
resource_id="af6b97d9-d172-4e06-b565-db1e97097340"
start="2025-08-09T00:00:00+00:00"
stop="2025-08-09T01:00:00+00:00"
granularity=600
openstack metric aggregates --start "${start}" \
--stop "${stop}" \
--resource-type instance \
--granularity ${granularity} \
"(/ (/ (metric cpu rate:mean) (metric vcpus mean)) $(echo "1000000000 * ${granularity}" | bc))" \
"id='${resource_id}'"
With the variables evaluated, this is what it looks like:
openstack metric aggregates --start "2025-08-09T00:00:00+00:00" \
--stop "2025-08-09T01:00:00+00:00" \
--resource-type instance \
--granularity 600 \
"(/ (/ (metric cpu rate:mean) (metric vcpus mean)) 600000000000)" \
"id='af6b97d9-d172-4e06-b565-db1e97097340'"
Example output:
$ openstack metric aggregates --start "2025-08-09T00:00:00+00:00" --stop "2025-08-09T01:00:00+00:00" --resource-type instance --granularity 600 "(/ (/ (metric cpu rate:mean) (metric vcpus mean)) 600000000000)" "id='af6b97d9-d172-4e06-b565-db1e97097340'"
+------------+---------------------------+-------------+-----------------------+
| name | timestamp | granularity | value |
+------------+---------------------------+-------------+-----------------------+
| aggregated | 2025-08-09T00:00:00+00:00 | 600.0 | 0.0018333333333333333 |
| aggregated | 2025-08-09T00:10:00+00:00 | 600.0 | 0.0014 |
| aggregated | 2025-08-09T00:20:00+00:00 | 600.0 | 0.0014666666666666667 |
| aggregated | 2025-08-09T00:30:00+00:00 | 600.0 | 0.0014666666666666667 |
| aggregated | 2025-08-09T00:40:00+00:00 | 600.0 | 0.0013833333333333334 |
| aggregated | 2025-08-09T00:50:00+00:00 | 600.0 | 0.0014333333333333333 |
+------------+---------------------------+-------------+-----------------------+
Run the following code:
resource_id = "af6b97d9-d172-4e06-b565-db1e97097340"
start = "2025-08-09T00:00:00+00:00"
stop = "2025-08-09T01:00:00+00:00"
granularity = 600
gnocchi_client.aggregates.fetch(
operations=[
"/",
[
"/",
["metric", "cpu", "rate:mean"],
["metric", "vcpus", "mean"],
],
1000000000 * granularity,
],
search={"=": {"id": resource_id}},
resource_type="instance",
start=start,
stop=stop,
granularity=granularity,
)
Example output:
>>> resource_id = "af6b97d9-d172-4e06-b565-db1e97097340"
>>> start = "2025-08-09T00:00:00+00:00"
>>> stop = "2025-08-09T01:00:00+00:00"
>>> granularity = 600
>>> pprint(gnocchi_client.aggregates.fetch(
... operations=[
... "/",
... [
... "/",
... ["metric", "cpu", "rate:mean"],
... ["metric", "vcpus", "mean"],
... ],
... 1000000000 * granularity,
... ],
... search={"=": {"id": resource_id}},
... resource_type="instance",
... start=start,
... stop=stop,
... granularity=granularity,
... ))
{'measures': {'aggregated': [(datetime.datetime(2025, 8, 9, 0, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
600.0,
0.18333333333333332),
(datetime.datetime(2025, 8, 9, 0, 10, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
600.0,
0.14),
(datetime.datetime(2025, 8, 9, 0, 20, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
600.0,
0.14666666666666667),
(datetime.datetime(2025, 8, 9, 0, 30, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
600.0,
0.14666666666666667),
(datetime.datetime(2025, 8, 9, 0, 40, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
600.0,
0.13833333333333334),
(datetime.datetime(2025, 8, 9, 0, 50, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
600.0,
0.14333333333333334)]}}}}
First, save a file containing the request payload.
resource_id="af6b97d9-d172-4e06-b565-db1e97097340"
start="2025-08-09T00:00:00+00:00"
stop="2025-08-09T01:00:00+00:00"
granularity=600
cat > payload.json << EOF
{
"operations": [
"/",
[
"/",
["metric", "cpu", "rate:mean"],
["metric", "vcpus", "mean"]
],
$(echo "1000000000 * $granularity" | bc)
],
"search": {"=": {"id": "${resource_id}"}},
"resource_type": "instance"
}
EOF
Here is what the payload should look like:
{
"operations": [
"/",
[
"/",
["metric", "cpu", "rate:mean"],
["metric", "vcpus", "mean"]
],
600000000000
],
"search": {"=": {"id": "af6b97d9-d172-4e06-b565-db1e97097340"}},
"resource_type": "instance"
}
Now, run the command to make the request.
curl -s \
-X POST \
-H "X-Auth-Token: ${OS_TOKEN}" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
https://api.$(echo "${OS_REGION_NAME}" | tr '_' '-').catalystcloud.nz:8041/v1/aggregates \
--url-query "start=${start}" \
--url-query "stop=${stop}" \
--url-query "granularity=${granularity}" \
--data-binary "@payload.json"
Example output:
$ curl -s -X POST -H "X-Auth-Token: ${OS_TOKEN}" -H "Content-Type: application/json" -H "Accept: application/json" https://api.$(echo "${OS_REGION_NAME}" | tr '_' '-').catalystcloud.nz:8041/v1/aggregates --url-query "start=${start}" --url-query "stop=${stop}" --url-query "granularity=${granularity}" --data-binary "@payload.json" | jq
{
"measures": {
"aggregated": [
[
"2025-08-09T00:00:00+00:00",
600.0,
0.0018333333333333333
],
[
"2025-08-09T00:10:00+00:00",
600.0,
0.0014
],
[
"2025-08-09T00:20:00+00:00",
600.0,
0.0014666666666666667
],
[
"2025-08-09T00:30:00+00:00",
600.0,
0.0014666666666666667
],
[
"2025-08-09T00:40:00+00:00",
600.0,
0.0013833333333333334
],
[
"2025-08-09T00:50:00+00:00",
600.0,
0.0014333333333333333
]
]
}
}
In this example we show how to get the 10 minute mean CPU usage across instances in a server group as a singular decimal percentage (0-1).
The query takes into account the mean number of vCPUs each instance ran with in each aggregated datapoint, to allow instance resizes to be handled gracefully.
Here are the commands we will run:
server_group_id="7a612ef2-ad1d-49fa-a72d-51253761cdda"
start="2025-08-09T00:00:00+00:00"
stop="2025-08-09T01:00:00+00:00"
granularity=600
openstack metric aggregates --start "${start}" \
--stop "${stop}" \
--resource-type instance \
--granularity ${granularity} \
"(/ (/ (aggregate mean (metric cpu rate:mean)) (metric vcpus mean)) $(echo "1000000000 * ${granularity}" | bc))" \
"server_group='${server_group_id}' and (started_at<'${stop}' and (ended_at>='${start}' or ended_at=null))"
With the variables evaluated, this is what it looks like:
openstack metric aggregates --start "2025-08-09T00:00:00+00:00" \
--stop "2025-08-09T01:00:00+00:00" \
--resource-type instance \
--granularity 600 \
"(/ (/ (aggregate mean (metric cpu rate:mean)) (metric vcpus mean)) 600000000000)" \
"server_group='7a612ef2-ad1d-49fa-a72d-51253761cdda' and (started_at<'2025-08-09T01:00:00+00:00' and (ended_at>='2025-08-09T00:00:00+00:00' or ended_at=null))"
Example output:
$ openstack metric aggregates --start "2025-08-09T00:00:00+00:00" --stop "2025-08-09T01:00:00+00:00" --resource-type instance --granularity 600 "(/ (/ (aggregate mean (metric cpu rate:mean)) (metric vcpus mean)) 600000000000)" "server_group='7a612ef2-ad1d-49fa-a72d-51253761cdda' and (started_at<'2025-08-09T01:00:00+00:00' and (ended_at>='2025-08-09T00:00:00+00:00' or ended_at=null))"
+------------+---------------------------+-------------+-----------------------+
| name | timestamp | granularity | value |
+------------+---------------------------+-------------+-----------------------+
| aggregated | 2025-08-09T00:00:00+00:00 | 600.0 | 0.5010833333333333 |
| aggregated | 2025-08-09T00:10:00+00:00 | 600.0 | 0.3352388888888889 |
| aggregated | 2025-08-09T00:20:00+00:00 | 600.0 | 0.0030166666666666666 |
| aggregated | 2025-08-09T00:30:00+00:00 | 600.0 | 0.0029 |
| aggregated | 2025-08-09T00:40:00+00:00 | 600.0 | 0.00285 |
| aggregated | 2025-08-09T00:50:00+00:00 | 600.0 | 0.004675 |
+------------+---------------------------+-------------+-----------------------+
Run the following code:
server_group_id = "7a612ef2-ad1d-49fa-a72d-51253761cdda"
start = "2025-08-09T00:00:00+00:00"
stop = "2025-08-09T01:00:00+00:00"
granularity = 600
gnocchi_client.aggregates.fetch(
operations=[
"/",
[
"/",
["aggregate", "mean", ["metric", "cpu", "rate:mean"]],
["metric", "vcpus", "mean"],
],
1000000000 * granularity,
],
search={
"and": [
{"=": {"server_group": server_group_id}},
{
"and": [
{"<": {"started_at": stop}},
{
"or": [
{">=": {"ended_at": start}},
{"=": {"ended_at": None}},
],
},
],
},
],
},
resource_type="instance",
start=start,
stop=stop,
granularity=granularity,
)
Example output:
>>> server_group_id = "7a612ef2-ad1d-49fa-a72d-51253761cdda"
>>> start = "2025-08-09T00:00:00+00:00"
>>> stop = "2025-08-09T01:00:00+00:00"
>>> granularity = 600
>>> pprint(gnocchi_client.aggregates.fetch(
... operations=[
... "/",
... [
... "/",
... ["aggregate", "mean", ["metric", "cpu", "rate:mean"]],
... ["metric", "vcpus", "mean"],
... ],
... 1000000000 * granularity,
... ],
... search={
... "and": [
... {"=": {"server_group": server_group_id}},
... {
... "and": [
... {"<": {"started_at": stop}},
... {
... "or": [
... {">=": {"ended_at": start}},
... {"=": {"ended_at": None}},
... ],
... },
... ],
... },
... ],
... },
... resource_type="instance",
... start=start,
... stop=stop,
... granularity=granularity,
... ))
{'measures': {'aggregated': [(datetime.datetime(2025, 8, 9, 0, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
600.0,
0.5010833333333333),
(datetime.datetime(2025, 8, 9, 0, 10, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
600.0,
0.3352388888888889),
(datetime.datetime(2025, 8, 9, 0, 20, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
600.0,
0.0030166666666666666),
(datetime.datetime(2025, 8, 9, 0, 30, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
600.0,
0.0029),
(datetime.datetime(2025, 8, 9, 0, 40, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
600.0,
0.00285),
(datetime.datetime(2025, 8, 9, 0, 50, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
600.0,
0.004675)]}}}}
First, save a file containing the request payload.
server_group_id="7a612ef2-ad1d-49fa-a72d-51253761cdda"
start="2025-08-09T00:00:00+00:00"
stop="2025-08-09T01:00:00+00:00"
granularity=600
cat > payload.json << EOF
{
"operations": [
"/",
[
"/",
["aggregate", "mean", ["metric", "cpu", "rate:mean"]],
["metric", "vcpus", "mean"]
],
$(echo "1000000000 * $granularity" | bc)
],
"search": {
"and": [
{"=": {"server_group": "${server_group_id}"}},
{
"and": [
{"<": {"started_at": "${stop}"}},
{
"or": [
{">=": {"ended_at": "${start}"}},
{"=": {"ended_at": null}}
]
}
]
}
]
},
"resource_type": "instance"
}
EOF
Here is what the payload should look like:
{
"operations": [
"/",
[
"/",
["aggregate", "mean", ["metric", "cpu", "rate:mean"]],
["metric", "vcpus", "mean"]
],
600000000000
],
"search": {
"and": [
{"=": {"server_group": "7a612ef2-ad1d-49fa-a72d-51253761cdda"}},
{
"and": [
{"<": {"started_at": "2025-08-09T01:00:00+00:00"}},
{
"or": [
{">=": {"ended_at": "2025-08-09T00:00:00+00:00"}},
{"=": {"ended_at": null}}
]
}
]
}
]
},
"resource_type": "instance"
}
Now, run the command to make the request.
curl -s \
-X POST \
-H "X-Auth-Token: ${OS_TOKEN}" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
https://api.$(echo "${OS_REGION_NAME}" | tr '_' '-').catalystcloud.nz:8041/v1/aggregates \
--url-query "start=${start}" \
--url-query "stop=${stop}" \
--url-query "granularity=${granularity}" \
--data-binary "@payload.json"
Example output:
$ curl -s -X POST -H "X-Auth-Token: ${OS_TOKEN}" -H "Content-Type: application/json" -H "Accept: application/json" https://api.$(echo "${OS_REGION_NAME}" | tr '_' '-').catalystcloud.nz:8041/v1/aggregates --url-query "start=${start}" --url-query "stop=${stop}" --url-query "granularity=${granularity}" --data-binary "@payload.json" | jq
{
"measures": {
"aggregated": [
[
"2025-08-09T00:00:00+00:00",
600.0,
0.5010833333333333
],
[
"2025-08-09T00:10:00+00:00",
600.0,
0.3352388888888889
],
[
"2025-08-09T00:20:00+00:00",
600.0,
0.0030166666666666666
],
[
"2025-08-09T00:30:00+00:00",
600.0,
0.0029
],
[
"2025-08-09T00:40:00+00:00",
600.0,
0.00285
],
[
"2025-08-09T00:50:00+00:00",
600.0,
0.004675
]
]
}
}
In this example we show how to get the 10 minute mean RAM usage of an instance as a decimal percentage (0-1).
The query takes into account the mean amount of memory the instance had in each aggregated datapoint, to allow instance resizes to be handled gracefully.
Here are the commands we will run:
resource_id="af6b97d9-d172-4e06-b565-db1e97097340"
start="2025-08-09T00:00:00+00:00"
stop="2025-08-09T01:00:00+00:00"
granularity=600
openstack metric aggregates --start "${start}" \
--stop "${stop}" \
--resource-type instance \
--granularity ${granularity} \
"(/ (metric memory.usage mean) (metric memory.available mean))" \
"id='${resource_id}'"
With the variables evaluated, this is what it looks like:
openstack metric aggregates --start "2025-08-09T00:00:00+00:00" \
--stop "2025-08-09T01:00:00+00:00" \
--resource-type instance \
--granularity 600 \
"(/ (metric memory.usage mean) (metric memory.available mean))" \
"id='af6b97d9-d172-4e06-b565-db1e97097340'"
Example output:
$ openstack metric aggregates --start "2025-08-09T00:00:00+00:00" --stop "2025-08-09T01:00:00+00:00" --resource-type instance --granularity 600 "(/ (metric memory.usage mean) (metric memory.available mean))" "id=af6b97d9-d172-4e06-b565-db1e97097340"
+------------+---------------------------+-------------+--------------------+
| name | timestamp | granularity | value |
+------------+---------------------------+-------------+--------------------+
| aggregated | 2025-08-09T00:00:00+00:00 | 600.0 | 0.7972831765935214 |
| aggregated | 2025-08-09T00:10:00+00:00 | 600.0 | 0.7983281086729362 |
| aggregated | 2025-08-09T00:20:00+00:00 | 600.0 | 0.7983281086729362 |
| aggregated | 2025-08-09T00:30:00+00:00 | 600.0 | 0.7983281086729362 |
| aggregated | 2025-08-09T00:40:00+00:00 | 600.0 | 0.7983281086729362 |
| aggregated | 2025-08-09T00:50:00+00:00 | 600.0 | 0.7983281086729362 |
+------------+---------------------------+-------------+--------------------+
Run the following code:
resource_id = "af6b97d9-d172-4e06-b565-db1e97097340"
start = "2025-08-09T00:00:00+00:00"
stop = "2025-08-09T01:00:00+00:00"
granularity = 600
gnocchi_client.aggregates.fetch(
operations=[
"/",
["metric", "memory.usage", "mean"],
["metric", "memory.available", "mean"],
],
search={"=": {"id": resource_id}},
resource_type="instance",
start=start,
stop=stop,
granularity=granularity,
)
Example output:
>>> resource_id = "af6b97d9-d172-4e06-b565-db1e97097340"
>>> start = "2025-08-09T00:00:00+00:00"
>>> stop = "2025-08-09T01:00:00+00:00"
>>> granularity = 600
>>> pprint(gnocchi_client.aggregates.fetch(
... operations=[
... "/",
... ["metric", "memory.usage", "mean"],
... ["metric", "memory.available", "mean"],
... ],
... search={"=": {"id": resource_id}},
... resource_type="instance",
... start=start,
... stop=stop,
... granularity=granularity,
... ))
{'measures': {'aggregated': [(datetime.datetime(2025, 8, 9, 0, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
600.0,
0.7972831765935214),
(datetime.datetime(2025, 8, 9, 0, 10, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
600.0,
0.7983281086729362),
(datetime.datetime(2025, 8, 9, 0, 20, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
600.0,
0.7983281086729362),
(datetime.datetime(2025, 8, 9, 0, 30, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
600.0,
0.7983281086729362),
(datetime.datetime(2025, 8, 9, 0, 40, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
600.0,
0.7983281086729362),
(datetime.datetime(2025, 8, 9, 0, 50, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
600.0,
0.7983281086729362)]}}}}
First, save a file containing the request payload.
resource_id="af6b97d9-d172-4e06-b565-db1e97097340"
start="2025-08-09T00:00:00+00:00"
stop="2025-08-09T01:00:00+00:00"
granularity=600
cat > payload.json << EOF
{
"operations": [
"/",
["metric", "memory.usage", "mean"],
["metric", "memory.available", "mean"]
],
"search": {"=": {"id": "${resource_id}"}},
"resource_type": "instance"
}
EOF
Here is what the payload should look like:
{
"operations": [
"/",
["metric", "memory.usage", "mean"],
["metric", "memory.available", "mean"]
],
"search": {"=": {"id": "af6b97d9-d172-4e06-b565-db1e97097340"}},
"resource_type": "instance"
}
Now, run the command to make the request.
curl -s \
-X POST \
-H "X-Auth-Token: ${OS_TOKEN}" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
https://api.$(echo "${OS_REGION_NAME}" | tr '_' '-').catalystcloud.nz:8041/v1/aggregates \
--url-query "start=${start}" \
--url-query "stop=${stop}" \
--url-query "granularity=${granularity}" \
--data-binary "@payload.json"
Example output:
$ curl -s -X POST -H "X-Auth-Token: ${OS_TOKEN}" -H "Content-Type: application/json" -H "Accept: application/json" https://api.$(echo "${OS_REGION_NAME}" | tr '_' '-').catalystcloud.nz:8041/v1/aggregates --url-query "start=${start}" --url-query "stop=${stop}" --url-query "granularity=${granularity}" --data-binary "@payload.json" | jq
{
"measures": {
"aggregated": [
[
"2025-08-09T00:00:00+00:00",
600.0,
0.7972831765935214
],
[
"2025-08-09T00:10:00+00:00",
600.0,
0.7983281086729362
],
[
"2025-08-09T00:20:00+00:00",
600.0,
0.7983281086729362
],
[
"2025-08-09T00:30:00+00:00",
600.0,
0.7983281086729362
],
[
"2025-08-09T00:40:00+00:00",
600.0,
0.7983281086729362
],
[
"2025-08-09T00:50:00+00:00",
600.0,
0.7983281086729362
]
]
}
}
In this example we show how to get the 10 minute mean RAM usage across instances in a server group as a singular decimal percentage (0-1).
The query takes into account the mean amount of memory each instance ran with in each aggregated datapoint, to allow instance resizes to be handled gracefully.
Here are the commands we will run:
server_group_id="7a612ef2-ad1d-49fa-a72d-51253761cdda"
start="2025-08-09T00:00:00+00:00"
stop="2025-08-09T01:00:00+00:00"
granularity=600
openstack metric aggregates --start "${start}" \
--stop "${stop}" \
--resource-type instance \
--granularity ${granularity} \
"(/ (metric memory.usage mean) (metric memory.available mean))" \
"server_group='${server_group_id}' and (started_at<'${stop}' and (ended_at>='${start}' or ended_at=null))"
With the variables evaluated, this is what it looks like:
openstack metric aggregates --start "2025-08-09T00:00:00+00:00" \
--stop "2025-08-09T01:00:00+00:00" \
--resource-type instance \
--granularity 600 \
"(/ (metric memory.usage mean) (metric memory.available mean))" \
"server_group='7a612ef2-ad1d-49fa-a72d-51253761cdda' and (started_at<'2025-08-09T01:00:00+00:00' and (ended_at>='2025-08-09T00:00:00+00:00' or ended_at=null))"
Example output:
$ openstack metric aggregates --start "2025-08-09T00:00:00+00:00" --stop "2025-08-09T01:00:00+00:00" --resource-type instance --granularity 600 "(/ (metric memory.usage mean) (metric memory.available mean))" "server_group='7a612ef2-ad1d-49fa-a72d-51253761cdda' and (started_at<'2025-08-09T01:00:00+00:00' and (ended_at>='2025-08-09T00:00:00+00:00' or ended_at=null))"
+------------+---------------------------+-------------+---------------------+
| name | timestamp | granularity | value |
+------------+---------------------------+-------------+---------------------+
| aggregated | 2025-08-09T00:00:00+00:00 | 600.0 | 0.32466181061394384 |
| aggregated | 2025-08-09T00:10:00+00:00 | 600.0 | 0.32362122788761705 |
| aggregated | 2025-08-09T00:20:00+00:00 | 600.0 | 0.32362122788761705 |
| aggregated | 2025-08-09T00:30:00+00:00 | 600.0 | 0.32362122788761705 |
| aggregated | 2025-08-09T00:40:00+00:00 | 600.0 | 0.32362122788761705 |
| aggregated | 2025-08-09T00:50:00+00:00 | 600.0 | 0.3537981269510926 |
+------------+---------------------------+-------------+---------------------+
Run the following code:
server_group_id = "7a612ef2-ad1d-49fa-a72d-51253761cdda"
start = "2025-08-09T00:00:00+00:00"
stop = "2025-08-09T01:00:00+00:00"
granularity = 600
gnocchi_client.aggregates.fetch(
operations=[
"/",
["metric", "memory.usage", "mean"],
["metric", "memory.available", "mean"],
],
search={
"and": [
{"=": {"server_group": server_group_id}},
{
"and": [
{"<": {"started_at": stop}},
{
"or": [
{">=": {"ended_at": start}},
{"=": {"ended_at": None}},
],
},
],
},
],
},
resource_type="instance",
start=start,
stop=stop,
granularity=granularity,
)
Example output:
>>> server_group_id = "7a612ef2-ad1d-49fa-a72d-51253761cdda"
>>> start = "2025-08-09T00:00:00+00:00"
>>> stop = "2025-08-09T01:00:00+00:00"
>>> granularity = 600
>>> pprint(gnocchi_client.aggregates.fetch(
... operations=[
... "/",
... ["metric", "memory.usage", "mean"],
... ["metric", "memory.available", "mean"],
... ],
... search={
... "and": [
... {"=": {"server_group": server_group_id}},
... {
... "and": [
... {"<": {"started_at": stop}},
... {
... "or": [
... {">=": {"ended_at": start}},
... {"=": {"ended_at": None}},
... ],
... },
... ],
... },
... ],
... },
... resource_type="instance",
... start=start,
... stop=stop,
... granularity=granularity,
... ))
{'measures': {'aggregated': [(datetime.datetime(2025, 8, 9, 0, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
600.0,
0.32466181061394384),
(datetime.datetime(2025, 8, 9, 0, 10, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
600.0,
0.32362122788761705),
(datetime.datetime(2025, 8, 9, 0, 20, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
600.0,
0.32362122788761705),
(datetime.datetime(2025, 8, 9, 0, 30, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
600.0,
0.32362122788761705),
(datetime.datetime(2025, 8, 9, 0, 40, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
600.0,
0.32362122788761705),
(datetime.datetime(2025, 8, 9, 0, 50, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
600.0,
0.3537981269510926)]}}}}
First, save a file containing the request payload.
server_group_id="7a612ef2-ad1d-49fa-a72d-51253761cdda"
start="2025-08-09T00:00:00+00:00"
stop="2025-08-09T01:00:00+00:00"
granularity=600
cat > payload.json << EOF
{
"operations": [
"/",
["metric", "memory.usage", "mean"],
["metric", "memory.available", "mean"]
],
"search": {
"and": [
{"=": {"server_group": "${server_group_id}"}},
{
"and": [
{"<": {"started_at": "${stop}"}},
{
"or": [
{">=": {"ended_at": "${start}"}},
{"=": {"ended_at": null}}
]
}
]
}
]
},
"resource_type": "instance"
}
EOF
Here is what the payload should look like:
{
"operations": [
"/",
["metric", "memory.usage", "mean"],
["metric", "memory.available", "mean"]
],
"search": {
"and": [
{"=": {"server_group": "7a612ef2-ad1d-49fa-a72d-51253761cdda"}},
{
"and": [
{"<": {"started_at": "2025-08-09T01:00:00+00:00"}},
{
"or": [
{">=": {"ended_at": "2025-08-09T00:00:00+00:00"}},
{"=": {"ended_at": null}}
]
}
]
}
]
},
"resource_type": "instance"
}
Now, run the command to make the request.
curl -s \
-X POST \
-H "X-Auth-Token: ${OS_TOKEN}" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
https://api.$(echo "${OS_REGION_NAME}" | tr '_' '-').catalystcloud.nz:8041/v1/aggregates \
--url-query "start=${start}" \
--url-query "stop=${stop}" \
--url-query "granularity=${granularity}" \
--data-binary "@payload.json"
Example output:
$ curl -s -X POST -H "X-Auth-Token: ${OS_TOKEN}" -H "Content-Type: application/json" -H "Accept: application/json" https://api.$(echo "${OS_REGION_NAME}" | tr '_' '-').catalystcloud.nz:8041/v1/aggregates --url-query "start=${start}" --url-query "stop=${stop}" --url-query "granularity=${granularity}" --data-binary "@payload.json" | jq
{
"measures": {
"aggregated": [
[
"2025-08-09T00:00:00+00:00",
600.0,
0.32466181061394384
],
[
"2025-08-09T00:10:00+00:00",
600.0,
0.32362122788761705
],
[
"2025-08-09T00:20:00+00:00",
600.0,
0.32362122788761705
],
[
"2025-08-09T00:30:00+00:00",
600.0,
0.32362122788761705
],
[
"2025-08-09T00:40:00+00:00",
600.0,
0.32362122788761705
],
[
"2025-08-09T00:50:00+00:00",
600.0,
0.3537981269510926
]
]
}
}
In this example we show how get the size of all existing block storage volumes in your project for a given hour.
This kind of request would be useful for plotting the usage trends of each volume in a graph.
Here are the commands we will run:
start="2025-08-09T00:00:00+00:00"
stop="2025-08-09T01:00:00+00:00"
openstack metric aggregates --start "${start}" \
--stop "${stop}" \
--resource-type volume \
--granularity 3600 \
"(metric volume.size max)" \
"started_at<'${stop}' and (ended_at>='${start}' or ended_at=null)"
With the variables evaluated, this is what it looks like:
openstack metric aggregates --start "2025-08-09T00:00:00+00:00" \
--stop "2025-08-09T01:00:00+00:00" \
--resource-type volume \
--granularity 3600 \
"(metric volume.size max)" \
"started_at<'2025-08-09T01:00:00+00:00' and (ended_at>='2025-08-09T00:00:00+00:00' or ended_at=null)"
Example output:
$ openstack metric aggregates --start "2025-08-09T00:00:00+00:00" --stop "2025-08-09T01:00:00+00:00" --resource-type volume --granularity 3600 "(metric volume.size max)" "started_at<'2025-08-09T01:00:00+00:00' and (ended_at>='2025-08-09T00:00:00+00:00' or ended_at=null)"
+------------------------------------------------------+---------------------------+-------------+-------+
| name | timestamp | granularity | value |
+------------------------------------------------------+---------------------------+-------------+-------+
| c8b2efc5-fb26-4bf8-851a-05f141b2f6f5/volume.size/max | 2025-08-09T00:00:00+00:00 | 3600.0 | 10.0 |
| fadcd6d9-5e1f-44ee-9957-f4139f87e437/volume.size/max | 2025-08-09T00:00:00+00:00 | 3600.0 | 1.0 |
+------------------------------------------------------+---------------------------+-------------+-------+
Run the following code:
start = "2025-08-09T00:00:00+00:00"
stop = "2025-08-09T01:00:00+00:00"
gnocchi_client.aggregates.fetch(
operations=["metric", "volume.size", "max"],
search={
"and": [
{"<": {"started_at": stop}},
{
"or": [
{">=": {"ended_at": start}},
{"=": {"ended_at": None}},
],
},
],
},
resource_type="volume",
start=start,
stop=stop,
granularity=3600,
)
Example output:
>>> start = "2025-08-09T00:00:00+00:00"
>>> stop = "2025-08-09T01:00:00+00:00"
>>> pprint(gnocchi_client.aggregates.fetch(
... operations=["metric", "volume.size", "max"],
... search={
... "and": [
... {"<": {"started_at": stop}},
... {
... "or": [
... {">=": {"ended_at": start}},
... {"=": {"ended_at": None}},
... ],
... },
... ],
... },
... resource_type="volume",
... start=start,
... stop=stop,
... granularity=3600,
... ))
{'measures': {'4ee78fdc-6682-4023-8fb1-a9abc70bd8aa': {'volume.size': {'max': [(datetime.datetime(2025, 8, 9, 0, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
10.0)]}},
'fadcd6d9-5e1f-44ee-9957-f4139f87e437': {'volume.size': {'max': [(datetime.datetime(2025, 8, 9, 0, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
1.0)]}}}}
First, save a file containing the request payload.
start="2025-08-09T00:00:00+00:00"
stop="2025-08-09T01:00:00+00:00"
cat > payload.json << EOF
{
"operations": ["metric", "volume.size", "max"],
"search": {
"and": [
{"<": {"started_at": "${stop}"}},
{
"or": [
{">=": {"ended_at": "${start}"}},
{"=": {"ended_at": null}}
]
}
]
},
"resource_type": "volume"
}
EOF
Here is what the payload should look like:
{
"operations": ["metric", "volume.size", "max"],
"search": {
"and": [
{"<": {"started_at": "2025-08-09T01:00:00+00:00"}},
{
"or": [
{">=": {"ended_at": "2025-08-09T00:00:00+00:00"}},
{"=": {"ended_at": null}}
]
}
]
},
"resource_type": "volume"
}
Now, run the command to make the request.
curl -s \
-X POST \
-H "X-Auth-Token: ${OS_TOKEN}" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
https://api.$(echo "${OS_REGION_NAME}" | tr '_' '-').catalystcloud.nz:8041/v1/aggregates \
--url-query "start=${start}" \
--url-query "stop=${stop}" \
--url-query "granularity=3600" \
--data-binary "@payload.json"
Example output:
$ curl -s -X POST -H "X-Auth-Token: ${OS_TOKEN}" -H "Content-Type: application/json" -H "Accept: application/json" https://api.$(echo "${OS_REGION_NAME}" | tr '_' '-').catalystcloud.nz:8041/v1/aggregates --url-query "start=${start}" --url-query "stop=${stop}" --url-query "granularity=3600" --data-binary "@payload.json" | jq
{
"measures": {
"c8b2efc5-fb26-4bf8-851a-05f141b2f6f5": {
"volume.size": {
"max": [
[
"2025-08-09T00:00:00+00:00",
3600.0,
10.0
]
]
}
},
"fadcd6d9-5e1f-44ee-9957-f4139f87e437": {
"volume.size": {
"max": [
[
"2025-08-09T00:00:00+00:00",
3600.0,
1.0
]
]
}
}
}
}
In this example we show how to get the total amount of block storage being consumed in your project on an hourly basis over 1 day as a single figure.
Here are the commands we will run:
start="2025-08-09T00:00:00+00:00"
stop="2025-08-10T00:00:00+00:00"
openstack metric aggregates --start "${start}" \
--stop "${stop}" \
--resource-type volume \
--granularity 3600 \
"(aggregate sum (metric volume.size max))" \
"started_at<'${stop}' and (ended_at>='${start}' or ended_at=null)"
With the variables evaluated, this is what it looks like:
openstack metric aggregates --start "2025-08-09T00:00:00+00:00" \
--stop "2025-08-10T00:00:00+00:00" \
--resource-type volume \
--granularity 3600 \
"(aggregate sum (metric volume.size max))" \
"started_at<'2025-08-10T00:00:00+00:00' and (ended_at>='2025-08-09T00:00:00+00:00' or ended_at=null)"
Example output:
$ openstack metric aggregates --start "2025-08-09T00:00:00+00:00" --stop "2025-08-10T00:00:00+00:00" --resource-type volume --granularity 3600 "(aggregate sum (metric volume.size max))" "started_at<'2025-08-10T00:00:00+00:00' and (ended_at>='2025-08-09T00:00:00+00:00' or ended_at=null)"
+------------+---------------------------+-------------+-------+
| name | timestamp | granularity | value |
+------------+---------------------------+-------------+-------+
| aggregated | 2025-08-09T00:00:00+00:00 | 3600.0 | 81.0 |
| aggregated | 2025-08-09T01:00:00+00:00 | 3600.0 | 81.0 |
| aggregated | 2025-08-09T02:00:00+00:00 | 3600.0 | 81.0 |
| aggregated | 2025-08-09T03:00:00+00:00 | 3600.0 | 81.0 |
| aggregated | 2025-08-09T04:00:00+00:00 | 3600.0 | 81.0 |
| aggregated | 2025-08-09T05:00:00+00:00 | 3600.0 | 81.0 |
| aggregated | 2025-08-09T06:00:00+00:00 | 3600.0 | 81.0 |
| aggregated | 2025-08-09T07:00:00+00:00 | 3600.0 | 81.0 |
| aggregated | 2025-08-09T08:00:00+00:00 | 3600.0 | 81.0 |
| aggregated | 2025-08-09T09:00:00+00:00 | 3600.0 | 81.0 |
| aggregated | 2025-08-09T10:00:00+00:00 | 3600.0 | 81.0 |
| aggregated | 2025-08-09T11:00:00+00:00 | 3600.0 | 81.0 |
| aggregated | 2025-08-09T12:00:00+00:00 | 3600.0 | 81.0 |
| aggregated | 2025-08-09T13:00:00+00:00 | 3600.0 | 81.0 |
| aggregated | 2025-08-09T14:00:00+00:00 | 3600.0 | 81.0 |
| aggregated | 2025-08-09T15:00:00+00:00 | 3600.0 | 81.0 |
| aggregated | 2025-08-09T16:00:00+00:00 | 3600.0 | 81.0 |
| aggregated | 2025-08-09T17:00:00+00:00 | 3600.0 | 81.0 |
| aggregated | 2025-08-09T18:00:00+00:00 | 3600.0 | 81.0 |
| aggregated | 2025-08-09T19:00:00+00:00 | 3600.0 | 81.0 |
| aggregated | 2025-08-09T20:00:00+00:00 | 3600.0 | 81.0 |
| aggregated | 2025-08-09T21:00:00+00:00 | 3600.0 | 81.0 |
| aggregated | 2025-08-09T22:00:00+00:00 | 3600.0 | 84.0 |
| aggregated | 2025-08-09T23:00:00+00:00 | 3600.0 | 84.0 |
+------------+---------------------------+-------------+-------+
Run the following code:
start = "2025-08-09T00:00:00+00:00"
stop = "2025-08-10T00:00:00+00:00"
gnocchi_client.aggregates.fetch(
operations=["aggregate", "sum", ["metric", "volume.size", "max"]],
search={
"and": [
{"<": {"started_at": stop}},
{
"or": [
{">=": {"ended_at": start}},
{"=": {"ended_at": None}},
],
},
],
},
resource_type="volume",
start=start,
stop=stop,
granularity=3600,
)
Example output:
>>> start = "2025-08-09T00:00:00+00:00"
>>> stop = "2025-08-10T00:00:00+00:00"
>>> pprint(gnocchi_client.aggregates.fetch(
... operations=["aggregate", "sum", ["metric", "volume.size", "max"]],
... search={
... "and": [
... {"<": {"started_at": stop}},
... {
... "or": [
... {">=": {"ended_at": start}},
... {"=": {"ended_at": None}},
... ],
... },
... ],
... },
... resource_type="volume",
... start=start,
... stop=stop,
... granularity=3600,
... ))
{'measures': {'aggregated': [(datetime.datetime(2025, 8, 9, 0, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
81.0),
(datetime.datetime(2025, 8, 9, 1, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
81.0),
(datetime.datetime(2025, 8, 9, 2, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
81.0),
(datetime.datetime(2025, 8, 9, 3, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
81.0),
(datetime.datetime(2025, 8, 9, 4, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
81.0),
(datetime.datetime(2025, 8, 9, 5, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
81.0),
(datetime.datetime(2025, 8, 9, 6, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
81.0),
(datetime.datetime(2025, 8, 9, 7, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
81.0),
(datetime.datetime(2025, 8, 9, 8, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
81.0),
(datetime.datetime(2025, 8, 9, 9, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
81.0),
(datetime.datetime(2025, 8, 9, 10, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
81.0),
(datetime.datetime(2025, 8, 9, 11, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
81.0),
(datetime.datetime(2025, 8, 9, 12, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
81.0),
(datetime.datetime(2025, 8, 9, 13, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
81.0),
(datetime.datetime(2025, 8, 9, 14, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
81.0),
(datetime.datetime(2025, 8, 9, 15, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
81.0),
(datetime.datetime(2025, 8, 9, 16, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
81.0),
(datetime.datetime(2025, 8, 9, 17, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
81.0),
(datetime.datetime(2025, 8, 9, 18, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
81.0),
(datetime.datetime(2025, 8, 9, 19, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
81.0),
(datetime.datetime(2025, 8, 9, 20, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
81.0),
(datetime.datetime(2025, 8, 9, 21, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
81.0),
(datetime.datetime(2025, 8, 9, 22, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
84.0),
(datetime.datetime(2025, 8, 9, 23, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
84.0)]}}
First, save a file containing the request payload.
start="2025-08-09T00:00:00+00:00"
stop="2025-08-10T00:00:00+00:00"
cat > payload.json << EOF
{
"operations": ["aggregate", "sum", ["metric", "volume.size", "max"]],
"search": {
"and": [
{"<": {"started_at": "${stop}"}},
{
"or": [
{">=": {"ended_at": "${start}"}},
{"=": {"ended_at": null}}
]
}
]
},
"resource_type": "volume"
}
EOF
Here is what the payload should look like:
{
"operations": ["aggregate", "sum", ["metric", "volume.size", "max"]],
"search": {
"and": [
{"<": {"started_at": "2025-08-10T00:00:00+00:00"}},
{
"or": [
{">=": {"ended_at": "2025-08-09T00:00:00+00:00"}},
{"=": {"ended_at": null}}
]
}
]
},
"resource_type": "volume"
}
Now, run the command to make the request.
curl -s \
-X POST \
-H "X-Auth-Token: ${OS_TOKEN}" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
https://api.$(echo "${OS_REGION_NAME}" | tr '_' '-').catalystcloud.nz:8041/v1/aggregates \
--url-query "start=${start}" \
--url-query "stop=${stop}" \
--url-query "granularity=3600" \
--data-binary "@payload.json"
Example output:
$ curl -s -X POST -H "X-Auth-Token: ${OS_TOKEN}" -H "Content-Type: application/json" -H "Accept: application/json" https://api.$(echo "${OS_REGION_NAME}" | tr '_' '-').catalystcloud.nz:8041/v1/aggregates --url-query "start=${start}" --url-query "stop=${stop}" --url-query "granularity=3600" --data-binary "@payload.json" | jq
{
"measures": {
"aggregated": [
[
"2025-08-09T00:00:00+00:00",
3600.0,
81.0
],
[
"2025-08-09T01:00:00+00:00",
3600.0,
81.0
],
[
"2025-08-09T02:00:00+00:00",
3600.0,
81.0
],
[
"2025-08-09T03:00:00+00:00",
3600.0,
81.0
],
[
"2025-08-09T04:00:00+00:00",
3600.0,
81.0
],
[
"2025-08-09T05:00:00+00:00",
3600.0,
81.0
],
[
"2025-08-09T06:00:00+00:00",
3600.0,
81.0
],
[
"2025-08-09T07:00:00+00:00",
3600.0,
81.0
],
[
"2025-08-09T08:00:00+00:00",
3600.0,
81.0
],
[
"2025-08-09T09:00:00+00:00",
3600.0,
81.0
],
[
"2025-08-09T10:00:00+00:00",
3600.0,
81.0
],
[
"2025-08-09T11:00:00+00:00",
3600.0,
81.0
],
[
"2025-08-09T12:00:00+00:00",
3600.0,
81.0
],
[
"2025-08-09T13:00:00+00:00",
3600.0,
81.0
],
[
"2025-08-09T14:00:00+00:00",
3600.0,
81.0
],
[
"2025-08-09T15:00:00+00:00",
3600.0,
81.0
],
[
"2025-08-09T16:00:00+00:00",
3600.0,
81.0
],
[
"2025-08-09T17:00:00+00:00",
3600.0,
81.0
],
[
"2025-08-09T18:00:00+00:00",
3600.0,
81.0
],
[
"2025-08-09T19:00:00+00:00",
3600.0,
81.0
],
[
"2025-08-09T20:00:00+00:00",
3600.0,
81.0
],
[
"2025-08-09T21:00:00+00:00",
3600.0,
81.0
],
[
"2025-08-09T22:00:00+00:00",
3600.0,
84.0
],
[
"2025-08-09T23:00:00+00:00",
3600.0,
84.0
]
]
}
}
Similar to block storage, aggregated metrics can be retrieved for object storage containers.
In this example we show how to get the total amount of object storage being consumed in your project on an hourly basis over 1 day as a single figure.
Here are the commands we will run:
start="2025-08-09T00:00:00+00:00"
stop="2025-08-10T00:00:00+00:00"
openstack metric aggregates --start "${start}" \
--stop "${stop}" \
--resource-type swift_account \
--granularity 3600 \
"(aggregate sum (metric storage.containers.objects.size max))" \
"started_at<'${stop}' and (ended_at>='${start}' or ended_at=null)"
With the variables evaluated, this is what it looks like:
openstack metric aggregates --start "2025-08-09T00:00:00+00:00" \
--stop "2025-08-10T00:00:00+00:00" \
--resource-type swift_account \
--granularity 3600 \
"(aggregate sum (metric storage.containers.objects.size max))" \
"started_at<'2025-08-10T00:00:00+00:00' and (ended_at>='2025-08-09T00:00:00+00:00' or ended_at=null)"
Example output:
$ openstack metric aggregates --start "2025-08-09T00:00:00+00:00" --stop "2025-08-10T00:00:00+00:00" --resource-type swift_account --granularity 3600 "(aggregate sum (metric storage.containers.objects.size max))" "started_at<'2025-08-10T00:00:00+00:00' and (ended_at>='2025-08-09T00:00:00+00:00' or ended_at=null)"
+------------+---------------------------+-------------+-----------+
| name | timestamp | granularity | value |
+------------+---------------------------+-------------+-----------+
| aggregated | 2025-08-09T00:00:00+00:00 | 3600.0 | 3903428.0 |
| aggregated | 2025-08-09T01:00:00+00:00 | 3600.0 | 3903428.0 |
| aggregated | 2025-08-09T02:00:00+00:00 | 3600.0 | 3903428.0 |
| aggregated | 2025-08-09T03:00:00+00:00 | 3600.0 | 3903428.0 |
| aggregated | 2025-08-09T04:00:00+00:00 | 3600.0 | 3903428.0 |
| aggregated | 2025-08-09T05:00:00+00:00 | 3600.0 | 3903428.0 |
| aggregated | 2025-08-09T06:00:00+00:00 | 3600.0 | 3903428.0 |
| aggregated | 2025-08-09T07:00:00+00:00 | 3600.0 | 3903428.0 |
| aggregated | 2025-08-09T08:00:00+00:00 | 3600.0 | 3903428.0 |
| aggregated | 2025-08-09T09:00:00+00:00 | 3600.0 | 3903428.0 |
| aggregated | 2025-08-09T10:00:00+00:00 | 3600.0 | 3903428.0 |
| aggregated | 2025-08-09T11:00:00+00:00 | 3600.0 | 3903428.0 |
| aggregated | 2025-08-09T12:00:00+00:00 | 3600.0 | 4837251.0 |
| aggregated | 2025-08-09T13:00:00+00:00 | 3600.0 | 4837251.0 |
| aggregated | 2025-08-09T14:00:00+00:00 | 3600.0 | 4837251.0 |
| aggregated | 2025-08-09T15:00:00+00:00 | 3600.0 | 4837251.0 |
| aggregated | 2025-08-09T16:00:00+00:00 | 3600.0 | 4837251.0 |
| aggregated | 2025-08-09T17:00:00+00:00 | 3600.0 | 4837251.0 |
| aggregated | 2025-08-09T18:00:00+00:00 | 3600.0 | 4837251.0 |
| aggregated | 2025-08-09T19:00:00+00:00 | 3600.0 | 4837251.0 |
| aggregated | 2025-08-09T20:00:00+00:00 | 3600.0 | 5912424.0 |
| aggregated | 2025-08-09T21:00:00+00:00 | 3600.0 | 5912424.0 |
| aggregated | 2025-08-09T22:00:00+00:00 | 3600.0 | 5912424.0 |
| aggregated | 2025-08-09T23:00:00+00:00 | 3600.0 | 5912424.0 |
+------------+---------------------------+-------------+-----------+
Run the following code:
start = "2025-08-09T00:00:00+00:00"
stop = "2025-08-10T00:00:00+00:00"
gnocchi_client.aggregates.fetch(
operations=["aggregate", "sum", ["metric", "storage.containers.objects.size", "max"]],
search={
"and": [
{"<": {"started_at": stop}},
{
"or": [
{">=": {"ended_at": start}},
{"=": {"ended_at": None}},
],
},
],
},
resource_type="swift_account",
start=start,
stop=stop,
granularity=3600,
)
Example output:
>>> start = "2025-08-09T00:00:00+00:00"
>>> stop = "2025-08-10T00:00:00+00:00"
>>> pprint(gnocchi_client.aggregates.fetch(
... operations=["aggregate", "sum", ["metric", "storage.containers.objects.size", "max"]],
... search={
... "and": [
... {"<": {"started_at": stop}},
... {
... "or": [
... {">=": {"ended_at": start}},
... {"=": {"ended_at": None}},
... ],
... },
... ],
... },
... resource_type="swift_account",
... start=start,
... stop=stop,
... granularity=3600,
... ))
{'measures': {'aggregated': [(datetime.datetime(2025, 8, 9, 0, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
3903428.0),
(datetime.datetime(2025, 8, 9, 1, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
3903428.0),
(datetime.datetime(2025, 8, 9, 2, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
3903428.0),
(datetime.datetime(2025, 8, 9, 3, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
3903428.0),
(datetime.datetime(2025, 8, 9, 4, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
3903428.0),
(datetime.datetime(2025, 8, 9, 5, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
3903428.0),
(datetime.datetime(2025, 8, 9, 6, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
3903428.0),
(datetime.datetime(2025, 8, 9, 7, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
3903428.0),
(datetime.datetime(2025, 8, 9, 8, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
3903428.0),
(datetime.datetime(2025, 8, 9, 9, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
3903428.0),
(datetime.datetime(2025, 8, 9, 10, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
3903428.0),
(datetime.datetime(2025, 8, 9, 11, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
3903428.0),
(datetime.datetime(2025, 8, 9, 12, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
4837251.0),
(datetime.datetime(2025, 8, 9, 13, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
4837251.0),
(datetime.datetime(2025, 8, 9, 14, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
4837251.0),
(datetime.datetime(2025, 8, 9, 15, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
4837251.0),
(datetime.datetime(2025, 8, 9, 16, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
4837251.0),
(datetime.datetime(2025, 8, 9, 17, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
4837251.0),
(datetime.datetime(2025, 8, 9, 18, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
4837251.0),
(datetime.datetime(2025, 8, 9, 19, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
4837251.0),
(datetime.datetime(2025, 8, 9, 20, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
5912424.0),
(datetime.datetime(2025, 8, 9, 21, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
5912424.0),
(datetime.datetime(2025, 8, 9, 22, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
5912424.0),
(datetime.datetime(2025, 8, 9, 23, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
5912424.0)]}}
First, save a file containing the request payload.
start="2025-08-09T00:00:00+00:00"
stop="2025-08-10T00:00:00+00:00"
cat > payload.json << EOF
{
"operations": ["aggregate", "sum", ["metric", "storage.containers.objects.size", "max"]],
"search": {
"and": [
{"<": {"started_at": "${stop}"}},
{
"or": [
{">=": {"ended_at": "${start}"}},
{"=": {"ended_at": null}}
]
}
]
},
"resource_type": "swift_account"
}
EOF
Here is what the payload should look like:
{
"operations": ["aggregate", "sum", ["metric", "storage.containers.objects.size", "max"]],
"search": {
"and": [
{"<": {"started_at": "2025-08-10T00:00:00+00:00"}},
{
"or": [
{">=": {"ended_at": "2025-08-09T00:00:00+00:00"}},
{"=": {"ended_at": null}}
]
}
]
},
"resource_type": "swift_account"
}
Now, run the command to make the request.
curl -s \
-X POST \
-H "X-Auth-Token: ${OS_TOKEN}" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
https://api.$(echo "${OS_REGION_NAME}" | tr '_' '-').catalystcloud.nz:8041/v1/aggregates \
--url-query "start=${start}" \
--url-query "stop=${stop}" \
--url-query "granularity=3600" \
--data-binary "@payload.json"
Example output:
$ curl -s -X POST -H "X-Auth-Token: ${OS_TOKEN}" -H "Content-Type: application/json" -H "Accept: application/json" https://api.$(echo "${OS_REGION_NAME}" | tr '_' '-').catalystcloud.nz:8041/v1/aggregates --url-query "start=${start}" --url-query "stop=${stop}" --url-query "granularity=3600" --data-binary "@payload.json" | jq
{
"measures": {
"aggregated": [
[
"2025-08-09T00:00:00+00:00",
3600.0,
3903428.0
],
[
"2025-08-09T01:00:00+00:00",
3600.0,
3903428.0
],
[
"2025-08-09T02:00:00+00:00",
3600.0,
3903428.0
],
[
"2025-08-09T03:00:00+00:00",
3600.0,
3903428.0
],
[
"2025-08-09T04:00:00+00:00",
3600.0,
3903428.0
],
[
"2025-08-09T05:00:00+00:00",
3600.0,
3903428.0
],
[
"2025-08-09T06:00:00+00:00",
3600.0,
3903428.0
],
[
"2025-08-09T07:00:00+00:00",
3600.0,
3903428.0
],
[
"2025-08-09T08:00:00+00:00",
3600.0,
3903428.0
],
[
"2025-08-09T09:00:00+00:00",
3600.0,
3903428.0
],
[
"2025-08-09T10:00:00+00:00",
3600.0,
3903428.0
],
[
"2025-08-09T11:00:00+00:00",
3600.0,
3903428.0
],
[
"2025-08-09T12:00:00+00:00",
3600.0,
4837251.0
],
[
"2025-08-09T13:00:00+00:00",
3600.0,
4837251.0
],
[
"2025-08-09T14:00:00+00:00",
3600.0,
4837251.0
],
[
"2025-08-09T15:00:00+00:00",
3600.0,
4837251.0
],
[
"2025-08-09T16:00:00+00:00",
3600.0,
4837251.0
],
[
"2025-08-09T17:00:00+00:00",
3600.0,
4837251.0
],
[
"2025-08-09T18:00:00+00:00",
3600.0,
4837251.0
],
[
"2025-08-09T19:00:00+00:00",
3600.0,
4837251.0
],
[
"2025-08-09T20:00:00+00:00",
3600.0,
5912424.0
],
[
"2025-08-09T21:00:00+00:00",
3600.0,
5912424.0
],
[
"2025-08-09T22:00:00+00:00",
3600.0,
5912424.0
],
[
"2025-08-09T23:00:00+00:00",
3600.0,
5912424.0
]
]
}
}
When performing aggregate queries, requests are normally made for a specific resource type, so to perform queries for multiple resource types you would need to make multiple requests.
By using the special generic resource type you can perform aggregate queries
across multiple resource types, even across different metrics. This allows you to
get all the metrics you need in a single request, improving performance and saving
bandwidth and round trips.
Note
When performing aggregate API queries
with resource details,
you do not get any metadata specific to certain resource types when using
the generic type.
If you require both detailed resource metadata and aggregates, you will need to do one query per resource type.
In this example we show how to get the total outbound inter-region/Internet network across routers and floating IPs, and object storage traffic for containers, in a single aggregated time series.
Here are the commands we will run:
start="2025-08-09T00:00:00+00:00"
stop="2025-08-10T00:00:00+00:00"
openstack metric aggregates --start "${start}" \
--stop "${stop}" \
--resource-type generic \
--granularity 3600 \
"(aggregate sum (metric (router.traffic.outbound.interregion sum) (router.traffic.outbound.internet sum) (ip.floating.traffic.outbound.interregion sum) (ip.floating.traffic.outbound.internet sum) (storage.objects.download.size.interregion sum) (storage.objects.download.size.internet sum)))" \
"started_at<'${stop}' and (ended_at>='${start}' or ended_at=null)"
With the variables evaluated, this is what it looks like:
openstack metric aggregates --start "2025-08-09T00:00:00+00:00" \
--stop "2025-08-10T00:00:00+00:00" \
--resource-type generic \
--granularity 3600 \
"(aggregate sum (metric (router.traffic.outbound.interregion sum) (router.traffic.outbound.internet sum) (ip.floating.traffic.outbound.interregion sum) (ip.floating.traffic.outbound.internet sum) (storage.objects.download.size.interregion sum) (storage.objects.download.size.internet sum)))" \
"started_at<'2025-08-10T00:00:00+00:00' and (ended_at>='2025-08-09T00:00:00+00:00' or ended_at=null)"
Example output:
$ openstack metric aggregates --start "2025-08-09T00:00:00+00:00" --stop "2025-08-10T00:00:00+00:00" --resource-type generic --granularity 3600 "(aggregate sum (metric (router.traffic.outbound.interregion sum) (router.traffic.outbound.internet sum) (ip.floating.traffic.outbound.interregion sum) (ip.floating.traffic.outbound.internet sum) (storage.objects.download.size.interregion sum) (storage.objects.download.size.internet sum)))" "started_at<'2025-08-10T00:00:00+00:00' and (ended_at>='2025-08-09T00:00:00+00:00' or ended_at=null)"
+------------+---------------------------+-------------+-----------+
| name | timestamp | granularity | value |
+------------+---------------------------+-------------+-----------+
| aggregated | 2025-08-09T00:00:00+00:00 | 3600.0 | 4410824.0 |
| aggregated | 2025-08-09T01:00:00+00:00 | 3600.0 | 3977323.0 |
| aggregated | 2025-08-09T02:00:00+00:00 | 3600.0 | 3919881.0 |
| aggregated | 2025-08-09T03:00:00+00:00 | 3600.0 | 4223212.0 |
| aggregated | 2025-08-09T04:00:00+00:00 | 3600.0 | 4319391.0 |
| aggregated | 2025-08-09T05:00:00+00:00 | 3600.0 | 4019030.0 |
| aggregated | 2025-08-09T06:00:00+00:00 | 3600.0 | 4251845.0 |
| aggregated | 2025-08-09T07:00:00+00:00 | 3600.0 | 4036213.0 |
| aggregated | 2025-08-09T08:00:00+00:00 | 3600.0 | 4241722.0 |
| aggregated | 2025-08-09T09:00:00+00:00 | 3600.0 | 4230418.0 |
| aggregated | 2025-08-09T10:00:00+00:00 | 3600.0 | 4111389.0 |
| aggregated | 2025-08-09T11:00:00+00:00 | 3600.0 | 4027456.0 |
| aggregated | 2025-08-09T12:00:00+00:00 | 3600.0 | 4447734.0 |
| aggregated | 2025-08-09T13:00:00+00:00 | 3600.0 | 4045877.0 |
| aggregated | 2025-08-09T14:00:00+00:00 | 3600.0 | 3950913.0 |
| aggregated | 2025-08-09T15:00:00+00:00 | 3600.0 | 4237583.0 |
| aggregated | 2025-08-09T16:00:00+00:00 | 3600.0 | 4186324.0 |
| aggregated | 2025-08-09T17:00:00+00:00 | 3600.0 | 3974627.0 |
| aggregated | 2025-08-09T18:00:00+00:00 | 3600.0 | 4111303.0 |
| aggregated | 2025-08-09T19:00:00+00:00 | 3600.0 | 3985836.0 |
| aggregated | 2025-08-09T20:00:00+00:00 | 3600.0 | 4224432.0 |
| aggregated | 2025-08-09T21:00:00+00:00 | 3600.0 | 4215721.0 |
| aggregated | 2025-08-09T22:00:00+00:00 | 3600.0 | 4044900.0 |
| aggregated | 2025-08-09T23:00:00+00:00 | 3600.0 | 3973582.0 |
+------------+---------------------------+-------------+-----------+
Run the following code:
start = "2025-08-09T00:00:00+00:00"
stop = "2025-08-10T00:00:00+00:00"
gnocchi_client.aggregates.fetch(
operations=[
"aggregate",
"sum",
[
"metric",
["router.traffic.outbound.interregion", "sum"],
["router.traffic.outbound.internet", "sum"],
["ip.floating.traffic.outbound.interregion", "sum"],
["ip.floating.traffic.outbound.internet", "sum"],
["storage.objects.download.size.interregion", "sum"],
["storage.objects.download.size.internet", "sum"],
],
],
search={
"and": [
{"<": {"started_at": stop}},
{
"or": [
{">=": {"ended_at": start}},
{"=": {"ended_at": None}},
],
},
],
},
resource_type="generic",
start=start,
stop=stop,
granularity=3600,
)
Example output:
>>> start = "2025-08-09T00:00:00+00:00"
>>> stop = "2025-08-10T00:00:00+00:00"
>>> gnocchi_client.aggregates.fetch(
... operations=[
... "aggregate",
... "sum",
... [
... "metric",
... ["router.traffic.outbound.interregion", "sum"],
... ["router.traffic.outbound.internet", "sum"],
... ["ip.floating.traffic.outbound.interregion", "sum"],
... ["ip.floating.traffic.outbound.internet", "sum"],
... ["storage.objects.download.size.interregion", "sum"],
... ["storage.objects.download.size.internet", "sum"],
... ],
... ],
... search={
... "and": [
... {"<": {"started_at": stop}},
... {
... "or": [
... {">=": {"ended_at": start}},
... {"=": {"ended_at": None}},
... ],
... },
... ],
... },
... resource_type="generic",
... start=start,
... stop=stop,
... granularity=3600,
... )
{'measures': {'aggregated': [(datetime.datetime(2025, 8, 9, 0, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
4410824.0),
(datetime.datetime(2025, 8, 9, 1, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
3977323.0),
(datetime.datetime(2025, 8, 9, 2, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
3919881.0),
(datetime.datetime(2025, 8, 9, 3, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
4223212.0),
(datetime.datetime(2025, 8, 9, 4, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
4319391.0),
(datetime.datetime(2025, 8, 9, 5, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
4019030.0),
(datetime.datetime(2025, 8, 9, 6, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
4251845.0),
(datetime.datetime(2025, 8, 9, 7, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
4036213.0),
(datetime.datetime(2025, 8, 9, 8, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
4241722.0),
(datetime.datetime(2025, 8, 9, 9, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
4230418.0),
(datetime.datetime(2025, 8, 9, 10, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
4111389.0),
(datetime.datetime(2025, 8, 9, 11, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
4027456.0),
(datetime.datetime(2025, 8, 9, 12, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
4447734.0),
(datetime.datetime(2025, 8, 9, 13, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
4045877.0),
(datetime.datetime(2025, 8, 9, 14, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
3950913.0),
(datetime.datetime(2025, 8, 9, 15, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
4237583.0),
(datetime.datetime(2025, 8, 9, 16, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
4186324.0),
(datetime.datetime(2025, 8, 9, 17, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
3974627.0),
(datetime.datetime(2025, 8, 9, 18, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
4111303.0),
(datetime.datetime(2025, 8, 9, 19, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
3985836.0),
(datetime.datetime(2025, 8, 9, 20, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
4224432.0),
(datetime.datetime(2025, 8, 9, 21, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
4215721.0),
(datetime.datetime(2025, 8, 9, 22, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
4044900.0),
(datetime.datetime(2025, 8, 9, 23, 0, tzinfo=datetime.timezone(datetime.timedelta(0), '+00:00')),
3600.0,
3973582.0)]}}
First, save a file containing the request payload.
start="2025-08-09T00:00:00+00:00"
stop="2025-08-10T00:00:00+00:00"
cat > payload.json << EOF
{
"operations": [
"aggregate",
"sum",
[
"metric",
["router.traffic.outbound.interregion", "sum"],
["router.traffic.outbound.internet", "sum"],
["ip.floating.traffic.outbound.interregion", "sum"],
["ip.floating.traffic.outbound.internet", "sum"],
["storage.objects.download.size.interregion", "sum"],
["storage.objects.download.size.internet", "sum"]
]
],
"search": {
"and": [
{"<": {"started_at": "${stop}"}},
{
"or": [
{">=": {"ended_at": "${start}"}},
{"=": {"ended_at": null}}
]
}
]
},
"resource_type": "generic"
}
EOF
Here is what the payload should look like:
{
"operations": [
"aggregate",
"sum",
[
"metric",
["router.traffic.outbound.interregion", "sum"],
["router.traffic.outbound.internet", "sum"],
["ip.floating.traffic.outbound.interregion", "sum"],
["ip.floating.traffic.outbound.internet", "sum"],
["storage.objects.download.size.interregion", "sum"],
["storage.objects.download.size.internet", "sum"]
]
],
"search": {
"and": [
{"<": {"started_at": "2025-08-10T00:00:00+00:00"}},
{
"or": [
{">=": {"ended_at": "2025-08-09T00:00:00+00:00"}},
{"=": {"ended_at": null}}
]
}
]
},
"resource_type": "generic"
}
Now, run the command to make the request.
curl -s \
-X POST \
-H "X-Auth-Token: ${OS_TOKEN}" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
https://api.$(echo "${OS_REGION_NAME}" | tr '_' '-').catalystcloud.nz:8041/v1/aggregates \
--url-query "start=${start}" \
--url-query "stop=${stop}" \
--url-query "granularity=3600" \
--data-binary "@payload.json"
Example output:
$ curl -s -X POST -H "X-Auth-Token: ${OS_TOKEN}" -H "Content-Type: application/json" -H "Accept: application/json" https://api.$(echo "${OS_REGION_NAME}" | tr '_' '-').catalystcloud.nz:8041/v1/aggregates --url-query "start=${start}" --url-query "stop=${stop}" --url-query "granularity=3600" --data-binary "@payload.json" | jq
{
"measures": {
"aggregated": [
[
"2025-08-09T00:00:00+00:00",
3600.0,
4410824.0
],
[
"2025-08-09T01:00:00+00:00",
3600.0,
3977323.0
],
[
"2025-08-09T02:00:00+00:00",
3600.0,
3919881.0
],
[
"2025-08-09T03:00:00+00:00",
3600.0,
4223212.0
],
[
"2025-08-09T04:00:00+00:00",
3600.0,
4319391.0
],
[
"2025-08-09T05:00:00+00:00",
3600.0,
4019030.0
],
[
"2025-08-09T06:00:00+00:00",
3600.0,
4251845.0
],
[
"2025-08-09T07:00:00+00:00",
3600.0,
4036213.0
],
[
"2025-08-09T08:00:00+00:00",
3600.0,
4241722.0
],
[
"2025-08-09T09:00:00+00:00",
3600.0,
4230418.0
],
[
"2025-08-09T10:00:00+00:00",
3600.0,
4111389.0
],
[
"2025-08-09T11:00:00+00:00",
3600.0,
4027456.0
],
[
"2025-08-09T12:00:00+00:00",
3600.0,
4447734.0
],
[
"2025-08-09T13:00:00+00:00",
3600.0,
4045877.0
],
[
"2025-08-09T14:00:00+00:00",
3600.0,
3950913.0
],
[
"2025-08-09T15:00:00+00:00",
3600.0,
4237583.0
],
[
"2025-08-09T16:00:00+00:00",
3600.0,
4186324.0
],
[
"2025-08-09T17:00:00+00:00",
3600.0,
3974627.0
],
[
"2025-08-09T18:00:00+00:00",
3600.0,
4111303.0
],
[
"2025-08-09T19:00:00+00:00",
3600.0,
3985836.0
],
[
"2025-08-09T20:00:00+00:00",
3600.0,
4224432.0
],
[
"2025-08-09T21:00:00+00:00",
3600.0,
4215721.0
],
[
"2025-08-09T22:00:00+00:00",
3600.0,
4044900.0
],
[
"2025-08-09T23:00:00+00:00",
3600.0,
3973582.0
]
]
}
}