Kusto: query to group http status codes - azure

I'm trying to query some Azure Application Gateway related things from Azure Log Analytics.
I get for a query like this results for every single http status code:
AzureDiagnostics
| where ResourceProvider == "MICROSOFT.NETWORK" and Category == "ApplicationGatewayAccessLog"
| summarize count() by httpStatus_d, Resource
Now I need those results grouped for 2xx, 3xx, 4xx and 5xx.
New to Kusto I don't find the right approach to achieve this.
Thanks for your hints!

you could try using the bin() function, e.g.:
AzureDiagnostics
| where ResourceProvider == "MICROSOFT.NETWORK" and Category == "ApplicationGatewayAccessLog"
| summarize count() by bin(httpStatus_d, 100), Resource

Thanks to #yoni who sent me into the right direction.
I solved this like this:
AzureDiagnostics
| where ResourceProvider == "MICROSOFT.NETWORK" and Category == "ApplicationGatewayAccessLog"
| extend HTTPStatus = case(httpStatus_d between (200 .. 299), "2XX",
httpStatus_d between (300 .. 399), "3XX",
httpStatus_d between (400 .. 499), "4XX",
"5XX")
| summarize count() by HTTPStatus, bin(timeStamp_t, 1h)
| render timechart

Group by all httpStatus_d values automatically.
AzureDiagnostics
| where TimeGenerated > ago(30d)
| summarize count=count() by httpStatus_d
| order by httpStatus_d asc

Related

Azure Kusto syntax

I need to run a very simple query
requests
| where cloud_RoleName == "blabla"
| summarize Count=count() by url
| order by Count desc
only thing i need to get the data just from the past 5 minutes
if i try this :
requests | where timestamp < ago(5m)
| where cloud_RoleName == "blabla"
| summarize Count=count() by url
| order by Count desc
or this
requests
| where cloud_RoleName == "blabla" and timestamp < ago(5m)
| summarize Count=count() by url
| order by Count desc
but all of them are returning answers with data older than 5 minutes.
ive read the doc and i see no other way of writing this query
can anyone assist?
Make sure to check if the timestamp is greater than the result of ago().
It returns the timestamp from e.g. 5 minutes ago, so if you want the data that is within last 5 minutes, you want the ones with a timestamp higher than that.
So the query should be:
requests
| where timestamp > ago(5m)
| where cloud_RoleName == "blabla"
| summarize Count=count() by url
| order by Count desc

Azure Log Analytics - How to view logs from last x days but only between certain hours?

I'd like to look at the app gateway 500 error logs over the last x number of days. But for those x number of days, I'd only like to see the logs that came in between 11:00 and 13:00 UTC. How can I do this? Here's what I have so far but it's not working.
AzureDiagnostics
| where TimeGenerated > ago(7d) and TimeGenerated between (datetime(11:00:00) .. datetime(13:00:00))
| where ResourceType == "APPLICATIONGATEWAYS" and httpStatus_d > 499
| where host_s == "my.website.com"
| summarize count() by clientIP_s, bin(TimeGenerated, 5m)
Obviously the second like (Timegenerated) is wrong. Can someone please advise on how to do this?
Thanks!
You could use hourofday(): https://learn.microsoft.com/en-us/azure/data-explorer/kusto/query/hourofdayfunction
For example:
AzureDiagnostics
| where TimeGenerated > ago(7d)
| where hourofday(TimeGenerated) between (11 .. 12) // 11:00 AM -> 12:59 PM
| where host_s == "my.website.com"
| where ResourceType == "APPLICATIONGATEWAYS"
| where httpStatus_d > 499
| summarize count() by clientIP_s, bin(TimeGenerated, 5m)

Azure Kusto time series

We are having some trouble using the time charts in Azure Kusto.
In this chart we have grouped http exceptions over time.
The issue is that the chart still reports the last seen value for points in time where that exception does not exist.
See red markings.
In this specific case we see that the chart reports 3.23k exceptions on the /poll endpoint at 5:28. while there are in fact no such error at that time.
The query looks like this
AppServiceHTTPLogs
| where TimeGenerated > ago(1d)
| where ScStatus >= 500
| summarize count() by tostring(CsUriStem), bin(TimeGenerated, 30m)
| render timechart
Using a column chart makes the issue go away, but this comes with the price of being much less clear.
Are there any other options?
Can we somehow make missing values default to 0 instead?
You should be able to fill with default zeros using make-series operator:
https://learn.microsoft.com/en-us/azure/data-explorer/kusto/query/make-seriesoperator
AppServiceHTTPLogs
| where TimeGenerated > ago(1d)
| where ScStatus >= 500
| make-series count() on TimeGenerated from ago(1d) to now() step 30min by tostring(CsUriStem)
| render timechart
Some UX clients do not know how to represent series data - and in this case you can expand it using mv-expand:
AppServiceHTTPLogs
| where TimeGenerated > ago(1d)
| where ScStatus >= 500
| make-series count() on TimeGenerated from ago(1d) to now() step 30min by tostring(CsUriStem)
| mv-expand count_ to typeof(long)
| render timechart

