Azure analytics kusto queries : how to group by 2 conditions? - azure

I am using Azure analytics for a mobile app. I have custom events for main app pages - that I can find inside the customEvents table.
I am very new to kusto, so using the samples I found the following query:
let start = startofday(ago(28d));
let events = union customEvents, pageViews
| where timestamp >= start
| where name in ('*') or '*' in ('*') or ('%' in ('*') and itemType == 'pageView') or ('#' in ('*')
and itemType == 'customEvent')
| extend Dim1 = tostring(name);
let overall = events | summarize Users = dcount(user_Id);
let allUsers = toscalar(overall);
events
| summarize Users = dcount(user_Id), Sessions = dcount(session_Id), Instances = count() by Dim1
| extend DisplayDim = strcat(' ', Dim1)
| order by Users desc
| project Dim1, DisplayDim, Users, Sessions, Instances
| project ['Activities'] = DisplayDim, Values = Dim1, ['Active Users'] = Users, ['Unique Sessions'] = Sessions, ['Total Instances'] = Instances
the query is working well, but I want to have all the page events grouped by client_CountryOrRegion
Is there any way I can do this split by client_CountryOrRegion?

Not sure if this is what you are looking for but if you want to have the result split by client_CountryOrRegion, you can just summarize by that column as well as:
let start = startofday(ago(28d));
let events = union customEvents, pageViews
| where timestamp >= start
| where name in ('*') or '*' in ('*') or ('%' in ('*') and itemType == 'pageView') or ('#' in ('*')
and itemType == 'customEvent')
| extend Dim1 = tostring(name);
let overall = events | summarize Users = dcount(user_Id);
let allUsers = toscalar(overall);
events
| summarize Users = dcount(user_Id), Sessions = dcount(session_Id), Instances = count() by Dim1, client_CountryOrRegion
| extend DisplayDim = strcat(' ', Dim1)
| order by Users desc
| project Dim1, DisplayDim, Users, Sessions, Instances
| project ['Activities'] = DisplayDim, Values = Dim1, ['Active Users'] = Users, ['Unique Sessions'] = Sessions, ['Total Instances'] = Instances, client_CountryOrRegion
The change is here:
summarize Users = dcount(user_Id), Sessions = dcount(session_Id), Instances = count() by Dim1 , client_CountryOrRegion

Related

Does grid row click actually work in Azure Workbooks?

I have a query in my workbook that has the counts of successful and failed API calls and what I want to do is, allow the user to click on a line within the grid and grab two values from the row as parameters, in order to use them to display all the detail lines in another query.
I found the following "grid row click" example, and I thought is was perfect, but for some reason, it is not populating the parameters for the detail query.
Set up a grid row click
This is my count query:
let funcRequests = requests
| where (cloud_RoleName contains "xxxxxapi-dev")
| project cloud_RoleName, name, success, funcId = tostring(customDimensions.InvocationId);
let funcExceptions = exceptions
| extend funcId = tostring(customDimensions.InvocationId), errorMessage = customDimensions.FormattedMessage
| project funcId, errorMessage
| join
(
funcRequests
) on funcId
| project funcId, cloud_RoleName, name, success, errorMessage;
funcRequests
| join kind=leftouter
(
funcExceptions
) on funcId
| summarize totals = count(), successes = countif(success == "True" and errorMessage == ""), failures = countif(success <> "True" or errorMessage <> "") by
service = cloud_RoleName, name
| project Site=service,
["Operation Name"] = name,
["Count"] = totals ,
["Success"] = successes,
["Failure"] = failures,
Status = iif(failures>0,"❌","✔️");
I set up two export parameters in the Advanced Settings tab, one for "service" and one for "name".
I then added the parameter names to my detail query and got a "Query could not run because some parameters are not set. Please set _service, _name"
This is the detail query:
let funcRequests = requests
| where (cloud_RoleName == '{_service}' and operation_Name == '{_name}')
| project cloud_RoleName, name, success, funcId = tostring(customDimensions.InvocationId), details = itemId;
let funcExceptions = exceptions
| extend funcId = tostring(customDimensions.InvocationId), errorMessage = customDimensions.FormattedMessage
| project funcId, errorMessage
| join
(
funcRequests
) on funcId
| project funcId, cloud_RoleName, name, success, errorMessage;
funcRequests
| join kind=leftouter
(
funcExceptions
) on funcId
| project Site=cloud_RoleName,
["Operation Name"] = name,
Status = iif(success=="False","❌","✔️"),
["Details"]=details;
Obviously, I' missing something, but not sure what it is. Any suggestions would be appreciated!
you have the workbooks set up to export a column named "service" as the parameter _service and a column named "name" as a parameter named _name
but you don't have columns with those names.
the projection at the end of your query:
project Site=service,
["Operation Name"] = name,
renamed the "service" column to "Site" and the "name" column to "Operation Name"
so when you select a row, it does exactly what you said, and exports no values for those parameters because they have no values in those rows.
if i do this, to add new ones with the right column names:
i get the right results:

