Dec 10th, 2021 - written by Kimserey with .
Kusto query is the query language used to query App Insights logs with Azure DevOps. In today post we will look at the most common used operators with some examples.
For this post, we will be using the sample azure data explorer.
App Insights works with tables
. By typing the table and `SHIFT+ENTER, we will return all the values for that table. For example:
1
StormEvents
will return all the storm events. This table is present in the sample explorer.
Starting from the table we can then use piping |
to construct our queries, with the most commonly used tabular operators where
and take
:
1
2
3
StormEvents
| where State == 'FLORIDA'
| take 10
This will return the 10 first storm events appearing for FLORIDA
and we could do != 'FLORIDA'
for returning the 10 first that aren’t Florida. For case insensitive we can use ~
with =~
and !~
.
So far we took the 10 first that appeared, but we usually want to have some sort of ordering. For that we can use sort by
:
1
2
3
4
StormEvents
| where State == 'FLORIDA'
| sort by StartTime desc
| take 10
order by
is an alias to sort by
, both are equivalent. And just like in other query language, we have asc
and desc
and we can sort by other column by adding them after a comma.
1
2
3
4
StormEvents
| where State == 'FLORIDA'
| sort by StartTime desc, EventId asc
| take 10
In logs we usually have regular columns, and an extra metadata
JSON object containing extra values. If we want to extract property of that object to bring it to the forefront, we can use extend
:
1
2
print metadata = dynamic({"requestId":"123","userId":"abc"})
| extend requestId = metadata.requestId, userId = metadata.userId
Here I simulated a metadata
column using print
and extracted from the content of metadata
the requestId
and userId
. Other than extracting from JSON, extract
can be used for computed values:
1
2
3
4
5
6
7
8
9
10
11
StormEvents
| sort by StartTime desc
| where State == 'FLORIDA'
| extend duration = EndTime - StartTime
| extend duration_format = strcat(
format_timespan(duration, 'd'), ' days ',
format_timespan(duration, 'H'), ' hours ',
format_timespan(duration, 'm'), ' minutes'
)
| sort by duration desc
| take 10
We used extend
to generate the duration
, then used extend
again with strcat
to create a human readable format of the duration.
Using extend
will add a new column on the result. To reduce the amount of columns return by the result and have a more compact view, we can use project
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
StormEvents
| sort by StartTime desc
| where State == 'FLORIDA'
| extend duration = EndTime - StartTime
| extend duration_format = strcat(
format_timespan(duration, 'd'), ' days ',
format_timespan(duration, 'H'), ' hours ',
format_timespan(duration, 'm'), ' minutes'
)
| project
EventId,
State,
duration_format,
StartTime,
EndTime
| take 10
Lastly in SQL we often use group by
to aggregate result and get count or min or max. In Kusto we have the same capabilities with summarize
:
1
2
3
4
5
StormEvents
| sort by StartTime desc
| take 2000
| summarize count() by State
| top 20 by count_
Here we count by state and get the top 20 by count. count()
is an aggregate function. Another useful summary is per buckets which we can achieve with bin
:
1
2
3
4
5
StormEvents
| sort by StartTime desc
| take 2000
| summarize count() by day = bin(StartTime, 1d)
| sort by day
bin
will round the value given to the closest bin, here the day. So if we project the bin on each event, we will see that it is rounded to the start of the day:
1
2
3
4
5
StormEvents
| sort by StartTime desc
| take 2000
| extend day = bin(StartTime, 1d)
| project day
With summarize
we seen that aggregate functions were used. The most common being:
count
: returns the count per summary,max
: returns the max value from the group,min
: returns the min value from the group,sum
: returns the sum of all the values (if numerical).For example here we can gtet the sum of direct injured per day:
1
2
3
StormEvents
| summarize sum(InjuriesDirect) by bin(StartTime, 1d)
| take 20
Lastly render
is a special tabular operator which renders a chart.
The most common charts are:
barchart
columnchart
linechart
piechart
Taking columnchart
as example, we can diplay the count per day:
1
2
3
4
StormEvents
| summarize count() by bin(StartTime, 1d)
| take 20
| render columnchart
We can also split further per state:
1
2
3
4
StormEvents
| summarize count() by bin(StartTime, 1d), State
| take 20
| render columnchart
Some visualizations have a kind
property for example with columnchart
we can do kind=stacked100
which would stack the column from the same bucket into a 100% height column. Other kind
for column chart are:
unstacked
stacked
stacked100
And that conludes today’s post, hope you like this post and I’ll see you on the next one!