112 lines
3.1 KiB
Python
112 lines
3.1 KiB
Python
"""dsc_datatool.output.prometheus
|
|
|
|
See `man dsc-datatool-output prometheus`.
|
|
|
|
Part of dsc_datatool.
|
|
|
|
:copyright: 2024 OARC, Inc.
|
|
"""
|
|
|
|
import re
|
|
import sys
|
|
import atexit
|
|
|
|
from dsc_datatool import Output, args, encoding
|
|
|
|
|
|
_re = re.compile(r'([\\\n"])')
|
|
|
|
|
|
def _key(key):
|
|
return re.sub(_re, r'\\\1', key)
|
|
|
|
|
|
def _val(val):
|
|
ret = re.sub(_re, r'\\\1', val)
|
|
if ret == '':
|
|
return '""'
|
|
return '"%s"' % ret
|
|
|
|
|
|
class Prometheus(Output):
|
|
show_timestamp = True
|
|
start_timestamp = True
|
|
fh = None
|
|
type_def = ''
|
|
type_printed = False
|
|
prefix = ''
|
|
|
|
|
|
def __init__(self, opts):
|
|
Output.__init__(self, opts)
|
|
timestamp = opts.get('timestamp', 'start')
|
|
if timestamp == 'hide':
|
|
self.show_timestamp = False
|
|
elif timestamp == 'start':
|
|
pass
|
|
elif timestamp == 'stop':
|
|
self.start_timestamp = False
|
|
else:
|
|
raise Exception('timestamp option invalid')
|
|
file = opts.get('file', None)
|
|
append = opts.get('append', False)
|
|
if file:
|
|
if append:
|
|
self.fh = open(file, 'a', encoding=encoding)
|
|
else:
|
|
self.fh = open(file, 'w', encoding=encoding)
|
|
atexit.register(self.close)
|
|
else:
|
|
self.fh = sys.stdout
|
|
self.prefix = opts.get('prefix', '')
|
|
|
|
|
|
def close(self):
|
|
if self.fh:
|
|
self.fh.close()
|
|
self.fh = None
|
|
|
|
|
|
def _process(self, tags, timestamp, dimension, fh):
|
|
if dimension.dimensions is None:
|
|
return
|
|
|
|
if len(dimension.dimensions) > 0:
|
|
if not (dimension.name == 'All' and dimension.value == 'ALL'):
|
|
tags += ',%s=%s' % (_key(dimension.name.lower()), _val(dimension.value))
|
|
for d2 in dimension.dimensions:
|
|
self._process(tags, timestamp, d2, fh)
|
|
return
|
|
|
|
if dimension.values is None:
|
|
return
|
|
|
|
if len(dimension.values) > 0:
|
|
tags += ',%s=' % _key(dimension.name.lower())
|
|
|
|
for k, v in dimension.values.items():
|
|
if not self.type_printed:
|
|
print(self.type_def, file=fh)
|
|
self.type_printed = True
|
|
if self.show_timestamp:
|
|
print('%s%s} %s %s' % (tags, _val(k), v, timestamp), file=fh)
|
|
else:
|
|
print('%s%s} %s' % (tags, _val(k), v), file=fh)
|
|
|
|
|
|
def process(self, datasets):
|
|
for dataset in datasets:
|
|
self.type_def = '# TYPE %s gauge' % _key(dataset.name.lower())
|
|
self.type_printed = False
|
|
tags = '%s%s{server=%s,node=%s' % (self.prefix, _key(dataset.name.lower()), _val(args.server), _val(args.node))
|
|
if self.start_timestamp:
|
|
timestamp = dataset.start_time * 1000
|
|
else:
|
|
timestamp = dataset.end_time * 1000
|
|
|
|
for d in dataset.dimensions:
|
|
self._process(tags, timestamp, d, self.fh)
|
|
|
|
|
|
if sys.version_info[0] == 3 and sys.version_info[1] == 5: # pragma: no cover
|
|
Output.__init_subclass__(Prometheus)
|