Skip to content

Commit

Permalink
[database watcher] Add info messages when top queries aren't shown fo…
Browse files Browse the repository at this point in the history
…r known reasons (#2867)

* QDS warnings for secondaries and non-collecting states

* Use a more compact message
  • Loading branch information
dimitri-furman authored Jan 13, 2025
1 parent 6df865b commit 8d1ec0a
Show file tree
Hide file tree
Showing 12 changed files with 260 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6167,18 +6167,18 @@
"comparison": "isEqualTo",
"value": "1"
},
{
"parameterName": "sqldb_database_properties",
"comparison": "isEqualTo",
"value": "1"
},
{
"parameterName": "serverName",
"comparison": "isNotEqualTo"
},
{
"parameterName": "databaseName",
"comparison": "isNotEqualTo"
},
{
"parameterName": "haReplica",
"comparison": "isEqualTo",
"value": "false"
}
],
"name": "top_queries_group"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"name": "qdsStartTime",
"type": 1,
"isRequired": true,
"query": "{\"version\":\"AzureDataExplorerQuery/1.0\",\"queryText\":\"union\\r\\n(\\r\\n// The most recent interval that is earlier than the end of time range.\\r\\n// This may be earlier than the start of time range by at most 2h.\\r\\nsqldb_database_query_runtime_stats\\r\\n| where interval_start_time between (({timeRange:start} - 2h) .. {timeRange:end})\\r\\n| where logical_server_name =~ @\\\"{serverName}\\\"\\r\\n| where database_name == @\\\"{databaseName}\\\"\\r\\n| summarize interval_start_time = max(interval_start_time)\\r\\n),\\r\\n(\\r\\n// earliest interval start within time range\\r\\nsqldb_database_query_runtime_stats\\r\\n| where interval_end_time >= {timeRange:start} and interval_start_time <= {timeRange:end}\\r\\n| where logical_server_name =~ @\\\"{serverName}\\\"\\r\\n| where database_name == @\\\"{databaseName}\\\"\\r\\n| summarize interval_start_time = min(interval_start_time)\\r\\n)\\r\\n// return the earliest of these times as start of QDS range\\r\\n// if there isn't a complete QDS interval within time range, this will show the most recent available interval outside of the range\\r\\n| summarize qds_start_time = min(interval_start_time)\\r\\n\",\"clusterName\":\"{adxClusterUri}\",\"databaseName\":\"{adxDatabase}\"}",
"query": "{\"version\":\"AzureDataExplorerQuery/1.0\",\"queryText\":\"union\\r\\n(\\r\\n// The most recent interval that is earlier than the end of time range.\\r\\n// This may be earlier than the start of time range by at most 2h.\\r\\nsqldb_database_query_runtime_stats\\r\\n| where interval_start_time between (({timeRange:start} - 2h) .. {timeRange:end})\\r\\n| where logical_server_name =~ @\\\"{serverName}\\\"\\r\\n| where database_name == @\\\"{databaseName}\\\"\\r\\n| where \\\"{replicaType}\\\" == \\\"Primary\\\"\\r\\n| summarize interval_start_time = max(interval_start_time)\\r\\n),\\r\\n(\\r\\n// earliest interval start within time range\\r\\nsqldb_database_query_runtime_stats\\r\\n| where interval_end_time >= {timeRange:start} and interval_start_time <= {timeRange:end}\\r\\n| where logical_server_name =~ @\\\"{serverName}\\\"\\r\\n| where database_name == @\\\"{databaseName}\\\"\\r\\n| where \\\"{replicaType}\\\" == \\\"Primary\\\"\\r\\n| summarize interval_start_time = min(interval_start_time)\\r\\n)\\r\\n// return the earliest of these times as start of QDS range\\r\\n// if there isn't a complete QDS interval within time range, this will show the most recent available interval outside of the range\\r\\n| summarize qds_start_time = min(interval_start_time)\\r\\n\",\"clusterName\":\"{adxClusterUri}\",\"databaseName\":\"{adxDatabase}\"}",
"isHiddenWhenLocked": true,
"queryType": 9
},
Expand All @@ -22,7 +22,7 @@
"name": "qdsEndTime",
"type": 1,
"isRequired": true,
"query": "{\"version\":\"AzureDataExplorerQuery/1.0\",\"queryText\":\"union\\r\\n(\\r\\n// The most recent interval that is earlier than the end of time range.\\r\\n// This may be earlier than the start of time range by at most 2h.\\r\\nsqldb_database_query_runtime_stats\\r\\n| where interval_end_time between (({timeRange:start} - 2h) .. {timeRange:end})\\r\\n| where logical_server_name =~ @\\\"{serverName}\\\"\\r\\n| where database_name == @\\\"{databaseName}\\\"\\r\\n| summarize interval_end_time = max(interval_end_time)\\r\\n),\\r\\n(\\r\\n// latest interval end within time range\\r\\nsqldb_database_query_runtime_stats\\r\\n| where interval_end_time >= {timeRange:start} and interval_start_time <= {timeRange:end}\\r\\n| where logical_server_name =~ @\\\"{serverName}\\\"\\r\\n| where database_name == @\\\"{databaseName}\\\"\\r\\n| summarize interval_end_time = max(interval_end_time)\\r\\n)\\r\\n// return the latest of these times as end of QDS range\\r\\n// if there isn't a complete QDS interval within time range, this will show the latest available interval\\r\\n| summarize qds_end_time = datetime_add(\\\"second\\\", 1, max(interval_end_time)) // make-series treats the end of interval as not inclusive, fudge by 1 second\\r\\n\",\"clusterName\":\"{adxClusterUri}\",\"databaseName\":\"{adxDatabase}\"}",
"query": "{\"version\":\"AzureDataExplorerQuery/1.0\",\"queryText\":\"union\\r\\n(\\r\\n// The most recent interval that is earlier than the end of time range.\\r\\n// This may be earlier than the start of time range by at most 2h.\\r\\nsqldb_database_query_runtime_stats\\r\\n| where interval_end_time between (({timeRange:start} - 2h) .. {timeRange:end})\\r\\n| where logical_server_name =~ @\\\"{serverName}\\\"\\r\\n| where database_name == @\\\"{databaseName}\\\"\\r\\n| where \\\"{replicaType}\\\" == \\\"Primary\\\"\\r\\n| summarize interval_end_time = max(interval_end_time)\\r\\n),\\r\\n(\\r\\n// latest interval end within time range\\r\\nsqldb_database_query_runtime_stats\\r\\n| where interval_end_time >= {timeRange:start} and interval_start_time <= {timeRange:end}\\r\\n| where logical_server_name =~ @\\\"{serverName}\\\"\\r\\n| where database_name == @\\\"{databaseName}\\\"\\r\\n| where \\\"{replicaType}\\\" == \\\"Primary\\\"\\r\\n| summarize interval_end_time = max(interval_end_time)\\r\\n)\\r\\n// return the latest of these times as end of QDS range\\r\\n// if there isn't a complete QDS interval within time range, this will show the latest available interval\\r\\n| summarize qds_end_time = datetime_add(\\\"second\\\", 1, max(interval_end_time)) // make-series treats the end of interval as not inclusive, fudge by 1 second\\r\\n\",\"clusterName\":\"{adxClusterUri}\",\"databaseName\":\"{adxDatabase}\"}",
"isHiddenWhenLocked": true,
"queryType": 9
},
Expand All @@ -35,6 +35,15 @@
"isHiddenWhenLocked": true,
"queryType": 9,
"id": "597f2e25-7cb4-416e-aaa8-d156dccd25b4"
},
{
"id": "621902c6-c42c-4102-bd83-08f58a7c4a3a",
"version": "KqlParameterItem/1.0",
"name": "qdsMissingDataWarningText",
"type": 1,
"query": "{\"version\":\"AzureDataExplorerQuery/1.0\",\"queryText\":\"sqldb_database_properties\\r\\n| where sample_time_utc between (({timeRange:start} - 2h) .. {timeRange:end})\\r\\n| where logical_server_name =~ @\\\"{serverName}\\\"\\r\\n| where database_name == @\\\"{databaseName}\\\"\\r\\n| where replica_type =='Primary' \\r\\n| where query_store_actual_state_desc != \\\"READ_WRITE\\\"\\r\\n| extend query_store_actual_state_desc = iif(isempty(query_store_actual_state_desc), \\\"<missing>\\\", query_store_actual_state_desc)\\r\\n| distinct query_store_actual_state_desc\\r\\n| sort by query_store_actual_state_desc asc\\r\\n| extend warning_row = strcat(\\\"| `\\\", query_store_actual_state_desc, \\\"` | \\\")\\r\\n| summarize warning = strcat_array(make_list(warning_row), \\\"\\\\r\\\\n\\\")\\r\\n| where isnotempty(warning)\\r\\n\",\"clusterName\":\"{adxClusterUri}\",\"databaseName\":\"{adxDatabase}\"}",
"isHiddenWhenLocked": true,
"queryType": 9
}
],
"style": "above",
Expand Down Expand Up @@ -64,6 +73,41 @@
],
"name": "qds_help"
},
{
"type": 1,
"content": {
"json": "Top query data in the selected time range might be missing or incomplete because the [Query Store](https://go.microsoft.com/fwlink/?linkid=2213253) state is other than `READ_WRITE`. For more information, see [Best practices for managing Query Store](https://go.microsoft.com/fwlink/?linkid=2198632).\r\n\r\n| Query Store state |\r\n|:--|\r\n{qdsMissingDataWarningText}",
"style": "info"
},
"conditionalVisibilities": [
{
"parameterName": "qdsStartTime",
"comparison": "isNotEqualTo"
},
{
"parameterName": "qdsEndTime",
"comparison": "isNotEqualTo"
},
{
"parameterName": "qdsMissingDataWarningText",
"comparison": "isNotEqualTo"
}
],
"name": "qds_warning_missing_data"
},
{
"type": 1,
"content": {
"json": "Top query data is not available for secondary replicas.",
"style": "info"
},
"conditionalVisibility": {
"parameterName": "replicaType",
"comparison": "isNotEqualTo",
"value": "Primary"
},
"name": "qds_warning_secondary"
},
{
"type": 9,
"content": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6029,6 +6029,11 @@
"comparison": "isEqualTo",
"value": "1"
},
{
"parameterName": "sqldb_database_properties",
"comparison": "isEqualTo",
"value": "1"
},
{
"parameterName": "matchPattern",
"comparison": "isNotEqualTo"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,15 @@
"query": "{\"version\":\"AzureDataExplorerQuery/1.0\",\"queryText\":\"union\\r\\n(\\r\\n// The most recent interval that is earlier than the end of time range.\\r\\n// This may be earlier than the start of time range by at most 2h.\\r\\nsqldb_database_query_runtime_stats\\r\\n| where interval_end_time between (({timeRange:start} - 2h) .. {timeRange:end})\\r\\n{subscriptionFilter}\\r\\n{resourceGroupFilter}\\r\\n{serverNameFilter}\\r\\n{databaseNameFilter}\\r\\n{elasticPoolNameFilter}\\r\\n| summarize interval_end_time = max(interval_end_time)\\r\\n),\\r\\n(\\r\\n// latest interval end within time range\\r\\nsqldb_database_query_runtime_stats\\r\\n| where interval_end_time >= {timeRange:start} and interval_start_time <= {timeRange:end}\\r\\n{subscriptionFilter}\\r\\n{resourceGroupFilter}\\r\\n{serverNameFilter}\\r\\n{databaseNameFilter}\\r\\n{elasticPoolNameFilter}\\r\\n| summarize interval_end_time = max(interval_end_time)\\r\\n)\\r\\n// return the latest of these times as end of QDS range\\r\\n// if there isn't a complete QDS interval within time range, this will show the latest available interval\\r\\n| summarize qds_end_time = datetime_add(\\\"second\\\", 1, max(interval_end_time)) // make-series treats the end of interval as not inclusive, fudge by 1 second\\r\\n\",\"clusterName\":\"{adxClusterUri}\",\"databaseName\":\"{adxDatabase}\"}",
"isHiddenWhenLocked": true,
"queryType": 9
},
{
"id": "621902c6-c42c-4102-bd83-08f58a7c4a3a",
"version": "KqlParameterItem/1.0",
"name": "qdsMissingDataWarningText",
"type": 1,
"query": "{\"version\":\"AzureDataExplorerQuery/1.0\",\"queryText\":\"sqldb_database_properties\\r\\n| where sample_time_utc between (({timeRange:start} - 2h) .. {timeRange:end})\\r\\n{subscriptionFilter}\\r\\n{resourceGroupFilter}\\r\\n{serverNameFilter}\\r\\n{databaseNameFilter}\\r\\n{elasticPoolNameFilter}\\r\\n| where replica_type == \\\"Primary\\\"\\r\\n| where query_store_actual_state_desc != \\\"READ_WRITE\\\"\\r\\n| extend query_store_actual_state_desc = iif(isempty(query_store_actual_state_desc), \\\"<missing>\\\", query_store_actual_state_desc)\\r\\n| distinct logical_server_name, database_name, logical_database_id, query_store_actual_state_desc\\r\\n| sort by database_name asc, logical_server_name asc\\r\\n| summarize databases = strcat(\\r\\n strcat_array(\\r\\n make_list(\\r\\n strcat(database_name, \\\" (\\\", logical_server_name, \\\")\\\"),\\r\\n 5\\r\\n ),\\r\\n \\\", \\\"\\r\\n ),\\r\\n iif(\\r\\n dcount(logical_database_id) > 5,\\r\\n strcat(\\\" and \\\", tostring(dcount(logical_database_id) - 5), \\\" more\\\"),\\r\\n \\\"\\\")\\r\\n )\\r\\n by query_store_actual_state_desc\\r\\n| sort by query_store_actual_state_desc asc\\r\\n| extend warning_row = strcat(\\\"| `\\\", query_store_actual_state_desc, \\\"` | \\\", databases, \\\" |\\\")\\r\\n| summarize warning = strcat_array(make_list(warning_row), \\\"\\\\r\\\\n\\\")\\r\\n| where isnotempty(warning)\\r\\n\",\"clusterName\":\"{adxClusterUri}\",\"databaseName\":\"{adxDatabase}\"}",
"isHiddenWhenLocked": true,
"queryType": 9
}
],
"style": "above",
Expand Down Expand Up @@ -54,6 +63,28 @@
],
"name": "qds_help"
},
{
"type": 1,
"content": {
"json": "Top query data in the selected time range might be missing or incomplete for some databases because their [Query Store](https://go.microsoft.com/fwlink/?linkid=2213253) state is other than `READ_WRITE`. For more information, see [Best practices for managing Query Store](https://go.microsoft.com/fwlink/?linkid=2198632).\r\n\r\n| Query Store state | Database(s) (logical server) |\r\n|:--|:--|\r\n{qdsMissingDataWarningText}",
"style": "info"
},
"conditionalVisibilities": [
{
"parameterName": "qdsStartTime",
"comparison": "isNotEqualTo"
},
{
"parameterName": "qdsEndTime",
"comparison": "isNotEqualTo"
},
{
"parameterName": "qdsMissingDataWarningText",
"comparison": "isNotEqualTo"
}
],
"name": "qds_warning_missing_data"
},
{
"type": 9,
"content": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3057,6 +3057,11 @@
"comparison": "isEqualTo",
"value": "1"
},
{
"parameterName": "sqlmi_database_properties",
"comparison": "isEqualTo",
"value": "1"
},
{
"parameterName": "matchPattern",
"comparison": "isNotEqualTo"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,15 @@
"query": "{\"version\":\"AzureDataExplorerQuery/1.0\",\"queryText\":\"union\\r\\n(\\r\\n// The most recent interval that is earlier than the end of time range.\\r\\n// This may be earlier than the start of time range by at most 2h.\\r\\nsqlmi_query_runtime_stats\\r\\n| where interval_end_time between (({timeRange:start} - 2h) .. {timeRange:end})\\r\\n{subscriptionFilter}\\r\\n{resourceGroupFilter}\\r\\n{managedInstanceNameFilter}\\r\\n| summarize interval_end_time = max(interval_end_time)\\r\\n),\\r\\n(\\r\\n// latest interval end within time range\\r\\nsqlmi_query_runtime_stats\\r\\n| where interval_end_time >= {timeRange:start} and interval_start_time <= {timeRange:end}\\r\\n{subscriptionFilter}\\r\\n{resourceGroupFilter}\\r\\n{managedInstanceNameFilter}\\r\\n| summarize interval_end_time = max(interval_end_time)\\r\\n)\\r\\n// return the latest of these times as end of QDS range\\r\\n// if there isn't a complete QDS interval within time range, this will show the latest available interval\\r\\n| summarize qds_end_time = datetime_add(\\\"second\\\", 1, max(interval_end_time)) // make-series treats the end of interval as not inclusive, fudge by 1 second\\r\\n\",\"clusterName\":\"{adxClusterUri}\",\"databaseName\":\"{adxDatabase}\"}",
"isHiddenWhenLocked": true,
"queryType": 9
},
{
"id": "621902c6-c42c-4102-bd83-08f58a7c4a3a",
"version": "KqlParameterItem/1.0",
"name": "qdsMissingDataWarningText",
"type": 1,
"query": "{\"version\":\"AzureDataExplorerQuery/1.0\",\"queryText\":\"sqlmi_database_properties\\r\\n| where sample_time_utc between (({timeRange:start} - 2h) .. {timeRange:end})\\r\\n{subscriptionFilter}\\r\\n{resourceGroupFilter}\\r\\n{managedInstanceNameFilter}\\r\\n| where database_id > 4\\r\\n| where replica_type == \\\"Primary\\\"\\r\\n| where query_store_actual_state_desc != \\\"READ_WRITE\\\"\\r\\n| extend query_store_actual_state_desc = iif(isempty(query_store_actual_state_desc), \\\"<missing>\\\", query_store_actual_state_desc)\\r\\n| distinct managed_instance_name = tostring(split(managed_instance_name, \\\".\\\")[0]), database_name, logical_database_id, query_store_actual_state_desc\\r\\n| sort by database_name asc, managed_instance_name asc\\r\\n| summarize databases = strcat(\\r\\n strcat_array(\\r\\n make_list(\\r\\n strcat(database_name, \\\" (\\\", managed_instance_name, \\\")\\\"),\\r\\n 5\\r\\n ),\\r\\n \\\", \\\"\\r\\n ),\\r\\n iif(\\r\\n dcount(logical_database_id) > 5,\\r\\n strcat(\\\" and \\\", tostring(dcount(logical_database_id) - 5), \\\" more\\\"),\\r\\n \\\"\\\")\\r\\n )\\r\\n by query_store_actual_state_desc\\r\\n| sort by query_store_actual_state_desc asc\\r\\n| extend warning_row = strcat(\\\"| `\\\", query_store_actual_state_desc, \\\"` | \\\", databases, \\\" |\\\")\\r\\n| summarize warning = strcat_array(make_list(warning_row), \\\"\\\\r\\\\n\\\")\\r\\n| where isnotempty(warning)\\r\\n\",\"clusterName\":\"{adxClusterUri}\",\"databaseName\":\"{adxDatabase}\"}",
"isHiddenWhenLocked": true,
"queryType": 9
}
],
"style": "above",
Expand Down Expand Up @@ -54,6 +63,28 @@
],
"name": "qds_help"
},
{
"type": 1,
"content": {
"json": "Top query data in the selected time range might be missing or incomplete for some databases because their [Query Store](https://go.microsoft.com/fwlink/?linkid=2213253) state is other than `READ_WRITE`. For more information, see [Best practices for managing Query Store](https://go.microsoft.com/fwlink/?linkid=2198632).\r\n\r\n| Query Store state | Database(s) (managed instance) |\r\n|:--|:--|\r\n{qdsMissingDataWarningText}",
"style": "info"
},
"conditionalVisibilities": [
{
"parameterName": "qdsStartTime",
"comparison": "isNotEqualTo"
},
{
"parameterName": "qdsEndTime",
"comparison": "isNotEqualTo"
},
{
"parameterName": "qdsMissingDataWarningText",
"comparison": "isNotEqualTo"
}
],
"name": "qds_warning_missing_data"
},
{
"type": 9,
"content": {
Expand Down
Loading

0 comments on commit 8d1ec0a

Please sign in to comment.