Grafana: Add filters to legend formatter with Prometheus datasource

Created on 16 Dec 2015  ·  20Comments  ·  Source: grafana/grafana

Similar to: http://prometheus.io/docs/visualization/promdash/#filters
Is this already supported today?

aredatasource datasourcPrometheus help wanted typfeature-request

Most helpful comment

It appears that this pull request, and the 3.1 release, has crippled the ability to run arbitrary JS, meaning that there's a regression in functionality here. That is, .replace() no-longer works, and this feature remains unimplemented, with no work around.

All 20 comments

Not yet.
In Grafana, underscore.js template function is used to generate legend string.
http://underscorejs.org/#template

So you can use the underscore.js feature.

You can just use a normal JS.

Say your metric name is mysql_global_status_blabla and you want to get its part blabla on the legend:

{{ __name__.replace("mysql_global_status_", "") }}

Similar with the labels. You can even use JS alert() function 😀

Ah. That's why {{ location }} puts the browser's URL into the legend instead of the location label value (don't have a Grafana lying around to try at the moment, but a friend had this problem). That sounds like a problem when random JS vars collide with Prometheus label names.

By default, template places the values from your data in the local scope via the with statement. However, you can specify a single variable name with the variable setting. This can significantly improve the speed at which a template is able to render.

http://underscorejs.org/#template

Avoid using "with statement" will fix {{ location }} problem, but it need to specify variable name like {{ labels.job }}.

I'm not sure which is better...

Would it be possible to have both in order to not break backwards compatibility? Like adding a labels variable in order to allow calls like labels.location and other overloaded names (ironically now labels.labels).

@grobie When setting "options.variable" in lodash, need to change "legend format string" itself.
https://lodash.com/docs#template
All variable name reference should have "options.variable" prefix.

I try to fix this by https://github.com/grafana/grafana/pull/5096 .

It appears that this pull request, and the 3.1 release, has crippled the ability to run arbitrary JS, meaning that there's a regression in functionality here. That is, .replace() no-longer works, and this feature remains unimplemented, with no work around.

Sorry for taking time to merge this, looks like a hotly requested feature. Just want to extract some of the logic to core grafana so other data sources can take advantage of this feature. Hope to be able to do this soon.

Oh no, legends without .replace()? Say it aint so!

To work around this, I'm using the label_replace function of Prometheus.

Thanks @pvalsecc , label_replace works like a charm!

@pvalsecc @mbjelac I can't figure this out. What would you write to simulate a _Legend Format_ .replace('some_long_name', 'short') using label_replace?

@Redsandro I used it for removing part of a label text, but I think you can use it for replacement too.
In the meantime I fixed my template regex, so I don't need this anymore, but I checked the docs again, and here's how I think it would work:

If my_metric has a label my_label, then

label_replace(my_metric, "other_label", "$1short$2", "my_label", "(.*)(some_long_name)(.*)")

should create a label other_label with some_long_name replaced with short.

But check the regex capture group syntax... I just wrote it from my head. It might have errors.

@pvalsecc @mbjelac amazing, thanks a lot for this, I've completely missed it in prometheus' doc!

Also ran into this today, and Prometheus' label_replace seems to work. I was able to use this to retrieve the first segment of a host's FQDN for an instance label:

label_replace(x_keys{job="myjob"} > 0, "instance", "$1", "instance", "(.*).internal.*")

It would be super nice if something could be done in the Legend format though, such as {{instance.trim_right(.)}}, but I have no clue how feasible that is. :) Thanks for Grafana.

I have a similar problem here. I want the legend to show prometheus tags ifDescr and ifAlias, but ifAlias is sometimes empty:

ifType_info{ifAlias="",ifDescr="vlan254",ifIndex="10",ifName="vlan254",ifType="l2vlan"} 1
ifType_info{ifAlias="",ifDescr="vlan255",ifIndex="9",ifName="vlan255",ifType="l2vlan"} 1
ifType_info{ifAlias="Hurricane Electric IPv6 Tunnel Broker",ifDescr="sit1",ifIndex="15",ifName="sit1",ifType="other"} 1

If I use the legend format of {{ifDescr}} {{ifAlias}}, then for any timeseries where ifAlias is empty, the literal string "ifAlias" appears in the legend. (I am guessing the value is undefined, and treated as an error?)

I've been unable to find any documentation of the syntax of legend formats, and what is allowed or not allowed within them.

But it certainly doesn't seem to be Javascript: e.g. {{ifAlias ? ifAlias : ifDescr}} just gives the whole thing as a literal string, whether or not ifAlias is defined.

In which Version this fix has being done. Currently i am using grafana-4.6.3-1.x86_64 and .replace() is not working on that

Thanks in advance

It appears that this pull request, and the 3.1 release, has crippled the ability to run arbitrary JS, meaning that there's a regression in functionality here. That is, .replace() no-longer works, and this feature remains unimplemented, with no work around.

Is this issue going to fix in later release

I think custom legend formatting should be supported now. Please reopen if still relevant

Can you point to the documentation of what syntax is allowed in legend expressions? And in what version did it change? Googling for "grafana custom legend formatting" isn't turning up anything useful.

With Grafana 6.7.4, I still get the issues mentioned earlier. Configuring this query with custom legend:

image

gives this result:

image

The problems are:

  1. This availability and syntax of this limited templating language in legends is not documented AFAICS
  2. If you expand a field like {{ifAlias}} and that value doesn't exist, you get the literal string ifAlias, and I want a way to replace this with a (possibly blank) default value
Was this page helpful?
0 / 5 - 0 ratings