Hey @jessgarson thanks for all the help !! & apologies for a delayed response.
I tried the gauge and  counter they are working and are correctly reflecting values on UI, but for my use case here I won't be able to use either of them as counter would just keep a single value which is the current count which can be incremented or decremented,so I would not be able to keep multiple values/entries like for HTTP Code or processing times
& the same goes for gauge which can be set to a certain value & when updated that values gets updated to a new value. gauge can be useful for a metric like health status (viz Good & Bad) & counter would be useful for showing the current count of request processed or similar.
Let me illustrate with an example for  HTTP Code (would be similar for processing time)
@app.get("/health")
async def health_check():
    choices = [400, 200, 500, 512]
    random_value = random.choice(choices)
    # Create a metric
    metricset.counter("test_gauge").val = random_value
    return {"status": "ok"}
Now here if this API endpoint is hit 5 times in 30s & random_value generated are in the order [200,500,200,400,512] and if the metrics_interval(whenever metrics are collected/sent) is set to 30s, then only the last value is sent to the server i.e. 512 .
class Gauge(BaseMetric):
    __slots__ = BaseMetric.__slots__ + ("_val",)
    def __init__(self, name, reset_on_collect=False, unit=None) -> None:
        """
        Creates a new gauge
        :param name: label of the gauge
        :param unit of the observed gauge. Unused for gauges
        """
        self._val = None
        super(Gauge, self).__init__(name, reset_on_collect=reset_on_collect)
    @property
    def val(self):
        return self._val
    @val.setter
    def val(self, value) -> None:
        self._val = value
    def reset(self) -> None:
        self._val = 0
class Counter(BaseMetric):
    __slots__ = BaseMetric.__slots__ + ("_lock", "_initial_value", "_val")
    def __init__(self, name, initial_value=0, reset_on_collect=False, unit=None) -> None:
        """
        Creates a new counter
        :param name: name of the counter
        :param initial_value: initial value of the counter, defaults to 0
        :param unit: unit of the observed counter. Unused for counters
        """
        self._lock = threading.Lock()
        self._val = self._initial_value = initial_value
        super(Counter, self).__init__(name, reset_on_collect=reset_on_collect)
    def inc(self, delta=1):
        """
        Increments the counter. If no delta is provided, it is incremented by one
        :param delta: the amount to increment the counter by
        :returns the counter itself
        """
        with self._lock:
            self._val += delta
        return self
    def dec(self, delta=1):
        """
        Decrements the counter. If no delta is provided, it is decremented by one
        :param delta: the amount to decrement the counter by
        :returns the counter itself
        """
        with self._lock:
            self._val -= delta
        return self
    def reset(self):
        """
        Reset the counter to the initial value
        :returns the counter itself
        """
        with self._lock:
            self._val = self._initial_value
        return self
    @property
    def val(self):
        """Returns the current value of the counter"""
        return self._val
    @val.setter
    def val(self, value) -> None:
        with self._lock:
            self._val = value
Checking the source code of gauge and  counter helps me understand that  both utilize a
a variable with maybe int or float type(maybe since type is not declared).
After looking at the source code of all available metrics, I think none of them can be utilized to store and send list-like (timeseries/mulitple values, like this [200,500,200,400,512] mentioned in above example ) values. histogram has self._counts which is of type list, but it saves frequency and not the actual value itself.
I was hoping that I could extend the BaseMetric class to create a metric which stores values in a list or dict like datastructure to be able to hold time-series like data. Would that be possible ? Also If this is something that would be helpful to the community I can also open a PR in apm-agent-python to a add new metric type. Would you be able ask someone from apm-agent-python team internally, if you have access, about this ?
Looking forward to your response .