// UniFi Data Connector Health Monitoring
let StaleThreshold = 30;
let DevicesHealth = Unifi_SiteManager_Devices_CL
| where TimeGenerated > ago(2h)
| summarize LastReceived = max(TimeGenerated)
| extend TableName = "Unifi_SiteManager_Devices_CL", TableDisplay = "Devices";
let HostsHealth = Unifi_SiteManager_Hosts_CL
| where TimeGenerated > ago(2h)
| summarize LastReceived = max(TimeGenerated)
| extend TableName = "Unifi_SiteManager_Hosts_CL", TableDisplay = "Hosts";
let SitesHealth = Unifi_SiteManager_Sites_CL
| where TimeGenerated > ago(2h)
| summarize LastReceived = max(TimeGenerated)
| extend TableName = "Unifi_SiteManager_Sites_CL", TableDisplay = "Sites";
let ISPHealth = Unifi_SiteManager_ISPMetrics_CL
| where TimeGenerated > ago(2h)
| summarize LastReceived = max(TimeGenerated)
| extend TableName = "Unifi_SiteManager_ISPMetrics_CL", TableDisplay = "ISP Metrics";
union DevicesHealth, HostsHealth, SitesHealth, ISPHealth
| extend
MinutesSinceData = datetime_diff('minute', now(), LastReceived),
Status = case(
datetime_diff('minute', now(), LastReceived) <= 15, "Healthy",
datetime_diff('minute', now(), LastReceived) <= 30, "Delayed",
datetime_diff('minute', now(), LastReceived) <= 60, "Stale",
"Critical"
)
| where MinutesSinceData >= StaleThreshold
| extend TimeGenerated = now()
| project
TimeGenerated,
TableName,
TableDisplay,
LastReceived,
MinutesSinceData,
Status
entityMappings:
- entityType: CloudApplication
fieldMappings:
- identifier: Name
columnName: TableDisplay
tactics:
- DefenseEvasion
requiredDataConnectors:
- dataTypes:
- Unifi_SiteManager_Sites_CL
- Unifi_SiteManager_Devices_CL
- Unifi_SiteManager_Hosts_CL
- Unifi_SiteManager_ISPMetrics_CL
connectorId: UniFiSiteManagerConnectorDefinition
incidentConfiguration:
groupingConfiguration:
enabled: true
lookbackDuration: PT4H
reopenClosedIncident: false
matchingMethod: AllEntities
createIncident: true
id: 1fb5c195-9bff-e18b-3e8f-5123f46bff9d
severity: Medium
subTechniques:
- T1562.006
status: Available
query: |
// UniFi Data Connector Health Monitoring
let StaleThreshold = 30;
let DevicesHealth = Unifi_SiteManager_Devices_CL
| where TimeGenerated > ago(2h)
| summarize LastReceived = max(TimeGenerated)
| extend TableName = "Unifi_SiteManager_Devices_CL", TableDisplay = "Devices";
let HostsHealth = Unifi_SiteManager_Hosts_CL
| where TimeGenerated > ago(2h)
| summarize LastReceived = max(TimeGenerated)
| extend TableName = "Unifi_SiteManager_Hosts_CL", TableDisplay = "Hosts";
let SitesHealth = Unifi_SiteManager_Sites_CL
| where TimeGenerated > ago(2h)
| summarize LastReceived = max(TimeGenerated)
| extend TableName = "Unifi_SiteManager_Sites_CL", TableDisplay = "Sites";
let ISPHealth = Unifi_SiteManager_ISPMetrics_CL
| where TimeGenerated > ago(2h)
| summarize LastReceived = max(TimeGenerated)
| extend TableName = "Unifi_SiteManager_ISPMetrics_CL", TableDisplay = "ISP Metrics";
union DevicesHealth, HostsHealth, SitesHealth, ISPHealth
| extend
MinutesSinceData = datetime_diff('minute', now(), LastReceived),
Status = case(
datetime_diff('minute', now(), LastReceived) <= 15, "Healthy",
datetime_diff('minute', now(), LastReceived) <= 30, "Delayed",
datetime_diff('minute', now(), LastReceived) <= 60, "Stale",
"Critical"
)
| where MinutesSinceData >= StaleThreshold
| extend TimeGenerated = now()
| project
TimeGenerated,
TableName,
TableDisplay,
LastReceived,
MinutesSinceData,
Status
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/UniFi Site Manager (CCF)/Analytic Rules/UniFiCloudDataConnectorHealth.yaml
kind: Scheduled
queryPeriod: 2h
version: 1.0.0
name: 'UniFi Site Manager: Data Connector Health'
queryFrequency: 15m
triggerThreshold: 0
relevantTechniques:
- T1562
description: |
Identifies when UniFi Site Manager data connectors stop sending data, ensuring visibility into the UniFi estate is maintained.
triggerOperator: gt