Home > Back-end >  float division in Go template
float division in Go template

Time:04-25

In grafana (which uses go templates for Loki line templating), I would like to divide a field (milliseconds) and get a float result.

Here is what I'd like to do :

| logfmt | line_format "{{ .microsec | float64 | div 1000 | printf \"%6.3f\" }}ms"

However, this obviously doesn't work because div is the integer divide function.

The following does work (but does not divide the number) :

| logfmt | line_format "{{ .microsec | float64 | printf \"%8.0f\" }}μs"

How can I get my output in millisecond format ?

EDIT : There is also a divf function, but the documentation says "Perform integer division". And I get very strange results with it (so I'm not sure how to use it) :

{{ .microsec | float64 | printf \"%8.0f\" }}μs {{  .microsec | float64 | divf 1000 | printf \"%6.3f\" }}ms?divf
6332μs   0.158ms?divf
22959μs  0.044ms?divf 
7034μs   0.142ms?divf 

CodePudding user response:

Grafana docs state that:

All sprig functions have been added to the template stage in Loki 2.3(along with function described below).

And the Float Math Functions include a divf function to perform floating point division.

Quoting from text/templates: Pipelines:

A pipeline may be "chained" by separating a sequence of commands with pipeline characters '|'. In a chained pipeline, the result of each command is passed as the last argument of the following command. The output of the final command in the pipeline is the value of the pipeline.

So when you do:

{{ .microsec | float64 | divf 1000 | float64 | printf "%6.3f" }}ms

You're actually dividing 1000 with the microsec value. Obviously you want the opposite, so simply do:

{{ divf .microsec 1000 | printf "%6.3f" }}ms

Also note that where floating point division is not supported (meaning there's no divf function), you can still do it with integer arithmetic.

{{ printf "%d.d" (div .microsec 1000) (mod .microsec 1000) | float64 }}ms

For more details, see How to get a float result from a HELM template division operation?

CodePudding user response:

Thanks to the help of @icza, I tried again around "divf" function, and the following works :

{{ divf .microsec 1000 | printf \"%6.3f\" }}ms

I still don't understand at this point why the following seems to return incorrect results :

{{ .microsec | float64 | divf 1000 | float64 | printf \"%6.3f\" }}ms

I also don't know where the documentation about divf can be found.

  • Related