azure log analytics - concat two graphs in log analytics

I have two queries: both have similar results. I just want to draw both on one time chart in azure log analytics.
customEvents
| where name startswith "USER_LOGIN"
| extend responseTime_in_sec = todouble(customMeasurements.responseTime)/1000
| summarize avg(responseTime_in_sec) by responseTime_in_sec, bin(timestamp, 1h)
| render timechart
customEvents
| where name startswith "DEPENDENT_SERVICE"
| extend responseTime_in_sec = todouble(customMeasurements.responseTime)/1000
| summarize avg(responseTime_in_sec) by responseTime_in_sec, bin(timestamp, 1h)
| render timechart
As discussed in the comments, sometimes the solution can be quite easy :)
customEvents
| where name startswith "DEPENDENT_SERVICE" or name startswith "USER_LOGIN"
| extend responseTime_in_sec = todouble(customMeasurements.responseTime)/1000
| summarize avg(responseTime_in_sec) by name, responseTime_in_sec, bin(timestamp, 1h)
| render timechart
If the query is more complex than this, often the union operator can help as welll.

Azure log analytics timechart with multiple dimensions

In the Azure new log analytics query platform you can query for performance counters and summarize them to finally create a nice graph.
Following the multiple dimensions documentation example it says
Multiple expressions in the by clause creates multiple rows, one for
each combination of values.
I want to query their sample database for networks bytes Send and Received per each computer. Starting with this query it should be something like
Perf
| where TimeGenerated > ago(1d)
| where (CounterName == "Bytes Received/sec" or CounterName == "Bytes Sent/sec")
| summarize avg(CounterValue) by bin(TimeGenerated, 1h), Computer, CounterName
| extend Threshold = 20
| render timechart
The problem is that Send and Received bytes gets grouped in the graph at computer level.
How can multiple dimensions be represented as stated in the documentation so that I have Computer X Bytes Send and Computer X Bytes Received instead of them grouped together witch doesn't make any sense?
Not to mention that in the previous version this was working as expected.
I though that if multiple dimensions are not really accepted a string concatenation would do the trick. A bit hackish in my opinion but it did.
Perf
| where (CounterName == "Bytes Received/sec" or CounterName == "Bytes Sent/sec") and InstanceName matches regex "^Microsoft Hyper-V Network Adapter.*$"
| summarize avg(CounterValue) by strcat(Computer, " ", CounterName), bin(TimeGenerated, 10s)
| render timechart
Another option is this
let RuntimeID = CosmosThroughput_CL
| where MetricName_s == "ProvisionedThroughput" and TimeGenerated between (ago(2h) .. ago(1h))
| order by TimeGenerated desc
| top 1 by TimeGenerated
| distinct RuntimeID_g;
CosmosThroughput_CL
| where MetricName_s == "ProvisionedThroughput" and RuntimeID_g in (RuntimeID)
| project Resource = toupper(Resource), Value = Throughput_d, Container = Container_s, Database = Database_s, MetricName = "Provisioned"
| union
(
AzureDiagnostics
| where ResourceProvider == "MICROSOFT.DOCUMENTDB" and Category == "PartitionKeyRUConsumption"
| where TimeGenerated between (ago(1d) .. ago(1d-1h))
| summarize Value = sum(todouble(requestCharge_s)) by Resource, databaseName_s, collectionName_s
| project Resource, Container = collectionName_s, Database = databaseName_s, Value, MetricName = "HourlyUsage"
)
| union
(
AzureDiagnostics
| where ResourceProvider == "MICROSOFT.DOCUMENTDB" and Category == "PartitionKeyRUConsumption"
| where TimeGenerated between (ago(1d) .. ago(1d-1h))
| summarize Value = sum(todouble(requestCharge_s)/3600) by Resource, databaseName_s, collectionName_s
| project Resource, Container = collectionName_s, Database = databaseName_s, Value, MetricName = "RUs"
)
| project Resource, Database, Container, Value, MetricName
The important part is to project the same column names. Value holds the different values from each table. Second union helps me project another value from the same table.

Resources