def __init__(self, get_response=None):
        if not hasattr(settings, 'DJANGO_SATELLA_METRICS'):
            self.summary_metric = getMetric('django.summary', 'summary')
            self.histogram_metric = getMetric('django.histogram', 'histogram')
            self.status_codes_metric = getMetric('django.status_codes',
                                                 'counter')
            self.monitor_metrics = False
            self.url_getter = lambda request: request.path
        else:

            def try_get(field_name, def_metric_name, def_metric_type):
                if field_name not in settings.DJANGO_SATELLA_METRICS:
                    setattr(self, field_name,
                            getMetric(def_metric_name, def_metric_type))
                else:
                    setattr(self, field_name,
                            settings.DJANGO_SATELLA_METRICS[field_name])

            try_get('summary_metric', 'django.summary', 'summary')
            try_get('histogram_metric', 'django.histogram', 'histogram')
            try_get('status_codes_metric', 'django.status_codes', 'counter')
            self.monitor_metrics = settings.DJANGO_SATELLA_METRICS.get(
                'monitor_metrics', False)
            self.url_getter = settings.DJANGO_SATELLA_METRICS.get(
                'url_getter', lambda request: request.path)
        if get_response is not None:
            super().__init__(get_response)
Exemple #2
0
def SatellaMetricsMiddleware(
        app: fastapi.FastAPI,
        summary_metric: tp.Optional[Metric] = None,
        histogram_metric: tp.Optional[Metric] = None,
        response_codes_metric: tp.Optional[Metric] = None):
    """
    Install handlers to measure metrics on an application.

    Metrics will be created by default is not specified. For summary metric it will be
    called "requests_summary", for histogram metric it will be called "requests_histogram",
    and for status codes "requests_response_codes".

    :param app: FastAPI application to monitor
    :param summary_metric: summary metric to use. Should be of type 'summary'
    :param histogram_metric: histogram metric to use. Should be of type 'histogram'
    :param response_codes_metric: Response codes counter to use. Should be of type 'counter'
    """
    summary_metric = summary_metric or getMetric(
        'requests_summary', 'summary', quantiles=[0.2, 0.5, 0.9, 0.95, 0.99])
    histogram_metric = histogram_metric or getMetric('requests_histogram',
                                                     'histogram')
    response_codes_metric = response_codes_metric or getMetric(
        'requests_response_codes', 'counter')

    @app.middleware('http')
    async def do_middleware(request: fastapi.Request, call_next):
        with measure() as measurement:
            response = await call_next(request)

        summary_metric.runtime(measurement(), endpoint=str(request.url))
        histogram_metric.runtime(measurement(), endpoint=str(request.url))
        response_codes_metric.runtime(+1, response_code=response.status_code)
        return response
 def try_get(field_name, def_metric_name, def_metric_type):
     if field_name not in settings.DJANGO_SATELLA_METRICS:
         setattr(self, field_name,
                 getMetric(def_metric_name, def_metric_type))
     else:
         setattr(self, field_name,
                 settings.DJANGO_SATELLA_METRICS[field_name])
def export_metrics(request):
    """A Django view to output the metrics"""
    root_data = getMetric().to_metric_data()
    for datum in root_data.values:
        if datum.internal:
            root_data.values.remove(datum)
    if hasattr(settings, 'DJANGO_SATELLA_METRICS'):
        root_data.add_labels(
            settings.DJANGO_SATELLA_METRICS.get('extra_labels', {}))
    return HttpResponse(metric_data_collection_to_prometheus(root_data))
 def export_prometheus():
     metric = getMetric()
     metric_data = metric.to_metric_data()
     new_values = set()
     for datum in metric_data.values:
         if not datum.internal:
             new_values.add(datum)
     metric_data.values = new_values
     metric_data.add_labels(labels)
     return fastapi.Response(
         content=metric_data_collection_to_prometheus(metric_data),
         media_type='text/plain')
def SatellaMetricsMiddleware(
        app: flask.Flask,
        summary_metric: tp.Optional[Metric] = None,
        histogram_metric: tp.Optional[Metric] = None,
        response_codes_metric: tp.Optional[Metric] = None):
    """
    Install handlers to measure metrics on an application

    :param app: flask application to monitor
    :param summary_metric: summary metric to use. Should be of type 'summary'
    :param histogram_metric: histogram metric to use. Should be of type 'histogram'
    :param response_codes_metric: Response codes counter to use. Should be of type 'counter'
    """
    app.metrics = MetricsContainer(
        summary_metric or getMetric('requests_summary',
                                    'summary',
                                    quantiles=[0.2, 0.5, 0.9, 0.95, 0.99]),
        histogram_metric or getMetric('requests_histogram', 'histogram'),
        response_codes_metric
        or getMetric('requests_response_codes', 'counter'))
    app.before_request(before_request)
    app.after_request(after_request)
    def test_satella_metrics(self):
        getMetric('my.internal.metric', 'counter', internal=True)
        q = requests.get('http://localhost:5000/')
        self.assertEqual(q.status_code, 200)

        q = requests.get('http://localhost:5000/value_error')
        self.assertEqual(q.status_code, 500)

        root_metric = getMetric().to_metric_data()
        request_codes = choose(
            lambda metric: metric.name == 'requests_response_codes' and metric.
            labels == {'response_code': 200}, root_metric.values)
        self.assertEqual(request_codes.value, 1)
        request_codes = choose(
            lambda metric: metric.name == 'requests_response_codes' and metric.
            labels == {'response_code': 500}, root_metric.values)
        self.assertEqual(request_codes.value, 1)

        q = requests.get('http://localhost:5000/metrics')
        self.assertEqual(q.status_code, 200)
        self.assertIn('service_name="my_service"', q.text)
        self.assertIn('requests_response_codes', q.text)
        self.assertNotIn('my_internal_metric', q.text)
Exemple #8
0

# Internationalization
# https://docs.djangoproject.com/en/3.0/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.0/howto/static-files/

STATIC_URL = '/static/'

from satella.instrumentation.metrics import getMetric
DJANGO_SATELLA_METRICS = {
    'summary_metric': getMetric('django.summary', 'summary'),
    'histogram_metric': getMetric('django.histogram', 'histogram'),
    'status_codes_metric': getMetric('django.status_codes', 'counter'),
    'extra_labels': {
        'service_name': 'test'
    },
    'monitor_metrics': False
}
def start():
    getMetric('my.internal.metric', 'counter', internal=True)
    uvicorn.run('tests.test_fastapi_satella_metrics:app',
                host='127.0.0.1',
                port=8000, reload=False)
Exemple #10
0
# Copyright 2020 SMOK sp. z o. o.
import itertools
import os
import logging
import requests
import re
import json
from flask import Flask, request
from flask_json import FlaskJSON, as_json
from flask_satella_metrics.prometheus_exporter import PrometheusExporter
from satella.instrumentation.metrics import getMetric

matched_regexes = getMetric('matched.regex', 'counter')
matched_nothing = getMetric('matched.nothing', 'counter')
total_entries = getMetric('entries.total', 'counter')
calls_made = getMetric('entries.calls', 'counter')
entries_dropped = getMetric('entries.dropped', 'counter')
seq_successes = getMetric('seq.successes', 'counter')
seq_failures = getMetric('seq.failures', 'counter')

logger = logging.getLogger(__name__)

app = Flask(__name__)
FlaskJSON(app)

app.register_blueprint(PrometheusExporter())

SERVER_URL = os.environ['SEQ_ADDRESS']
if not SERVER_URL.endswith('/'):
    SERVER_URL = SERVER_URL + '/'