aboutsummaryrefslogtreecommitdiffstats
path: root/resources/tools/telemetry/serializer.py
diff options
context:
space:
mode:
Diffstat (limited to 'resources/tools/telemetry/serializer.py')
-rw-r--r--resources/tools/telemetry/serializer.py111
1 files changed, 111 insertions, 0 deletions
diff --git a/resources/tools/telemetry/serializer.py b/resources/tools/telemetry/serializer.py
new file mode 100644
index 0000000000..e28454fc8b
--- /dev/null
+++ b/resources/tools/telemetry/serializer.py
@@ -0,0 +1,111 @@
+# 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:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Config executor library."""
+
+from importlib import import_module
+from logging import getLogger
+
+
+class Serializer:
+ """
+ Executor class responsible for executing configuration.
+ """
+ def __init__(self):
+ """
+ Config Executor init.=
+ """
+ self.metric_registry = dict()
+
+ def create(self, metrics):
+ """
+ Create metrics based on input configuration.
+
+ :param metrics: Metric list to create.
+ :type metrics: list
+ """
+ for metric_type, metric_list in metrics.items():
+ for metric in metric_list:
+ module = import_module(
+ name=u"telemetry.metrics", package=metric_type.capitalize()
+ )
+ self.metric_registry[metric[u"name"]] = getattr(
+ module, metric_type.capitalize()
+ )(**metric)
+
+ def serialize(self, metric, labels, item):
+ """
+ Serialize metric into destination format.
+
+ :param metrics: Metric name.
+ :param labels: Metric labels.
+ :param item: Metric dict.
+ :type metrics: str
+ :type labels: dict
+ :type item: dict
+ """
+ if type(self.metric_registry[metric]).__name__ == u"Counter":
+ self.metric_registry[metric].labels(**labels).inc(
+ float(item[u"value"])
+ )
+ if type(self.metric_registry[metric]).__name__ == u"Gauge":
+ self.metric_registry[metric].labels(**labels).set(
+ float(item[u"value"])
+ )
+ if type(self.metric_registry[metric]).__name__ == u"Info":
+ self.metric_registry[metric].labels(**labels).info(
+ item[u"value"]
+ )
+
+ def publish(self):
+ """
+ Publish metric into logger.
+ """
+ output = []
+ for _, metric_list in self.metric_registry.items():
+ for metric in metric_list.collect():
+ mname = metric.name
+ mtype = metric.type
+
+ # Adjust from OpenMetrics into Prometheus format.
+ mname = f"{mname}_total" if mtype == u"counter" else mname
+ mname = f"{mname}_info" if mtype == u"info" else mname
+ if mtype in (u"info", u"stateset"):
+ mtype = u"gauge"
+ if mtype in (u"gaugehistogram", u"histogram"):
+ mtype = u"histogram"
+
+ mdocumentation = metric.documentation.replace(u"\\", r"\\")
+ mdocumentation = mdocumentation.replace(u"\n", r"\n")
+ output.append(f"# HELP {mname} {mdocumentation}\n")
+ output.append(f"# TYPE {mname} {mtype}\n")
+
+ for line in metric.samples:
+ if line.labels:
+ llabel = []
+ for k, value in sorted(line.labels.items()):
+ value = str(value)
+ value = value.replace(u"\\", r"\\")
+ value = value.replace(u"\n", r"\n")
+ value = value.replace(u'"', r'\"')
+ llabel.append(f'{k}="{value}"')
+ labelstr = f"{{{','.join(llabel)}}}"
+ else:
+ labelstr = u""
+
+ timestamp = f" {int(float(line.timestamp) * 1000):d}" \
+ if line.timestamp else u""
+ output.append(
+ f"{line.name}{labelstr} {line.value}{timestamp}\n"
+ )
+ getLogger(u"prom").info(u"".join(output))