"Error in plugin: key "...." not in Fields" triggered by Starlark processor plugin

The problem

  • Telegraf gives errors
    **2020-12-02T18:58:07Z E! [processors.starlark] Error in plugin: key “Allocated Virtual Memory” not in Fields.

=====
telegraf.conf has:

[[inputs.snmp]]
agents = [“udp://127.0.0.1:161”]
name = “Local VM”
:
[[inputs.snmp]]
agents = [“udp://192.168.9.1:161,udp://192.168.9.1:162”]
name = “remote VM”
:
[[processors.starlark]]
script = “/home/hn1961/starlark/mine.star”

===

The starlark script ‘mine.star’ has the following:

def apply(metric):
allocatedMem = metric.fields[‘Allocated Virtual Memory’]
usedMem = metric.fields[‘Used Virtual Memory’]
metric.fields[‘freeMem’]= allocatedMem - usedMem
return metric

===

The goal
To have a new metric ‘freeMem’ with the desirable result.

==

Observations

  • Chronograf shows:
  • Only 127.0.0.1 (with measurement=“Local VM”) have metric names and data.
  • Other hosts (192.168.x.x) associated with name = “remote VM” have metric names but no data for any metric field.
  • It appears that Telegraf stopped collecting metrics for hosts that do not have metrics mentioned in the starlark script.

=======

The environment:

  • Both ‘Allocated Virtual Memory’ and ‘Used Virtual Memory’ are custom MIBs
  • Only agent with measurement=“Local VM” has metrics ‘Allocated Virtual Memory’ and ‘Used Virtual Memory’
  • Agents with Measurement = “remote VM” do not have the custom MIBs, hence, the metrics are not applicable to them.

======

I tried adding IF-ELSE statement in the starlark script so that the calculation are done for the ‘Local VM’ measurement.
However, I am unable to determine the Condition parameter, for instance,
def apply(metric):
if MEASUREMENT[‘Name’] == “Local VM”:
allocatedMem = metric.fields[‘Allocated Virtual Memory’]
usedMem = metric.fields[‘Used Virtual Memory’]
metric.fields[‘freeMem’]= allocatedMem - usedMem
return metric
else:
return metric

I get errors:
2020-12-02T19:08:56Z E! [telegraf] Error running agent: could not initialize processor starlark: /home/hn1961/starlark/sam.star:2:6: undefined: MEASUREMENT

Next Steps
Any pointer is greatly appreciated.

Hello there, it seems like your issue is that you want the starlark script to only process on the Local VM measurement. I believe a simple way to do this is with a ‘namepass’ in the processor’s config. You could do something like namepass = [“Local VM”] underneath [[processors.starlark]] and I think that should act to filter to only the Local VM measurements. Just be sure to remove the if MEASUREMENT[‘Name’] == “Local VM” line for that solution.

Note that the measurement is called metric.name, not MEASUREMENT.

also if you are not sure if the field exists, you could use metric.fields.get() instead of metric.fields[] to get the field value. Note that you may want to limit the metrics that the processor is looking at with namepass.

Using namepass as a filter works well. See script below.

[[processors.starlark]]
namepass = [‘Local VM’]
source = ‘’’
def apply(metric):
allocatedMem = metric.fields[‘Allocated Virtual Memory’]
usedMem = metric.fields[‘Used Virtual Memory’]
metric.fields[‘freeMem’]= allocatedMem - usedMem
return metric
‘’’

This way, the processor only acts on collection targets that have the measurement in the script.

As a heads up, a Processor script can stop reporting metrics unintentionally if not planned carefully (as I reported above). Hope it will be more robust than it is now. In the meantime, I will try metric.fields.get() as a safe guard.

Thank you so much for the help.

1 Like