How to rename axes in Azure Log Analytics Timechart Query - azure

I have the following query that I want to change the name of the axes. I tried the optional attributes of render, but it doesn't seem to recognize any of them. What am I missing?
AzureStorage_CL
| where ResourceGroup == "rg-sdl-adw"
| where PercentClientOtherError_d > 0
| summarize AV = any(PercentClientOtherError_d) by bin(TimeGenerated, 30m) |
render timechart with (ytitle = "Y new title")
Current results:

The "ytitle" isn't supported in Log Analytics since it uses a different rendering engine.
An issue has been submitted to track it.

Did you get your answer to this?
The axis aren't easy to edit, and the format you are constrained by are a bit restrictive, but essentially you need to rename the axes by taking your query:
AzureStorage_CL
| where ResourceGroup == "rg-sdl-adw"
| where PercentClientOtherError_d > 0
| summarize AV = any(PercentClientOtherError_d) by bin(TimeGenerated, 30m)
| render timechart
Now add in an extra line to rename the axis | project-rename NewAxisTitle = AV where the NewAxisTitle is your desired name, and the AV is your old name:
AzureStorage_CL
| where ResourceGroup == "rg-sdl-adw"
| where PercentClientOtherError_d > 0
| summarize AV = any(PercentClientOtherError_d) by bin(TimeGenerated, 30m)
| project-rename NewAxisTitle = AV
| render timechart
Be aware that any time you refer to the axis after the point you rename it you need to refer to it as it's new name.
Hope that all makes sense.

There are now some keywords available to achieve this (at least in the log analytics workspace) as here from GitHub.
For example, you maybe able to say:
| render timechart with (title = "Your Title", xtitle= "Your X Axis Title", yaxis = "Your X Axis title")
Please mark this as the answer if you that agree this feature is now supported. Thank you

Related

Get a category name from the id in the url using kusto query

I need to get the category name from category id using kusto query.
First i have got the most searched url from the website using the below kusto query and ran it in app insights logs
Requests
| where resultCode==200
| where url contains "bCatID"
| summarize count=sum(itemCount) by url
| sort by count
| take 1
From the above query i got the result like
https://www.test.com/item.aspx?idItem=123456789&bCatID=1282
So for corresponding categoryid=1282 i need to get the category name using kusto
you can use the parse operator.
for example:
print input = 'https://www.test.com/item.aspx?idItem=123456789&bCatID=1282'
| parse input with 'https://www.test.com/item.aspx?idItem=123456789&bCatID='category_id:long
parse_urlquery
print url ="https://www.test.com/item.aspx?idItem=123456789&bCatID=1282"
| extend tolong(parse_urlquery(url)["Query Parameters"]["bCatID"])
url
Query Parameters_bCatID
https://www.test.com/item.aspx?idItem=123456789&bCatID=1282
1282
Fiddle
Feedback to the OP query
Not an answer
KQL is case sensitive. The name of the table in Azure Application Insights is requests (and not Requests).
resultCode is of type string (and not integer/long) and should be compared to "200" (and not 200)
bCatID is a token and therefore can be searched using has or even has_cs, which should be preferred over contains due to performance reasons.
URLs can be used with different parameters. It might make more sense to summarize only by the Host & Path parts + the bCatID query parameter.
count is a reserved word. It can be used as alias only if qualified: ["count"] or ['count'] (or better not used at all).
sort followed by take 1 can be replaced with the more elegant top 1 by ...
requests
| where resultCode == "200"
| project url = parse_url(url), itemCount
| summarize sum(itemCount) by tostring(url.Host), tostring(url.Path), tolong(url["Query Parameters"]["bCatID"])
| top 1 by sum_itemCount

How to render a cumulative histogram based on ALA

