How do I evaluate value which potentially is not supplied? - kql

I'm trying to make Azure monitor workbook with Azure Resource Graph (ARG) query as backend. There is dropdown presented to use to choose datetime value which is passed as parameter to ARG to filter results. It's expressed as {dateCreated:start} value in query. This works fine as long as there is something selected by user in dropdown, problem is that if nothing is selected in datetime field then condition essentially becomes coalesce(todatetime(),todatetime('2016-11-09T02:53:17.4582226Z')) which obviously fails validation logic since todatetime() expects something being passed to it. Is there something in KQL which will allow to overcome this?
Resources
| where type == 'microsoft.compute/virtualmachines'
| where tags['datecreated'] > coalesce(todatetime({dateCreated:start}),todatetime('2016-11-09T02:53:17.4582226Z') )

iff() and isempty() will do the trick for you:
Resources
| where type == 'microsoft.compute/virtualmachines'
| where tags['datecreated'] > iff(isempty({dateCreated:start}), todatetime('2016-11-09T02:53:17.4582226Z'), todatetime({dateCreated:start}))

Related

Azure Workbook parameter for resource and resource group

I've been defeated by Kusto on what I thought to be a simple query...
I'm making my first workbook and playing with parameters. I can list and select a Resource Group, but I can't make the following parameter (Virtual Machines) populate with the VMs when more than one Resource Group is selected. The ResourceGroup passes a comma delineated string of the group names as a property resourcegroup just fine. I cannot figure out how to translate that string into a usable where-statement. My query works just fine when I manually string several Resource Groups together so I assume I'm getting burned by my understanding of let and arrays in Kusto. If there is a better way of doing what I'm trying to do, please let me know.
//This will work so long as 1 Resource Group is passed from the previous parameter
resources
| where resourceGroup in ('{ResourceGroup:resourcegroup}') and type =~ microsoft.compute/virtualmachines'
| project value = id , label = name
I've figured out I can get a proper array with split('{ResourceGroup:resourcegroup}',","), but, again, I haven't been able to marry up that object with a where-statement.
Any help is much appreciated!
in https://github.com/microsoft/Application-Insights-Workbooks/blob/master/Documentation/Parameters/DropDown.md#special-casing-all
NORMALLY there is a way to do this:
let resourceGroups = dynamic([{ResourceGroup:resourcegroup}]);// turns even an empty string into a valid array
resources
| where (array_length(resourceGroups)==0 // allows 0 length array to be "all"
or resourceGroup in (resourceGroups)) // or filters to only those in the set
and type =~ microsoft.compute/virtualmachines'
| project value = id , label = name
however, i don't think Azure Resource Graph allows using let this way?
if you get an error that let isn't allowed, you'll have to do that dynamic thing inline a couple times instead:
resources
| where (array_length(dynamic([{ResourceGroup:resourcegroup}]))==0 // allows 0 length array to be "all"
or resourceGroup in (dynamic([{ResourceGroup:resourcegroup}]))) // or filters to only those in the set
and type =~ microsoft.compute/virtualmachines'
| project value = id , label = name

splunk date time difference

I am new to Splunk. My goal is to optimize the API call, since that particular API method is taking more than 5 minutes to execute.
In Splunk I searched using context ID, I got all the functions and sub functions call by main API call function for that particular execution. Now I want to figure what which sub function took the maximum time. In Splunk in left side, in the list of fields, I see field name CallStartUtcTime (e.g. "2021-02-12T20:17:42.3308285Z") and CallEndUtcTime (e.g. "2021-02-12T20:18:02.3702937Z"). In search how can I write a function which will give me difference between these two times. I google and found we can use eval() function but for me its returning null value.
Additional Info:
search:
clicked on "create table view" and checked start, end and diff fields in the left side fields list. but all three are coming as null
not sure what wrong I am doing. I want to find out the time taken by each function.
Splunk cannot compare timestamps in string form. They must be converted to epoch (integer) form, first. Use the strptime() function for that.
...
| eval start = strptime(CallStartUtcTime, "%Y-%m-%dT%H:%M:%S.%7N%Z")
| eval end = strptime(CallEndUtcTime, "%Y-%m-%dT%H:%M:%S.%7N%Z")
| eval diff = end - start
...

Axiomatics - condition editor

