Source code for duct.outputs.prometheus

"""
.. module:: prometheus
   :synopsis: Prometheus output

.. moduleauthor:: Colin Alston <colin@tamvera.com>
"""
import logging

from aiohttp import web

from duct.objects import Output

log = logging.getLogger(__name__)


[docs] class Prometheus(Output): """Prometheus scrape-endpoint output :param port: Listening port (default: 9100) :type port: int. :param metric_path: Metrics path (default: metrics) :type metric_path: str. :param prefix: Prometheus metric prefix (default: duct\\_) :type prefix: str. """ def __init__(self, *a): Output.__init__(self, *a) self.port = int(self.config.get('port', 9100)) self.metric_path = self.config.get('metric_path', 'metrics') self.prefix = self.config.get('prefix', 'duct_') self.metric_table = {} self._runner = None async def _handle_metrics(self, _request): content = ''.join( f'{k} {v}\n' for k, v in self.metric_table.items() ) return web.Response(text=content, content_type='text/plain') async def _handle_root(self, _request): body = ( '<html><head><title>Duct</title></head>' '<body><h1>Duct</h1>' f'<p><a href="/{self.metric_path}">Metrics</a></p>' '</body></html>' ) return web.Response(text=body, content_type='text/html')
[docs] async def createClient(self): app = web.Application() app.router.add_get('/' + self.metric_path, self._handle_metrics) app.router.add_get('/', self._handle_root) self._runner = web.AppRunner(app, access_log=None) await self._runner.setup() site = web.TCPSite(self._runner, '0.0.0.0', self.port) await site.start() log.info('Prometheus metrics available on :%s/%s', self.port, self.metric_path)
[docs] async def stop(self): if self._runner: await self._runner.cleanup()
[docs] async def eventsReceived(self, events): for event in events: metric_name = self.prefix + event.service.replace('.', '_') if event.attributes: labels = ','.join( f'{k}="{v}"' for k, v in event.attributes.items() ) metric_name += f'{{{labels}}}' self.metric_table[metric_name] = event.metric