Azure Application Insight Query to get success rate

Have a question about how could I show success rate on Azure Dashboard.
If I have single temeletry event that indicates success or failure - it's quite simple:
customEvents
| where name == "ResponseEvent" and customDimensions.Condition == "test"
| summarize count() by tostring(customDimensions.State) //State could be Success|Failure
| render piechart
But in my case - I have 2 events: RequestEvent, SuccessResponseEvent and from those two I want to get success rate, something like: successRate = 100*successCount/requestCount.
I end up with this join:
customEvents
| where name == "RequestEvent" and customDimensions.Condition == "test"
| summarize requestCount = count()
| extend joinField = "1"
| join ( customEvents
| where name == "SuccessResponseEvent" and customDimensions.Condition == "test"
| summarize successCount = count()
| extend joinField = "1")
on joinField
| extend successRate = (100 * successCount / requestCount)
//////| extend failureRate = 100 - successRate
| project successRate
| render table
I got the value I need, but I only manage to display it as table, while I need a piechart.
I thought about adding union:
let success = view () { print x=toint(80) };
let failure = view () { print x=toint(20) };
union withsource=TableName success, failure
| render piechart
But I don't see how to do this in my request.
Or create variables using let statement and try to calculate everything and join using materialize(createRequestRecieved), but it causes quite a lot of errors and I hope some simple way exists.
Question is: maybe somebody could point me to how I could achieve this: calculate one value, maybe display it as two values (success and 100-success) and arrange them in format valid for "render piechart" operator?
And second question, not so important: could I join them by some existing field? Whey I'm trying to use joinField = tostring(customDimensions.MappingField) I'm getting an error: Ensure that expression: customDimensions.MappingField is indeed a simple name
If you are going for a piechart, it would require a string legend field and a value on each row for that legens, so union of two results should work:
requests
| summarize Success = sumif(itemCount, success == true)
| project Legend = "Success", Value = Success
| union
(requests
| summarize Failed = sumif(itemCount, success == false)
| project Legend = "Failed", Value = Failed )
| render piechart
Going for a barchart would allow to use both summarize clauses in one query without join/union and may speed up performance:
requests
| summarize Success = sumif(itemCount, success == true), Failed = sumif(itemCount, success == false)
| project Legend = "Status", Success, Failed
| render barchart
Similarly, to calculate the rate in the same query:
requests
| summarize Success = sumif(itemCount, success == true), Failed = sumif(itemCount, success == false)
| extend SuccessRate = Success * 1.0 / (Success + Failed)
I'm quite sure it's not the best option an I'm mising something in this query language capabilities, but I could put my request in variable, apply some caching and repeat it twice, I suppose:
let dataSource = customEvents
| where name == "RequestEvent" and customDimensions.Condition == "test"
| summarize requestCount = count()
| extend joinField = "1"
| join ( customEvents
| where name == "SuccessResponseEvent" and customDimensions.Condition == "test"
| summarize successCount = count()
| extend joinField = "1")
on joinField
| extend successRate = (100 * successCount / requestCount)
| extend failureRate = 100 - successRate;
let cacheddataSource = materialize(dataSource);
cacheddataSource
| project Legend = "Success", Value = successRate
| union (
dataSource
|project Legend = "Failure", Value = failureRate
)
| render piechart
So, let and materialize more or less helps, maybe some tweaks will be necessary to display actual amount of successes and failures.

Search Query should contain 'AggregatedValue' and 'bin(timestamp, [roundTo])' for Metric alert type

