Get the name of a month in Application Insights - azure

I am new to application insights and I am writing a query to pull few data from Azure. I need to fetch the name of the month. I tried the below query, but I am getting just the numeric value of 1 in output.
I need the value as string in a separate column like "January", "February". Below is the output snap:
Query I wrote:
customEvents | summarize Count = dcount(cloud_RoleInstance) by ProductVersion = tostring(customDimensions.["Version"]), Month = monthofyear(timestamp)
Any suggestion would be highly helpful. Thanks.

There is no built-in function for this. So you should define a user-defined function to achieve this.
The sample code like below, and you can modify it to meet your need:
let f=(a:int){
case(a==1,"Jan",
a==2,"Feb",
a==3,"Mar",
//add the other month
a==12,"Dec",
"Error"
)
};
traces
| summarize count() by cloud_RoleName ,Month=f(getmonth(timestamp))
The test result:
And here is the query just for your case, please add other month in the function.
let f=(a:int){
case(a==1,"Jan",
a==2,"Feb",
a==3,"Mar",
//add the other month
a==12,"Dec",
"Error"
)
};
customEvents
| summarize Count = dcount(cloud_RoleInstance) by ProductVersion = tostring(customDimensions.["Version"]), Month = f(getmonth(timestamp))

Related

Passing Query Result to a function as a parameter Kusto

I want to create a function that allows me to pass the tabular result of a query as a parameter without specifying the table column names.
This is what I want as a result:
let Func = (T) {
T
| where Source has_any ("value")
};
let EventVar = Event | where TimeGenerated > ago(30d);
Func (EventVar);
You do not need to specify all columns in the tabular parameter schema, only those columns that you need to use inside the function.
For example, this is how your query can look like:
let CustomFunc = (T:(Source:string)) {
T | where Source has_any ("value")
};
let EventVar = Event | where TimeGenerated > ago(30d);
CustomFunc(EventVar);
The query above will output all columns from the table EventVar if its rows match the condition in your function. The only requirement is that the table EventVar has a column of type string with name Source, and it can have any number of other columns.
It is also possible to accept any tabular schema by defining the input tabular parameter like T:(*), but in this case you will not be able to reference any column names inside the function. See example 4 on the documentation page for reference.

Passing column name as parameter in Kusto query

I need to pass the column name dynamically into the query. While following is syntactically correct it does not really execute the condition on the particular column.
Is this even possible in Kusto?
let foo = (duration: timespan, column:string) {
SigninLogs
| where TimeGenerated >= ago(duration)
| summarize totalPerCol = count() by ['column']
};
//foo('requests')<-- does not work
//foo('user') <-- does not work
//foo('ip')<-- does not work
you can try using the column_ifexists() function: https://learn.microsoft.com/en-us/azure/data-explorer/kusto/query/columnifexists.
for example:
let foo = (column_name:string) {
datatable(col_a:string)["hello","world"]
| summarize totalPerCol = count() by column_ifexists(column_name, "")
};
foo('col_a')
col_a
totalPerCol
hello
1
world
1

Custom aggregate function on summarize

I want to calculate a statistic mode on a column during summarization of a table.
My CalculateMode function that I try is like this:
.create function CalculateMode(Action:int, Asset:string, Start:long, End:long) {
Event
| where Time between (Start .. End) and IdAction == Action and IdDevice == Device
| summarize Count = countif(isnotnull(Result) and isnotempty(Result)) by tostring(Result)
| top 1 by Count desc
| project ActionResult
}
OR
.create function CalculateMode(T:(data:dynamic)) {
T
| summarize Count = countif(isnotnull(data) and isnotempty(data)) by tostring(data)
| top 1 by Count desc
| project data
}
when i using first coding on summarizing:
Event
| summarize Result = CalculateMode(toint(IdAction), tostring(IdDevice), Start, End) by Category
Obtain this error No tabular expression statement found and
when i using second coding on summarizing:
Event
| summarize Result = CalculateMode(Result) by Category
I get this error
CalculateMode(): argument #1 must be a tabular expression
What can I do? Where am I doing something wrong?
Thanks
You can't just do summarize Result = CalculateMode(Result). You have to decide which aggregation function you want to summarize by (see the full list of aggregation functions here).

How to calculate time grain based on selected period from azure dashboard in a custom chart

While writing a kusto query to create a custom chart on my azure dashboard, I want to be able to calculate the time grain based on the period the user selected on the dashboard.
For example: last 4h => time grain 2 mins, last 24h => 10 mins
I tried the following to calculate the period because we are still unable to access it (as far as I could find on the internet).
let timeGrain = traces
| summarize min_time = min(timestamp), max_time = max(timestamp)
| extend timeWindow = max_time - min_time // days / hrs/ min / seconds
| project timeWindow
| extend timeGrain = case(timeWindow <= 4h, "2m",
timeWindow <= 12h, "5m",
timeWindow <= 24h, "10m",
"2h")
| project timeGrain;
The query returns me the time grain I want to achieve but I am unable to use this variable inside of my other query.
traces
...
| summarize percentile(DurationInMs, 50) by bin(timestamp, timeGrain), CommandType
| render areachart with (ytitle = "Duration In Ms", xtitle = "Timestamp");
(I know traces isn't the best place to store data regarding duration, we are gonna change this to metrics but it's not the scope of the question)
This gives me the following error: 'summarize' operator: Failed to resolve scalar expression named 'timeGrain'
Is there a way to fix this error or is there a better way to create a dynamic time grain?
Obviously I do not have the same fields in my traces but you should use a timespan instead of a string to define timeGrain.
Also, to use the query result timeGrain as a variable, use toscalar (docs):
let timeGrain = toscalar(traces
| summarize min_time = min(timestamp), max_time = max(timestamp)
| extend timeWindow = max_time - min_time // days / hrs/ min / seconds
| project timeWindow
| extend timeGrain = case(timeWindow <= 4h, 2m,
timeWindow <= 12h, 5m,
timeWindow <= 24h, 10m,
2h)
| project timeGrain);
traces
| summarize count() by bin(timestamp, timeGrain)
| order by timestamp desc
this works just fine.
This may not be a direct answer to the question but may be useful for others who do not want to create logic to infer time grain from time range.
Use a workbook to create chart from app insights query. Add a time range parameter and refer to the parameter in query. {TimeRange:grain} would give you granularity corresponding to time range selected. Now pin the query part to dashboard and voila! Your chart is ready to use time range selected on dashboard, auto refresh parameter.
Create workbook and pin parts to dashboard: https://learn.microsoft.com/en-us/azure/azure-monitor/visualize/workbooks-overview
Time range parameter: https://learn.microsoft.com/en-us/azure/azure-monitor/visualize/workbooks-time

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.

Resources