Get data from serial input


I have quite a simple problem but I just cannot think of a way of how to do this:
I have serial input looking like this:

PID     0x204
V       48535
VS      4
I       -45392
P       -2203
CE      -207202
SOC     753
TTG     169
Alarm   OFF

I think I should do this with the tail plugin probably, and I already managed to get the data to this plugin:

  files = ["/dev/bat_2"]
  pipe = true
  character_encoding = ""

But how to proceed from here? Should I use grok or something else?

There are many roads to Rome :wink:

I would say which solution you prefer depends on your knowledge and how you can get to a working solution the fastest.

grok might work, but I personally don’t like it, regex is always a pain…

But before we start any solutions:
Does the above data all belong together? Is this one dataset that belongs together?
If so: can you format the serial data differently in a common format? I see the problem that you will get a lot of single metrics, because each row is processed separately as a metric.

Yes, the dataset belongs together, it’s a constant stream of data. I’d just need four measurements out of it that keep getting repeated every second…
Right now I am thinking about preprocessing this data in Python and then giving it to Telegraf, maybe this would be the easiest?

This is a working solution.
However a bit dirty, because we have to fool the merge aggregator by reducing the precision.
Precision may have to be adjusted for the real data and this solution may not work in real usage scenarios.

  # your config here ...
  name_override = "serial"
  precision = "1ms"  # trick to fool the merge aggregator, may adjust it
  fieldpass = ["pid", "v", "vs", "alarm"]  # keep only those fields, drop all others
  data_format = "grok"
  grok_patterns = [
    'PID\s* %{BASE16NUM:pid:int}',
    'V\s* %{INT:v:int}',
    'VS\s* %{INT:vs:int}',
    'I\s* %{INT:i:int}',
    'P\s* %{INT:p:int}',
    'CE\s* %{INT:ce:int}',
    'SOC\s* %{INT:soc:int}',
    'TTG\s* %{INT:ttg:int}',
    'Alarm\s* %{WORD:alarm:string}',

  drop_original = true

Then you can keep only those fields in the input plugin, for example:

fieldpass = ["pid", "v", "vs", "alarm"]

Then you can probably set

precision = "100ms"

Thank you very much! So I applied your config and it seems like the space between the fields and the values is actually a tab, so it looked like this "V\t53340". So after changing to 'V\t*%{INT:v:int}' it started working and now I seem to understand grok more.