I'd like to render a cumulative histogram of the duration of various workflows.
This is the query I use to compute the duration of various workflows, and the timeElapsedInMs result can be used to do things like compute percentiles (as shown). The durations span a fairly sizable range, from under a second to several minutes. What I would like to do is render a cumulative histogram of the data. My best guess at this point is that the accumulate property of one of the render types might work, but I can't seem to wrap my head around how to do that.
let start = fluentbit_CL
| where log_s has_cs "<starting event>"
| project trackingId = trackingId_g, timestampStart= _timestamp_t;
let finish = fluentbit_CL
| where log_s contains "<ending event>"
| project trackingId = trackingId_g, timestampFinish = _timestamp_t;
start
| join finish on trackingId
| extend timeElapsedInMs = datetime_diff('millisecond', todatetime(timestampFinish ), todatetime(timestampStart))
| summarize min=min(timeElapsedInMs), avg=avg(timeElapsedInMs), percentiles_array(timeElapsedInMs, 50, 95), max=max(timeElapsedInMs)
I'd also be happy with another sensible way to render the data to get a look at the percentiles, but my current best approaches don't get a very clear impression of the data.
There is no need to write one query for starting event and one for ending event and then join them. This can be done with a single query, using summarize.
Histogram can be easily created using bin (doc)
Accumulated histogram can be easily rendered using with (accumulate=True) (doc)
// This part of the code is just for data sample generation and is not part of the solution
let start = materialize (range trackingId_g from 1 to 100 step 1 | extend _timestamp_t = ago(24h * rand()), log_s = "<starting event>");
let finish = materialize (start | extend _timestamp_t = _timestamp_t + 5m * rand(), log_s = "<ending event>");
let fluentbit_CL = (union start, finish);
// The solution starts from here
fluentbit_CL
| summarize duration = anyif(_timestamp_t, log_s has_cs "<ending event>") - anyif(_timestamp_t, log_s has_cs "<starting event>")
by trackingId_g
| summarize count() by bin(duration, 10s)
| order by duration asc
| render timechart with (accumulate=True)
Fiddle

Create variables from tag values

I am trying to create different variables for the 'costcenter' tag. Each tag key "costcenter" has a respective value of "AB12" for example. I want to create a new variable in kusto to show that for every costcenter with the value of "AB12" I want to have this labeled as "HR Department".
I am unfamiliar with the syntax but need to get the value from costcenter that equals "AB12" and then store that as "Hr Department" so when I create a chart it shows HR department instead of "AB12"
resources
| extend cost = tostring(tags['costcenter'])
you can try using the case() function, or a mapping from actual value to desired value:
resources
| extend costcenter = tostring(tags['costcenter'])
| extend costcenter = case(costcenter == "AB12", "HR Department", costcenter)
| ...
let mapping = dynamic({"AB12":"HR Department", "AB23":"something else"});
resources
| extend costcenter = mapping[tostring(tags['costcenter'])]
| ...

How do I create a variable and set it equal to the count of a specific customEvent?

I have telemetry in my code that creates two custom events(longNameHere_event_success/longNameHere_event_error). I have a small AI Analytics query that looks for my events, gets the count of each, and renders a pie chart for a percentage metric.
As my event names are rather long, I'd like to create a variable for each to make the pie chart more legible.
customEvents
| where name contains "event"
|summarize count() by name
| render piechart
Current result is a pie chart with percentages for "longNameHere_event_success" and "longNameHere_event_error"
Desired result would be renaming "longNameHere_event_success" to "Success" and "longNameHere_event_error" to "Failure".
You can rename the column value as follows (I used an inline function for readability, but you can replace the function call with the case statement). Is this what you were looking for?
let rename = (original:string)
{
case(original == "longNameHere_event_success", "success",
original == "longNameHere_event_error", "error",
"unknown")
};
let customEvents = datatable(name:string)
[
"longNameHere_event_success",
"longNameHere_event_success",
"longNameHere_event_error"
];
customEvents
| where name contains "event"
| summarize count() by name
| project name = rename(name), count_
| render piechart

Is it possible to get query results in an App Insights inline function?

I am trying to write an App Insights query that will report back the timespan between two known events, specifically circuit breaker open and close events. The assumption is that these events always occur in pairs, so we need to know the time between the two for every occurrence in a time period.
My first attempt was to use an inline function. Simplified version below.
let timeOpened = (timeClosed:datetime)
{
let result = customEvents
| where name == 'CircuitBreakerStatusChange'
| where customDimensions['State'] == 'Open'
| where timestamp < timeClosed
| order by timestamp desc
| take 1
| project timestamp;
let scalar = toscalar(result);
scalar
};
customEvents
| where timestamp > ago(4h)
| where name == 'CircuitBreakerStatusChange'
| where customDimensions['State'] == 'Closed'
| extend timeOpen = timestamp - timeOpened(timestamp)
There may be a better way to do this. If so your ideas are welcome! But in this particular attempt the only feedback I get from Azure when running this is "Syntax error". However, I don't believe there's a syntax error here because if I just change the return value of the function from scalar to now() it runs successfully. Also I can run the body of the function in isolation successfully. Any idea what's wrong here?
I think you are getting syntax error because query language does not allow possibly recursive constructs. Now() worked because it was statically (not dynamically) retrieved at the query time.
I think you may achieve the desired outcome with serialize and prev() operators:
Table | order by timestamp asc | serialize
| extend previousTime = prev(timestamp,1)
| extend Diff = iff(customDimensions['State'] == 'Closed', timestamp - previousTime, 0)
| where Diff > 0
Note: I haven't tested the example above and it may need some additional thought to make it work (e.g. making sure that the previous record is actually "Opened" before doing previousTime calculation).

Resources