telemetry: linux telemetry with perf-stat
[csit.git] / resources / tools / telemetry / metrics.py
index e5a66b3..ba6bae5 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2021 Cisco and/or its affiliates.
+# Copyright (c) 2022 Cisco and/or its affiliates.
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
 # You may obtain a copy of the License at:
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-"""Metric library."""
+"""Metric library.
+
+Time measurements are done by time.time().
+Although time.time() is susceptible to big (or even negative) jumps
+when a system is badly synchronized, it is still better
+than time.monotonic(), as that value has no relation to epoch time.
+"""
 
 from collections import namedtuple
 from threading import Lock
-from time import monotonic
+from time import time
 import re
 
 
@@ -41,7 +47,7 @@ class Value:
         """
         with self._lock:
             self._value += amount
-            self._timestamp = monotonic()
+            self._timestamp = time()
 
     def set(self, value):
         """
@@ -53,7 +59,7 @@ class Value:
         """
         with self._lock:
             self._value = value
-            self._timestamp = monotonic()
+            self._timestamp = time()
 
     def get(self):
         """
@@ -98,7 +104,7 @@ class Metric:
             u"Sample", [u"name", u"labels", u"value", u"timestamp"]
         )
 
-        if not re.compile(r"^[a-zA-Z_:][a-zA-Z0-9_:]*$").match(name):
+        if not re.compile(r"^[a-zA-Z_:\-.][a-zA-Z0-9_:\-.]*$").match(name):
             raise ValueError(f"Invalid metric name: {name}!")
         if typ not in self.metric_types:
             raise ValueError(f"Invalid metric type: {typ}!")
@@ -208,7 +214,7 @@ class MetricBase:
         full_name += f"{subsystem}_" if subsystem else u""
         full_name += name
 
-        if not re.compile(r"^[a-zA-Z_:][a-zA-Z0-9_:]*$").match(full_name):
+        if not re.compile(r"^[a-zA-Z_:\-.][a-zA-Z0-9_:\-.]*$").match(full_name):
             raise ValueError(
                 f"Invalid metric name: {full_name}!"
             )
@@ -334,7 +340,7 @@ class MetricBase:
 
     def samples(self):
         """
-        Returns samples wheter an object is parent or child.
+        Returns samples whether an object is parent or child.
 
         :returns: List of Metric objects with values.
         :rtype: list
@@ -596,9 +602,9 @@ class Info(MetricBase):
         """
         Set info to the given value.
 
-        :param amount: Value to set.
-        :type amount: int or float
-        :raises ValueError: If lables are overlapping.
+        :param value: Value to set.
+        :type value: int or float
+        :raises ValueError: If labels are overlapping.
         """
         if self._labelname_set.intersection(value.keys()):
             raise ValueError(
@@ -616,4 +622,4 @@ class Info(MetricBase):
         :rtype: tuple
         """
         with self._lock:
-            return ((u"_info", self._value, 1.0, monotonic()),)
+            return ((u"_info", self._value, 1.0, time()),)