Parsing Help -- SNMP field to multiple records

Given the following from the vendor mib

		-- 1.3.6.1.4.1.9070.1.2.5.7.8.4.3
	    gnssSatlist OBJECT-TYPE
		    SYNTAX		DisplayString (SIZE(1..128))
		    MAX-ACCESS	read-only
		    STATUS		current	
		    DESCRIPTION 
			    "Displays the GNSS satellite tracking information in the
			format of:

			N,X1,Y1,C1,...,XN,YN,CN

			defined as follows:
			======================================================	
			N        Number of satellites. If one or more satellites 
			         are available, Xi,Yi,Zi follows N.

			Xi       Satellite vehicle number.

			Yi       Index

			Ci       GNSS Constellations.
			
			Example 1 :
                        11,X2,Y1,CBeiDou,X3,Y2,CBeiDou,X5,Y3,CBeiDou,X9,Y4,CBeiDou,X3,Y5,CGLONASS,X4,Y6,CGLONASS,X13,Y7,CGLONASS,X14,Y8,CGLONASS,X15,Y9,CGLONASS,X18,Y10,CGLONASS,X19,Y11,CGLONASS.

                        Interpretation of above example
                        11 (Number of Satellites)
                        X2, Y1, CBeiDou :  X2 (satellite vehicle number), Y1 (Index), CBeiDou (constellation)
                        
                        Example 2:
                        17,X1,Y1,CGPS,X10,Y2,CGPS,X11,Y3,CGPS,X14,Y4,CGPS,X16,Y5,CGPS,X20,Y6,CGPS,X22,Y7,CGPS,X25,Y8,CGPS,X26,Y9,CGPS,X27,Y10,CGPS,X31,Y11,CGPS,X32,Y12,CGPS,X40,Y13,CSBAS,X3,Y14,CBeiDou,X5,Y15,CBeiDou,X7,Y16,CBeiDou,X9,Y17,CBeiDou

  			Example 3:
  			0
                        No Satellites

			======================================================"
	    ::= {gnss 3}

which is queried via the following

[[inputs.snmp.field]]
  name = "sat_list"
  oid = "S650::gnssSatlist.0

I would like to parse this out so that I have say field satellite with the tags vehicle and constellation. I don’t see much value for the count as this could then be derived by doing a sum on the data for the interval or index (seems to just be an index into the list).

Parsing the total count is easily done with a regex but what I don’t know how to do is chunk up the returned string to multiple entries. If it is possible to pass this field to a shell script I could whip something up in bash/python easy enough but I am not sure how to make a call for just the field (maybe just the metric) to be processed by the script.

so from the example (#2) ^^ in the mib it would come out to something like this

satellite vehicle=1,constellation=GPS
satellite vehicle=10,constellation=GPS
..
satellite vehicle=9,constellation=BeiDou

Thoughts/pointers appreciated

Best way to do this would be using the starlark processor. You can use the split() method and then walk the resulting array.

Thanks for this, the name starlark didnt mean anything to me so hadn’t looked at that processor but this seems to be working great.

If you see anything that can be improved, I’d appreciate the feedback. If others come across this, currently using the following

[[processors.starlark]]
  namepass = ["ntp_server"]
  metricpass = ["sat_list"]

  source = '''
# when logging, use info or higher as running with debug can be quite noisy
#load("logging.star", "log")
def apply(metric):
  if metric.fields.get("sat_list"):
    # remove null terminator and split off the satellite count
    satellites, entries = metric.fields["sat_list"].rstrip("\x00").split(",", 1)

    # now that we have the data, we don't want this field in the metrics we generate from this
    metric.fields.pop("sat_list")

    # convert the string split value to an integer
    satellites = int(satellites)

    metrics = []
    # loop over all entries in the original metric and build new metrics representing each satellite reported
    for idx in range(satellites):
      entry_parts = entries.split(",", 3)

      #log.info("'{}' - '{}'".format(entry_parts[2][1:], entry_parts[0][1:]))
      new_metric = deepcopy(metric)
      new_metric.tags["constellation"] = entry_parts[2][1:].strip()
      new_metric.tags["vehicle"] = entry_parts[0][1:].strip()
      new_metric.fields["satellite"] = 1
      metrics.append(new_metric)

      entries = entry_parts[3] if len(entry_parts) == 4 else None

    return metrics

  # return metrics that are not `sat_list` unmodified
  return metric
'''