I have a subject like "accessTo" = ["123", "123-edit"]
and a resource like "interestedId" = "123"
Now I'm trying to write a condition - where it checks "interestedId" concatenated with "-edit" equals "123-edit" in "AccessTo".
Im trying to write rule like this
anyOfAny_xacml1(function[stringEqual], "accessTo", "interestedId"+"-edit")
It is not allowing to do this.
Any help is appreciated.
In addition to the answer from Keerthi S ...
If you know there should only be one value of interestedId then you can do this to prevent the indeterminate from happening:
stringBagSize(interestedId) == 1 && anyOfAny(function[stringEqual], accessTo, stringOneAndOnly(interestedId) + "-edit")
If more than value is present then evaluation stops prior to reaching the function that expects only one value. This condition would return false if more than one value is present.
On the other hand if interestedId can have multiple values then this would work:
anyOfAny(function[stringEqual], accessTo, map(function[stringConcatenate],interestedId, "-edit"))
The map function will apply the stringConcatenate function to all values in the bag.
Since Axiomatics products are compliant with XACML specification, all attributes by default are assumed to contain multiple values(called as 'bags').
So if you would like to append a string to an attribute use stringOneAndOnly XACML function for the attribute to indicate that the attribute can have only one value.
So assuming you mean accessTo has attribute ID as Attributes.access_subject.subject_id, interestedId has the attribute ID as Attributes.resource.resource_id and anyOfAny_xacml1 is equivalent to anyOfAny XACML function, the resulting condition would look like,
anyOfAny(function[stringEqual], Attributes.access_subject.subject_id, stringOneAndOnly(Attributes.resource.resource_id) + "-edit")

Log Analtyics - How to use "inverted commas" within search query

I am trying to create a search query for when a Public IP is assigned to a NIC, and then create an alert off that. I can find the part which identifies the assignment, but I need to use "inverted commas" within my search, but I can't...
My query:
AzureActivity
| where OperationName == "Microsoft.Network/networkInterfaces/write" and ActivityStatus == "Started"
| where Properties contains "<>"
Within that "contains", I need to use the following JSON pulled from the properties JSON (which I found doing a search without Properties Contains):
\"provisioningState\":\"Succeeded"\
However, I know I can't use "inverted commas" within an already inverted comma area. Is there a way to allow me to put that inside, perhaps with some sort of cancelling or bracketing?
You can use # for escaping - see here:
https://docs.loganalytics.io/docs/Language-Reference/Data-types/string
or, possibly better yet, you can use extractjson (or parsejson) functions
https://docs.loganalytics.io/docs/Language-Reference/Scalar-functions/extractjson()
I have found my solution, thanks to the links submitted by #Oleg Ananiev.
AzureActivity
| sort by TimeGenerated desc nulls last
| where OperationName == "Microsoft.Network/networkInterfaces/write" and ActivityStatus == "Started"
| where Properties contains '\\"provisioningState\\":\\"Succeeded\\"'
A better way to read to the nested property in JSON format using parse_json. For example if you would like to read to provisioningState property's value, simple do the following query
| where parse_json(Properties).provisioningState == 'Succeeded'
Please let me know if that helps!

Using a filter in part of a string

I have a filter that formats a number based on what stat type it is (percent, integer, currency, etc). I want to use this filter on a value as part of a string. See below:
<js-widget
v-on:click="this.selectedReportId = key"
:selected="this.selectedReportId == key"
:icon="report.icon"
:stat="report.current | stat report.statType"
:title="report.title"
:tooltip="report.tooltip"
:percent="report.percent"
:description="'Previous value: '+(report.past | stat report.statType)">
</js-widget>
As you can see in the :stat parameter, I can use the filter if it is the only thing in the expression. But when it tries to evaluate the :description parameter, I get Error when evaluating expression. Is it possible to use a filter in this way?
It's been very long since the question was asked, but if someone searches, I happen to know the solution.
First there is a way to call a filter from inside the vue component. Actually all filters are stored in the
this.$options.filters
collection. So if you want to call a filter from inside the component you should do
...
this.$options.filters.stat(report.past, report.statType)
...
And if you want to do the same from the markup, you should also call filter not like filter (| syntax), but like the component method
<js-widget
v-on:click="this.selectedReportId = key"
:selected="this.selectedReportId == key"
:icon="report.icon"
:stat="report.current | stat report.statType"
:title="report.title"
:tooltip="report.tooltip"
:percent="report.percent"
:description="'Previous value: '+ $options.filters.stat(report.past, report.statType)">
</js-widget>
Or, better, with template string
:description = "`Previous value: ${$options.filters.stat(report.past, report.statType)}`"
The filter is something available outside of the expression you are evaluating – so that's not going to work syntactially
I would use a computed property instead. For more information, see http://vuejs.org/guide/computed.html.