{
  "leansignal_demand_export": "1.0",
  "exported_at": "2026-07-17T00:00:00Z",
  "source_tenant": "leansignal-catalog",
  "catalog": {
    "slug": "azure-monitor-otel-demand-essential",
    "integration": "azure-monitor",
    "variant": "essential",
    "title": "Azure Monitor — Essential",
    "category": "Cloud",
    "dashboards": 1,
    "panels": 8,
    "alerts": 5,
    "docs_url": "https://docs.leansignal.io/integrations/azure-monitor/"
  },
  "demand": {
    "ref": "demand",
    "name": "Azure Monitor — Essential",
    "description": "The cross-service failure signals — VM CPU and available memory, App Service 4xx/5xx responses, Azure SQL CPU and storage headroom, storage account availability, and Service Bus backlog and dead letters. Enough to know something in the subscription is broken.",
    "dashboards": [
      {
        "ref": "dash-azure-monitor",
        "name": "Azure Monitor — Essential",
        "description": "Azure Monitor metrics for Virtual Machines, App Service, Azure SQL, Storage accounts, and Service Bus — CPU, memory, 5xx rates, storage headroom, availability, latency, and message backlogs.",
        "data": {
          "display": {
            "name": "Azure Monitor — Essential"
          },
          "panels": {
            "vm_cpu": {
              "kind": "Panel",
              "spec": {
                "display": {
                  "name": "CPU utilization",
                  "description": "Per-VM CPU as the hypervisor sees it — the first thing to check on a slow VM."
                },
                "plugin": {
                  "kind": "TimeSeriesChart",
                  "spec": {
                    "legend": {
                      "position": "bottom",
                      "mode": "list"
                    },
                    "yAxis": {
                      "format": {
                        "unit": "percent"
                      },
                      "min": 0,
                      "max": 100
                    }
                  }
                },
                "queries": [
                  {
                    "kind": "TimeSeriesQuery",
                    "spec": {
                      "plugin": {
                        "kind": "PrometheusTimeSeriesQuery",
                        "spec": {
                          "query": "avg by (resource_group, name) (azure_percentage_cpu_average{resource_group=~\"$instance\",type=\"Microsoft.Compute/virtualMachines\"})",
                          "seriesNameFormat": "{{name}}"
                        }
                      }
                    }
                  }
                ]
              }
            },
            "vm_available_memory": {
              "kind": "Panel",
              "spec": {
                "display": {
                  "name": "Available memory",
                  "description": "Memory still free on the VM. A steady decline ends in paging, then in the OOM killer."
                },
                "plugin": {
                  "kind": "TimeSeriesChart",
                  "spec": {
                    "legend": {
                      "position": "bottom",
                      "mode": "list"
                    },
                    "yAxis": {
                      "format": {
                        "unit": "bytes"
                      },
                      "min": 0
                    }
                  }
                },
                "queries": [
                  {
                    "kind": "TimeSeriesQuery",
                    "spec": {
                      "plugin": {
                        "kind": "PrometheusTimeSeriesQuery",
                        "spec": {
                          "query": "min by (resource_group, name) (azure_available_memory_bytes_average{resource_group=~\"$instance\",type=\"Microsoft.Compute/virtualMachines\"})",
                          "seriesNameFormat": "{{name}}"
                        }
                      }
                    }
                  }
                ]
              }
            },
            "app_requests": {
              "kind": "Panel",
              "spec": {
                "display": {
                  "name": "Requests (per period)",
                  "description": "Requests served per app per Azure Monitor period."
                },
                "plugin": {
                  "kind": "TimeSeriesChart",
                  "spec": {
                    "legend": {
                      "position": "bottom",
                      "mode": "list"
                    },
                    "yAxis": {
                      "format": {
                        "unit": "decimal"
                      },
                      "min": 0
                    }
                  }
                },
                "queries": [
                  {
                    "kind": "TimeSeriesQuery",
                    "spec": {
                      "plugin": {
                        "kind": "PrometheusTimeSeriesQuery",
                        "spec": {
                          "query": "sum by (resource_group, name) (azure_requests_total{resource_group=~\"$instance\",type=\"Microsoft.Web/sites\"})",
                          "seriesNameFormat": "{{name}}"
                        }
                      }
                    }
                  }
                ]
              }
            },
            "app_errors": {
              "kind": "Panel",
              "spec": {
                "display": {
                  "name": "4xx / 5xx responses (per period)",
                  "description": "Client errors beside server errors — 5xx is yours to fix, a 4xx spike usually is not."
                },
                "plugin": {
                  "kind": "TimeSeriesChart",
                  "spec": {
                    "legend": {
                      "position": "bottom",
                      "mode": "list"
                    },
                    "yAxis": {
                      "format": {
                        "unit": "decimal"
                      },
                      "min": 0
                    }
                  }
                },
                "queries": [
                  {
                    "kind": "TimeSeriesQuery",
                    "spec": {
                      "plugin": {
                        "kind": "PrometheusTimeSeriesQuery",
                        "spec": {
                          "query": "sum by (resource_group, name) (azure_http5xx_total{resource_group=~\"$instance\",type=\"Microsoft.Web/sites\"})",
                          "seriesNameFormat": "{{name}} · 5xx"
                        }
                      }
                    }
                  },
                  {
                    "kind": "TimeSeriesQuery",
                    "spec": {
                      "plugin": {
                        "kind": "PrometheusTimeSeriesQuery",
                        "spec": {
                          "query": "sum by (resource_group, name) (azure_http4xx_total{resource_group=~\"$instance\",type=\"Microsoft.Web/sites\"})",
                          "seriesNameFormat": "{{name}} · 4xx"
                        }
                      }
                    }
                  }
                ]
              }
            },
            "sql_cpu": {
              "kind": "Panel",
              "spec": {
                "display": {
                  "name": "CPU utilization",
                  "description": "Per-database CPU against its service tier — this is a fraction of the tier, not of a machine."
                },
                "plugin": {
                  "kind": "TimeSeriesChart",
                  "spec": {
                    "legend": {
                      "position": "bottom",
                      "mode": "list"
                    },
                    "yAxis": {
                      "format": {
                        "unit": "percent"
                      },
                      "min": 0,
                      "max": 100
                    }
                  }
                },
                "queries": [
                  {
                    "kind": "TimeSeriesQuery",
                    "spec": {
                      "plugin": {
                        "kind": "PrometheusTimeSeriesQuery",
                        "spec": {
                          "query": "avg by (resource_group, name) (azure_cpu_percent_average{resource_group=~\"$instance\",type=\"Microsoft.Sql/servers/databases\"})",
                          "seriesNameFormat": "{{name}}"
                        }
                      }
                    }
                  }
                ]
              }
            },
            "sql_storage": {
              "kind": "Panel",
              "spec": {
                "display": {
                  "name": "Storage used",
                  "description": "A database that fills its allocated storage stops accepting writes — watch the trend, not just the level."
                },
                "plugin": {
                  "kind": "TimeSeriesChart",
                  "spec": {
                    "legend": {
                      "position": "bottom",
                      "mode": "list"
                    },
                    "yAxis": {
                      "format": {
                        "unit": "percent"
                      },
                      "min": 0,
                      "max": 100
                    }
                  }
                },
                "queries": [
                  {
                    "kind": "TimeSeriesQuery",
                    "spec": {
                      "plugin": {
                        "kind": "PrometheusTimeSeriesQuery",
                        "spec": {
                          "query": "max by (resource_group, name) (azure_storage_percent_average{resource_group=~\"$instance\",type=\"Microsoft.Sql/servers/databases\"})",
                          "seriesNameFormat": "{{name}}"
                        }
                      }
                    }
                  }
                ]
              }
            },
            "storage_availability": {
              "kind": "Panel",
              "spec": {
                "display": {
                  "name": "Availability",
                  "description": "Share of requests the storage account served without a service-side error — the single best storage health signal."
                },
                "plugin": {
                  "kind": "TimeSeriesChart",
                  "spec": {
                    "legend": {
                      "position": "bottom",
                      "mode": "list"
                    },
                    "yAxis": {
                      "format": {
                        "unit": "percent"
                      },
                      "min": 0,
                      "max": 100
                    }
                  }
                },
                "queries": [
                  {
                    "kind": "TimeSeriesQuery",
                    "spec": {
                      "plugin": {
                        "kind": "PrometheusTimeSeriesQuery",
                        "spec": {
                          "query": "min by (resource_group, name) (azure_availability_average{resource_group=~\"$instance\",type=\"Microsoft.Storage/storageAccounts\"})",
                          "seriesNameFormat": "{{name}}"
                        }
                      }
                    }
                  }
                ]
              }
            },
            "sb_backlog": {
              "kind": "Panel",
              "spec": {
                "display": {
                  "name": "Active and dead-lettered messages",
                  "description": "Messages waiting to be received, and messages that gave up trying — a rising dead-letter count is a stuck consumer."
                },
                "plugin": {
                  "kind": "TimeSeriesChart",
                  "spec": {
                    "legend": {
                      "position": "bottom",
                      "mode": "list"
                    },
                    "yAxis": {
                      "format": {
                        "unit": "decimal"
                      },
                      "min": 0
                    }
                  }
                },
                "queries": [
                  {
                    "kind": "TimeSeriesQuery",
                    "spec": {
                      "plugin": {
                        "kind": "PrometheusTimeSeriesQuery",
                        "spec": {
                          "query": "sum by (resource_group, name) (azure_activemessages_average{resource_group=~\"$instance\",type=\"Microsoft.ServiceBus/namespaces\"})",
                          "seriesNameFormat": "{{name}} · active"
                        }
                      }
                    }
                  },
                  {
                    "kind": "TimeSeriesQuery",
                    "spec": {
                      "plugin": {
                        "kind": "PrometheusTimeSeriesQuery",
                        "spec": {
                          "query": "sum by (resource_group, name) (azure_deadletteredmessages_average{resource_group=~\"$instance\",type=\"Microsoft.ServiceBus/namespaces\"})",
                          "seriesNameFormat": "{{name}} · dead-lettered"
                        }
                      }
                    }
                  }
                ]
              }
            }
          },
          "layouts": [
            {
              "kind": "Grid",
              "spec": {
                "display": {
                  "title": "Virtual Machines",
                  "collapse": {
                    "open": true
                  }
                },
                "items": [
                  {
                    "x": 0,
                    "y": 0,
                    "width": 12,
                    "height": 8,
                    "content": {
                      "$ref": "#/spec/panels/vm_cpu"
                    }
                  },
                  {
                    "x": 12,
                    "y": 0,
                    "width": 12,
                    "height": 8,
                    "content": {
                      "$ref": "#/spec/panels/vm_available_memory"
                    }
                  }
                ]
              }
            },
            {
              "kind": "Grid",
              "spec": {
                "display": {
                  "title": "App Service",
                  "collapse": {
                    "open": true
                  }
                },
                "items": [
                  {
                    "x": 0,
                    "y": 0,
                    "width": 12,
                    "height": 8,
                    "content": {
                      "$ref": "#/spec/panels/app_requests"
                    }
                  },
                  {
                    "x": 12,
                    "y": 0,
                    "width": 12,
                    "height": 8,
                    "content": {
                      "$ref": "#/spec/panels/app_errors"
                    }
                  }
                ]
              }
            },
            {
              "kind": "Grid",
              "spec": {
                "display": {
                  "title": "Azure SQL",
                  "collapse": {
                    "open": true
                  }
                },
                "items": [
                  {
                    "x": 0,
                    "y": 0,
                    "width": 12,
                    "height": 8,
                    "content": {
                      "$ref": "#/spec/panels/sql_cpu"
                    }
                  },
                  {
                    "x": 12,
                    "y": 0,
                    "width": 12,
                    "height": 8,
                    "content": {
                      "$ref": "#/spec/panels/sql_storage"
                    }
                  }
                ]
              }
            },
            {
              "kind": "Grid",
              "spec": {
                "display": {
                  "title": "Storage",
                  "collapse": {
                    "open": true
                  }
                },
                "items": [
                  {
                    "x": 0,
                    "y": 0,
                    "width": 12,
                    "height": 8,
                    "content": {
                      "$ref": "#/spec/panels/storage_availability"
                    }
                  }
                ]
              }
            },
            {
              "kind": "Grid",
              "spec": {
                "display": {
                  "title": "Service Bus",
                  "collapse": {
                    "open": true
                  }
                },
                "items": [
                  {
                    "x": 0,
                    "y": 0,
                    "width": 12,
                    "height": 8,
                    "content": {
                      "$ref": "#/spec/panels/sb_backlog"
                    }
                  }
                ]
              }
            }
          ],
          "variables": [
            {
              "kind": "ListVariable",
              "spec": {
                "name": "instance",
                "display": {
                  "name": "Instance"
                },
                "allowAllValue": true,
                "allowMultiple": true,
                "customAllValue": ".*",
                "defaultValue": ".*",
                "plugin": {
                  "kind": "PrometheusLabelValuesVariable",
                  "spec": {
                    "labelName": "resource_group"
                  }
                }
              }
            }
          ],
          "duration": "1h",
          "refreshInterval": "30s",
          "datasources": {}
        }
      }
    ],
    "alert_rules": [
      {
        "ref": "alert-azure-app-high-5xx-ratio",
        "name": "App Service high 5xx ratio",
        "description": "A large share of requests to an App Service app are getting 5xx responses, so users are seeing errors.",
        "query": "sum by (resource_group, name) (azure_http5xx_total{type=\"Microsoft.Web/sites\"}) / clamp_min(sum by (resource_group, name) (azure_requests_total{type=\"Microsoft.Web/sites\"}), 1)",
        "condition_op": "gt",
        "threshold": 0.05,
        "interval": "1m",
        "for": "10m",
        "severity": "warning",
        "message": "App Service {{labels.name}} ({{labels.resource_group}}) is serving {{value | percent:1}} 5xx responses.",
        "notify_on_resolve": true,
        "paused": false,
        "channels": []
      },
      {
        "ref": "alert-azure-sql-storage-high",
        "name": "Azure SQL storage nearly full",
        "description": "An Azure SQL database is close to its allocated storage; it stops accepting writes when full.",
        "query": "max by (resource_group, name) (azure_storage_percent_average{type=\"Microsoft.Sql/servers/databases\"})",
        "condition_op": "gt",
        "threshold": 90,
        "interval": "1m",
        "for": "15m",
        "severity": "critical",
        "message": "Database {{labels.name}} ({{labels.resource_group}}) is {{value}}% full — it stops accepting writes at 100%.",
        "notify_on_resolve": true,
        "paused": false,
        "channels": []
      },
      {
        "ref": "alert-azure-storage-availability-low",
        "name": "Storage account availability degraded",
        "description": "A storage account is failing requests service-side, so applications reading or writing it see errors.",
        "query": "min by (resource_group, name) (azure_availability_average{type=\"Microsoft.Storage/storageAccounts\"})",
        "condition_op": "lt",
        "threshold": 99,
        "interval": "1m",
        "for": "10m",
        "severity": "critical",
        "message": "Storage account {{labels.name}} ({{labels.resource_group}}) is at {{value}}% availability — requests are failing service-side.",
        "notify_on_resolve": true,
        "paused": false,
        "channels": []
      },
      {
        "ref": "alert-azure-servicebus-deadletter",
        "name": "Service Bus dead-lettered messages",
        "description": "Messages are landing in the dead-letter queue, meaning consumers are rejecting or timing out.",
        "query": "sum by (resource_group, name) (azure_deadletteredmessages_average{type=\"Microsoft.ServiceBus/namespaces\"})",
        "condition_op": "gt",
        "threshold": 0,
        "interval": "1m",
        "for": "15m",
        "severity": "warning",
        "message": "Service Bus namespace {{labels.name}} ({{labels.resource_group}}) holds {{value}} dead-lettered message(s) — consumers are rejecting or timing out.",
        "notify_on_resolve": true,
        "paused": false,
        "channels": []
      },
      {
        "ref": "alert-azure-vm-low-memory",
        "name": "VM low available memory",
        "description": "A VM is nearly out of available memory, so paging and the OOM killer come next.",
        "query": "min by (resource_group, name) (azure_available_memory_bytes_average{type=\"Microsoft.Compute/virtualMachines\"})",
        "condition_op": "lt",
        "threshold": 268435456,
        "interval": "1m",
        "for": "15m",
        "severity": "critical",
        "message": "VM {{labels.name}} ({{labels.resource_group}}) has {{value | bytes}} of memory left — paging and the OOM killer come next.",
        "notify_on_resolve": true,
        "paused": false,
        "channels": []
      }
    ]
  }
}