I'm trying to create a custom metric alert based on some metrics in my Application Insights logs. Below is the query I'm using;
let start = customEvents
| where customDimensions.configName == "configName"
| where name == "name"
| extend timestamp, correlationId = tostring(customDimensions.correlationId), configName = tostring(customDimensions.configName);
let ending = customEvents
| where customDimensions.configName == configName"
| where name == "anotherName"
| where customDimensions.taskName == "taskName"
| extend timestamp, correlationId = tostring(customDimensions.correlationId), configName = tostring(customDimensions.configName), name= name, nameTimeStamp= timestamp ;
let timeDiffs = start
| join (ending) on correlationId
| extend timeDiff = nameTimeStamp- timestamp
| project timeDiff, timestamp, nameTimeStamp, name, anotherName, correlationId;
timeDiffs
| summarize AggregatedValue=avg(timeDiff) by bin(timestamp, 1m)
When I run this query in Analytics page, I get results, however when I try to create a custom metric alert, I got the error Search Query should contain 'AggregatedValue' and 'bin(timestamp, [roundTo])' for Metric alert type
The only response I found was adding AggregatedValue which I already have, I'm not sure why custom metric alert page is giving me this error.
I found what was wrong with my query. Essentially, aggregated value needs to be numeric, however AggregatedValue=avg(timeDiff) produces time value, but it was in seconds, so it was a bit hard to notice. Converting it to int solves the problem,
I have just updated last bit as follows
timeDiffs
| summarize AggregatedValue=toint(avg(timeDiff)/time(1ms)) by bin(timestamp, 5m)
This brings another challenge on Aggregate On while creating the alert as AggregatedValue is not part of the grouping that is coming after by statement.

Azure Application Insights Analytics Query join by parsed url and summarize

I need to combine requests and customMetrics tables by parsed url. On output it should have common parsed url, avg duration of requests and avg value of requests from CustomMetrics.
This code doesn't work ^(
let parseUrlOwn = (stringUrl:string) {
let halfparsed = substring(stringUrl,157);
substring(halfparsed,0 , indexof(halfparsed, "?"))
};
customMetrics
| where name == "Api.GetData"
| extend urlURI = tostring(customDimensions.RequestedUri)
| extend urlcustomMeticsParsed = parseUrlOwn(urlURI)
| extend unionColumnUrl = urlcustomMeticsParsed
| summarize summaryCustom = avg(value) by unionColumnUrl
| project summaryCustom, unionColumnUrl
| join (
requests
| where isnotempty(cloud_RoleName)
| extend urlRequestsParsed = parseUrlOwn(url)
| extend unionColumnUrl = urlRequestsParsed
| summarize summaryRequests =sum(itemCount), avg(duration)
| project summaryRequests, unionColumnUrl
) on unionColumnUrl
Instead of inventing your own url parsing, how about using parse_url (https://docs.loganalytics.io/docs/Language-Reference/Scalar-functions/parse_url()) and using that instead?
It also appears that your summarize line in the requests join, isn't summarizing on url, so I'm not sure how that works.
Shouldn't this line:
| summarize summaryRequests =sum(itemCount), avg(duration)
be
| summarize summaryRequests =sum(itemCount), avg(duration) by unionColumnUrl
like it is in the metrics part of the query. Also, why are you calculating the average in that summarize? you're just throwing it away by not projecting it on the next line.

How to use a filter in subselect

I want to perform a subselect on a related set of data. That subdata needs to be filtered using data from the main query:
customEvents
| extend envId = tostring(customDimensions.EnvironmentId)
| extend organisation = tostring(customDimensions.OrganisationName)
| extend version = tostring(customDimensions.Version)
| extend app = tostring(customDimensions.Appname)
| where customDimensions.EventName contains "ApiSessionStartStart"
| extend dbInfo = toscalar(
customEvents
| extend dbInfo = tostring(customDimensions.dbInfo)
| extend serverEnvId = tostring(customDimensions.EnvironmentId)
| where customDimensions.EventName == "ServiceSessionStart" or customDimensions.EventName == "ServiceSessionContinuation"
| where serverEnvId = envId // This gives and error
| project dbInfo
| take 1)
| order by timestamp desc
| project timestamp, customDimensions.OrganisationName, customDimensions.Version, customDimensions.onBehalfOf, customDimensions.userId, customDimensions.Appname, customDimensions.apiKey, customDimensions.remoteIp, session_Id , dbInfo, envId
The above query results in an error:
Failed to resolve entity 'envId'
How can I filter the data in the subselect based on the field envId in the main query?
i believe you'd need to use join instead, where you'd join to get that value from the second query
docs for join: https://docs.loganalytics.io/docs/Language-Reference/Tabular-operators/join-operator
the left hand side of the join is your "outer" query, and the right hand side of the join would be that "inner" query, though instead of doing take 1, you'd probably do a simpler query that just gets distinct values of serverEnvId, dbInfo

Resources