Starlark for inputs.file with name_override

Hi All

I am extracting the cpu temperature from a Raspberry Pi using the following in my telegraf.conf

[[inputs.file]]
    files = ["/sys/class/thermal/thermal_zone0/temp"]
    name_override = "cpu_temperature"
    data_format = "value"
    data_type = "integer"

This entry is working but unfortunately the value in the “temp” file is stored as an integer to allow for 3 decimal places of precision i.e. 50.307 is written to the file as 50307 so I get a displayed CPU temperature of 50k C instead of 50 C.

I would like to use a starlark processor to divide the original value by 1000 so that the outputted value is in the correct form but have been unable to get the processor to work. I have tried the following:

[[processors.starlark]]
source='''
original = metric.fields["cpu_temperature"]
metric.fields["cpu_temperature"] = original / 1000
return metric
'''

but using this code I get as error telling me that the cpu_temperature field does not exist. I have tried to log out the metric object to see what the actual structure is after the name_override but this has also not been successful.

[[processors.starlark]]
load("logging.star", log)

log.debug(metric)

I also tried a more generic loop to see if I could avoid the naming issue but this seemed to try and apply the logic in the loop to every measure in the conf rather than just the one in [[inputs.file]] (possible indentation requirement to restrict processor to specific input?)

[[processors.starlark]]
for k, v in metric.fields.items():
 if type(v) == "int":
    metric.fields[k] = v * 10
return metric

From all of this I have three questions

  1. How do I modify the value of my “name overridden” measurement so that the outputted value is divided by 1000?
  2. How do I log out items and/or values when running Telegraf? (it would be good to be able to see what’s in the metric object)
  3. How do I ensure that the processor only applies its logic to the enclosing “input” and is not applied to the entire list of inputs?

Many thanks in advance
Regard
Ian Carson

Welcome to the community!

I haven’t tested it, but this should work:

[[processors.starlark]]
  namepass = ["cpu_temperature"]  # therefore only cpu_temperature input is processed
  source = '''
load("logging.star", "log")  # load logging library

def apply(metric):
  original = metric.fields.get("value")
  metric.fields["cpu_temperature"] = original / 1000
  log.debug(metric.fields)  # example logging
  return metric
'''

[[outputs.file]] # file output only for debugging
  files = ["test.out"]
  influx_sort_fields = true

Thanks for the prompt reply but unfortunately your suggestion has not worked quite as expected (at least as I expected)

I think I was confusing fields and measurements. If I’m reading it right your code says

"Only apply this to a measurement called cpu_temperature
Put the number found in the value field of cpu_temperature into a variable ‘original’
Create a new field called “cpu_temperature” in the measurement and set its value to ‘original’’

As an experiment I tried to do

metric.fields["value"] = original /1000

but it seems like the value field does not want to be overwritten.

To reduce confusing it with the measurement I renamed the new field to “correctedValue” and this field became available for charting in both InfluxDB and Grafana when using a Flux query.

Here is the working code (omitted the logging as unnecessary)

[[inputs.file]]
files = ["/sys/class/thermal/thermal_zone0/temp"]
name_override = "cpu_temperature"
data_format = "value"
data_type = "integer"

[[processors.starlark]]
namepass = ["cpu_temperature"]
source='''
def apply(metric):
    original = metric.fields.get("value")
    metric.fields["correctedValue"] = original / 1000
    return metric       
'''

Interestingly the new field “correctedValue” does not show in the QueryBuilder in InfluxDB despite being accessible from Flux.

Any pointers as to why this might be?

With regards to logging out the metrics it seems that simply putting an entry to a valid file in the [[outputs.file]] section is enough to output all measurements and their fields.

Is there a special use case in mind for “log.debug” given this behavior?