Basics of KQL

In the previous two post we’ve looked at logging and using the TelemetryClient to send information to Application Insights. Application Insights offers a powerful query language (Kusto Query Language – KQL) for filtering logs.

We cannot possibly cover all options of KQL, so this post will just cover some of the basics and useful queries.

Tables

Application Insights supplied several tables as ways tracking events, information and various logging data.

The main tables are as follows

  • requests: Logs information regarding HTTP requests in your application.
  • dependencies: Tracks calls made to external services or databases.
  • exceptions: Logs exceptions within your application.
  • traces: Diagnostic log messages and traces from your application.
  • pageViews: Page views and user interactions within your web application.
  • customEvents: Custom events that are defined to track specific actions or user interactions.
  • metrics: Tracks performance metrics and custom metrics.
  • availabilityResults: Availability tests that check uptime and responsiveness of your application/
  • appExceptions: Like exceptions, specifically for application exceptions.
  • appMetrics: Like metrics, specifically for application metrics.
  • appPageViews: Like pageViews, specifically for application page views.
  • appPerformanceCounters: Performance counters for your application.
  • appSystemEvents: System level events within your application.
  • appTraces: Like traces, specifically for your application traces.
  • azureActivity: Azure activity logs.
  • browserTimings: Captures detailed timings information about the browser’s performance when loading web pages.

We can combine timespan, so 1d6h30m means 1 day, 6 hours and 30 minutes.

Get everything

We can get everything across all tables (see below for information on the tables) using

search *

Tables

We can just get everything from a table by running the query against a table, so for example for the traces table

traces

Filtering

Obviously returning all traces for example, is probably returning more rows than we want, so we can filter using the where keyword

traces
| where severityLevel == 3

Projections

traces
| where severityLevel == 3
| project timestamp, message

Aggregation

traces
| where severityLevel == 3
| summarize count() by bin(timestamp, 1h)

Ordering

requests
| where success == "false"
| summarize count() by bin(timestamp, 1h)
| order by bin(timestamp, 1h) desc

Samples

Get all the tables that have data

search * 
| distinct $table

Get all records within a table for the last 10 minutes

traces
| where timestamp > ago(1m)

The ago function allows us to use a timespan which includes

  • d: Days, for example 3d for three days
  • h: Hours, for example 2h for two hours
  • m: Minutes, for example 30m for thirty minutes
  • s: Seconds, for example 10s for ten seconds
  • ms: Milliseconds, for example 100ms for a hundred milliseconds
  • microsecond: Microseconds, for example 20microsecond for 20 microseconds
  • tick: Nanoseconds, for example 1tick for 100 nanoseconds

Summarizing each day’s request count into a timechart (a line chart). We also have options got a bar chart (barchart), pie chart (piechart), area chart (areachart) and scatter chart (scatterchart)

requests
| summarize request_count = count() by bin(timestamp, 1d)
| render timechart 

For some of the other chart types we need to supply difference information, so let’s look at a pie chart of the different requests

requests
| summarize request_count = count() by name
| render piechart    

We can get requests between two dates, including using of the now() function

requests
| where timestamp between (datetime(2025-02-14T00:00:00Z) .. now())

References

Kusto Query Language (KQL) overview