29 Apr 2024 08:12 AM - edited 29 Apr 2024 08:13 AM
Hello
I'm using variables on dashboard to filter in DQL.
I would like the filter command to be applied only if the variable has a selected value : if no value is selected for the variable, the variable isn't used to filter the request as if the filter command is skipped.
I didn't find a way to do it, like testing the value of a variable before using it.
Is it something feasible ?
Regards
Solved! Go to Solution.
09 Jun 2024 02:48 AM
Hi @GerardJ
If you are using Dashboard Gen 3, I recommend using Javascript:
1.- Capture filter information
2.- Create a Method that evaluates whether the filter variables have data (depending on it, apply one logic or another).
3.- Start working with that new final value
Something like this :
let array_tags = $GeneralTags
addTags(query_requestcountfilter, array_tags, array_environmentVariablesTags );
function addTags(query, array_tags, array_environmentVariablesTags){
var new_query_1 = ""
var new_query_2 = ""
var tags = "tag(~\""+ array_tags[0]+"~\")";
let i = 1;
while (i < array_tags.length ) {
if (array_tags[i]==null) break;
tags = tags + ",tag(~\""+array_tags[i]+"~\")";
i++;
}
if ( array_tags.length > 0){
new_query_1 = query.replace("CHANGE_TAG_GENERAL",tags)
}else{
new_query_1 = query.replace("CHANGE_TAG_GENERAL", "")
}
tags = "not(tag(~\""+array_environmentVariablesTags[0]+"~\"))";
i = 1;
while (i < array_environmentVariablesTags.length ) {
if (array_environmentVariablesTags[i]==null) break;
tags = tags + ",not(tag(~\""+array_environmentVariablesTags[i]+"~\"))";
i++;
}
if ( array_environmentVariablesTags.length > 0){
new_query_2 = new_query_1.replace("CHANGE_TAG",tags)
}else{
new_query_2 = new_query_1.replace("CHANGE_TAG","")
}
return new_query_2;
}
Of course, you can still optimize this code
I hope it's helpful 💪
09 Jun 2024 11:00 AM
You can check for variable values with a code snippet, if the value you expect is set then continue with the DQL
export default async function () {
if ($important_filter != "expected value") {
return null
}
// execute DQL...
...
return data;
}
https://developer.dynatrace.com/reference/sdks/client-query/#queryexecute
10 Jun 2024 07:41 PM
Maybe this is not exactly what you asked for for but I hope it is close and usable. Let's define variable as a list of values you want (in my example I used 2 popular keys of log lines) to filter by and one additional special value. In my case it is "*".
If the condition is the query is build this way:
fetch logs
| filter $Traffic=="*" or contains(content,$Traffic)
| limit 10
second part of the filter is simply ignored when value of $Traffic variable is *
btw: I do not like "Define a value in the referenced variable" message displayed in case when nothing is selected. Or dashboard should not allow this state or variable should have w value (i.e. null)
Kris
10 Jun 2024 07:51 PM
That is going to be an issue if nothing is found you will potentially still scan a couple of GB.
If you go this way I would at least suggest reading through this guide in order to reduce the amount of data scanned if nothing is found: https://docs.dynatrace.com/docs/platform/grail/dynatrace-query-language/dql-best-practices#dql-best-...
10 Jun 2024 08:15 PM
Thanks for pointing this out. Presence of "always false conditions" in theory should not have any influence on query execution as they can be eliminated up front. This is place where we can optimize 🙂
21 Jun 2024 01:33 PM
Hi All
thank you for all your suggestions.
As our aim is often to provide end-users with dashboards that they can evolve or adapt, using javascript tiles is never our first option so I'll probably go with the one suggested by @krzysztof_hoja
In fact what I'd like is to be able to do an if before a filter in DQL to only filter if the variable is set like this :
fetch logs
| if (isNotNull($myvariable), filter matchesValue(examplefield,$myvariable))
21 Jun 2024 09:34 PM
Unfortunately when variable is not selected it does not get value "null" and such state causes query to fail (probably this is something which can be improved). That's why I proposed special value for "all records".
If my previous example looks confusing and not intuitive, maybe this is clearer:
| filter if( $Traffic=="*", true, else: contains(content,$Traffic) )
but internally does the same.
If variable value is "*", then condition is always true, so effectively filter disappears.