8

I have a Grafana dashboard with variable called host. Host can be "domain1.com", "domain2.com" or "domain3.com".

I need another custom variable var2 that would somehow be connected to the host. For example, when user choose "domain1.com" as host, var2 should become "some text", if "domain2.com" - "another text", etc.

How can I define this custom variable?

2 Answers 2

13

You have two way of dealing with this:

Easier one

If both your values are constant and known on variable creation, you can use single variable with labels.

For example Custom variable can be defined with the following Value:

label1 : value1, label2 : value2

This way you will see in dropdown labels "label1", "label2".

And you can use this variable in the following way:

  • $var or ${var:value} will return value of selected item, for example value1,
  • ${var:text} will return label of selected item, for example lable1.

You can see demo here.

And for the case described in the question you'll need Value field of variable to be set to

domain1.com : some text, domain2.com : another text, domain3.com : etc

More agile one

If values dependent variable are not known on the creation stage, or if you want second variable to have more than one value for user to chose from, you'll need to use two variables and some (pseudo-)query with first variable as parameter to generate value of the second one.

This way you can chain multiple variables and create complex rules. But it requires a data source, that will allow to evaluate this rules.

Here are couple examples of data sources allowing for such rules:

SQL

Chaining of variables if you have any SQL data source is arguable the easiest case. You can use, CTEs, functions and much more. For my examples I'll use MySQL syntax, but I believe same can be done with all (or almost all) databases.

To accommodate one-to-one relation like in question you can utilize case statement to decode value:

select case 
  when '$var' = 'host1.com' then 'some text'
  when '$var' = 'host2.com' then 'another text'
  else 'Unexpected text'
end

To provide multiple values for dependent variable, you can use CTE with pairs of variables and filter them like you need:

with PAIRS as (
  select 'var1' var1, 'var1-dependent1' var2 union all
  select 'var1', 'var1-dependent2' union all
  select 'var2', 'var2-dependent1' union all
  select 'var2', 'var2-dependent2' union all
  select 'var2', 'var2-dependent3'  
)
select var2
from PAIRS
where var1 = '$var'

You can event apply transformation to content of original variable to get dependent variable. For example: replace all dots with underscores:

select replace('$var', '.', '_'); 
Prometheus

Prometheus is less ideal for such tricks, but most of the tasks can be accommodated by combination of boolean operators and absent.

For case where initial variable is numeric:

  • single value for dependent variable:
query_result(
  absent(non_existent{pseudo_label="value1"}) * 1 == $var1 or
  absent(non_existent{pseudo_label="value2"}) * 2 == $var1 or
  absent(non_existent{pseudo_label="value3"}) * 3 == $var1
)
  • multiple values for dependent variable:
query_result(
  absent(non_existent{pseudo_label="dependent1 for 1"}) * 1 == $var1 or
  absent(non_existent{pseudo_label="dependent2 for 1"}) * 1 == $var1 or
  absent(non_existent{pseudo_label="dependent1 for 2"}) * 2 == $var1 or
  absent(non_existent{pseudo_label="dependent2 for 2"}) * 2 == $var1 or
  absent(non_existent{pseudo_label="dependent1 for 3"}) * 3 == $var1
)

For string values:

  • single value for dependent variable:
query_result(
  (absent(non_existent{pseudo_label="output1"}) and on() (absent(non_existent{pseudo_input="input1"}) and absent(non_existent{pseudo_input="$value1"}))) or
  (absent(non_existent{pseudo_label="output2"}) and on() (absent(non_existent{pseudo_input="input2"}) and absent(non_existent{pseudo_input="$value1"}))) or
  (absent(non_existent{pseudo_label="output3"}) and on() (absent(non_existent{pseudo_input="input3"}) and absent(non_existent{pseudo_input="$value1"})))
)
  • multiple values for dependent variable:
query_result(
  (absent(non_existent{pseudo_label="dependent1 for input1"} or absent(non_existent{pseudo_label="dependent2 for input1"})
    and on() (absent(non_existent{pseudo_input="input1"}) and absent(non_existent{pseudo_input="$value1"}))) or
  (absent(non_existent{pseudo_label="dependent1 for input2"} or absent(non_existent{pseudo_label="dependent2 for input2"})
    and on() (absent(non_existent{pseudo_input="input2"}) and absent(non_existent{pseudo_input="$value1"}))) or
  (absent(non_existent{pseudo_label="dependent1 for input3"})
    and on() (absent(non_existent{pseudo_input="input3"}) and absent(non_existent{pseudo_input="$value1"})))
)

Some regex modification is also possible. For example you can replace last dot in your variable with underscore like this:

label_replace(
  absent(non_existent{pseudo_input="$value1"}),
  "pseudo_input", "${1}_$2",
  "pseudo_input", "(.*)\\.(.*)"
)

But this approach is more limited than what can be done with SQL data sources.

IMPORTANT: In all Prometheus' cases you need to provide Regex for linked variable, to extract label from result of query. For examples provided here regex will be /pseudo_label="(.+?)"/

Sign up to request clarification or add additional context in comments.

Comments

3

I had a related question to this post where I was working in grafana enterprise and needed to create a new variable var2 which was dependent on the first variable var1 but then applied a regex expression.

Example of value for var1: foo:12345. It would fluctuate in values but the colon would always be there and I only wanted the portion before the colon.

  1. Create new variable as a "Query".

  2. Select the same data source as the first variable.

  3. Set the query to equal the following SQL query (referencing some SQL examples in the above response):

    select '$var1'
    
  4. Set the regex portion to:

     /^(.*?):/
    

This is based on a regex query on stack overflow (link). The query will grab all values before the colon. And var2 will update when var1 is changed.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.