From 5174c9f45400b37e9ea3120ed4eae4f23ae657d8 Mon Sep 17 00:00:00 2001 From: Chenxiong Qi Date: Mar 01 2019 07:50:30 +0000 Subject: Build python package With this commit, it is possible to build Python source distribution package with `python setup.py sdist'. A few relative changes to code base are * setup.py is added with project metadata and dependencies. * A readme file is added. * Python module monitor is moved to a package named monitor_flask_sqlalchemy. As a result, package can be imported like `import monitor_flask_sqlalchemy'. Signed-off-by: Chenxiong Qi --- diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1d56ec9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +*.swp +build/ +dist/ +*.egg-info/ diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..16b52e4 --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1 @@ +include tests/*.py diff --git a/README.rst b/README.rst index e69de29..8b13789 100644 --- a/README.rst +++ b/README.rst @@ -0,0 +1 @@ + diff --git a/__init__.py b/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/__init__.py +++ /dev/null diff --git a/monitor.py b/monitor.py deleted file mode 100644 index a11b4d3..0000000 --- a/monitor.py +++ /dev/null @@ -1,120 +0,0 @@ -# Some license header # FIXME - -# For an up-to-date version of this module, see: -# https://pagure.io/monitor-flask-sqlalchemy - -import os -import tempfile - -from flask import Blueprint, Response -from prometheus_client import ( # noqa: F401 - ProcessCollector, CollectorRegistry, Counter, multiprocess, - Histogram, generate_latest, start_http_server, CONTENT_TYPE_LATEST) -from sqlalchemy import event - -# Service-specific imports - - -if not os.environ.get('prometheus_multiproc_dir'): - os.environ.setdefault('prometheus_multiproc_dir', tempfile.mkdtemp()) -registry = CollectorRegistry() -ProcessCollector(registry=registry) -multiprocess.MultiProcessCollector(registry) -if os.getenv('MONITOR_STANDALONE_METRICS_SERVER_ENABLE', 'false') == 'true': - port = os.getenv('MONITOR_STANDALONE_METRICS_SERVER_PORT', '10040') - start_http_server(int(port), registry=registry) - - -# Generic metrics -messaging_rx_counter = Counter( - 'messaging_rx', - 'Total number of messages received', - registry=registry) -messaging_rx_ignored_counter = Counter( - 'messaging_rx_ignored', - 'Number of received messages, which were ignored', - registry=registry) -messaging_rx_processed_ok_counter = Counter( - 'messaging_rx_processed_ok', - 'Number of received messages, which were processed successfully', - registry=registry) -messaging_rx_failed_counter = Counter( - 'messaging_rx_failed', - 'Number of received messages, which failed during processing', - registry=registry) - -messaging_tx_to_send_counter = Counter( - 'messaging_tx_to_send', - 'Total number of messages to send', - registry=registry) -messaging_tx_stopped_counter = Counter( - 'messaging_tx_stopped', - 'Number of messages, which were eventually stopped before sending', - registry=registry) -messaging_tx_sent_ok_counter = Counter( - 'messaging_tx_sent_ok', - 'Number of messages, which were sent successfully', - registry=registry) -messaging_tx_failed_counter = Counter( - 'messaging_tx_failed', - 'Number of messages, for which the sender failed', - registry=registry) - -db_dbapi_error_counter = Counter( - 'db_dbapi_error', - 'Number of DBAPI errors', - registry=registry) -db_engine_connect_counter = Counter( - 'db_engine_connect', - 'Number of \'engine_connect\' events', - registry=registry) -db_handle_error_counter = Counter( - 'db_handle_error', - 'Number of exceptions during connection', - registry=registry) -db_transaction_rollback_counter = Counter( - 'db_transaction_rollback', - 'Number of transactions, which were rolled back', - registry=registry) - -# Service-specific metrics - - -def db_hook_event_listeners(target=None): - # Service-specific import of db - from myproject import db # FIXME - - if not target: - target = db.engine - - @event.listens_for(target, 'dbapi_error', named=True) - def receive_dbapi_error(**kw): - db_dbapi_error_counter.inc() - - @event.listens_for(target, 'engine_connect') - def receive_engine_connect(conn, branch): - db_engine_connect_counter.inc() - - @event.listens_for(target, 'handle_error') - def receive_handle_error(exception_context): - db_handle_error_counter.inc() - - @event.listens_for(target, 'rollback') - def receive_rollback(conn): - db_transaction_rollback_counter.inc() - - -monitor_api = Blueprint( - 'monitor', __name__, - url_prefix='') # FIXME: set some URL prefix or delete the arg - - -@monitor_api.route('/') -def index(): - return Response('Monitor API') - - -@monitor_api.route('/metrics') -def metrics(): - return Response(generate_latest(registry), - content_type=CONTENT_TYPE_LATEST) diff --git a/monitor_flask_sqlalchemy/__init__.py b/monitor_flask_sqlalchemy/__init__.py new file mode 100644 index 0000000..a11b4d3 --- /dev/null +++ b/monitor_flask_sqlalchemy/__init__.py @@ -0,0 +1,120 @@ +# Some license header # FIXME + +# For an up-to-date version of this module, see: +# https://pagure.io/monitor-flask-sqlalchemy + +import os +import tempfile + +from flask import Blueprint, Response +from prometheus_client import ( # noqa: F401 + ProcessCollector, CollectorRegistry, Counter, multiprocess, + Histogram, generate_latest, start_http_server, CONTENT_TYPE_LATEST) +from sqlalchemy import event + +# Service-specific imports + + +if not os.environ.get('prometheus_multiproc_dir'): + os.environ.setdefault('prometheus_multiproc_dir', tempfile.mkdtemp()) +registry = CollectorRegistry() +ProcessCollector(registry=registry) +multiprocess.MultiProcessCollector(registry) +if os.getenv('MONITOR_STANDALONE_METRICS_SERVER_ENABLE', 'false') == 'true': + port = os.getenv('MONITOR_STANDALONE_METRICS_SERVER_PORT', '10040') + start_http_server(int(port), registry=registry) + + +# Generic metrics +messaging_rx_counter = Counter( + 'messaging_rx', + 'Total number of messages received', + registry=registry) +messaging_rx_ignored_counter = Counter( + 'messaging_rx_ignored', + 'Number of received messages, which were ignored', + registry=registry) +messaging_rx_processed_ok_counter = Counter( + 'messaging_rx_processed_ok', + 'Number of received messages, which were processed successfully', + registry=registry) +messaging_rx_failed_counter = Counter( + 'messaging_rx_failed', + 'Number of received messages, which failed during processing', + registry=registry) + +messaging_tx_to_send_counter = Counter( + 'messaging_tx_to_send', + 'Total number of messages to send', + registry=registry) +messaging_tx_stopped_counter = Counter( + 'messaging_tx_stopped', + 'Number of messages, which were eventually stopped before sending', + registry=registry) +messaging_tx_sent_ok_counter = Counter( + 'messaging_tx_sent_ok', + 'Number of messages, which were sent successfully', + registry=registry) +messaging_tx_failed_counter = Counter( + 'messaging_tx_failed', + 'Number of messages, for which the sender failed', + registry=registry) + +db_dbapi_error_counter = Counter( + 'db_dbapi_error', + 'Number of DBAPI errors', + registry=registry) +db_engine_connect_counter = Counter( + 'db_engine_connect', + 'Number of \'engine_connect\' events', + registry=registry) +db_handle_error_counter = Counter( + 'db_handle_error', + 'Number of exceptions during connection', + registry=registry) +db_transaction_rollback_counter = Counter( + 'db_transaction_rollback', + 'Number of transactions, which were rolled back', + registry=registry) + +# Service-specific metrics + + +def db_hook_event_listeners(target=None): + # Service-specific import of db + from myproject import db # FIXME + + if not target: + target = db.engine + + @event.listens_for(target, 'dbapi_error', named=True) + def receive_dbapi_error(**kw): + db_dbapi_error_counter.inc() + + @event.listens_for(target, 'engine_connect') + def receive_engine_connect(conn, branch): + db_engine_connect_counter.inc() + + @event.listens_for(target, 'handle_error') + def receive_handle_error(exception_context): + db_handle_error_counter.inc() + + @event.listens_for(target, 'rollback') + def receive_rollback(conn): + db_transaction_rollback_counter.inc() + + +monitor_api = Blueprint( + 'monitor', __name__, + url_prefix='') # FIXME: set some URL prefix or delete the arg + + +@monitor_api.route('/') +def index(): + return Response('Monitor API') + + +@monitor_api.route('/metrics') +def metrics(): + return Response(generate_latest(registry), + content_type=CONTENT_TYPE_LATEST) diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..3c44814 --- /dev/null +++ b/setup.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*_ + +from setuptools import setup + + +def read_file(filename): + with open(filename, 'r') as f: + return f.read() + + +setup( + name='monitor-flask-sqlalchemy', + version='0.0', + description='A plugable Flask blueprint exposing an HTTP endpoint to ' + 'provide metrics to Prometheus', + long_description=read_file('README.rst'), + author='Filip Valder', + author_email='fvalder@redhat.com', + url='https://pagure.io/monitor-flask-sqlalchemy/', + license='', + keywords='monitor metric prometheus', + packages=['flask_prometheus_monitor'], + install_requires=[ + 'Flask', + 'SQLAlchemy', + 'prometheus_client', + ], + tests_require=[ + 'six', + ], + classifiers=[ + 'Framework :: Flask', + 'Programming Language :: Python :: 2', + 'Programming Language :: Python :: 3', + 'Topic :: Software Development :: Libraries :: Python Modules', + ], +)