Search code examples
prometheuspromqlgo-templates

Prometheus go templating: error calling first: first() called on vector with no elements


I'm trying to query a label within annotations. Though I don't know how to handle empty vectors. The query works when there are existing results for the query but I cannot call first on empty vector.

I'm getting

<error expanding template: error executing template __alert_Test: template: __alert_Test:6:6: executing "__alert_Test" at : error calling first: first() called on vector with no elements>

annotations:
  test: >-
    {{
      $myvar := (printf
        "metric{instance='%s'}"
        $labels.instance
        | query
        | first).Labels
    }}
    Foo: "{{ $myvar.label_a }}"

How to handle the empty vector and also the text output?

I'd like to achieve

Foo: "lablevalue" when there's a query result
nothingfound when the vector is empty.


Solution

  • Can you check the length of the slice before attempting first?

    I'd not used Prometheus templating and your question was a good opportunity for me to try it out. As a result this is likely not the best way but it works:

    {{
        $m := (printf "up{instance='%s'}" "localhost:9090" | query)
         
    }}
    Job: {{ if eq (len $m) 0 }}nothingfound{{ else }}{{ index ($m | first).Labels "job" }}{{ end }}
    

    I'm using up for want of metric.

    I'm using a constant value for %s.

    • localhost:9090 is a valid instance and returns Job: prometheus
    • localhost:9091 is an invalid instance and returns Job: nothingfound