"""    
    FROM https://github.com/ITISFoundation/osparc-simcore/blob/3e80ce451352c906f2876113dbb6ae33e8574be1/packages/service-library/src/servicelib/monitoring.py    
    &&  https://github.com/ITISFoundation/osparc-simcore/blob/3e80ce451352c906f2876113dbb6ae33e8574be1/packages/service-library/src/servicelib/monitoring.py    
"""    
import time    
    
from flask import request, current_app, Response    
from prometheus_client import Counter, Histogram    
from prometheus_client import multiprocess    
from prometheus_client import generate_latest, CollectorRegistry, CONTENT_TYPE_LATEST, Gauge    
    
IN_PROGRESS = Gauge("inprogress_requests", "help", multiprocess_mode='livesum')    
    
    
@IN_PROGRESS.track_inprogress()    
def app(environ, start_response):    
    registry = CollectorRegistry()    
    multiprocess.MultiProcessCollector(registry)    
    data = generate_latest(registry)    
    status = '200 OK'    
    response_headers = [    
        ('Content-type', CONTENT_TYPE_LATEST),    
        ('Content-Length', str(len(data)))    
    ]    
    start_response(status, response_headers)    
    return iter([data])    
    
    
def setup_monitoring(app, app_name=None):    
    if app_name is None:    
        app_name = app.name    
    
    def start_timer():    
        request.start_time = time.time()    
        current_app.extensions["prometheus"]['REQUEST_IN_PROGRESS'].labels(    
            app_name, request.endpoint, request.method).inc()    
    
    def record_request_data(response):    
        resp_time = time.time() - request.start_time    
        endpoint = request.endpoint    
        ext_prometheus = current_app.extensions["prometheus"]    
        ext_prometheus['REQUEST_LATENCY'].labels(app_name, endpoint).observe(resp_time)    
        ext_prometheus['REQUEST_IN_PROGRESS'].labels(app_name, endpoint, request.method).dec()    
        ext_prometheus['REQUEST_COUNT'].labels(app_name, request.method, endpoint, response.status).inc()    
        return response    
    
    app.before_request(start_timer)    
    app.after_request(record_request_data)    
    
    extensions_prometheus = dict()    
    extensions_prometheus['app_name'] = app_name    
    extensions_prometheus['REQUEST_COUNT'] = Counter(    
        'http_requests_total', 'Total Request Count',    
        ['app_name', 'method', 'endpoint', 'http_status']    
    )    
    
    
    extensions_prometheus['REQUEST_LATENCY'] = Histogram(    
        'http_request_latency_seconds', 'Request latency',    
        ['app_name', 'endpoint']    
    )    
    
    extensions_prometheus['REQUEST_IN_PROGRESS'] = Gauge(    
        'http_requests_in_progress_total', 'Requests in progress',    
        ['app_name', 'endpoint', 'method']    
    )    
    
    app.extensions["prometheus"] = extensions_prometheus    
    
    @app.route("/metrics")    
    def metrics():    
        registry = CollectorRegistry()    
        multiprocess.MultiProcessCollector(registry)    
        data = generate_latest(registry)    
        return Response(data, mimetype=CONTENT_TYPE_LATEST)