diff --git a/docs/resources/integration.md b/docs/resources/integration.md
new file mode 100644
index 000000000..c34db344a
--- /dev/null
+++ b/docs/resources/integration.md
@@ -0,0 +1,123 @@
+---
+# generated by https://github.com/hashicorp/terraform-plugin-docs
+page_title: "grafana_integration Resource - terraform-provider-grafana"
+subcategory: "Cloud"
+description: |-
+ Manages Grafana Cloud integrations.
+ Official documentation https://grafana.com/docs/grafana-cloud/data-configuration/integrations/
+ Required access policy scopes:
+ folders:readfolders:writedashboards:readdashboards:write
+ Note: This resource creates folders and dashboards as part of the integration installation process, which requires additional permissions beyond the basic integration scopes.
+---
+
+# grafana_integration (Resource)
+
+Manages Grafana Cloud integrations.
+
+* [Official documentation](https://grafana.com/docs/grafana-cloud/data-configuration/integrations/)
+
+Required access policy scopes:
+
+* folders:read
+* folders:write
+* dashboards:read
+* dashboards:write
+
+**Note:** This resource creates folders and dashboards as part of the integration installation process, which requires additional permissions beyond the basic integration scopes.
+
+## Example Usage
+
+```terraform
+# Install Docker integration with logs and alerts enabled
+resource "grafana_integration" "docker" {
+ slug = "docker"
+
+ configuration {
+ configurable_logs {
+ logs_disabled = false
+ }
+ configurable_alerts {
+ alerts_disabled = false
+ }
+ }
+}
+
+# Install Linux Node integration with logs enabled but alerts disabled
+resource "grafana_integration" "linux_node" {
+ slug = "linux-node"
+
+ configuration {
+ configurable_logs {
+ logs_disabled = false
+ }
+ configurable_alerts {
+ alerts_disabled = true
+ }
+ }
+}
+
+# Install Windows integration with minimal configuration
+resource "grafana_integration" "windows" {
+ slug = "windows-exporter"
+}
+
+# Output integration information
+output "docker_integration" {
+ value = {
+ name = grafana_integration.docker.name
+ version = grafana_integration.docker.version
+ installed = grafana_integration.docker.installed
+ dashboard_folder = grafana_integration.docker.dashboard_folder
+ }
+}
+```
+
+
+## Schema
+
+### Required
+
+- `slug` (String) The slug of the integration to install (e.g., 'docker', 'linux-node').
+
+### Optional
+
+- `configuration` (Block List, Max: 1) Configuration options for the integration. (see [below for nested schema](#nestedblock--configuration))
+
+### Read-Only
+
+- `dashboard_folder` (String) The dashboard folder associated with this integration.
+- `id` (String) The ID of this resource.
+- `installed` (Boolean) Whether the integration is currently installed.
+- `name` (String) The display name of the integration.
+- `version` (String) The version of the installed integration.
+
+
+### Nested Schema for `configuration`
+
+Optional:
+
+- `configurable_alerts` (Block List, Max: 1) Alerts configuration for the integration. (see [below for nested schema](#nestedblock--configuration--configurable_alerts))
+- `configurable_logs` (Block List, Max: 1) Logs configuration for the integration. (see [below for nested schema](#nestedblock--configuration--configurable_logs))
+
+
+### Nested Schema for `configuration.configurable_alerts`
+
+Optional:
+
+- `alerts_disabled` (Boolean) Whether to disable alerts for this integration. Defaults to `false`.
+
+
+
+### Nested Schema for `configuration.configurable_logs`
+
+Optional:
+
+- `logs_disabled` (Boolean) Whether to disable logs collection for this integration. Defaults to `false`.
+
+## Import
+
+Import is supported using the following syntax:
+
+```shell
+terraform import grafana_integration.name "{{ slug }}"
+```
diff --git a/examples/resources/grafana_integration/import.sh b/examples/resources/grafana_integration/import.sh
new file mode 100644
index 000000000..07389126f
--- /dev/null
+++ b/examples/resources/grafana_integration/import.sh
@@ -0,0 +1 @@
+terraform import grafana_integration.name "{{ slug }}"
diff --git a/examples/resources/grafana_integration/resource.tf b/examples/resources/grafana_integration/resource.tf
new file mode 100644
index 000000000..4db78c6bf
--- /dev/null
+++ b/examples/resources/grafana_integration/resource.tf
@@ -0,0 +1,42 @@
+# Install Docker integration with logs and alerts enabled
+resource "grafana_integration" "docker" {
+ slug = "docker"
+
+ configuration {
+ configurable_logs {
+ logs_disabled = false
+ }
+ configurable_alerts {
+ alerts_disabled = false
+ }
+ }
+}
+
+# Install Linux Node integration with logs enabled but alerts disabled
+resource "grafana_integration" "linux_node" {
+ slug = "linux-node"
+
+ configuration {
+ configurable_logs {
+ logs_disabled = false
+ }
+ configurable_alerts {
+ alerts_disabled = true
+ }
+ }
+}
+
+# Install Windows integration with minimal configuration
+resource "grafana_integration" "windows" {
+ slug = "windows-exporter"
+}
+
+# Output integration information
+output "docker_integration" {
+ value = {
+ name = grafana_integration.docker.name
+ version = grafana_integration.docker.version
+ installed = grafana_integration.docker.installed
+ dashboard_folder = grafana_integration.docker.dashboard_folder
+ }
+}
diff --git a/internal/common/resource.go b/internal/common/resource.go
index 6b5b323e7..bbd35b5cf 100644
--- a/internal/common/resource.go
+++ b/internal/common/resource.go
@@ -27,6 +27,7 @@ var (
CategoryFleetManagement ResourceCategory = "Fleet Management"
CategoryFrontendO11y ResourceCategory = "Frontend Observability"
CategoryK6 ResourceCategory = "k6"
+ CategoryIntegration ResourceCategory = "Integration"
)
type ResourceCommon struct {
diff --git a/internal/resources/integrations/api-quick-doc.md b/internal/resources/integrations/api-quick-doc.md
new file mode 100644
index 000000000..1c92101e2
--- /dev/null
+++ b/internal/resources/integrations/api-quick-doc.md
@@ -0,0 +1,96 @@
+base path: ``
+
+
+# List integrations
+- method GET
+- path /grafana-easystart-app/integrations-api-editor/integrations
+- parameters:
+ - `installed=true` for only the installed one
+- expected:
+ - code 200
+ - example body:
+ ```
+ {"data":{"docker":{"name":"Docker","slug":"docker","version":"1.3.4","overview":"Docker is a popular open-source platform that enables developers to create, deploy, and run applications in a virtualized environment called a container. It allows developers to package an application with all its dependencies, libraries, and other components required to run it, into a single container image. The Docker integration collects metrics and logs from a Docker instance and provides useful pre-built dashboards to monitor them. \n\n**Links** \n[Docker mixin](https://github.com/grafana/jsonnet-libs/tree/master/docker-mixin) \n[Docker docs](https://grafana.com/docs/grafana-cloud/data-configuration/integrations/integration-reference/integration-docker/) \n","logo":{"dark_theme_url":"https://storage.googleapis.com/grafanalabs-integration-logos/docker.png","light_theme_url":"https://storage.googleapis.com/grafanalabs-integration-logos/docker.png"},"type":"agent","installation":{"version":"1.3.4","installed_on":"2025-03-28T18:26:54Z"},"search_keywords":["container","deployment","docker"],"categories":["Servers and VMs"],"dashboard_folder":"Integration - Docker","has_update":false,"metrics_check_query":"","logs_check_query":"","rule_namespace":"integrations-docker"},"linux-node":{"name":"Linux Server","slug":"linux-node","version":"1.6.1","overview":"Linux is a family of open-source Unix-like operating systems based on the Linux kernel. Linux is the leading operating system on servers, and is one of the most prominent examples of free and open-source software collaboration.\n\nLinux Server integration for Grafana Cloud enables you to collect metrics related to the operating system running on a node, including aspects like CPU usage, load average, memory usage, and disk and networking I/O using node_exporter integration. It also allows you to use Grafana Alloy to scrape logs.\n\n**Links** \n[Linux Server mixin](https://github.com/grafana/node_exporter/tree/master/docs/node-mixin/lib/linux) \n[Linux Server docs](https://grafana.com/docs/grafana-cloud/data-configuration/integrations/integration-reference/integration-linux-node/) \n[Learning journey: Monitor a Linux server in Grafana Cloud](https://grafana.com/docs/learning-journeys/linux-server-integration/)\n","logo":{"dark_theme_url":"https://storage.googleapis.com/grafanalabs-integration-logos/linux.png","light_theme_url":"https://storage.googleapis.com/grafanalabs-integration-logos/linux.png"},"type":"agent","installation":{"version":"1.6.1","installed_on":"2025-04-27T17:06:08Z"},"search_keywords":["operating system","server","linux","node","linux-node"],"categories":["Servers and VMs","Operating System"],"dashboard_folder":"Integration - Linux Node","has_update":false,"metrics_check_query":"","logs_check_query":"","rule_namespace":"integrations-linux-node"},"traefik":{"name":"Traefik","slug":"traefik","version":"0.0.6","overview":"Traefik is a dynamic load balancer designed for ease of configuration, especially in dynamic environments. It supports automatic discovery of services, metrics, tracing, and has Let's Encrypt support out of the box. Traefik provides a “ready to go” system for serving production traffic with these additions.\n\n**Links** \n[Traefik mixin](https://github.com/grafana/jsonnet-libs/tree/master/traefik-mixin) \n[Traefik docs](https://grafana.com/docs/grafana-cloud/data-configuration/integrations/integration-reference/integration-traefik/)\n","logo":{"dark_theme_url":"https://storage.googleapis.com/grafanalabs-integration-logos/traefik.png","light_theme_url":"https://storage.googleapis.com/grafanalabs-integration-logos/traefik.png"},"type":"agent","installation":{"version":"0.0.6","installed_on":"2023-11-04T15:32:35Z"},"search_keywords":["load","balancer","networking","traefik"],"categories":["Networking"],"dashboard_folder":"Integration - Traefik","has_update":false,"metrics_check_query":"","logs_check_query":"","rule_namespace":""},"windows-exporter":{"name":"Windows","slug":"windows-exporter","version":"1.1.5","overview":"Monitor Windows instances using Grafana Alloy. The integration comes with pre installed dashboards, which give an overview of your Windows' fleet at once, a single host overview, as well as additional dashboards that provide more metrics for further system performance analysis.\nThe integration also provides dashboard showing Windows event logs.\n\n**Links** \n[Windows mixin](https://github.com/grafana/jsonnet-libs/tree/master/windows-mixin) \n[Windows docs](https://grafana.com/docs/grafana-cloud/data-configuration/integrations/integration-reference/integration-windows-exporter/) \n","logo":{"dark_theme_url":"https://storage.googleapis.com/grafanalabs-integration-logos/windows.png","light_theme_url":"https://storage.googleapis.com/grafanalabs-integration-logos/windows.png"},"type":"agent","installation":{"version":"1.1.5","installed_on":"2025-05-15T09:38:02Z"},"search_keywords":["operating system","windows","microsoft","windows-exporter"],"categories":["Operating System","Servers and VMs"],"dashboard_folder":"Integration - Windows Exporter","has_update":false,"metrics_check_query":"","logs_check_query":"","rule_namespace":"integrations-windows-exporter"}}}
+ ```
+
+# Get one integration state
+- method GET
+- path /grafana-easystart-app/integrations-api-editor/integrations/{slug}
+- parameters:
+ - `{slug}` the integration
+- expected:
+ - code 200
+ - example body:
+ ```
+ {"data":{"name":"Docker","slug":"docker","version":"1.3.4","overview":"Docker is a popular open-source platform that enables developers to create, deploy, and run applications in a virtualized environment called a container. It allows developers to package an application with all its dependencies, libraries, and other components required to run it, into a single container image. The Docker integration collects metrics and logs from a Docker instance and provides useful pre-built dashboards to monitor them. \n\n**Links** \n[Docker mixin](https://github.com/grafana/jsonnet-libs/tree/master/docker-mixin) \n[Docker docs](https://grafana.com/docs/grafana-cloud/data-configuration/integrations/integration-reference/integration-docker/) \n","logo":{"dark_theme_url":"https://storage.googleapis.com/grafanalabs-integration-logos/docker.png","light_theme_url":"https://storage.googleapis.com/grafanalabs-integration-logos/docker.png"},"type":"agent","installation":{"version":"1.3.4","installed_on":"2025-03-28T18:26:54Z","configuration":{"configurable_logs":{"logs_disabled":false},"configurable_alerts":{"alerts_disabled":false}}},"search_keywords":null,"categories":["Servers and VMs"],"dashboard_folder":"Integration - Docker","has_update":false,"metrics_check_query":"vector(1) and on() ((count(up{job=\"integrations/docker\"} == 1) \u003e 0) and (absent(absent(machine_scrape_error{job=\"integrations/docker\"})))) or vector(0) and on() ((count(up{job=\"integrations/docker\"}) \u003e 0) and (absent(machine_scrape_error{job=\"integrations/docker\"})))","logs_check_query":"sum(count_over_time({job=\"integrations/docker\"}[5m]))","rule_namespace":"","agent_configuration":{"supported_platforms":["linux"]},"metrics":{"status":"available","available_metrics":[{"name":"container_cpu_usage_seconds_total","type":"counter","description":"Cumulative cpu time consumed in seconds."},{"name":"container_fs_reads_total","type":"counter","description":"Cumulative count of reads completed"},{"name":"container_fs_usage_bytes","type":"gauge","description":"Number of bytes that are consumed by the container on this filesystem."},{"name":"container_fs_writes_total","type":"counter","description":"Cumulative count of writes completed"},{"name":"container_last_seen","type":"gauge","description":"Last time a container was seen by the exporter"},{"name":"container_memory_usage_bytes","type":"gauge","description":"Current memory usage in bytes, including all memory regardless of when it was accessed"},{"name":"container_network_receive_bytes_total","type":"counter","description":"Cumulative count of bytes received"},{"name":"container_network_receive_errors_total","type":"counter","description":"Cumulative count of errors encountered while receiving"},{"name":"container_network_receive_packets_dropped_total","type":"counter","description":"Cumulative count of packets dropped while receiving"},{"name":"container_network_transmit_bytes_total","type":"counter","description":"Cumulative count of bytes transmitted"},{"name":"container_network_transmit_errors_total","type":"counter","description":"Cumulative count of errors encountered while transmitting"},{"name":"container_network_transmit_packets_dropped_total","type":"counter","description":"Cumulative count of packets dropped while transmitting"},{"name":"container_spec_memory_reservation_limit_bytes","type":"gauge","description":"Memory reservation limit for the container."},{"name":"machine_memory_bytes","type":"gauge","description":"Amount of memory installed on the machine."},{"name":"machine_scrape_error","type":"gauge","description":"1 if there was an error while getting machine metrics, 0 otherwise."},{"name":"up"}]},"rules":{"status":"available","available_rules":[{"namespace":"integrations-docker","group":"asserts-integration-docker.rules","name":"asserts:resource:usage"},{"namespace":"integrations-docker","group":"asserts-integration-docker.rules","name":"asserts:resource:gauge"},{"namespace":"integrations-docker","group":"asserts-integration-docker.rules","name":"asserts:resource:total"},{"namespace":"integrations-docker","group":"asserts-integration-docker.rules","name":"asserts:resource:total"},{"namespace":"integrations-docker","group":"asserts-integration-docker.rules","name":"asserts:resource:gauge"}]},"alerts":{"status":"not_supported"},"logs":{"status":"available"},"traces":{"status":"not_supported"},"asserts":{"status":"available"},"dashboards":{"status":"available","screenshots":[{"url":"https://storage.googleapis.com/grafanalabs-integration-assets/docker/screenshots/docker-1.2.png","sort_order":1,"description":"Overview \u0026 Compute"},{"url":"https://storage.googleapis.com/grafanalabs-integration-assets/docker/screenshots/docker-logs-1.2.png","sort_order":2,"description":"Logs"}],"folder_name":"Integration - Docker"},"configuration_defaults":{"enable_logs_toggle":true,"enable_alerts_toggle":false,"configurable_logs_defaults":{"logs_disabled":false},"configurable_alerts_defaults":{"alerts_disabled":false}}}}
+ ```
+
+# Install one integration
+## Get the dashboards
+- method POST
+- path /api/plugin-proxy/grafana-easystart-app/integrations-api-admin/integrations/{slug}/dashboards
+- parameters:
+ - `{slug}` the integration
+- body example:
+ ```
+ {"configuration":{"configurable_logs":{"logs_disabled":false}}}
+ ```
+- expected:
+ - code 200
+ - example body
+ ```
+ {"data":[{"dashboard":{"__inputs":[],"__requires":[],"annotations":{"list":[]},"description":"","editable":false,"gnetId":null,"graphTooltip":0,"hideControls":false,"id":null,"links":[{"asDropdown":false,"icon":"external link","includeVars":true,"keepTime":true,"tags":["apache-activemq-integration"],"targetBlank":false,"title":"Other Apache ActiveMQ dashboards","type":"dashboards","url":""}],"panels":[{"datasource":{"type":"datasource","uid":"-- Mixed --"},"description":"Shows if metrics are being received for the selected time range.","fieldConfig":{"defaults":{"color":{"fixedColor":"text","mode":"fixed"},"mappings":[{"options":{"match":"null","result":{"color":"light-red","index":0,"text":"No metrics received - Check configuration"}},"type":"special"},{"options":{"from":0,"result":{"color":"light-red","index":1,"text":"Failed to collect metrics"},"to":0},"type":"range"},{"options":{"from":1,"result":{"color":"light-green","index":2,"text":"Receiving metrics"},"to":1000000},"type":"range"}],"noValue":"No data","unit":"string"}},"gridPos":{"h":2,"w":8,"x":0,"y":0},"options":{"colorMode":"background","graphMode":"none","reduceOptions":{"calcs":["lastNotNull"]}},"pluginVersion":"v10.0.0","targets":[{"datasource":{"type":"prometheus","uid":"$prometheus_datasource"},"expr":"sum(up{job=~\"$job\"})\n"}],"title":"Metrics","type":"stat"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"description":"Shows the timestamp of the latest metrics received for this integration in the last 24 hours.","fieldConfig":{"defaults":{"color":{"fixedColor":"text","mode":"fixed"},"noValue":"No data","unit":"dateTimeFromNow"}},"gridPos":{"h":2,"w":8,"x":8,"y":0},"options":{"colorMode":"background","graphMode":"none","reduceOptions":{"calcs":["lastNotNull"],"fields":"Time"}},"pluginVersion":"v10.0.0","targets":[{"datasource":{"type":"prometheus","uid":"$prometheus_datasource"},"expr":"sum(up{job=~\"$job\"})\n"}],"timeFrom":"now-24h","title":"Latest metrics received","type":"stat"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"description":"Shows the installed version of this integration.","fieldConfig":{"defaults":{"color":{"fixedColor":"text","mode":"fixed"},"noValue":"1.0.1","unit":"string"}},"gridPos":{"h":2,"w":8,"x":16,"y":0},"pluginVersion":"v10.0.0","title":"Integration version","type":"stat"},{"datasource":{"uid":"${prometheus_datasource}"},"description":"Number of clusters that are reporting metrics from ActiveMQ.","fieldConfig":{"defaults":{"color":{"mode":"fixed"},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null}]},"unit":"none"},"overrides":[]},"gridPos":{"h":4,"w":6,"x":0,"y":3},"id":2,"options":{"colorMode":"none","graphMode":"area","justifyMode":"auto","orientation":"auto","reduceOptions":{"calcs":["lastNotNull"],"fields":"","values":false},"textMode":"auto"},"pluginVersion":"10.2.0-60139","targets":[{"datasource":{"uid":"${prometheus_datasource}"},"expr":"count (activemq_memory_usage_ratio{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\"})","format":"time_series","intervalFactor":2,"legendFormat":"__auto"}],"title":"Clusters","type":"stat"},{"datasource":{"uid":"${prometheus_datasource}"},"description":"Number of broker instances across clusters.","fieldConfig":{"defaults":{"color":{"mode":"fixed"},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null}]},"unit":"none"},"overrides":[]},"gridPos":{"h":4,"w":6,"x":6,"y":3},"id":3,"options":{"colorMode":"none","graphMode":"area","justifyMode":"auto","orientation":"auto","reduceOptions":{"calcs":["lastNotNull"],"fields":"","values":false},"textMode":"auto"},"pluginVersion":"10.2.0-60139","targets":[{"datasource":{"uid":"${prometheus_datasource}"},"expr":"count (activemq_memory_usage_ratio{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\"})","format":"time_series","intervalFactor":2,"legendFormat":"__auto"}],"title":"Brokers","type":"stat"},{"datasource":{"uid":"${prometheus_datasource}"},"description":"Number of message producers active on destinations across clusters.","fieldConfig":{"defaults":{"color":{"mode":"fixed"},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null}]},"unit":"none"},"overrides":[]},"gridPos":{"h":4,"w":6,"x":12,"y":3},"id":4,"options":{"colorMode":"none","graphMode":"area","justifyMode":"auto","orientation":"auto","reduceOptions":{"calcs":["lastNotNull"],"fields":"","values":false},"textMode":"auto"},"pluginVersion":"10.2.0-60139","targets":[{"datasource":{"uid":"${prometheus_datasource}"},"expr":"sum (activemq_queue_producer_count{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\"}) + sum (activemq_topic_producer_count{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\",destination!~\"ActiveMQ.Advisory.*\"})","format":"time_series","intervalFactor":2,"legendFormat":"__auto"}],"title":"Producers","type":"stat"},{"datasource":{"uid":"${prometheus_datasource}"},"description":"The number of consumers subscribed to destinations across clusters.","fieldConfig":{"defaults":{"color":{"mode":"fixed"},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null}]},"unit":"none"},"overrides":[]},"gridPos":{"h":4,"w":6,"x":18,"y":3},"id":5,"options":{"colorMode":"none","graphMode":"area","justifyMode":"auto","orientation":"auto","reduceOptions":{"calcs":["lastNotNull"],"fields":"","values":false},"textMode":"auto"},"pluginVersion":"10.2.0-60139","targets":[{"datasource":{"uid":"${prometheus_datasource}"},"expr":"sum (activemq_queue_consumer_count{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\"}) + sum (activemq_topic_consumer_count{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\",destination!~\"ActiveMQ.Advisory.*\"})","format":"time_series","intervalFactor":2,"legendFormat":"__auto"}],"title":"Consumers","type":"stat"},{"datasource":{"uid":"${prometheus_datasource}"},"description":"Number of messages that have been sent to destinations in a cluster","fieldConfig":{"defaults":{"color":{"fixedColor":"#C8F2C2","mode":"palette-classic"},"custom":{"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","axisShow":false,"barAlignment":0,"drawStyle":"line","fillOpacity":25,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"smooth","lineWidth":2,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"never","spanNulls":false,"stacking":{"group":"A","mode":"normal"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null}]},"unit":"none"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":0,"y":9},"id":6,"options":{"legend":{"calcs":[],"displayMode":"list","placement":"right","showLegend":true},"tooltip":{"mode":"multi","sort":"desc"}},"targets":[{"datasource":{"uid":"${prometheus_datasource}"},"expr":"sum by (activemq_cluster, job) (increase(activemq_queue_enqueue_count{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\"}[$__interval:])) + sum by (activemq_cluster, job) (increase(activemq_topic_enqueue_count{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\", destination!~\"ActiveMQ.Advisory.*\"}[$__interval:]))","format":"time_series","interval":"1m","intervalFactor":2,"legendFormat":"{{activemq_cluster}}"}],"title":"Enqueue / $__interval","type":"timeseries"},{"datasource":{"uid":"${prometheus_datasource}"},"description":"Number of messages that have been acknowledged (and removed) from destinations in a cluster.","fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","axisShow":false,"barAlignment":0,"drawStyle":"line","fillOpacity":25,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"smooth","lineWidth":2,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"never","spanNulls":false,"stacking":{"group":"A","mode":"normal"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null}]},"unit":"none"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":12,"y":9},"id":7,"options":{"legend":{"calcs":[],"displayMode":"list","placement":"right","showLegend":true},"tooltip":{"mode":"multi","sort":"desc"}},"targets":[{"datasource":{"uid":"${prometheus_datasource}"},"expr":"sum by (activemq_cluster, job) (increase(activemq_queue_dequeue_count{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\"}[$__interval:])) + sum by (activemq_cluster, job) (increase(activemq_topic_dequeue_count{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\", destination!~\"ActiveMQ.Advisory.*\"}[$__interval:]))","format":"time_series","interval":"1m","intervalFactor":2,"legendFormat":"{{activemq_cluster}}"}],"title":"Dequeue / $__interval","type":"timeseries"},{"datasource":{"uid":"${prometheus_datasource}"},"description":"Average percentage of temporary memory used across clusters.","fieldConfig":{"defaults":{"color":{"mode":"thresholds"},"mappings":[],"max":1,"min":0,"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"#EAB839","value":50},{"color":"red","value":70}]},"unit":"percentunit"},"overrides":[]},"gridPos":{"h":10,"w":8,"x":0,"y":17},"id":8,"options":{"displayMode":"gradient","minVizHeight":10,"minVizWidth":0,"orientation":"horizontal","reduceOptions":{"calcs":["lastNotNull"],"fields":"","values":false},"showUnfilled":false,"text":{},"valueMode":"color"},"pluginVersion":"10.2.0-60139","targets":[{"datasource":{"uid":"${prometheus_datasource}"},"expr":"avg by (activemq_cluster, job) (activemq_temp_usage_ratio{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\"})","format":"time_series","intervalFactor":2,"legendFormat":"{{activemq_cluster}}"}],"title":"Average temporary memory usage","type":"bargauge"},{"datasource":{"uid":"${prometheus_datasource}"},"description":"Average percentage of store memory used across clusters.","fieldConfig":{"defaults":{"color":{"mode":"thresholds"},"mappings":[],"max":1,"min":0,"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"#EAB839","value":50},{"color":"red","value":70}]},"unit":"percentunit"},"overrides":[]},"gridPos":{"h":10,"w":8,"x":8,"y":17},"id":9,"options":{"displayMode":"gradient","minVizHeight":10,"minVizWidth":0,"orientation":"horizontal","reduceOptions":{"calcs":["lastNotNull"],"fields":"","values":false},"showUnfilled":false,"valueMode":"color"},"pluginVersion":"10.2.0-60139","targets":[{"datasource":{"uid":"${prometheus_datasource}"},"expr":"avg by (activemq_cluster, job) (activemq_store_usage_ratio{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\"})","format":"time_series","intervalFactor":2,"legendFormat":"{{activemq_cluster}}"}],"title":"Average store memory usage","type":"bargauge"},{"datasource":{"uid":"${prometheus_datasource}"},"description":"Average percentage of broker memory used across clusters.","fieldConfig":{"defaults":{"color":{"mode":"thresholds"},"mappings":[],"max":1,"min":0,"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"#EAB839","value":50},{"color":"red","value":70}]},"unit":"percentunit"},"overrides":[]},"gridPos":{"h":10,"w":8,"x":16,"y":17},"id":10,"options":{"displayMode":"gradient","minVizHeight":10,"minVizWidth":0,"orientation":"horizontal","reduceOptions":{"calcs":["lastNotNull"],"fields":"","values":false},"showUnfilled":false,"valueMode":"color"},"pluginVersion":"10.2.0-60139","targets":[{"datasource":{"uid":"${prometheus_datasource}"},"expr":"avg by (activemq_cluster, job) (activemq_memory_usage_ratio{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\"})","format":"time_series","intervalFactor":2,"legendFormat":"{{activemq_cluster}}"}],"title":"Average broker memory usage","type":"bargauge"}],"refresh":"30s","rows":[],"schemaVersion":14,"style":"dark","tags":["apache-activemq-integration"],"templating":{"list":[{"current":{},"hide":0,"label":"Data source","name":"prometheus_datasource","options":[],"query":"prometheus","refresh":1,"regex":"(?!grafanacloud-usage|grafanacloud-ml-metrics).+","type":"datasource"},{"allValue":".+","current":{},"datasource":{"uid":"${prometheus_datasource}"},"hide":0,"includeAll":true,"label":"Job","multi":true,"name":"job","options":[],"query":"label_values(activemq_topic_producer_count,job)","refresh":2,"regex":"","sort":0,"tagValuesQuery":"","tags":[],"tagsQuery":"","type":"query","useTags":false},{"allValue":".*","current":{},"datasource":{"uid":"${prometheus_datasource}"},"hide":0,"includeAll":true,"label":"Cluster","multi":true,"name":"cluster","options":[],"query":"label_values(activemq_memory_usage_ratio{job=~\"$job\", cluster=~\"$cluster\"},cluster)","refresh":2,"regex":"","sort":0,"tagValuesQuery":"","tags":[],"tagsQuery":"","type":"query","useTags":false},{"allValue":".+","current":{},"datasource":{"uid":"${prometheus_datasource}"},"hide":0,"includeAll":true,"label":"ActiveMQ cluster","multi":true,"name":"activemq_cluster","options":[],"query":"label_values(activemq_memory_usage_ratio{job=~\"$job\", cluster=~\"$cluster\"},activemq_cluster)","refresh":2,"regex":"","sort":0,"tagValuesQuery":"","tags":[],"tagsQuery":"","type":"query","useTags":false}]},"time":{"from":"now-30m","to":"now"},"timepicker":{"refresh_intervals":["5s","10s","30s","1m","5m","15m","30m","1h","2h","1d"],"time_options":["5m","15m","1h","6h","12h","24h","2d","7d","30d"]},"timezone":"default","title":"Apache ActiveMQ cluster overview","uid":"apache-activemq-cluster-overview","version":0},"folder_name":"Integration - Apache ActiveMQ","overwrite":true},{"dashboard":{"__inputs":[],"__requires":[],"annotations":{"list":[]},"description":"","editable":false,"gnetId":null,"graphTooltip":0,"hideControls":false,"id":null,"links":[{"asDropdown":false,"icon":"external link","includeVars":true,"keepTime":true,"tags":["apache-activemq-integration"],"targetBlank":false,"title":"Other Apache ActiveMQ dashboards","type":"dashboards","url":""}],"panels":[{"datasource":{"uid":"${prometheus_datasource}"},"description":"The percentage of memory used by both topics and queues across brokers.","fieldConfig":{"defaults":{"color":{"mode":"thresholds"},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"#EAB839","value":50},{"color":"red","value":70}]},"unit":"percentunit"},"overrides":[]},"gridPos":{"h":4,"w":6,"x":0,"y":0},"id":2,"options":{"minVizHeight":75,"minVizWidth":75,"orientation":"auto","reduceOptions":{"calcs":["lastNotNull"],"fields":"","values":false},"showThresholdLabels":false,"showThresholdMarkers":true},"pluginVersion":"10.2.0-60139","targets":[{"datasource":{"uid":"${prometheus_datasource}"},"expr":"avg (activemq_memory_usage_ratio{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\", instance=~\"$instance\"})","format":"time_series","intervalFactor":2,"legendFormat":"{{activemq_cluster}} - {{instance}}"}],"title":"Average broker memory usage","type":"gauge"},{"datasource":{"uid":"${prometheus_datasource}"},"description":"The percentage of store memory used by both topics and queues across brokers.","fieldConfig":{"defaults":{"color":{"mode":"thresholds"},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"#EAB839","value":50},{"color":"red","value":70}]},"unit":"percentunit"},"overrides":[]},"gridPos":{"h":4,"w":6,"x":6,"y":0},"id":3,"options":{"minVizHeight":75,"minVizWidth":75,"orientation":"auto","reduceOptions":{"calcs":["lastNotNull"],"fields":"","values":false},"showThresholdLabels":false,"showThresholdMarkers":true},"pluginVersion":"10.2.0-60139","targets":[{"datasource":{"uid":"${prometheus_datasource}"},"expr":"avg (activemq_store_usage_ratio{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\", instance=~\"$instance\"})","format":"time_series","intervalFactor":2,"legendFormat":"__auto"}],"title":"Average store memory usage","type":"gauge"},{"datasource":{"uid":"${prometheus_datasource}"},"description":"The percentage of temporary memory used by both topics and queues across brokers.","fieldConfig":{"defaults":{"color":{"mode":"thresholds"},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"#EAB839","value":50},{"color":"red","value":70}]},"unit":"percentunit"},"overrides":[]},"gridPos":{"h":4,"w":6,"x":12,"y":0},"id":4,"options":{"minVizHeight":75,"minVizWidth":75,"orientation":"auto","reduceOptions":{"calcs":["lastNotNull"],"fields":"","values":false},"showThresholdLabels":false,"showThresholdMarkers":true},"pluginVersion":"10.2.0-60139","targets":[{"datasource":{"uid":"${prometheus_datasource}"},"expr":"avg (activemq_temp_usage_ratio{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\", instance=~\"$instance\"})","format":"time_series","intervalFactor":2,"legendFormat":"__auto"}],"title":"Average temporary memory usage","type":"gauge"},{"datasource":{"uid":"${prometheus_datasource}"},"description":"Recent number of unacknowledged messages on the broker.","fieldConfig":{"defaults":{"color":{"mode":"fixed"},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null}]},"unit":"none"},"overrides":[]},"gridPos":{"h":4,"w":6,"x":18,"y":0},"id":5,"options":{"colorMode":"none","graphMode":"area","justifyMode":"auto","orientation":"auto","reduceOptions":{"calcs":["lastNotNull"],"fields":"","values":false},"textMode":"auto"},"pluginVersion":"10.2.0-60139","targets":[{"datasource":{"uid":"${prometheus_datasource}"},"expr":"sum (increase(activemq_message_total{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\", instance=~\"$instance\"}[$__interval:]))","format":"time_series","interval":"1m","intervalFactor":2,"legendFormat":"__auto"}],"title":"Unacknowledged messages / $__interval","type":"stat"},{"datasource":{"uid":"${prometheus_datasource}"},"description":"Firing alerts for Apache ActiveMQ environment.","gridPos":{"h":6,"w":12,"x":0,"y":4},"id":6,"options":{"alertInstanceLabelFilter":"{job=~\"${job:regex}\", cluster=~\"${cluster:regex}\", activemq_cluster=~\"${activemq_cluster:regex}\", instance=~\"${instance:regex}\"}","alertName":"","dashboardAlerts":false,"datasource":{"uid":"${prometheus_datasource}"},"groupBy":[],"groupMode":"default","maxItems":5,"sortOrder":1,"stateFilter":{"error":true,"firing":true,"noData":true,"normal":true,"pending":true},"viewMode":"list"},"targets":[],"title":"ActiveMQ alerts","type":"alertlist"},{"datasource":{"uid":"${prometheus_datasource}"},"description":"The number of producers attached to destinations.","fieldConfig":{"defaults":{"color":{"mode":"fixed"},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null}]},"unit":"none"},"overrides":[]},"gridPos":{"h":6,"w":6,"x":12,"y":4},"id":7,"options":{"colorMode":"none","graphMode":"area","justifyMode":"auto","orientation":"auto","reduceOptions":{"calcs":["lastNotNull"],"fields":"","values":false},"textMode":"auto"},"pluginVersion":"10.2.0-60139","targets":[{"datasource":{"uid":"${prometheus_datasource}"},"expr":"sum (activemq_queue_producer_count{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\", instance=~\"$instance\"}) + sum (activemq_topic_producer_count{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\", instance=~\"$instance\", destination!~\"ActiveMQ.Advisory.*\"})","format":"time_series","intervalFactor":2,"legendFormat":"__auto"}],"title":"Producers","type":"stat"},{"datasource":{"uid":"${prometheus_datasource}"},"description":"The number of consumers subscribed to destinations on the broker.","fieldConfig":{"defaults":{"color":{"mode":"fixed"},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null}]},"unit":"none"},"overrides":[]},"gridPos":{"h":6,"w":6,"x":18,"y":4},"id":8,"options":{"colorMode":"none","graphMode":"area","justifyMode":"auto","orientation":"auto","reduceOptions":{"calcs":["lastNotNull"],"fields":"","values":false},"textMode":"auto"},"pluginVersion":"10.2.0-60139","targets":[{"datasource":{"uid":"${prometheus_datasource}"},"expr":"sum (activemq_queue_consumer_count{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\", instance=~\"$instance\"}) + sum (activemq_topic_consumer_count{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\", instance=~\"$instance\", destination!~\"ActiveMQ.Advisory.*\"})","format":"time_series","intervalFactor":2,"legendFormat":"__auto"}],"title":"Consumers","type":"stat"},{"datasource":{"uid":"${prometheus_datasource}"},"description":"Number of messages on queue destinations, including any that have been dispatched but not acknowledged.","fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","axisShow":false,"barAlignment":0,"drawStyle":"line","fillOpacity":25,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"smooth","lineWidth":2,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"never","spanNulls":false,"stacking":{"group":"A","mode":"normal"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null}]},"unit":"none"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":0,"y":10},"id":9,"options":{"legend":{"calcs":[],"displayMode":"list","placement":"right","showLegend":true},"tooltip":{"mode":"multi","sort":"desc"}},"targets":[{"datasource":{"uid":"${prometheus_datasource}"},"expr":"sum by(instance, activemq_cluster, job) (activemq_queue_queue_size{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\", instance=~\"$instance\"})","format":"time_series","intervalFactor":2,"legendFormat":"{{activemq_cluster}} - {{instance}}"}],"title":"Queue size","type":"timeseries"},{"datasource":{"uid":"${prometheus_datasource}"},"description":"The percentage of memory being used by topic and queue destinations.","fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","axisShow":false,"barAlignment":0,"drawStyle":"line","fillOpacity":25,"gradientMode":"opacity","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"smooth","lineWidth":2,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"never","spanNulls":false,"stacking":{"group":"A","mode":"normal"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"max":100,"min":0,"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null}]},"unit":"percent"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":12,"y":10},"id":10,"options":{"legend":{"calcs":[],"displayMode":"list","placement":"right","showLegend":true},"tooltip":{"mode":"multi","sort":"desc"}},"targets":[{"datasource":{"uid":"${prometheus_datasource}"},"expr":"sum by(instance, activemq_cluster, job) (activemq_queue_memory_percent_usage{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\", instance=~\"$instance\"})","format":"time_series","intervalFactor":2,"legendFormat":"{{activemq_cluster}} - {{instance}} - queue"},{"datasource":{"uid":"${prometheus_datasource}"},"expr":"sum by(instance, activemq_cluster, job) (activemq_topic_memory_percent_usage{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\", instance=~\"$instance\", destination!~\"ActiveMQ.Advisory.*\"})","format":"time_series","intervalFactor":2,"legendFormat":"{{activemq_cluster}} - {{instance}} - topic"}],"title":"Destination memory usage","type":"timeseries"},{"datasource":{"uid":"${prometheus_datasource}"},"description":"Number of messages that have been sent to the destination.","fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","axisShow":false,"barAlignment":0,"drawStyle":"line","fillOpacity":25,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"smooth","lineWidth":2,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"never","spanNulls":false,"stacking":{"group":"A","mode":"normal"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null}]},"unit":"none"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":0,"y":18},"id":11,"options":{"legend":{"calcs":[],"displayMode":"list","placement":"right","showLegend":true},"tooltip":{"mode":"multi","sort":"desc"}},"targets":[{"datasource":{"uid":"${prometheus_datasource}"},"expr":"sum by(instance, activemq_cluster, job) (increase(activemq_queue_enqueue_count{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\", instance=~\"$instance\"}[$__interval:]))","format":"time_series","interval":"1m","intervalFactor":2,"legendFormat":"{{activemq_cluster}} - {{instance}} - queue"},{"datasource":{"uid":"${prometheus_datasource}"},"expr":"sum by(instance, activemq_cluster, job) (increase(activemq_topic_enqueue_count{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\", instance=~\"$instance\", destination!~\"ActiveMQ.Advisory.*\"}[$__interval:]))","format":"time_series","interval":"1m","intervalFactor":2,"legendFormat":"{{activemq_cluster}} - {{instance}} - topic"}],"title":"Enqueue / $__interval","type":"timeseries"},{"datasource":{"uid":"${prometheus_datasource}"},"description":"Number of messages that have been acknowledged (and removed) from the destinations.","fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","axisShow":false,"barAlignment":0,"drawStyle":"line","fillOpacity":25,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"smooth","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"never","spanNulls":false,"stacking":{"group":"A","mode":"normal"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null}]},"unit":"none"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":12,"y":18},"id":12,"options":{"legend":{"calcs":[],"displayMode":"list","placement":"right","showLegend":true},"tooltip":{"mode":"multi","sort":"desc"}},"targets":[{"datasource":{"uid":"${prometheus_datasource}"},"expr":"sum by(instance, activemq_cluster) (increase(activemq_queue_dequeue_count{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\", instance=~\"$instance\"}[$__interval:]))","format":"time_series","interval":"1m","intervalFactor":2,"legendFormat":"{{activemq_cluster}} - {{instance}} - queue"},{"datasource":{"uid":"${prometheus_datasource}"},"expr":"sum by(instance, activemq_cluster) (increase(activemq_topic_dequeue_count{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\", instance=~\"$instance\", destination!~\"ActiveMQ.Advisory.*\"}[$__interval:]))","format":"time_series","interval":"1m","intervalFactor":2,"legendFormat":"{{activemq_cluster}} - {{instance}} - topic"}],"title":"Dequeue / $__interval","type":"timeseries"},{"datasource":{"uid":"${prometheus_datasource}"},"description":"Average time a message was held across all destinations.","fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","axisShow":false,"barAlignment":0,"drawStyle":"line","fillOpacity":25,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"smooth","lineWidth":2,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"never","spanNulls":false,"stacking":{"group":"A","mode":"normal"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null}]},"unit":"ms"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":0,"y":26},"id":13,"options":{"legend":{"calcs":[],"displayMode":"list","placement":"right","showLegend":true},"tooltip":{"mode":"multi","sort":"desc"}},"targets":[{"datasource":{"uid":"${prometheus_datasource}"},"expr":"avg by (activemq_cluster, instance, job) (activemq_queue_average_enqueue_time{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\", instance=~\"$instance\"})","format":"time_series","intervalFactor":2,"legendFormat":"{{activemq_cluster}} - {{instance}} - queue"},{"datasource":{"uid":"${prometheus_datasource}"},"expr":"avg by (activemq_cluster, instance, job) (activemq_topic_average_enqueue_time{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\", instance=~\"$instance\", destination!~\"ActiveMQ.Advisory.*\"})","format":"time_series","intervalFactor":2,"legendFormat":"{{activemq_cluster}} - {{instance}} - topic"}],"title":"Average enqueue time","type":"timeseries"},{"datasource":{"uid":"${prometheus_datasource}"},"description":"Number of messages across destinations that are expired.","fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","axisShow":false,"barAlignment":0,"drawStyle":"line","fillOpacity":25,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"smooth","lineWidth":2,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"never","spanNulls":false,"stacking":{"group":"A","mode":"normal"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null}]},"unit":"none"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":12,"y":26},"id":14,"options":{"legend":{"calcs":[],"displayMode":"list","placement":"right","showLegend":true},"tooltip":{"mode":"multi","sort":"desc"}},"targets":[{"datasource":{"uid":"${prometheus_datasource}"},"expr":"sum by(instance, activemq_cluster, job) (increase(activemq_queue_expired_count{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\", instance=~\"$instance\"}[$__interval:]))","format":"time_series","interval":"1m","intervalFactor":2,"legendFormat":"{{activemq_cluster}} - {{instance}} - queue"},{"datasource":{"uid":"${prometheus_datasource}"},"expr":"sum by(instance, activemq_cluster, job) (increase(activemq_topic_expired_count{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\", instance=~\"$instance\", destination!~\"ActiveMQ.Advisory.*\"}[$__interval:]))","format":"time_series","interval":"1m","intervalFactor":2,"legendFormat":"{{activemq_cluster}} - {{instance}} - topic"}],"title":"Expired messages / $__interval","type":"timeseries"},{"collapsed":false,"datasource":{"uid":"${prometheus_datasource}"},"gridPos":{"h":1,"w":24,"x":0,"y":34},"id":15,"targets":[],"title":"JVM resources","type":"row"},{"datasource":{"uid":"${prometheus_datasource}"},"description":"The time spent performing recent garbage collections","fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","axisShow":false,"barAlignment":0,"drawStyle":"line","fillOpacity":25,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"smooth","lineWidth":2,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"never","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green"}]},"unit":"s"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":0,"y":35},"id":16,"options":{"legend":{"calcs":[],"displayMode":"list","placement":"right","showLegend":true},"tooltip":{"mode":"multi","sort":"desc"}},"targets":[{"datasource":{"uid":"${prometheus_datasource}"},"expr":"jvm_gc_duration_seconds{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\", instance=~\"$instance\"}","format":"time_series","interval":"1m","intervalFactor":2,"legendFormat":"{{activemq_cluster}} - {{instance}}"}],"title":"Garbage collection duration","type":"timeseries"},{"datasource":{"uid":"${prometheus_datasource}"},"description":"The recent increase in the number of garbage collection events for the JVM.","fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","axisShow":false,"barAlignment":0,"drawStyle":"line","fillOpacity":25,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"smooth","lineWidth":2,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"never","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green"}]},"unit":"none"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":12,"y":35},"id":17,"options":{"legend":{"calcs":[],"displayMode":"list","placement":"right","showLegend":true},"tooltip":{"mode":"multi","sort":"desc"}},"targets":[{"datasource":{"uid":"${prometheus_datasource}"},"expr":"increase(jvm_gc_collection_count{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\", instance=~\"$instance\", name=\"G1 Young Generation\"}[$__interval:])","format":"time_series","interval":"1m","intervalFactor":2,"legendFormat":"{{activemq_cluster}} - {{instance}}"}],"title":"Garbage collection count / $__interval","type":"timeseries"}],"refresh":"30s","rows":[],"schemaVersion":14,"style":"dark","tags":["apache-activemq-integration"],"templating":{"list":[{"current":{},"hide":0,"label":"Data source","name":"prometheus_datasource","options":[],"query":"prometheus","refresh":1,"regex":"(?!grafanacloud-usage|grafanacloud-ml-metrics).+","type":"datasource"},{"allValue":".+","current":{},"datasource":{"uid":"${prometheus_datasource}"},"hide":0,"includeAll":true,"label":"Job","multi":true,"name":"job","options":[],"query":"label_values(activemq_topic_producer_count,job)","refresh":2,"regex":"","sort":0,"tagValuesQuery":"","tags":[],"tagsQuery":"","type":"query","useTags":false},{"allValue":".*","current":{},"datasource":{"uid":"${prometheus_datasource}"},"hide":0,"includeAll":true,"label":"Cluster","multi":true,"name":"cluster","options":[],"query":"label_values(activemq_memory_usage_ratio{job=~\"$job\"},cluster)","refresh":2,"regex":"","sort":0,"tagValuesQuery":"","tags":[],"tagsQuery":"","type":"query","useTags":false},{"allValue":".+","current":{},"datasource":{"uid":"${prometheus_datasource}"},"hide":0,"includeAll":true,"label":"ActiveMQ cluster","multi":true,"name":"activemq_cluster","options":[],"query":"label_values(activemq_memory_usage_ratio{job=~\"$job\", cluster=~\"$cluster\"},activemq_cluster)","refresh":2,"regex":"","sort":0,"tagValuesQuery":"","tags":[],"tagsQuery":"","type":"query","useTags":false},{"allValue":".+","current":{},"datasource":{"uid":"${prometheus_datasource}"},"hide":0,"includeAll":true,"label":"Instance","multi":true,"name":"instance","options":[],"query":"label_values(activemq_topic_producer_count{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\"},instance)","refresh":2,"regex":"","sort":0,"tagValuesQuery":"","tags":[],"tagsQuery":"","type":"query","useTags":false}]},"time":{"from":"now-30m","to":"now"},"timepicker":{"refresh_intervals":["5s","10s","30s","1m","5m","15m","30m","1h","2h","1d"],"time_options":["5m","15m","1h","6h","12h","24h","2d","7d","30d"]},"timezone":"default","title":"Apache ActiveMQ instance overview","uid":"apache-activemq-instance-overview","version":0},"folder_name":"Integration - Apache ActiveMQ","overwrite":true},{"dashboard":{"editable":false,"id":null,"links":[{"asDropdown":false,"icon":"external link","includeVars":true,"keepTime":true,"tags":["apache-activemq-integration"],"targetBlank":false,"title":"Other Apache ActiveMQ dashboards","type":"dashboards","url":""}],"panels":[{"datasource":{"type":"datasource","uid":"-- Mixed --"},"description":"Shows if logs are being received for the selected time range.","fieldConfig":{"defaults":{"color":{"fixedColor":"text","mode":"fixed"},"mappings":[{"options":{"match":"null","result":{"color":"light-yellow","index":0,"text":"Failed to collect logs or no logs available"}},"type":"special"},{"options":{"from":0,"result":{"color":"light-yellow","index":1,"text":"Failed to collect logs or no logs available"},"to":0},"type":"range"},{"options":{"from":1,"result":{"color":"light-green","index":2,"text":"Receiving logs"},"to":1000000},"type":"range"}],"noValue":"No data","unit":"string"}},"gridPos":{"h":2,"w":8,"x":0,"y":0},"options":{"colorMode":"background","graphMode":"none","reduceOptions":{"calcs":["lastNotNull"]}},"pluginVersion":"v10.0.0","targets":[{"datasource":{"type":"loki","uid":"$loki_datasource"},"expr":"sum(count_over_time({job=~\"$job\"}[5m]))\n"}],"title":"Logs","type":"stat"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"description":"Shows the timestamp of the latest logs received for this integration in the last 24 hours.","fieldConfig":{"defaults":{"color":{"fixedColor":"text","mode":"fixed"},"noValue":"No data","unit":"dateTimeFromNow"}},"gridPos":{"h":2,"w":8,"x":8,"y":0},"options":{"colorMode":"background","graphMode":"none","reduceOptions":{"calcs":["lastNotNull"],"fields":"Time"}},"pluginVersion":"v10.0.0","targets":[{"datasource":{"type":"loki","uid":"$loki_datasource"},"expr":"sum(count_over_time({job=~\"$job\"}[5m]))\n"}],"timeFrom":"now-24h","title":"Latest logs received","type":"stat"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"description":"Shows the installed version of this integration.","fieldConfig":{"defaults":{"color":{"fixedColor":"text","mode":"fixed"},"noValue":"1.0.1","unit":"string"}},"gridPos":{"h":2,"w":8,"x":16,"y":0},"pluginVersion":"v10.0.0","title":"Integration version","type":"stat"},{"datasource":{"type":"loki","uid":"${loki_datasource}"},"description":"Logs volume grouped by \"level\" label.","fieldConfig":{"defaults":{"custom":{"drawStyle":"bars","fillOpacity":50,"stacking":{"mode":"normal"}},"unit":"none"},"overrides":[{"matcher":{"id":"byRegexp","options":"(E|e)merg|(F|f)atal|(A|a)lert|(C|c)rit.*"},"properties":[{"id":"color","value":{"fixedColor":"purple","mode":"fixed"}}]},{"matcher":{"id":"byRegexp","options":"(E|e)(rr.*|RR.*)"},"properties":[{"id":"color","value":{"fixedColor":"red","mode":"fixed"}}]},{"matcher":{"id":"byRegexp","options":"(W|w)(arn.*|ARN.*|rn|RN)"},"properties":[{"id":"color","value":{"fixedColor":"orange","mode":"fixed"}}]},{"matcher":{"id":"byRegexp","options":"(N|n)(otice|ote)|(I|i)(nf.*|NF.*)"},"properties":[{"id":"color","value":{"fixedColor":"green","mode":"fixed"}}]},{"matcher":{"id":"byRegexp","options":"dbg.*|DBG.*|(D|d)(EBUG|ebug)"},"properties":[{"id":"color","value":{"fixedColor":"blue","mode":"fixed"}}]},{"matcher":{"id":"byRegexp","options":"(T|t)(race|RACE)"},"properties":[{"id":"color","value":{"fixedColor":"light-blue","mode":"fixed"}}]},{"matcher":{"id":"byRegexp","options":"logs"},"properties":[{"id":"color","value":{"fixedColor":"text","mode":"fixed"}}]}]},"gridPos":{"h":6,"w":24,"y":3},"id":1,"interval":"30s","options":{"tooltip":{"mode":"multi","sort":"desc"}},"pluginVersion":"v10.0.0","targets":[{"datasource":{"type":"loki","uid":"${loki_datasource}"},"expr":"sum by (level) (count_over_time({job=~\"integrations/apache-activemq\",job=~\"$job\",activemq_cluster=~\"$activemq_cluster\",instance=~\"$instance\",level=~\"$level\"}\n|~ \"$regex_search\"\n\n[$__interval]))\n","legendFormat":"{{ level }}"}],"title":"Logs volume","transformations":[{"id":"renameByRegex","options":{"regex":"Value","renamePattern":"logs"}}],"type":"timeseries"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"gridPos":{"h":18,"w":24,"y":3},"id":2,"options":{"dedupStrategy":"exact","enableLogDetails":true,"prettifyLogMessage":true,"showTime":false,"wrapLogMessage":true},"pluginVersion":"v10.0.0","targets":[{"datasource":{"type":"loki","uid":"${loki_datasource}"},"expr":"{job=~\"integrations/apache-activemq\",job=~\"$job\",activemq_cluster=~\"$activemq_cluster\",instance=~\"$instance\",level=~\"$level\"} \n|~ \"$regex_search\"\n\n\n"}],"title":"Logs","type":"logs"}],"refresh":"30s","schemaVersion":36,"tags":["apache-activemq-integration"],"templating":{"list":[{"label":"Loki data source","name":"loki_datasource","query":"loki","regex":"(?!grafanacloud.+usage-insights|grafanacloud.+alert-state-history).+","type":"datasource"},{"allValue":".*","datasource":{"type":"loki","uid":"${loki_datasource}"},"includeAll":true,"label":"Job","multi":true,"name":"job","query":"label_values({job=~\"integrations/apache-activemq\"}, job)","refresh":2,"sort":1,"type":"query"},{"allValue":".*","datasource":{"type":"loki","uid":"${loki_datasource}"},"includeAll":true,"label":"Activemq_cluster","multi":true,"name":"activemq_cluster","query":"label_values({job=~\"integrations/apache-activemq\",job=~\"$job\"}, activemq_cluster)","refresh":2,"sort":1,"type":"query"},{"allValue":".*","datasource":{"type":"loki","uid":"${loki_datasource}"},"includeAll":true,"label":"Instance","multi":true,"name":"instance","query":"label_values({job=~\"integrations/apache-activemq\",job=~\"$job\",activemq_cluster=~\"$activemq_cluster\"}, instance)","refresh":2,"sort":1,"type":"query"},{"allValue":".*","datasource":{"type":"loki","uid":"${loki_datasource}"},"includeAll":true,"label":"Level","multi":true,"name":"level","query":"label_values({job=~\"integrations/apache-activemq\",job=~\"$job\",activemq_cluster=~\"$activemq_cluster\",instance=~\"$instance\"}, level)","refresh":2,"sort":1,"type":"query"},{"current":{"selected":false,"text":"","value":""},"label":"Regex search","name":"regex_search","options":[{"selected":true,"text":"","value":""}],"query":"","type":"textbox"}]},"time":{"from":"now-30m","to":"now"},"timezone":"utc","title":"Apache ActiveMQ logs","uid":"apache-activemq-logs"},"folder_name":"Integration - Apache ActiveMQ","overwrite":true},{"dashboard":{"__inputs":[],"__requires":[],"annotations":{"list":[]},"description":"","editable":false,"gnetId":null,"graphTooltip":0,"hideControls":false,"id":null,"links":[{"asDropdown":false,"icon":"external link","includeVars":true,"keepTime":true,"tags":["apache-activemq-integration"],"targetBlank":false,"title":"Other Apache ActiveMQ dashboards","type":"dashboards","url":""}],"panels":[{"datasource":{"uid":"${prometheus_datasource}"},"description":"Number of queues connected with the broker instance.","fieldConfig":{"defaults":{"color":{"mode":"fixed"},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null}]},"unit":"none"},"overrides":[]},"gridPos":{"h":4,"w":6,"x":0,"y":0},"id":2,"options":{"colorMode":"none","graphMode":"area","justifyMode":"auto","orientation":"auto","reduceOptions":{"calcs":["lastNotNull"],"fields":"","values":false},"textMode":"auto"},"pluginVersion":"10.2.0-60139","targets":[{"datasource":{"uid":"${prometheus_datasource}"},"expr":"count (activemq_queue_queue_size{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\", instance=~\"$instance\"})","format":"time_series","intervalFactor":2,"legendFormat":"__auto"}],"title":"Queues","type":"stat"},{"datasource":{"uid":"${prometheus_datasource}"},"description":"Number of messages in queue destinations.","fieldConfig":{"defaults":{"color":{"mode":"fixed"},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null}]}},"overrides":[]},"gridPos":{"h":4,"w":6,"x":6,"y":0},"id":3,"options":{"colorMode":"none","graphMode":"area","justifyMode":"auto","orientation":"auto","reduceOptions":{"calcs":["lastNotNull"],"fields":"","values":false},"textMode":"auto"},"pluginVersion":"10.2.0-60139","targets":[{"datasource":{"uid":"${prometheus_datasource}"},"expr":"sum (activemq_queue_queue_size{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\", instance=~\"$instance\"})","format":"time_series","intervalFactor":2,"legendFormat":"__auto"}],"title":"Queue size","type":"stat"},{"datasource":{"uid":"${prometheus_datasource}"},"description":"The number of producers attached to queue destinations.","fieldConfig":{"defaults":{"color":{"mode":"fixed"},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null}]},"unit":"none"},"overrides":[]},"gridPos":{"h":4,"w":6,"x":12,"y":0},"id":4,"options":{"colorMode":"none","graphMode":"area","justifyMode":"auto","orientation":"auto","reduceOptions":{"calcs":["lastNotNull"],"fields":"","values":false},"textMode":"auto"},"pluginVersion":"10.2.0-60139","targets":[{"datasource":{"uid":"${prometheus_datasource}"},"expr":"sum (activemq_queue_producer_count{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\", instance=~\"$instance\"})","format":"time_series","intervalFactor":2,"legendFormat":"__auto"}],"title":"Producers","type":"stat"},{"datasource":{"uid":"${prometheus_datasource}"},"description":"The number of consumers subscribed to queue destinations.","fieldConfig":{"defaults":{"color":{"mode":"fixed"},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null}]},"unit":"none"},"overrides":[]},"gridPos":{"h":4,"w":6,"x":18,"y":0},"id":5,"options":{"colorMode":"none","graphMode":"area","justifyMode":"auto","orientation":"auto","reduceOptions":{"calcs":["lastNotNull"],"fields":"","values":false},"textMode":"auto"},"pluginVersion":"10.2.0-60139","targets":[{"datasource":{"uid":"${prometheus_datasource}"},"expr":"sum (activemq_queue_consumer_count{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\", instance=~\"$instance\"})","format":"time_series","intervalFactor":2,"legendFormat":"__auto"}],"title":"Consumers","type":"stat"},{"datasource":{"uid":"${prometheus_datasource}"},"description":"The rate messages sent to queue destinations.","fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","axisShow":false,"barAlignment":0,"drawStyle":"line","fillOpacity":25,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"smooth","lineWidth":2,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"never","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null}]},"unit":"mps"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":0,"y":4},"id":6,"options":{"legend":{"calcs":[],"displayMode":"list","placement":"right","showLegend":true},"tooltip":{"mode":"multi","sort":"desc"}},"targets":[{"datasource":{"uid":"${prometheus_datasource}"},"expr":"topk by(instance, activemq_cluster, job) ($k_selector, rate(activemq_queue_enqueue_count{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\", instance=~\"$instance\", destination=~\".*$name.*\"}[$__rate_interval]))","format":"time_series","intervalFactor":2,"legendFormat":"{{activemq_cluster}} - {{instance}} - {{destination}}"}],"title":"Top queues by enqueue rate","type":"timeseries"},{"datasource":{"uid":"${prometheus_datasource}"},"description":"The rate messages have been acknowledged (and removed) from queue destinations.","fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","axisShow":false,"barAlignment":0,"drawStyle":"line","fillOpacity":25,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"smooth","lineWidth":2,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"never","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null}]},"unit":"mps"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":12,"y":4},"id":7,"options":{"legend":{"calcs":[],"displayMode":"list","placement":"right","showLegend":true},"tooltip":{"mode":"multi","sort":"desc"}},"targets":[{"datasource":{"uid":"${prometheus_datasource}"},"expr":"topk by(instance, activemq_cluster) ($k_selector, rate(activemq_queue_dequeue_count{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\",instance=~\"$instance\", destination=~\".*$name.*\"}[$__rate_interval]))","format":"time_series","intervalFactor":2,"legendFormat":"{{activemq_cluster}} - {{instance}} - {{destination}}"}],"title":"Top queues by dequeue rate","type":"timeseries"},{"datasource":{"uid":"${prometheus_datasource}"},"description":"Average time a message was held on queue destinations.","fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","axisShow":false,"barAlignment":0,"drawStyle":"line","fillOpacity":25,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"smooth","lineWidth":2,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"never","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null}]},"unit":"ms"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":0,"y":12},"id":8,"options":{"legend":{"calcs":[],"displayMode":"list","placement":"right","showLegend":true},"tooltip":{"mode":"multi","sort":"desc"}},"targets":[{"datasource":{"uid":"${prometheus_datasource}"},"expr":"topk by(instance, activemq_cluster) ($k_selector, activemq_queue_average_enqueue_time{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\", instance=~\"$instance\", destination=~\".*$name.*\"})","format":"time_series","intervalFactor":2,"legendFormat":"{{activemq_cluster}} - {{instance}} - {{destination}}"}],"title":"Top queues by average enqueue time","type":"timeseries"},{"datasource":{"uid":"${prometheus_datasource}"},"description":"The rate messages have expired on queue destinations.","fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","axisShow":false,"barAlignment":0,"drawStyle":"line","fillOpacity":25,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"smooth","lineWidth":2,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"never","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null}]},"unit":"mps"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":12,"y":12},"id":9,"options":{"legend":{"calcs":[],"displayMode":"list","placement":"right","showLegend":true},"tooltip":{"mode":"multi","sort":"desc"}},"targets":[{"datasource":{"uid":"${prometheus_datasource}"},"expr":"topk by(instance, activemq_cluster, job) ($k_selector, rate(activemq_queue_expired_count{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\", instance=~\"$instance\", destination=~\".*$name.*\"}[$__rate_interval]))","format":"time_series","intervalFactor":2,"legendFormat":"{{activemq_cluster}} - {{instance}} - {{destination}}"}],"title":"Top queues by expired message rate","type":"timeseries"},{"datasource":{"uid":"${prometheus_datasource}"},"description":"Average message size on queue destinations.","fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","axisShow":false,"axisSoftMin":0,"barAlignment":0,"drawStyle":"line","fillOpacity":25,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"smooth","lineWidth":2,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"never","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"min":0,"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null}]},"unit":"decbytes"},"overrides":[]},"gridPos":{"h":7,"w":24,"x":0,"y":20},"id":10,"options":{"legend":{"calcs":[],"displayMode":"list","placement":"right","showLegend":true},"tooltip":{"mode":"multi","sort":"desc"}},"targets":[{"datasource":{"uid":"${prometheus_datasource}"},"expr":"topk by(instance, activemq_cluster, job) ($k_selector, activemq_queue_average_message_size{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\", instance=~\"$instance\", destination=~\".*$name.*\"})","format":"time_series","intervalFactor":2,"legendFormat":"{{activemq_cluster}} - {{instance}} - {{destination}}"}],"title":"Top queues by average message size","type":"timeseries"},{"datasource":{"uid":"${prometheus_datasource}"},"description":"Summary of queues showing queue name, enqueue and dequeue rate, average enqueue time, and average message size.","fieldConfig":{"defaults":{"color":{"mode":"thresholds"},"custom":{"align":"center","cellOptions":{"type":"auto"},"inspect":false},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green"}]}},"overrides":[{"matcher":{"id":"byName","options":"Average message size"},"properties":[{"id":"unit","value":"decbytes"}]},{"matcher":{"id":"byName","options":"Enqueue rate"},"properties":[{"id":"unit","value":"mps"}]},{"matcher":{"id":"byName","options":"Dequeue rate"},"properties":[{"id":"unit","value":"mps"}]},{"matcher":{"id":"byName","options":"Average enqueue time"},"properties":[{"id":"unit","value":"ms"}]},{"matcher":{"id":"byName","options":"ActiveMQ cluster"},"properties":[{"id":"links","value":[{"title":"Cluster link","url":"d/apache-activemq-cluster-overview?var-activemq_cluster=${__data.fields.activemq_cluster}\u0026${__url_time_range}\u0026var-datasource=${datasource}"}]}]},{"matcher":{"id":"byName","options":"Instance"},"properties":[{"id":"links","value":[{"title":"Instance link","url":"d/apache-activemq-instance-overview?var-instance=${__data.fields.instance}\u0026${__url_time_range}\u0026var-datasource=${datasource}"}]}]}]},"gridPos":{"h":7,"w":24,"x":0,"y":27},"id":11,"options":{"cellHeight":"sm","footer":{"countRows":false,"fields":"","reducer":["sum"],"show":false},"showHeader":true,"sortBy":[]},"pluginVersion":"10.2.0-60139","targets":[{"datasource":{"uid":"${prometheus_datasource}"},"expr":"rate(activemq_queue_enqueue_count{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\", instance=~\"$instance\", destination=~\".*$name.*\"}[$__rate_interval:])","format":"table","intervalFactor":2,"legendFormat":"{{instance}}"},{"datasource":{"uid":"${prometheus_datasource}"},"expr":"rate(activemq_queue_dequeue_count{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\", instance=~\"$instance\", destination=~\".*$name.*\"}[$__rate_interval:])","format":"table","intervalFactor":2,"legendFormat":"{{instance}}"},{"datasource":{"uid":"${prometheus_datasource}"},"expr":"activemq_queue_average_enqueue_time{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\", instance=~\"$instance\", destination=~\".*$name.*\"}","format":"table","intervalFactor":2,"legendFormat":"{{instance}}"},{"datasource":{"uid":"${prometheus_datasource}"},"expr":"activemq_queue_average_message_size{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\", instance=~\"$instance\", destination=~\".*$name.*\"}","format":"table","intervalFactor":2,"legendFormat":"{{instance}}"}],"title":"Queue summary","transformations":[{"id":"joinByField","options":{"byField":"destination","mode":"outer"}},{"id":"organize","options":{"indexByName":{},"renameByName":{"Time 1":"","Value #A":"Enqueue rate","Value #B":"Dequeue rate","Value #C":"Average enqueue time","Value #D":"Average message size","activemq_cluster 1":"ActiveMQ cluster","destination":"Destination","instance 1":"Instance"}}},{"id":"filterFieldsByName","options":{"include":{"names":["ActiveMQ cluster","Instance","Enqueue rate","Dequeue rate","Average enqueue time","Average message size","Destination"]}}}],"type":"table"}],"refresh":"30s","rows":[],"schemaVersion":14,"style":"dark","tags":["apache-activemq-integration"],"templating":{"list":[{"current":{},"hide":0,"label":"Data source","name":"prometheus_datasource","options":[],"query":"prometheus","refresh":1,"regex":"(?!grafanacloud-usage|grafanacloud-ml-metrics).+","type":"datasource"},{"allValue":".+","current":{},"datasource":{"uid":"${prometheus_datasource}"},"hide":0,"includeAll":true,"label":"Job","multi":true,"name":"job","options":[],"query":"label_values(activemq_topic_producer_count,job)","refresh":2,"regex":"","sort":0,"tagValuesQuery":"","tags":[],"tagsQuery":"","type":"query","useTags":false},{"allValue":".*","current":{},"datasource":{"uid":"${prometheus_datasource}"},"hide":0,"includeAll":true,"label":"Cluster","multi":true,"name":"cluster","options":[],"query":"label_values(activemq_memory_usage_ratio{job=~\"$job\"},cluster)","refresh":2,"regex":"","sort":0,"tagValuesQuery":"","tags":[],"tagsQuery":"","type":"query","useTags":false},{"allValue":".+","current":{},"datasource":{"uid":"${prometheus_datasource}"},"hide":0,"includeAll":true,"label":"ActiveMQ cluster","multi":true,"name":"activemq_cluster","options":[],"query":"label_values(activemq_memory_usage_ratio{job=~\"$job\", cluster=~\"$cluster\"},activemq_cluster)","refresh":2,"regex":"","sort":0,"tagValuesQuery":"","tags":[],"tagsQuery":"","type":"query","useTags":false},{"allValue":".+","current":{},"datasource":{"uid":"${prometheus_datasource}"},"hide":0,"includeAll":true,"label":"Instance","multi":true,"name":"instance","options":[],"query":"label_values(activemq_topic_producer_count{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\"},instance)","refresh":2,"regex":"","sort":0,"tagValuesQuery":"","tags":[],"tagsQuery":"","type":"query","useTags":false},{"allValue":"","current":{"text":"4","value":"4"},"hide":0,"includeAll":false,"label":"Top queue count","multi":false,"name":"k_selector","options":[{"text":"2","value":"2"},{"text":"4","value":"4"},{"text":"6","value":"6"},{"text":"8","value":"8"},{"text":"10","value":"10"}],"query":"2,4,6,8,10","refresh":0,"type":"custom"},{"current":{"selected":false,"text":"","value":""},"label":"Queue by name","name":"name","query":"","type":"textbox"}]},"time":{"from":"now-30m","to":"now"},"timepicker":{"refresh_intervals":["5s","10s","30s","1m","5m","15m","30m","1h","2h","1d"],"time_options":["5m","15m","1h","6h","12h","24h","2d","7d","30d"]},"timezone":"default","title":"Apache ActiveMQ queue overview","uid":"apache-activemq-queue-overview","version":0},"folder_name":"Integration - Apache ActiveMQ","overwrite":true},{"dashboard":{"__inputs":[],"__requires":[],"annotations":{"list":[]},"description":"","editable":false,"gnetId":null,"graphTooltip":0,"hideControls":false,"id":null,"links":[{"asDropdown":false,"icon":"external link","includeVars":true,"keepTime":true,"tags":["apache-activemq-integration"],"targetBlank":false,"title":"Other Apache ActiveMQ dashboards","type":"dashboards","url":""}],"panels":[{"datasource":{"uid":"${prometheus_datasource}"},"description":"Number of topics connected with the broker instance.","fieldConfig":{"defaults":{"color":{"mode":"fixed"},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null}]},"unit":"none"},"overrides":[]},"gridPos":{"h":4,"w":6,"x":0,"y":0},"id":2,"options":{"colorMode":"none","graphMode":"area","justifyMode":"auto","orientation":"auto","reduceOptions":{"calcs":["lastNotNull"],"fields":"","values":false},"textMode":"auto"},"pluginVersion":"10.2.0-60139","targets":[{"datasource":{"uid":"${prometheus_datasource}"},"expr":"count (activemq_topic_queue_size{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\", instance=~\"$instance\", destination!~\"ActiveMQ.Advisory.*\"})","format":"time_series","intervalFactor":2,"legendFormat":"__auto"}],"title":"Topics","type":"stat"},{"datasource":{"uid":"${prometheus_datasource}"},"description":"The number of producers attached to topic destinations.","fieldConfig":{"defaults":{"color":{"mode":"fixed"},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null}]},"unit":"none"},"overrides":[]},"gridPos":{"h":4,"w":6,"x":6,"y":0},"id":3,"options":{"colorMode":"none","graphMode":"area","justifyMode":"auto","orientation":"auto","reduceOptions":{"calcs":["lastNotNull"],"fields":"","values":false},"textMode":"auto"},"pluginVersion":"10.2.0-60139","targets":[{"datasource":{"uid":"${prometheus_datasource}"},"expr":"sum (activemq_topic_producer_count{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\", instance=~\"$instance\", destination!~\"ActiveMQ.Advisory.*\"})","format":"time_series","intervalFactor":2,"legendFormat":"__auto"}],"title":"Producers","type":"stat"},{"datasource":{"uid":"${prometheus_datasource}"},"description":"The number of consumers subscribed to topic destinations.","fieldConfig":{"defaults":{"color":{"mode":"fixed"},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null}]},"unit":"none"},"overrides":[]},"gridPos":{"h":4,"w":6,"x":12,"y":0},"id":4,"options":{"colorMode":"none","graphMode":"area","justifyMode":"auto","orientation":"auto","reduceOptions":{"calcs":["lastNotNull"],"fields":"","values":false},"textMode":"auto"},"pluginVersion":"10.2.0-60139","targets":[{"datasource":{"uid":"${prometheus_datasource}"},"expr":"sum (activemq_topic_consumer_count{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\", instance=~\"$instance\", destination!~\"ActiveMQ.Advisory.*\"})","format":"time_series","intervalFactor":2,"legendFormat":"__auto"}],"title":"Consumers","type":"stat"},{"datasource":{"uid":"${prometheus_datasource}"},"description":"Average number of consumers per topic.","fieldConfig":{"defaults":{"color":{"mode":"fixed"},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null}]},"unit":"none"},"overrides":[]},"gridPos":{"h":4,"w":6,"x":18,"y":0},"id":5,"options":{"colorMode":"none","graphMode":"area","justifyMode":"auto","orientation":"auto","reduceOptions":{"calcs":["lastNotNull"],"fields":"","values":false},"textMode":"auto"},"pluginVersion":"10.2.0-60139","targets":[{"datasource":{"uid":"${prometheus_datasource}"},"expr":"avg (activemq_topic_consumer_count{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\", instance=~\"$instance\", destination!~\"ActiveMQ.Advisory.*\"})","format":"time_series","intervalFactor":2,"legendFormat":"__auto"}],"title":"Average consumers per topic","type":"stat"},{"datasource":{"uid":"${prometheus_datasource}"},"description":"The rate messages are sent to topic destinations.","fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","axisShow":false,"barAlignment":0,"drawStyle":"line","fillOpacity":25,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"smooth","lineWidth":2,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"never","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null}]},"unit":"mps"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":0,"y":4},"id":6,"options":{"legend":{"calcs":[],"displayMode":"list","placement":"right","showLegend":true},"tooltip":{"mode":"multi","sort":"desc"}},"targets":[{"datasource":{"uid":"${prometheus_datasource}"},"expr":"topk by(instance, activemq_cluster, job) ($k_selector, rate(activemq_topic_enqueue_count{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\", instance=~\"$instance\", destination!~\"ActiveMQ.Advisory.*\", destination=~\".*$name.*\"}[$__rate_interval]))","format":"time_series","intervalFactor":2,"legendFormat":"{{activemq_cluster}} - {{instance}} - {{destination}}"}],"title":"Top topics by enqueue rate","type":"timeseries"},{"datasource":{"uid":"${prometheus_datasource}"},"description":"The rate messages have been acknowledged (and removed) from topic destinations","fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","axisShow":false,"barAlignment":0,"drawStyle":"line","fillOpacity":25,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"smooth","lineWidth":2,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"never","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null}]},"unit":"mps"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":12,"y":4},"id":7,"options":{"legend":{"calcs":[],"displayMode":"list","placement":"right","showLegend":true},"tooltip":{"mode":"multi","sort":"desc"}},"targets":[{"datasource":{"uid":"${prometheus_datasource}"},"expr":"topk by(instance, activemq_cluster, job) ($k_selector, rate(activemq_topic_dequeue_count{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\", instance=~\"$instance\", destination!~\"ActiveMQ.Advisory.*\", destination=~\".*$name.*\"}[$__rate_interval]))","format":"time_series","intervalFactor":2,"legendFormat":"{{activemq_cluster}} - {{instance}} - {{destination}}"}],"title":"Top topics by dequeue rate","type":"timeseries"},{"datasource":{"uid":"${prometheus_datasource}"},"description":"Average time a message was held across all topic destinations.","fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","axisShow":false,"barAlignment":0,"drawStyle":"line","fillOpacity":25,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"smooth","lineWidth":2,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"never","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null}]},"unit":"ms"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":0,"y":12},"id":8,"options":{"legend":{"calcs":[],"displayMode":"list","placement":"right","showLegend":true},"tooltip":{"mode":"multi","sort":"desc"}},"targets":[{"datasource":{"uid":"${prometheus_datasource}"},"expr":"topk by(instance, activemq_cluster, job) ($k_selector, activemq_topic_average_enqueue_time{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\", instance=~\"$instance\", destination!~\"ActiveMQ.Advisory.*\", destination=~\".*$name.*\"})","format":"time_series","intervalFactor":2,"legendFormat":"{{activemq_cluster}} - {{instance}} - {{destination}}"}],"title":"Top topics by average enqueue time","type":"timeseries"},{"datasource":{"uid":"${prometheus_datasource}"},"description":"The rate messages have expired on topic destinations.","fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","axisShow":false,"barAlignment":0,"drawStyle":"line","fillOpacity":25,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"smooth","lineWidth":2,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"never","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null}]},"unit":"mps"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":12,"y":12},"id":9,"options":{"legend":{"calcs":[],"displayMode":"list","placement":"right","showLegend":true},"tooltip":{"mode":"multi","sort":"desc"}},"targets":[{"datasource":{"uid":"${prometheus_datasource}"},"expr":"topk by(instance, activemq_cluster, job) ($k_selector, rate(activemq_topic_expired_count{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\", instance=~\"$instance\", destination!~\"ActiveMQ.Advisory.*\", destination=~\".*$name.*\"}[$__rate_interval]))","format":"time_series","intervalFactor":2,"legendFormat":"{{activemq_cluster}} - {{instance}} - {{destination}}"}],"title":"Top topics by expired message rate","type":"timeseries"},{"datasource":{"uid":"${prometheus_datasource}"},"description":"The number of consumers subscribed to the most active/used topics.","fieldConfig":{"defaults":{"color":{"mode":"fixed"},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null}]},"unit":"none"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":0,"y":20},"id":10,"options":{"displayMode":"gradient","minVizHeight":10,"minVizWidth":0,"orientation":"horizontal","reduceOptions":{"calcs":["lastNotNull"],"fields":"","values":false},"showUnfilled":true,"valueMode":"color"},"pluginVersion":"10.2.0-60139","targets":[{"datasource":{"uid":"${prometheus_datasource}"},"expr":"topk by(instance, activemq_cluster, job) ($k_selector, activemq_topic_consumer_count{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\", instance=~\"$instance\", destination!~\"ActiveMQ.Advisory.*\", destination=~\".*$name.*\"})","format":"time_series","intervalFactor":2,"legendFormat":"{{activemq_cluster}} - {{instance}} - {{destination}}"}],"title":"Top topics by consumers","type":"bargauge"},{"datasource":{"uid":"${prometheus_datasource}"},"description":"Average message size on topic destinations.","fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","axisShow":false,"axisSoftMin":0,"barAlignment":0,"drawStyle":"line","fillOpacity":25,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"smooth","lineWidth":2,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"never","spanNulls":false,"stacking":{"group":"A","mode":"normal"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"min":0,"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null}]},"unit":"decbytes"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":12,"y":20},"id":11,"options":{"legend":{"calcs":[],"displayMode":"list","placement":"right","showLegend":true},"tooltip":{"mode":"multi","sort":"desc"}},"targets":[{"datasource":{"uid":"${prometheus_datasource}"},"expr":"topk by(instance, activemq_cluster, job) ($k_selector, activemq_topic_average_message_size{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\", instance=~\"$instance\", destination!~\"ActiveMQ.Advisory.*\", destination=~\".*$name.*\"})","format":"time_series","intervalFactor":2,"legendFormat":"{{activemq_cluster}} - {{instance}} - {{destination}}"}],"title":"Top topics by average message size","type":"timeseries"},{"datasource":{"uid":"${prometheus_datasource}"},"description":"Summary of topics showing topic name, enqueue and dequeue rate, average enqueue time, and average message size.","fieldConfig":{"defaults":{"color":{"mode":"thresholds"},"custom":{"align":"left","cellOptions":{"type":"auto"},"inspect":false},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green"}]}},"overrides":[{"matcher":{"id":"byName","options":"Enqueue rate"},"properties":[{"id":"unit","value":"mps"}]},{"matcher":{"id":"byName","options":"Dequeue rate"},"properties":[{"id":"unit","value":"mps"}]},{"matcher":{"id":"byName","options":"Average enqueue time"},"properties":[{"id":"unit","value":"ms"}]},{"matcher":{"id":"byName","options":"Average message size"},"properties":[{"id":"unit","value":"decbytes"}]},{"matcher":{"id":"byName","options":"ActiveMQ cluster"},"properties":[{"id":"links","value":[{"title":"Cluster link","url":"d/apache-activemq-cluster-overview?var-activemq_cluster=${__data.fields.activemq_cluster}\u0026${__url_time_range}\u0026var-datasource=${datasource}"}]}]},{"matcher":{"id":"byName","options":"Instance"},"properties":[{"id":"links","value":[{"title":"Instance link","url":"d/apache-activemq-instance-overview?var-instance=${__data.fields.instance}\u0026${__url_time_range}\u0026var-datasource=${datasource}"}]}]}]},"gridPos":{"h":8,"w":24,"x":0,"y":28},"id":12,"options":{"cellHeight":"sm","footer":{"countRows":false,"fields":"","reducer":["sum"],"show":false},"showHeader":true},"pluginVersion":"10.2.0-60139","targets":[{"datasource":{"uid":"${prometheus_datasource}"},"expr":"rate(activemq_topic_enqueue_count{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\", instance=~\"$instance\", destination!~\"ActiveMQ.Advisory.*\", destination=~\".*$name.*\"}[$__rate_interval])","format":"table","intervalFactor":2,"legendFormat":"{{instance}}"},{"datasource":{"uid":"${prometheus_datasource}"},"expr":"rate(activemq_topic_dequeue_count{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\", instance=~\"$instance\", destination!~\"ActiveMQ.Advisory.*\", destination=~\".*$name.*\"}[$__rate_interval])","format":"table","intervalFactor":2,"legendFormat":"{{instance}}"},{"datasource":{"uid":"${prometheus_datasource}"},"expr":"activemq_topic_average_enqueue_time{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\", instance=~\"$instance\", destination!~\"ActiveMQ.Advisory.*\", destination=~\".*$name.*\"}","format":"table","intervalFactor":2,"legendFormat":"{{instance}}"},{"datasource":{"uid":"${prometheus_datasource}"},"expr":"activemq_topic_average_message_size{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\", instance=~\"$instance\", destination!~\"ActiveMQ.Advisory.*\", destination=~\".*$name.*\"}","format":"table","intervalFactor":2,"legendFormat":"{{instance}}"}],"title":"Topic summary","transformations":[{"id":"joinByField","options":{"byField":"destination","mode":"outer"}},{"id":"organize","options":{"indexByName":{},"renameByName":{"Time 3":"","Value #A":"Enqueue rate","Value #B":"Dequeue rate","Value #C":"Average enqueue time","Value #D":"Average message size","activemq_cluster 1":"ActiveMQ cluster","destination":"Destination","instance 1":"Instance"}}},{"id":"filterFieldsByName","options":{"include":{"names":["ActiveMQ cluster","Instance","Enqueue rate","Dequeue rate","Average enqueue time","Average message size","Destination"]}}}],"type":"table"}],"refresh":"30s","rows":[],"schemaVersion":14,"style":"dark","tags":["apache-activemq-integration"],"templating":{"list":[{"current":{},"hide":0,"label":"Data source","name":"prometheus_datasource","options":[],"query":"prometheus","refresh":1,"regex":"(?!grafanacloud-usage|grafanacloud-ml-metrics).+","type":"datasource"},{"allValue":".+","current":{},"datasource":{"uid":"${prometheus_datasource}"},"hide":0,"includeAll":true,"label":"Job","multi":true,"name":"job","options":[],"query":"label_values(activemq_topic_producer_count,job)","refresh":2,"regex":"","sort":0,"tagValuesQuery":"","tags":[],"tagsQuery":"","type":"query","useTags":false},{"allValue":".*","current":{},"datasource":{"uid":"${prometheus_datasource}"},"hide":0,"includeAll":true,"label":"Cluster","multi":true,"name":"cluster","options":[],"query":"label_values(activemq_memory_usage_ratio{job=~\"$job\"},cluster)","refresh":2,"regex":"","sort":0,"tagValuesQuery":"","tags":[],"tagsQuery":"","type":"query","useTags":false},{"allValue":".+","current":{},"datasource":{"uid":"${prometheus_datasource}"},"hide":0,"includeAll":true,"label":"ActiveMQ cluster","multi":true,"name":"activemq_cluster","options":[],"query":"label_values(activemq_memory_usage_ratio{job=~\"$job\", cluster=~\"$cluster\"},activemq_cluster)","refresh":2,"regex":"","sort":0,"tagValuesQuery":"","tags":[],"tagsQuery":"","type":"query","useTags":false},{"allValue":".+","current":{},"datasource":{"uid":"${prometheus_datasource}"},"hide":0,"includeAll":true,"label":"Instance","multi":true,"name":"instance","options":[],"query":"label_values(activemq_topic_producer_count{job=~\"$job\", cluster=~\"$cluster\",activemq_cluster=~\"$activemq_cluster\"},instance)","refresh":2,"regex":"","sort":0,"tagValuesQuery":"","tags":[],"tagsQuery":"","type":"query","useTags":false},{"allValue":"","current":{"text":"4","value":"4"},"hide":0,"includeAll":false,"label":"Top topic count","multi":false,"name":"k_selector","options":[{"text":"2","value":"2"},{"text":"4","value":"4"},{"text":"6","value":"6"},{"text":"8","value":"8"},{"text":"10","value":"10"}],"query":"2,4,6,8,10","refresh":0,"type":"custom"},{"current":{"selected":false,"text":"","value":""},"label":"Topic by name","name":"name","query":"","type":"textbox"}]},"time":{"from":"now-30m","to":"now"},"timepicker":{"refresh_intervals":["5s","10s","30s","1m","5m","15m","30m","1h","2h","1d"],"time_options":["5m","15m","1h","6h","12h","24h","2d","7d","30d"]},"timezone":"default","title":"Apache ActiveMQ topic overview","uid":"apache-activemq-topic-overview","version":0},"folder_name":"Integration - Apache ActiveMQ","overwrite":true}]}
+ ```
+
+## Create the folders
+- method POST
+- path /api/folders
+- body example:
+ ```
+ {"title":"Integration - Apache ActiveMQ","uid":"integration---apache-activemq"}
+ ```
+- expected:
+ - code 200
+ - body example
+ ```
+ {"id":224,"uid":"integration---apache-activemq","orgId":1,"title":"Integration - Apache ActiveMQ","url":"/dashboards/f/integration---apache-activemq/integration-apache-activemq","hasAcl":false,"canSave":true,"canEdit":true,"canAdmin":true,"canDelete":true,"createdBy":"clement2b5f","created":"2025-05-23T15:17:59Z","updatedBy":"clement2b5f","updated":"2025-05-23T15:17:59Z","version":1}
+ ```
+
+## Add the dashboard (Iterate for each dashboard of the integration)
+- method POST
+- path /api/dashboards/db
+- body example:
+ ```
+ {"dashboard":{"__inputs":[],"__requires":[],"annotations":{"list":[]},"description":"","editable":false,"gnetId":null,"graphTooltip":0,"hideControls":false,"id":null,"links":[{"asDropdown":false,"icon":"external link","includeVars":true,"keepTime":true,"tags":["apache-activemq-integration"],"targetBlank":false,"title":"Other Apache ActiveMQ dashboards","type":"dashboards","url":""}],"panels":[{"datasource":{"type":"datasource","uid":"-- Mixed --"},"description":"Shows if metrics are being received for the selected time range.","fieldConfig":{"defaults":{"color":{"fixedColor":"text","mode":"fixed"},"mappings":[{"options":{"match":"null","result":{"color":"light-red","index":0,"text":"No metrics received - Check configuration"}},"type":"special"},{"options":{"from":0,"result":{"color":"light-red","index":1,"text":"Failed to collect metrics"},"to":0},"type":"range"},{"options":{"from":1,"result":{"color":"light-green","index":2,"text":"Receiving metrics"},"to":1000000},"type":"range"}],"noValue":"No data","unit":"string"}},"gridPos":{"h":2,"w":8,"x":0,"y":0},"options":{"colorMode":"background","graphMode":"none","reduceOptions":{"calcs":["lastNotNull"]}},"pluginVersion":"v10.0.0","targets":[{"datasource":{"type":"prometheus","uid":"$prometheus_datasource"},"expr":"sum(up{job=~\"$job\"})\n"}],"title":"Metrics","type":"stat"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"description":"Shows the timestamp of the latest metrics received for this integration in the last 24 hours.","fieldConfig":{"defaults":{"color":{"fixedColor":"text","mode":"fixed"},"noValue":"No data","unit":"dateTimeFromNow"}},"gridPos":{"h":2,"w":8,"x":8,"y":0},"options":{"colorMode":"background","graphMode":"none","reduceOptions":{"calcs":["lastNotNull"],"fields":"Time"}},"pluginVersion":"v10.0.0","targets":[{"datasource":{"type":"prometheus","uid":"$prometheus_datasource"},"expr":"sum(up{job=~\"$job\"})\n"}],"timeFrom":"now-24h","title":"Latest metrics received","type":"stat"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"description":"Shows the installed version of this integration.","fieldConfig":{"defaults":{"color":{"fixedColor":"text","mode":"fixed"},"noValue":"1.0.1","unit":"string"}},"gridPos":{"h":2,"w":8,"x":16,"y":0},"pluginVersion":"v10.0.0","title":"Integration version","type":"stat"},{"datasource":{"uid":"${prometheus_datasource}"},"description":"Number of clusters that are reporting metrics from ActiveMQ.","fieldConfig":{"defaults":{"color":{"mode":"fixed"},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null}]},"unit":"none"},"overrides":[]},"gridPos":{"h":4,"w":6,"x":0,"y":3},"id":2,"options":{"colorMode":"none","graphMode":"area","justifyMode":"auto","orientation":"auto","reduceOptions":{"calcs":["lastNotNull"],"fields":"","values":false},"textMode":"auto"},"pluginVersion":"10.2.0-60139","targets":[{"datasource":{"uid":"${prometheus_datasource}"},"expr":"count (activemq_memory_usage_ratio{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\"})","format":"time_series","intervalFactor":2,"legendFormat":"__auto"}],"title":"Clusters","type":"stat"},{"datasource":{"uid":"${prometheus_datasource}"},"description":"Number of broker instances across clusters.","fieldConfig":{"defaults":{"color":{"mode":"fixed"},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null}]},"unit":"none"},"overrides":[]},"gridPos":{"h":4,"w":6,"x":6,"y":3},"id":3,"options":{"colorMode":"none","graphMode":"area","justifyMode":"auto","orientation":"auto","reduceOptions":{"calcs":["lastNotNull"],"fields":"","values":false},"textMode":"auto"},"pluginVersion":"10.2.0-60139","targets":[{"datasource":{"uid":"${prometheus_datasource}"},"expr":"count (activemq_memory_usage_ratio{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\"})","format":"time_series","intervalFactor":2,"legendFormat":"__auto"}],"title":"Brokers","type":"stat"},{"datasource":{"uid":"${prometheus_datasource}"},"description":"Number of message producers active on destinations across clusters.","fieldConfig":{"defaults":{"color":{"mode":"fixed"},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null}]},"unit":"none"},"overrides":[]},"gridPos":{"h":4,"w":6,"x":12,"y":3},"id":4,"options":{"colorMode":"none","graphMode":"area","justifyMode":"auto","orientation":"auto","reduceOptions":{"calcs":["lastNotNull"],"fields":"","values":false},"textMode":"auto"},"pluginVersion":"10.2.0-60139","targets":[{"datasource":{"uid":"${prometheus_datasource}"},"expr":"sum (activemq_queue_producer_count{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\"}) + sum (activemq_topic_producer_count{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\",destination!~\"ActiveMQ.Advisory.*\"})","format":"time_series","intervalFactor":2,"legendFormat":"__auto"}],"title":"Producers","type":"stat"},{"datasource":{"uid":"${prometheus_datasource}"},"description":"The number of consumers subscribed to destinations across clusters.","fieldConfig":{"defaults":{"color":{"mode":"fixed"},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null}]},"unit":"none"},"overrides":[]},"gridPos":{"h":4,"w":6,"x":18,"y":3},"id":5,"options":{"colorMode":"none","graphMode":"area","justifyMode":"auto","orientation":"auto","reduceOptions":{"calcs":["lastNotNull"],"fields":"","values":false},"textMode":"auto"},"pluginVersion":"10.2.0-60139","targets":[{"datasource":{"uid":"${prometheus_datasource}"},"expr":"sum (activemq_queue_consumer_count{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\"}) + sum (activemq_topic_consumer_count{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\",destination!~\"ActiveMQ.Advisory.*\"})","format":"time_series","intervalFactor":2,"legendFormat":"__auto"}],"title":"Consumers","type":"stat"},{"datasource":{"uid":"${prometheus_datasource}"},"description":"Number of messages that have been sent to destinations in a cluster","fieldConfig":{"defaults":{"color":{"fixedColor":"#C8F2C2","mode":"palette-classic"},"custom":{"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","axisShow":false,"barAlignment":0,"drawStyle":"line","fillOpacity":25,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"smooth","lineWidth":2,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"never","spanNulls":false,"stacking":{"group":"A","mode":"normal"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null}]},"unit":"none"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":0,"y":9},"id":6,"options":{"legend":{"calcs":[],"displayMode":"list","placement":"right","showLegend":true},"tooltip":{"mode":"multi","sort":"desc"}},"targets":[{"datasource":{"uid":"${prometheus_datasource}"},"expr":"sum by (activemq_cluster, job) (increase(activemq_queue_enqueue_count{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\"}[$__interval:])) + sum by (activemq_cluster, job) (increase(activemq_topic_enqueue_count{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\", destination!~\"ActiveMQ.Advisory.*\"}[$__interval:]))","format":"time_series","interval":"1m","intervalFactor":2,"legendFormat":"{{activemq_cluster}}"}],"title":"Enqueue / $__interval","type":"timeseries"},{"datasource":{"uid":"${prometheus_datasource}"},"description":"Number of messages that have been acknowledged (and removed) from destinations in a cluster.","fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","axisShow":false,"barAlignment":0,"drawStyle":"line","fillOpacity":25,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"smooth","lineWidth":2,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"never","spanNulls":false,"stacking":{"group":"A","mode":"normal"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null}]},"unit":"none"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":12,"y":9},"id":7,"options":{"legend":{"calcs":[],"displayMode":"list","placement":"right","showLegend":true},"tooltip":{"mode":"multi","sort":"desc"}},"targets":[{"datasource":{"uid":"${prometheus_datasource}"},"expr":"sum by (activemq_cluster, job) (increase(activemq_queue_dequeue_count{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\"}[$__interval:])) + sum by (activemq_cluster, job) (increase(activemq_topic_dequeue_count{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\", destination!~\"ActiveMQ.Advisory.*\"}[$__interval:]))","format":"time_series","interval":"1m","intervalFactor":2,"legendFormat":"{{activemq_cluster}}"}],"title":"Dequeue / $__interval","type":"timeseries"},{"datasource":{"uid":"${prometheus_datasource}"},"description":"Average percentage of temporary memory used across clusters.","fieldConfig":{"defaults":{"color":{"mode":"thresholds"},"mappings":[],"max":1,"min":0,"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"#EAB839","value":50},{"color":"red","value":70}]},"unit":"percentunit"},"overrides":[]},"gridPos":{"h":10,"w":8,"x":0,"y":17},"id":8,"options":{"displayMode":"gradient","minVizHeight":10,"minVizWidth":0,"orientation":"horizontal","reduceOptions":{"calcs":["lastNotNull"],"fields":"","values":false},"showUnfilled":false,"text":{},"valueMode":"color"},"pluginVersion":"10.2.0-60139","targets":[{"datasource":{"uid":"${prometheus_datasource}"},"expr":"avg by (activemq_cluster, job) (activemq_temp_usage_ratio{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\"})","format":"time_series","intervalFactor":2,"legendFormat":"{{activemq_cluster}}"}],"title":"Average temporary memory usage","type":"bargauge"},{"datasource":{"uid":"${prometheus_datasource}"},"description":"Average percentage of store memory used across clusters.","fieldConfig":{"defaults":{"color":{"mode":"thresholds"},"mappings":[],"max":1,"min":0,"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"#EAB839","value":50},{"color":"red","value":70}]},"unit":"percentunit"},"overrides":[]},"gridPos":{"h":10,"w":8,"x":8,"y":17},"id":9,"options":{"displayMode":"gradient","minVizHeight":10,"minVizWidth":0,"orientation":"horizontal","reduceOptions":{"calcs":["lastNotNull"],"fields":"","values":false},"showUnfilled":false,"valueMode":"color"},"pluginVersion":"10.2.0-60139","targets":[{"datasource":{"uid":"${prometheus_datasource}"},"expr":"avg by (activemq_cluster, job) (activemq_store_usage_ratio{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\"})","format":"time_series","intervalFactor":2,"legendFormat":"{{activemq_cluster}}"}],"title":"Average store memory usage","type":"bargauge"},{"datasource":{"uid":"${prometheus_datasource}"},"description":"Average percentage of broker memory used across clusters.","fieldConfig":{"defaults":{"color":{"mode":"thresholds"},"mappings":[],"max":1,"min":0,"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"#EAB839","value":50},{"color":"red","value":70}]},"unit":"percentunit"},"overrides":[]},"gridPos":{"h":10,"w":8,"x":16,"y":17},"id":10,"options":{"displayMode":"gradient","minVizHeight":10,"minVizWidth":0,"orientation":"horizontal","reduceOptions":{"calcs":["lastNotNull"],"fields":"","values":false},"showUnfilled":false,"valueMode":"color"},"pluginVersion":"10.2.0-60139","targets":[{"datasource":{"uid":"${prometheus_datasource}"},"expr":"avg by (activemq_cluster, job) (activemq_memory_usage_ratio{job=~\"$job\", cluster=~\"$cluster\", activemq_cluster=~\"$activemq_cluster\"})","format":"time_series","intervalFactor":2,"legendFormat":"{{activemq_cluster}}"}],"title":"Average broker memory usage","type":"bargauge"}],"refresh":"30s","rows":[],"schemaVersion":14,"style":"dark","tags":["apache-activemq-integration"],"templating":{"list":[{"current":{},"hide":0,"label":"Data source","name":"prometheus_datasource","options":[],"query":"prometheus","refresh":1,"regex":"(?!grafanacloud-usage|grafanacloud-ml-metrics).+","type":"datasource"},{"allValue":".+","current":{},"datasource":{"uid":"${prometheus_datasource}"},"hide":0,"includeAll":true,"label":"Job","multi":true,"name":"job","options":[],"query":"label_values(activemq_topic_producer_count,job)","refresh":2,"regex":"","sort":0,"tagValuesQuery":"","tags":[],"tagsQuery":"","type":"query","useTags":false},{"allValue":".*","current":{},"datasource":{"uid":"${prometheus_datasource}"},"hide":0,"includeAll":true,"label":"Cluster","multi":true,"name":"cluster","options":[],"query":"label_values(activemq_memory_usage_ratio{job=~\"$job\", cluster=~\"$cluster\"},cluster)","refresh":2,"regex":"","sort":0,"tagValuesQuery":"","tags":[],"tagsQuery":"","type":"query","useTags":false},{"allValue":".+","current":{},"datasource":{"uid":"${prometheus_datasource}"},"hide":0,"includeAll":true,"label":"ActiveMQ cluster","multi":true,"name":"activemq_cluster","options":[],"query":"label_values(activemq_memory_usage_ratio{job=~\"$job\", cluster=~\"$cluster\"},activemq_cluster)","refresh":2,"regex":"","sort":0,"tagValuesQuery":"","tags":[],"tagsQuery":"","type":"query","useTags":false}]},"time":{"from":"now-30m","to":"now"},"timepicker":{"refresh_intervals":["5s","10s","30s","1m","5m","15m","30m","1h","2h","1d"],"time_options":["5m","15m","1h","6h","12h","24h","2d","7d","30d"]},"timezone":"default","title":"Apache ActiveMQ cluster overview","uid":"apache-activemq-cluster-overview","version":0},"folderUid":"integration---apache-activemq","overwrite":true,"message":"creating dashboard from the Cloud Connections plugin"}
+ ```
+- expected:
+ - code 200
+ - example body
+ ```
+ {"folderUid":"integration---apache-activemq","id":235,"slug":"apache-activemq-cluster-overview","status":"success","uid":"apache-activemq-cluster-overview","url":"/d/apache-activemq-cluster-overview/apache-activemq-cluster-overview","version":1}
+ ```
+
+## Install the integration
+- method POST
+- path /api/plugin-proxy/grafana-easystart-app/integrations-api-admin/integrations/{slug}/install
+- parameters:
+ - `{slug}` the integration
+- body example:
+ ```
+ {"configuration":{"configurable_logs":{"logs_disabled":false},"configurable_alerts":{"alerts_disabled":false}}}
+ ```
+- expected:
+ - code 204
+ - no body
+
+# Uninstall one integration
+- method POST
+- path /api/plugin-proxy/grafana-easystart-app/integrations-api-admin/integrations/{slug}/uninstall
+- parameters:
+ - `{slug}` the integration
+- expected:
+ - code 204
+ - no body
+
+
+> WARNING. I have a doubt that the webclient is actually the one deleting the folders
\ No newline at end of file
diff --git a/internal/resources/integrations/client.go b/internal/resources/integrations/client.go
new file mode 100644
index 000000000..a7b805d59
--- /dev/null
+++ b/internal/resources/integrations/client.go
@@ -0,0 +1,371 @@
+package integrations
+
+import (
+ "bytes"
+ "context"
+ "encoding/json"
+ "fmt"
+ "io"
+ "net/http"
+ "net/url"
+ "strings"
+ "time"
+
+ "github.com/grafana/grafana-openapi-client-go/client/dashboards"
+ "github.com/grafana/grafana-openapi-client-go/client/folders"
+ "github.com/grafana/grafana-openapi-client-go/models"
+ "github.com/hashicorp/go-retryablehttp"
+)
+
+const (
+ // Base paths for different API operations
+ editorBasePath = "/api/plugin-proxy/grafana-easystart-app/integrations-api-editor"
+ adminBasePath = "/api/plugin-proxy/grafana-easystart-app/integrations-api-admin"
+
+ defaultRetries = 3
+ defaultTimeout = 90 * time.Second
+)
+
+// Client wraps the HTTP client for integrations API calls
+type Client struct {
+ authToken string
+ client *http.Client
+ grafanaAPIHost string
+ userAgent string
+ defaultHeaders map[string]string
+ foldersClient folders.ClientService // Grafana OpenAPI client for folder operations
+ dashboardsClient dashboards.ClientService // Grafana OpenAPI client for dashboard operations
+}
+
+// NewClient creates a new integrations client
+func NewClient(grafanaAPIHost string, authToken string, client *http.Client, userAgent string, defaultHeaders map[string]string) (*Client, error) {
+ if client == nil {
+ retryClient := retryablehttp.NewClient()
+ retryClient.RetryMax = defaultRetries
+ client = retryClient.StandardClient()
+ client.Timeout = defaultTimeout
+ }
+
+ return &Client{
+ authToken: authToken,
+ client: client,
+ grafanaAPIHost: grafanaAPIHost,
+ userAgent: userAgent,
+ defaultHeaders: defaultHeaders,
+ foldersClient: nil, // Will be set by the resource when available
+ dashboardsClient: nil, // Will be set by the resource when available
+ }, nil
+}
+
+// SetFoldersClient sets the Grafana OpenAPI folders client
+func (c *Client) SetFoldersClient(foldersClient folders.ClientService) {
+ c.foldersClient = foldersClient
+}
+
+// SetDashboardsClient sets the Grafana OpenAPI dashboards client
+func (c *Client) SetDashboardsClient(dashboardsClient dashboards.ClientService) {
+ c.dashboardsClient = dashboardsClient
+}
+
+// ListIntegrations retrieves all integrations, optionally filtering by installed status
+func (c *Client) ListIntegrations(ctx context.Context, installed bool) (*ListIntegrationsResponse, error) {
+ path := fmt.Sprintf("%s/integrations", editorBasePath)
+
+ // Add query parameter if filtering by installed
+ if installed {
+ path += "?installed=true"
+ }
+
+ var response ListIntegrationsResponse
+ err := c.doAPIRequest(ctx, http.MethodGet, path, nil, &response)
+ if err != nil {
+ return nil, fmt.Errorf("failed to list integrations: %w", err)
+ }
+
+ return &response, nil
+}
+
+// GetIntegration retrieves a specific integration by slug
+func (c *Client) GetIntegration(ctx context.Context, slug string) (*GetIntegrationResponse, error) {
+ path := fmt.Sprintf("%s/integrations/%s", editorBasePath, url.PathEscape(slug))
+
+ var response GetIntegrationResponse
+ err := c.doAPIRequest(ctx, http.MethodGet, path, nil, &response)
+ if err != nil {
+ return nil, fmt.Errorf("failed to get integration %s: %w", slug, err)
+ }
+
+ return &response, nil
+}
+
+// PostDashboards posts dashboards for an integration with the given configuration
+func (c *Client) PostDashboards(ctx context.Context, slug string, config *InstallationConfig) (*GetDashboardsResponse, error) {
+ path := fmt.Sprintf("%s/integrations/%s/dashboards", adminBasePath, url.PathEscape(slug))
+
+ requestBody := InstallIntegrationRequest{
+ Configuration: config,
+ }
+
+ var response GetDashboardsResponse
+ err := c.doAPIRequest(ctx, http.MethodPost, path, &requestBody, &response)
+ if err != nil {
+ return nil, fmt.Errorf("failed to post dashboards for integration %s: %w", slug, err)
+ }
+
+ return &response, nil
+}
+
+// generateFolderUID generates a folder UID from an integration slug
+func (c *Client) generateFolderUID(slug string) string {
+ // Replace any special characters with dashes and add the integration prefix
+ uid := strings.ReplaceAll(slug, "_", "-")
+ uid = strings.ReplaceAll(uid, " ", "-")
+ return fmt.Sprintf("integration---%s", uid)
+}
+
+// CreateFolder creates a folder using the Grafana OpenAPI client
+func (c *Client) CreateFolder(ctx context.Context, title, uid string) error {
+ if c.foldersClient == nil {
+ return fmt.Errorf("folders client not available")
+ }
+
+ body := models.CreateFolderCommand{
+ Title: title,
+ UID: uid,
+ }
+
+ _, err := c.foldersClient.CreateFolder(&body)
+ if err != nil {
+ return fmt.Errorf("failed to create folder %s: %w", title, err)
+ }
+
+ return nil
+}
+
+// DeleteFolder deletes a folder using the Grafana OpenAPI client
+func (c *Client) DeleteFolder(ctx context.Context, uid string) error {
+ if c.foldersClient == nil {
+ return fmt.Errorf("folders client not available")
+ }
+
+ _, err := c.foldersClient.DeleteFolder(folders.NewDeleteFolderParams().WithFolderUID(uid))
+ if err != nil {
+ return fmt.Errorf("failed to delete folder %s: %w", uid, err)
+ }
+
+ return nil
+}
+
+// CreateDashboard creates a dashboard in the specified folder using the Grafana OpenAPI client
+func (c *Client) CreateDashboard(ctx context.Context, dashboard Dashboard, folderUID string) error {
+ if c.dashboardsClient == nil {
+ // Fallback to raw HTTP request if OpenAPI client is not available
+ return c.createDashboardHTTP(ctx, dashboard, folderUID)
+ }
+
+ // Make a copy of the dashboard data to avoid modifying the original
+ dashboardData := make(map[string]interface{})
+ for k, v := range dashboard.Dashboard {
+ dashboardData[k] = v
+ }
+
+ // Remove id from dashboard if present (similar to resource_dashboard.go)
+ delete(dashboardData, "id")
+
+ // Convert the dashboard data to the proper format
+ dashboardCommand := models.SaveDashboardCommand{
+ Dashboard: dashboardData,
+ FolderUID: folderUID,
+ Overwrite: dashboard.Overwrite,
+ Message: "creating dashboard from the Cloud Connections plugin",
+ }
+
+ // Use the OpenAPI client
+ _, err := c.dashboardsClient.PostDashboard(&dashboardCommand)
+ if err != nil {
+ return fmt.Errorf("failed to create dashboard using OpenAPI client: %w", err)
+ }
+
+ return nil
+}
+
+// createDashboardHTTP creates a dashboard using raw HTTP requests as fallback
+func (c *Client) createDashboardHTTP(ctx context.Context, dashboard Dashboard, folderUID string) error {
+ path := "/api/dashboards/db"
+
+ // Make a copy of the dashboard data to avoid modifying the original
+ dashboardData := make(map[string]interface{})
+ for k, v := range dashboard.Dashboard {
+ dashboardData[k] = v
+ }
+
+ // Remove id from dashboard if present
+ delete(dashboardData, "id")
+
+ requestBody := map[string]interface{}{
+ "dashboard": dashboardData,
+ "folderUid": folderUID,
+ "overwrite": dashboard.Overwrite,
+ "message": "creating dashboard from the Cloud Connections plugin",
+ }
+
+ err := c.doAPIRequest(ctx, http.MethodPost, path, &requestBody, nil)
+ if err != nil {
+ return fmt.Errorf("failed to create dashboard using HTTP client: %w", err)
+ }
+
+ return nil
+}
+
+// InstallIntegration installs an integration with the given configuration using the new multi-step workflow
+func (c *Client) InstallIntegration(ctx context.Context, slug string, config *InstallationConfig) error {
+ // Step 1: Get the integration details to get the folder name
+ integration, err := c.GetIntegration(ctx, slug)
+ if err != nil {
+ return fmt.Errorf("failed to get integration details: %w", err)
+ }
+
+ // Step 2: Post dashboards (this prepares the dashboards)
+ dashboardsResponse, err := c.PostDashboards(ctx, slug, config)
+ if err != nil {
+ return fmt.Errorf("failed to post dashboards: %w", err)
+ }
+
+ // Step 3: Create the folder
+ folderUID := c.generateFolderUID(slug)
+ folderTitle := integration.Data.DashboardFolder
+ err = c.CreateFolder(ctx, folderTitle, folderUID)
+ if err != nil {
+ // Check if it's a 412 error (folder already exists)
+ if strings.Contains(err.Error(), "412") || strings.Contains(err.Error(), "already exists") {
+ // Folder already exists, continue with dashboard creation
+ } else {
+ return fmt.Errorf("failed to create folder: %w", err)
+ }
+ }
+
+ // Step 4: Add each dashboard to the folder
+ for i, dashboard := range dashboardsResponse.Data {
+ err = c.CreateDashboard(ctx, dashboard, folderUID)
+ if err != nil {
+ // If dashboard creation fails, try to clean up the folder
+ _ = c.DeleteFolder(ctx, folderUID)
+ return fmt.Errorf("failed to create dashboard %d: %w", i+1, err)
+ }
+ }
+
+ // Step 5: Install the integration
+ path := fmt.Sprintf("%s/integrations/%s/install", adminBasePath, url.PathEscape(slug))
+
+ requestBody := InstallIntegrationRequest{
+ Configuration: config,
+ }
+
+ err = c.doAPIRequest(ctx, http.MethodPost, path, &requestBody, nil)
+ if err != nil {
+ // If installation fails, try to clean up the folder
+ _ = c.DeleteFolder(ctx, folderUID)
+ return fmt.Errorf("failed to install integration %s: %w", slug, err)
+ }
+
+ return nil
+}
+
+// UninstallIntegration uninstalls an integration and deletes its folder
+func (c *Client) UninstallIntegration(ctx context.Context, slug string) error {
+ // Step 1: Uninstall the integration
+ path := fmt.Sprintf("%s/integrations/%s/uninstall", adminBasePath, url.PathEscape(slug))
+
+ err := c.doAPIRequest(ctx, http.MethodPost, path, nil, nil)
+ if err != nil {
+ return fmt.Errorf("failed to uninstall integration %s: %w", slug, err)
+ }
+
+ // Step 2: Delete the folder
+ folderUID := c.generateFolderUID(slug)
+ err = c.DeleteFolder(ctx, folderUID)
+ if err != nil {
+ // Log the error but don't fail the uninstall if folder deletion fails
+ return fmt.Errorf("integration uninstalled but failed to delete folder %s: %w", folderUID, err)
+ }
+
+ return nil
+}
+
+// IsIntegrationInstalled checks if an integration is currently installed
+func (c *Client) IsIntegrationInstalled(ctx context.Context, slug string) (bool, error) {
+ integration, err := c.GetIntegration(ctx, slug)
+ if err != nil {
+ return false, err
+ }
+
+ return integration.Data.Installation != nil, nil
+}
+
+var (
+ ErrNotFound = fmt.Errorf("not found")
+ ErrUnauthorized = fmt.Errorf("request not authorized")
+)
+
+func (c *Client) doAPIRequest(ctx context.Context, method string, path string, body any, responseData any) error {
+ parsedURL, err := url.Parse(c.grafanaAPIHost)
+ if err != nil {
+ return fmt.Errorf("failed to parse grafana API url: %w", err)
+ }
+
+ var reqBodyBytes io.Reader
+ if body != nil {
+ bs, err := json.Marshal(body)
+ if err != nil {
+ return fmt.Errorf("failed to marshal request body: %w", err)
+ }
+ reqBodyBytes = bytes.NewReader(bs)
+ }
+
+ // Ensure no double slashes in URL construction
+ baseURL := strings.TrimSuffix(parsedURL.String(), "/")
+ fullURL := baseURL + path
+ req, err := http.NewRequestWithContext(ctx, method, fullURL, reqBodyBytes)
+ if err != nil {
+ return fmt.Errorf("failed to create request: %w", err)
+ }
+
+ // Add default headers
+ for k, v := range c.defaultHeaders {
+ req.Header.Add(k, v)
+ }
+
+ // Add authentication
+ req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", c.authToken))
+ req.Header.Add("Content-Type", "application/json")
+ req.Header.Add("User-Agent", c.userAgent)
+
+ // Debug logging - add the full URL to error messages
+ resp, err := c.client.Do(req)
+ if err != nil {
+ return fmt.Errorf("failed to do request to %s: %w", fullURL, err)
+ }
+
+ bodyContents, err := io.ReadAll(resp.Body)
+ defer resp.Body.Close()
+ if err != nil {
+ return fmt.Errorf("failed to read response body: %w", err)
+ }
+
+ switch {
+ case resp.StatusCode == http.StatusNotFound:
+ return ErrNotFound
+ case resp.StatusCode == http.StatusUnauthorized:
+ return ErrUnauthorized
+ case resp.StatusCode >= 400:
+ return fmt.Errorf("status: %d for URL: %s, body: %s", resp.StatusCode, fullURL, string(bodyContents))
+ case responseData == nil || resp.StatusCode == http.StatusNoContent:
+ return nil
+ }
+
+ err = json.Unmarshal(bodyContents, &responseData)
+ if err != nil {
+ return fmt.Errorf("failed to unmarshal response body: %w", err)
+ }
+ return nil
+}
diff --git a/internal/resources/integrations/models.go b/internal/resources/integrations/models.go
new file mode 100644
index 000000000..c9d2acb5a
--- /dev/null
+++ b/internal/resources/integrations/models.go
@@ -0,0 +1,102 @@
+package integrations
+
+import "time"
+
+// Integration represents an integration from the API
+type Integration struct {
+ Name string `json:"name"`
+ Slug string `json:"slug"`
+ Version string `json:"version"`
+ Overview string `json:"overview"`
+ Logo Logo `json:"logo"`
+ Type string `json:"type"`
+ Installation *Installation `json:"installation,omitempty"`
+ SearchKeywords []string `json:"search_keywords"`
+ Categories []string `json:"categories"`
+ DashboardFolder string `json:"dashboard_folder"`
+ HasUpdate bool `json:"has_update"`
+ MetricsCheckQuery string `json:"metrics_check_query"`
+ LogsCheckQuery string `json:"logs_check_query"`
+ RuleNamespace string `json:"rule_namespace"`
+}
+
+// Logo represents the logo URLs for an integration
+type Logo struct {
+ DarkThemeURL string `json:"dark_theme_url"`
+ LightThemeURL string `json:"light_theme_url"`
+}
+
+// Installation represents the installation details of an integration
+type Installation struct {
+ Version string `json:"version"`
+ InstalledOn time.Time `json:"installed_on"`
+ Configuration *InstallationConfig `json:"configuration,omitempty"`
+}
+
+// InstallationConfig represents the configuration for installing an integration
+type InstallationConfig struct {
+ ConfigurableLogs *ConfigurableLogs `json:"configurable_logs,omitempty"`
+ ConfigurableAlerts *ConfigurableAlerts `json:"configurable_alerts,omitempty"`
+}
+
+// ConfigurableLogs represents the logs configuration
+type ConfigurableLogs struct {
+ LogsDisabled bool `json:"logs_disabled"`
+}
+
+// ConfigurableAlerts represents the alerts configuration
+type ConfigurableAlerts struct {
+ AlertsDisabled bool `json:"alerts_disabled"`
+}
+
+// ListIntegrationsResponse represents the response from the list integrations API
+type ListIntegrationsResponse struct {
+ Data map[string]Integration `json:"data"`
+}
+
+// GetIntegrationResponse represents the response from the get integration API
+type GetIntegrationResponse struct {
+ Data Integration `json:"data"`
+}
+
+// InstallIntegrationRequest represents the request body for installing an integration
+type InstallIntegrationRequest struct {
+ Configuration *InstallationConfig `json:"configuration,omitempty"`
+}
+
+// Dashboard represents a dashboard from the get dashboards API
+type Dashboard struct {
+ Dashboard map[string]interface{} `json:"dashboard"`
+ FolderName string `json:"folder_name"`
+ Overwrite bool `json:"overwrite"`
+}
+
+// GetDashboardsResponse represents the response from the get dashboards API
+type GetDashboardsResponse struct {
+ Data []Dashboard `json:"data"`
+}
+
+// CreateFolderRequest represents the request body for creating a folder
+type CreateFolderRequest struct {
+ Title string `json:"title"`
+ UID string `json:"uid"`
+}
+
+// CreateFolderResponse represents the response from creating a folder
+type CreateFolderResponse struct {
+ ID int `json:"id"`
+ UID string `json:"uid"`
+ OrgID int `json:"orgId"`
+ Title string `json:"title"`
+ URL string `json:"url"`
+ HasACL bool `json:"hasAcl"`
+ CanSave bool `json:"canSave"`
+ CanEdit bool `json:"canEdit"`
+ CanAdmin bool `json:"canAdmin"`
+ CanDelete bool `json:"canDelete"`
+ CreatedBy string `json:"createdBy"`
+ Created time.Time `json:"created"`
+ UpdatedBy string `json:"updatedBy"`
+ Updated time.Time `json:"updated"`
+ Version int `json:"version"`
+}
diff --git a/internal/resources/integrations/resource_integration.go b/internal/resources/integrations/resource_integration.go
new file mode 100644
index 000000000..bf4af7d6b
--- /dev/null
+++ b/internal/resources/integrations/resource_integration.go
@@ -0,0 +1,314 @@
+package integrations
+
+import (
+ "context"
+ "fmt"
+
+ "github.com/grafana/terraform-provider-grafana/v3/internal/common"
+ "github.com/hashicorp/terraform-plugin-sdk/v2/diag"
+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
+)
+
+func resourceIntegration() *common.Resource {
+ schema := &schema.Resource{
+ Description: `
+Manages Grafana Cloud integrations.
+
+* [Official documentation](https://grafana.com/docs/grafana-cloud/data-configuration/integrations/)
+
+Required access policy scopes:
+
+* folders:read
+* folders:write
+* dashboards:read
+* dashboards:write
+
+**Note:** This resource creates folders and dashboards as part of the integration installation process, which requires additional permissions beyond the basic integration scopes.
+`,
+
+ CreateContext: createIntegration,
+ ReadContext: readIntegration,
+ UpdateContext: updateIntegration,
+ DeleteContext: deleteIntegration,
+ Importer: &schema.ResourceImporter{
+ StateContext: schema.ImportStatePassthroughContext,
+ },
+
+ Schema: map[string]*schema.Schema{
+ "slug": {
+ Type: schema.TypeString,
+ Required: true,
+ ForceNew: true,
+ Description: "The slug of the integration to install (e.g., 'docker', 'linux-node').",
+ },
+ "installed": {
+ Type: schema.TypeBool,
+ Computed: true,
+ Description: "Whether the integration is currently installed.",
+ },
+ "version": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "The version of the installed integration.",
+ },
+ "name": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "The display name of the integration.",
+ },
+ "dashboard_folder": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "The dashboard folder associated with this integration.",
+ },
+ "configuration": {
+ Type: schema.TypeList,
+ Optional: true,
+ MaxItems: 1,
+ Description: "Configuration options for the integration.",
+ Elem: &schema.Resource{
+ Schema: map[string]*schema.Schema{
+ "configurable_logs": {
+ Type: schema.TypeList,
+ Optional: true,
+ MaxItems: 1,
+ Description: "Logs configuration for the integration.",
+ Elem: &schema.Resource{
+ Schema: map[string]*schema.Schema{
+ "logs_disabled": {
+ Type: schema.TypeBool,
+ Optional: true,
+ Default: false,
+ Description: "Whether to disable logs collection for this integration.",
+ },
+ },
+ },
+ },
+ "configurable_alerts": {
+ Type: schema.TypeList,
+ Optional: true,
+ MaxItems: 1,
+ Description: "Alerts configuration for the integration.",
+ Elem: &schema.Resource{
+ Schema: map[string]*schema.Schema{
+ "alerts_disabled": {
+ Type: schema.TypeBool,
+ Optional: true,
+ Default: false,
+ Description: "Whether to disable alerts for this integration.",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ }
+
+ return common.NewLegacySDKResource(
+ common.CategoryCloud,
+ "grafana_integration",
+ common.NewResourceID(common.StringIDField("slug")),
+ schema,
+ )
+}
+
+func createIntegration(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
+ client, err := getIntegrationsClient(meta)
+ if err != nil {
+ return diag.FromErr(err)
+ }
+
+ slug := d.Get("slug").(string)
+
+ // Check if integration already exists and is installed
+ installed, err := client.IsIntegrationInstalled(ctx, slug)
+ if err != nil {
+ return diag.FromErr(fmt.Errorf("failed to check integration status: %w", err))
+ }
+
+ if installed {
+ // Integration is already installed, just set the ID and read the state
+ d.SetId(slug)
+ return readIntegration(ctx, d, meta)
+ }
+
+ // Parse configuration
+ config := parseInstallationConfig(d)
+
+ // Install the integration
+ err = client.InstallIntegration(ctx, slug, config)
+ if err != nil {
+ return diag.FromErr(fmt.Errorf("failed to install integration: %w", err))
+ }
+
+ d.SetId(slug)
+ return readIntegration(ctx, d, meta)
+}
+
+func readIntegration(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
+ client, err := getIntegrationsClient(meta)
+ if err != nil {
+ return diag.FromErr(err)
+ }
+
+ slug := d.Id()
+
+ integration, err := client.GetIntegration(ctx, slug)
+ if err != nil {
+ if err == ErrNotFound {
+ return common.WarnMissing("integration", d)
+ }
+ return diag.FromErr(fmt.Errorf("failed to get integration: %w", err))
+ }
+
+ // Set computed attributes
+ d.Set("slug", integration.Data.Slug)
+ d.Set("name", integration.Data.Name)
+ d.Set("version", integration.Data.Version)
+ d.Set("dashboard_folder", integration.Data.DashboardFolder)
+ d.Set("installed", integration.Data.Installation != nil)
+
+ // Set configuration if available
+ if integration.Data.Installation != nil && integration.Data.Installation.Configuration != nil {
+ config := flattenInstallationConfig(integration.Data.Installation.Configuration)
+ d.Set("configuration", config)
+ }
+
+ return nil
+}
+
+func updateIntegration(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
+ client, err := getIntegrationsClient(meta)
+ if err != nil {
+ return diag.FromErr(err)
+ }
+
+ slug := d.Id()
+
+ // For now, we handle updates by uninstalling and reinstalling
+ // This is because the API doesn't seem to have an update endpoint
+ if d.HasChange("configuration") {
+ // Uninstall first
+ err = client.UninstallIntegration(ctx, slug)
+ if err != nil {
+ return diag.FromErr(fmt.Errorf("failed to uninstall integration for update: %w", err))
+ }
+
+ // Parse new configuration
+ config := parseInstallationConfig(d)
+
+ // Reinstall with new configuration
+ err = client.InstallIntegration(ctx, slug, config)
+ if err != nil {
+ return diag.FromErr(fmt.Errorf("failed to reinstall integration with new configuration: %w", err))
+ }
+ }
+
+ return readIntegration(ctx, d, meta)
+}
+
+func deleteIntegration(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
+ client, err := getIntegrationsClient(meta)
+ if err != nil {
+ return diag.FromErr(err)
+ }
+
+ slug := d.Id()
+
+ err = client.UninstallIntegration(ctx, slug)
+ if err != nil {
+ if err == ErrNotFound {
+ // Integration is already uninstalled
+ return nil
+ }
+ return diag.FromErr(fmt.Errorf("failed to uninstall integration: %w", err))
+ }
+
+ return nil
+}
+
+func getIntegrationsClient(meta interface{}) (*Client, error) {
+ client := meta.(*common.Client)
+
+ // Get the auth token from the Grafana API config
+ authToken := ""
+ if client.GrafanaAPIConfig != nil {
+ authToken = client.GrafanaAPIConfig.APIKey
+ }
+
+ // Create integrations client using the same pattern as frontendo11y
+ integrationsClient, err := NewClient(
+ client.GrafanaAPIURL,
+ authToken,
+ nil, // Use default HTTP client
+ "terraform-provider-grafana",
+ nil, // No default headers for now
+ )
+ if err != nil {
+ return nil, fmt.Errorf("failed to create integrations client: %w", err)
+ }
+
+ // Set the Grafana OpenAPI clients for folder and dashboard operations
+ if client.GrafanaAPI != nil {
+ integrationsClient.SetFoldersClient(client.GrafanaAPI.Folders)
+ integrationsClient.SetDashboardsClient(client.GrafanaAPI.Dashboards)
+ }
+
+ return integrationsClient, nil
+}
+
+func parseInstallationConfig(d *schema.ResourceData) *InstallationConfig {
+ configList := d.Get("configuration").([]interface{})
+ if len(configList) == 0 {
+ return nil
+ }
+
+ configMap := configList[0].(map[string]interface{})
+ config := &InstallationConfig{}
+
+ // Parse configurable_logs
+ if logsConfigList, ok := configMap["configurable_logs"].([]interface{}); ok && len(logsConfigList) > 0 {
+ logsConfigMap := logsConfigList[0].(map[string]interface{})
+ config.ConfigurableLogs = &ConfigurableLogs{
+ LogsDisabled: logsConfigMap["logs_disabled"].(bool),
+ }
+ }
+
+ // Parse configurable_alerts
+ if alertsConfigList, ok := configMap["configurable_alerts"].([]interface{}); ok && len(alertsConfigList) > 0 {
+ alertsConfigMap := alertsConfigList[0].(map[string]interface{})
+ config.ConfigurableAlerts = &ConfigurableAlerts{
+ AlertsDisabled: alertsConfigMap["alerts_disabled"].(bool),
+ }
+ }
+
+ return config
+}
+
+func flattenInstallationConfig(config *InstallationConfig) []interface{} {
+ if config == nil {
+ return nil
+ }
+
+ result := make(map[string]interface{})
+
+ if config.ConfigurableLogs != nil {
+ result["configurable_logs"] = []interface{}{
+ map[string]interface{}{
+ "logs_disabled": config.ConfigurableLogs.LogsDisabled,
+ },
+ }
+ }
+
+ if config.ConfigurableAlerts != nil {
+ result["configurable_alerts"] = []interface{}{
+ map[string]interface{}{
+ "alerts_disabled": config.ConfigurableAlerts.AlertsDisabled,
+ },
+ }
+ }
+
+ return []interface{}{result}
+}
diff --git a/internal/resources/integrations/resources.go b/internal/resources/integrations/resources.go
new file mode 100644
index 000000000..b87da090d
--- /dev/null
+++ b/internal/resources/integrations/resources.go
@@ -0,0 +1,9 @@
+package integrations
+
+import (
+ "github.com/grafana/terraform-provider-grafana/v3/internal/common"
+)
+
+var Resources = []*common.Resource{
+ resourceIntegration(),
+}
diff --git a/pkg/provider/resources.go b/pkg/provider/resources.go
index a3613210d..0231b4042 100644
--- a/pkg/provider/resources.go
+++ b/pkg/provider/resources.go
@@ -11,6 +11,7 @@ import (
"github.com/grafana/terraform-provider-grafana/v3/internal/resources/fleetmanagement"
"github.com/grafana/terraform-provider-grafana/v3/internal/resources/frontendo11y"
"github.com/grafana/terraform-provider-grafana/v3/internal/resources/grafana"
+ "github.com/grafana/terraform-provider-grafana/v3/internal/resources/integrations"
"github.com/grafana/terraform-provider-grafana/v3/internal/resources/k6"
"github.com/grafana/terraform-provider-grafana/v3/internal/resources/machinelearning"
"github.com/grafana/terraform-provider-grafana/v3/internal/resources/oncall"
@@ -65,6 +66,7 @@ func Resources() []*common.Resource {
var resources []*common.Resource
resources = append(resources, cloud.Resources...)
resources = append(resources, grafana.Resources...)
+ resources = append(resources, integrations.Resources...)
resources = append(resources, machinelearning.Resources...)
resources = append(resources, oncall.Resources...)
resources = append(resources, slo.Resources...)