= Kusto Queries in Azure =
**Summary**: In Azure the kusto query language is mostly used to query Azure Monitor. On this page I explain a few of the basics I use a lot and a selection of examples I use or have used. \\
**Date**: Around 2023 \\
**Refactor**: 8 December 2024: Added examples and hints from [[cheatsheet]] and refactored for new layout. \\
{{tag>azure kusto}}
= Structure =
^ Expression ^ Description ^ Example ^
| == | Check equality (case-sensitive) | {{{Level == 8}}} |
| =~ | Check equality (case-insensitive) | {{{EventSourceName =~ "microsoft-windows-security-auditing"}}} |
| !=, <> | Check inequality (both expressions are identical) | {{{Level != 4}}} |
| and or | Required between conditions | {{{Level == 16 or CommandLine != ""}}} |
^ Command ^ Description ^ Example ^
| take *n* | Ideally suited to small result sets. Take returns n rows from the result set in no particular order. | {{{AuditLogs | Take 10}}} |
| top *n* by *field* | Use this filter command to return the top n rows, sorted by the nominated field. | {{{AuditLogs | Top 10 by timeGenerated }}} |
| sort by *field* (desc) | If you want to sort only the result set, you can use the sort command. You need to specify the field to sort on, and then you can optionally add the desc instruction to specify a descending sort pattern. | {{{AuditLogs | Sort by timeGenerated desc }}} |
| Where field (expression) value | The principal filtering command. You nominate the field, expression, and comparator value. You can stack multiple where commands, each separated by a pipe. | {{{AuditLogs | where CreatedDateTime >= ago(2d) }}} |
| project fields | If you want to restrict the result set to display only nominated fields or columns, you can use the project command with a comma-separated list of the fields. | {{{AuditLogs | project timeGenerated, OperationName, ResourceGroup, Result }}} |
= Basic Queries =
== Check for incoming data ==
Perf
| where TimeGenerated > ago(10m)
| order by TimeGenerated desc
Event
| where TimeGenerated > ago(10m)
| order by TimeGenerated desc
RabbitMQ_CL
| where TimeGenerated > ago(10m)
| order by TimeGenerated desc
W3CIISLog
| where TimeGenerated > ago(10m)
| order by TimeGenerated desc
== Show errors ==
> every 10 minutes in a stacked graph
APP_LOG
| where RawData contains "error"
| summarize count() by Computer, bin(TimeGenerated, 10m)
| order by TimeGenerated
| render areachart
\\
> Week overview of errors per service account in a column graph
APP_LOG
| where LogType_CF == '[error]'
| summarize count() by UserName_CF, Computer, bin(TimeGenerated, 1d)
| order by TimeGenerated, UserName_CF
| render columnchart
\\
> All exceptions per 30 seconds per application
exceptions
| where outerMessage contains "timeout"
| where cloud_RoleName != ""
| summarize count() by bin(timestamp, 30s), cloud_RoleName
| order by timestamp
\\
> All high severity level exceptions of a specific type
exceptions
| where severityLevel > 2 and type == 'MassTransit.RequestTimeoutException'
| summarize count() by cloud_RoleName, bin(timestamp, 1d)
| render columnchart
== SQL timeouts in a column graph ==
exceptions
| where outerMessage has "timeout" and outerType == "Microsoft.Data.SqlClient.SqlException"
| summarize count() by bin(timestamp, 1d), cloud_RoleName
| order by timestamp
| render columnchart
== Unique Logitems per RoleName/RoleInstance ==
> Get unique logitems per rolename/roleinstance in an appi log
requests
| distinct cloud_RoleName, cloud_RoleInstance
| sort by cloud_RoleInstance
== Find all errors of cloud_rolename ==
union exceptions, traces
| where cloud_RoleName == "Shift.Service"
| order by timestamp desc
= Log Analytics for Windows VMs =
This obviously requires you to have the Log Analytics agent installed on the VMs, and send the logs to Log Analytics. \\
== Failed Login Events VM ==
SecurityEvent
| where EventID = 4625
| summarize count() by TargetAccount
== Users Flagged as Risky ==
See how many of your users were flagged as risky in the last 14 days:
SigninLogs
| where CreatedDateTime >= ago(14d)
| where isRisky = true
== Errors from Server Eventlog ==
Event
| where TimeGenerated > ago(24h) and EventLevel == 1 and EventLog == 'Application'
| where Computer contains 'SRV01.SHIFT.LOCAL'
| limit 100
== Errors from Server Eventlog - Search for service errors in time range ==
Event
| where TimeGenerated > startofday(datetime("2022-01-02")) and TimeGenerated < endofday(datetime("2022-01-04")) and EventLevel == 1 and EventLog == 'Application'
| where Computer contains 'appprd01.shift'
| where RenderedDescription contains "shift.ServiceName"
=== With eventlevel 1 or 2 ===
Event
| where TimeGenerated between (datetime('2022-02-17 11:25')..datetime('2022-02-17 11:31'))
| where EventLevel <= 2
== Searching for Crashed Service ==
Event
| where RenderedDescription contains "coreServiceShell.exe"
| summarize count() by bin(TimeGenerated, 1d), Computer
| order by TimeGenerated
= Queries for RabbitMQ log =
This requires you to have the RabbitMQ logs in Log Analytics. \\
== RabbitMQ Missed Heartbeats ==
RabbitMQ_CL
| where RawData contains "missed heartbeats"
| summarize count() by Computer, bin(TimeGenerated, 1d)
| order by TimeGenerated
== RabbitMQ Errors ==
RabbitMQ_CL
| where LogType_CF == '[error]'
=== Add a Timeframe to your query ===
RabbitMQ_CL
| where DateTime_CF between (datetime('2022-07-10 10:25')..datetime('2022-07-11 12:31')) and LogType_CF == '[error]'
== RabbitMQ Errors per Server per Day ==
RabbitMQ_CL
| where LogType_CF == '[error]'
| summarize count() by Computer, bin(TimeGenerated, 1d)
| order by TimeGenerated
= Azure DevOps Audit Stream =
== yaml and classic release that were not successful ==
AzureDevOpsAuditing
| where OperationName == "Pipelines.DeploymentJobCompleted" or OperationName == "Release.DeploymentCompleted"
| where Data.DeploymentResult != "Succeeded"
| extend deployment = strcat(Data.PipelineName, "-", Data.StageName)
| project TimeGenerated, deployment
| summarize count() by bin(TimeGenerated, 10m), deployment
| render columnchart
== yaml releases to production that were successful ==
AzureDevOpsAuditing
| where OperationName == "Pipelines.DeploymentJobCompleted" and Data.DeploymentResult == "Succeeded" and Data.StageName contains "Production"
| extend deployment = strcat(Data.PipelineName, "-", Data.StageName)
| project TimeGenerated, deployment
| summarize count() by bin(TimeGenerated, 1d), deployment
| render columnchart
== classis releases that were not successful ==
AzureDevOpsAuditing
| where OperationName == "Release.DeploymentCompleted" and Data.DeploymentResult != "Succeeded"
| extend deployment = strcat(Data.PipelineName, "-", Data.StageName)
| project TimeGenerated, deployment
| summarize count() by bin(TimeGenerated, 1d), deployment
| render columnchart
= Azure Resource Graph Explorer =
The Azure Resource Graph Explorer also uses Kusto queries. \\
== Get all resources, type, location, subName and rgName ==
resources
| join kind=inner (
resourcecontainers
| where type == 'microsoft.resources/subscriptions'
| project subscriptionId, subscriptionName = name)
on subscriptionId
| project name, type, location, subscriptionName, resourceGroup
| order by type asc
== Get all application insights resources without a workspace ==
resources
| where type == "microsoft.insights/components"
| where properties['WorkspaceResourceId'] == ""
| join kind=inner (
resourcecontainers
| where type == 'microsoft.resources/subscriptions'
| project subscriptionId, subscriptionName = name)
on subscriptionId
| project name, type, subscriptionName, resourceGroup
| order by subscriptionName asc
== Get all storage accounts with an old tls version ==
resources
| where type == "microsoft.storage/storageaccounts"
| where properties['minimumTlsVersion'] != "TLS1_2"
| project name, resourceGroup, properties.minimumTlsVersion
== Get backup job status ==
For use with multiple log analytics workspaces, change the scope
AddonAzureBackupJobs
| parse VaultName with 'bvault-euw-' Spoke '-' Environment '-' Service
| extend JobDurationInSecsApprox = datetime_diff('second', TimeGenerated, JobStartDateTime)
| where JobOperation == 'Backup'
| project BackupItemFriendlyName, JobOperation, JobStartDateTime, JobDurationInSecsApprox, JobStatus, JobFailureCode, Environment, Spoke, Service, BackupItemUniqueId, VaultName, JobUniqueId, _ResourceId
= Useful links =
* [[https://learn.microsoft.com/en-us/azure/devops/organizations/audit/auditing-streaming?view=azure-devops|Azure Devops: Audit Stream to Log Analytics]]
* [[https://learn.microsoft.com/en-us/azure/devops/organizations/audit/auditing-events?view=azure-devops|Azure Devops: Auditing event list]]