Мониторинг Python приложений с помощью Proto Observability Platform
На этой странице:
- Введение
- Установка Python трейсера
- Поддерживаемые технологии трейсером
- Дополнительная инструментация вызовов
- Кастомные метрики Python приложений
Введение
Общий процесс подключения Python приложения на мониторинг:
- Установка ProtoOBP Агента
- Установка трейсера
Установка Python трейсера
-
Установите библиотеку
pobptrace
выполнив:pip install pobptrace --user --index-url "https://<token_name>:<token_key>@git.proto.group/api/v4/projects/125/packages/pypi/simple"
Пример для
Dockerfile
и.gitlab-ci.yml
:-
в настройках проекта в Gitlab добавьте две переменные окружения (
Проект
->Settings
->CI/CD
->Variables
):- имя:
PROTOOBP_INSTALL_TOKEN_NAME
, значение = ваши данные из лицензионного сертификата (token
илилогин
) - имя:
PROTOOBP_INSTALL_TOKEN_KEY
, значение = ваши данные из лицензионного сертификата (пароль
)
- имя:
Имя и значение токена находятся в вашем лицензионном сертификате Proto Observability Platform.
-
.gitlab-ci.yml
– необходимо передать значения переменных от Gitlab CI кdocker build
через--build-arg
:script: - docker build --build-arg PROTOOBP_INSTALL_TOKEN_NAME=${PROTOOBP_INSTALL_TOKEN_NAME} --build-arg PROTOOBP_INSTALL_TOKEN_KEY=${PROTOOBP_INSTALL_TOKEN_KEY} .
-
Dockerfile
– необходимо добавить переменные окружения черезARG
и передать их вpip install --index-url
:FROM python:latest ARG PROTOOBP_INSTALL_TOKEN_NAME ARG PROTOOBP_INSTALL_TOKEN_KEY RUN pip install pobptrace --user --index-url "https://${PROTOOBP_INSTALL_TOKEN_NAME}:${PROTOOBP_INSTALL_TOKEN_KEY}@git.proto.group/api/v4/projects/125/packages/pypi/simple"
-
-
Добавьте
pobptrace-run
команду какentrypoint
вашего приложения. Например:pobptrace-run python app.py
-
Пример для типового Python приложения:
CMD ["pobptrace-run", "python", "app.py"]
-
Пример для
uwsgi
иDockerfile
:CMD ["pobptrace-run", "uwsgi", "--ini", "app.ini"]
-
-
Добавьте следующие переменные окружения:
POBP_SERVICE=<service_name>
- имя сервиса, как он будет отображаться в интерфейсе Proto Observability PlatformPOBP_TRACE_TELEMETRY_ENABLED="false"
- обязательно
Если приложение запускается в Docker контейнере
Выполните пункты указанные выше и добавьте следующую переменную окружения:
ENV POBP_AGENT_HOST="protoobp-agent"
Укажите IP адрес хоста, где запущен ProtoOBP агент, доступные из сети Docker контейнера. В случае если агент запускается в виде Docker контейнера, то достаточно указать имя контейнера с агентом.
Пример полного Dockerfile
:
FROM python:latest
WORKDIR /
COPY requirements.txt .
ARG PROTOOBP_INSTALL_TOKEN_NAME
ARG PROTOOBP_INSTALL_TOKEN_KEY
RUN pip install pobptrace --user --index-url "https://${PROTOOBP_INSTALL_TOKEN_NAME}:${PROTOOBP_INSTALL_TOKEN_KEY}@git.proto.group/api/v4/projects/125/packages/pypi/simple"
RUN pip install -r requirements.txt --user
ENV POBP_SERVICE="hello-world"
ENV POBP_AGENT_HOST="protoobp-agent"
ENV POBP_TRACE_TELEMETRY_ENABLED="false"
CMD ["pobptrace-run", "python", "app.py"]
Если приложение работает в Kubernetes
Убедитесь, что у вас успешно установлен и настроен ProtoOBP Агент для Kubernetes.
Без использования автоматического подключения трейсера
Дополнительно необходимо передать поду переменную окружения POBP_AGENT_HOST
со значением IP адреса воркер-ноды, а также переменные окружения для связи трейсов с инфраструктурой (имя k8s кластера нужно задать вручную).
apiVersion: apps/v1
kind: Deployment
#(...)
spec:
containers:
- name: "<CONTAINER_NAME>"
image: "<CONTAINER_IMAGE>/<TAG>"
env:
- name: POBP_SERVICE
value: dispatch
- name: POBP_AGENT_HOST
valueFrom:
fieldRef:
fieldPath: status.hostIP
- name: NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POBP_TAGS
value: "pod_name:$(POD_NAME),node:$(NODE_NAME),kube_namespace:$(POD_NAMESPACE),kube_cluster_name:<my_cluster_name>"
С использованием автоматического подключения трейсера
Агент ProtoOBP в K8s кластере по умолчанию инструментирует Python приложения с лейблом: admission.proto.group/enabled: "true"
-
В спецификации пода приложения добавьте анотацию и лейбл с версией Python трейсинг агента:
apiVersion: apps/v1 kind: Deployment metadata: labels: ... ... template: metadata: annotations: admission.proto.group/python-lib.version: "2.3.0" #Если Версия Python < 3.7, тогда необходимо указать версию "v1" creationTimestamp: null labels: admission.proto.group/enabled: "true" # Включение автоматической инструментации tags.proto.group/service: "my_service" #Укажите имя сервиса service: my_service
-
В спецификации пода добавьте
imagePullSecrets
для доступа к Docker репозиторию ProtoOBP. Подробнее о добавление Secret указано в документации Установка агента в KubernetesapiVersion: apps/v1 kind: Deployment metadata: labels: ... ... template: metadata: annotations: admission.proto.group/python-lib.version: "2.3.0" #Если Версия Python < 3.7, тогда необходимо указать версию "v1" creationTimestamp: null labels: admission.proto.group/enabled: "true" # Включение автоматической инструментации service: my_service spec: containers: ... ... imagePullSecrets: - name: protoobp-registry
Автоматическое подключение трейсера без использования лейблов
В конфигурации агента вы можете включить автоматическую инструментацию без использования лейблов.
Обратите внимание
При этом все равно необходимо добавлять аннотацию к поду, в которой указать версию образа библиотеки инструментации.Поддерживаемые технологии трейсером
Версии Python
Поддерживает CPython версий 2.7, 3.5-3.10.
Автоматическая инструментация библиотек и фреймворков
Фреймворк | Версии | Автоматически подключается |
---|---|---|
asgi | >= 2.0 | нет |
aiohttp (клиент) | >= 2.0 | да |
aiohttp (сервер) | >= 2.0 | нет |
Bottle | >= 0.11 | нет |
CherryPy | >= 11.2.0 | нет |
Django | >= 1.8 | да |
djangorestframework | >= 3.4 | да |
Falcon | >= 1.0 | нет |
Flask | >= 0.10 | да |
FastAPI | >= 0.51 | да |
Molten | >= 0.7.0 | да |
Pylons | >= 0.9.6 | нет |
Pyramid | >= 1.7 | нет |
pytest | >= 3.0 | нет |
Sanic | >= 19.6.0 | да |
Starlette | >= 0.13.0 | да |
Tornado | >= 4.0 | нет |
Хранилища данных
Хранилище | Версии | Автоматически подключается |
---|---|---|
algoliasearch | >= 1.20.0 | да |
asyncpg | >= 0.18.0 | да |
Cassandra | >= 3.5 | да |
Elasticsearch | >= 1.6 | да |
Flask Cache | >= 0.12 | нет |
Mariadb | >= 1.0.0 | да |
Memcached pylibmc | >= 1.4 | да |
Memcached pymemcache | >= 1.3 | да |
MongoDB Mongoengine | >= 0.11 | да |
MongoDB Pymongo | >= 3.0 | да |
MySQL MySQL-Python | >= 1.2.3 | да |
MySQL mysqlclient | >= 1.3 | да |
MySQL mysql-connector | >= 2.1 | да |
Postgres aiopg | >= 0.12.0, <= 0.16 | да |
Postgres psycopg | >= 2.4 | да |
PyMySQL | >= 0.7 | да |
PynamoDB | >= 4.0 | да |
PyODBC | >= 4.0 | да |
Redis | >= 2.6 | да |
Redis redis-py-cluster | >= 1.3.5 | да |
SQLAlchemy | >= 1.0 | нет |
SQLite3 | все | да |
Vertica | >= 0.6 | да |
Библиотеки
Библиотека | Версии | Автоматически подключается |
---|---|---|
aiobotocore | >= 0.2.3 | нет |
asyncio | все | > Python 3.7 да |
Botocore | >= 1.4.51 | да |
Boto2 | >= 2.29.0 | да |
Celery | >= 3.1 | да |
Consul | >= 0.7 | да |
Futures | все | да |
gevent | >= 1.0 | нет |
Grpc | >= 1.8.0 | да |
httplib | все | нет |
Jinja2 | >= 2.7 | да |
Kombu | >= 4.0 | нет |
Mako | >= 0.1.0 | да |
Requests | >= 2.08 | да |
urllib3 | >= 1.22 | нет |
graphql-core | >= 2.0 | да |
Дополнительная инструментация вызовов
Дополнительную инструментацию можно использовать, если в перечене автоматически инструментированных библиотек и фреймворков нет необходимых.
Для примера будет использоваться следующий код приложения:
def make_sandwich_request(request):
ingredients = get_ingredients()
sandwich = assemble_sandwich(ingredients)
@tracer.wrap(service="my-sandwich-making-svc", resource="resource_name")
def get_ingredients():
# сходить в кладовку
# сходить к холодильнику
# может быть сходить в магазин
return
# можно добавить больше данных для кастомизации спана
@tracer.wrap("assemble_sandwich", service="my-sandwich-making-svc", resource="resource_name")
def assemble_sandwich(ingredients):
return
from pobptrace import tracer
def make_sandwich_request(request):
# запишем обе операции в спаны
with tracer.trace("sandwich.make"):
ingredients = get_ingredients()
sandwich = assemble_sandwich(ingredients)
def make_sandwich_request(request):
# запишем обе операции в спаны
with tracer.trace("sandwich.create", resource="resource_name") as outer_span:
with tracer.trace("get_ingredients", resource="resource_name") as span:
ingredients = get_ingredients()
with tracer.trace("assemble_sandwich", resource="resource_name") as span:
sandwich = assemble_sandwich(ingredients)
from pobptrace import tracer
def make_sandwich_request(request):
span = tracer.trace("sandwich.create", resource="resource_name")
ingredients = get_ingredients()
sandwich = assemble_sandwich(ingredients)
span.finish() # не забудьте закрыть спан
Кастомные метрики Python приложений
Кастомные, например, бизнес-метрики, можно генерировать напрямую из приложения и отсылать на Агента.
Обратите внимание
Агент должен быть установлен и запущен на том хосте, на котором запускаются Python приложения.-
Подключите библиотеку
protoobp
выполнив:pip install protoobp --user --index-url "https://<token_name>:<token_key>@git.proto.group/api/v4/projects/125/packages/pypi/simple"
имя и значение токена находятся в вашем лицензионном сертификате Proto Observability Platform.
Пример для
Dockerfile
и.gitlab-ci.yml
:-
в настройках проекта в Gitlab добавьте две переменные окружения (
Проект
->Settings
->CI/CD
->Variables
):- имя:
PROTOOBP_INSTALL_TOKEN_NAME
, значение = ваши данные из лицензионного сертификата (token
илилогин
) - имя:
PROTOOBP_INSTALL_TOKEN_KEY
, значение = ваши данные из лицензионного сертификата (пароль
)
- имя:
-
.gitlab-ci.yml
– необходимо передать значения переменных от Gitlab CI кdocker build
через--build-arg
:script: - docker build --build-arg PROTOOBP_INSTALL_TOKEN_NAME=${PROTOOBP_INSTALL_TOKEN_NAME} --build-arg PROTOOBP_INSTALL_TOKEN_KEY=${PROTOOBP_INSTALL_TOKEN_KEY} .
-
Dockerrfile
– необходимо добавить переменные окружения черезARG
и передать их вpip install --index-url
:FROM python:latest ARG PROTOOBP_INSTALL_TOKEN_NAME ARG PROTOOBP_INSTALL_TOKEN_KEY RUN pip install protoobp --user --index-url "https://${PROTOOBP_INSTALL_TOKEN_NAME}:${PROTOOBP_INSTALL_TOKEN_KEY}@git.proto.group/api/v4/projects/125/packages/pypi/simple"
-
-
Инициализируйте StatsD клиента, используя UDP в коде приложения:
from protoobp import initialize, statsd options = { "statsd_host": "127.0.0.1", "statsd_port": 8125, } initialize(**options)
-
Теперь можно добавлять собственные метрики, пример использования:
from protoobp import initialize, statsd import time options = { 'statsd_host':'127.0.0.1', 'statsd_port':8125 } initialize(**options) while(1): statsd.increment('example_metric.increment', tags=["environment:dev"]) statsd.decrement('example_metric.decrement', tags=["environment:dev"]) time.sleep(10)
Типы кастомных метрик
После установки библиотеки для отправки метрик в Protoobp будут доступны следующие функции в зависимости от типа метрик. Функции имеют следующие общие параметры:
Параметр | Тип | Обязательно | |
---|---|---|---|
<METRIC_NAME> |
String | Да | Имя метрики |
<METRIC_VALUE> |
Double | Да | Значение метрики |
<SAMPLE_RATE> |
Double | Нет | Рейт сэмплирования. Значение между 0 (все сэмплируется, то есть ничего не отправляется) и 1 (нет сэмплирования). |
<TAGS> |
List of strings | Нет | Список тегов для метрики |
-
COUNT
-
increment(<METRIC_NAME>, <SAMPLE_RATE>, <TAGS>)
Используется для увеличения значения метрики типаCOUNT
. -
decrement(<METRIC_NAME>, <SAMPLE_RATE>, <TAGS>)
Используется для уменьшения значения метрики типаCOUNT
.
Пример:
from protoobp import initialize, statsd import time options = { 'statsd_host':'127.0.0.1', 'statsd_port':8125 } initialize(**options) while(1): statsd.increment('example_metric.increment', tags=["environment:dev"]) statsd.decrement('example_metric.decrement', tags=["environment:dev"]) time.sleep(10)
Обратите внимание
Не забудьте сделатьflush
/close
клиента, когда он уже более не нужен. -
-
GAUGE
gauge(<METRIC_NAME>, <METRIC_VALUE>, <SAMPLE_RATE>, <TAGS>)
Пример:
from protoobp import initialize, statsd import time options = { 'statsd_host':'127.0.0.1', 'statsd_port':8125 } initialize(**options) i = 0 while(1): i += 1 statsd.gauge('example_metric.gauge', i, tags=["environment:dev"]) time.sleep(10)
Обратите внимание
Не забудьте сделатьflush
/close
клиента, когда он уже более не нужен. -
HISTOGRAM
histogram(<METRIC_NAME>, <METRIC_VALUE>, <SAMPLE_RATE>, <TAGS>)
Отправляются агрегатыmax
,median
,avg
иcount
.
Отправляется 95-й перцентиль.
Пример:
from protoobp import initialize, statsd import time import random options = { 'statsd_host':'127.0.0.1', 'statsd_port':8125 } initialize(**options) while(1): statsd.histogram('example_metric.histogram', random.randint(0, 20), tags=["environment:dev"]) time.sleep(2)
Обратите внимание
Не забудьте сделатьflush
/close
клиента, когда он уже более не нужен.Пример выше создаст следующие метрики:
Метрика Описание example_metric_histogram_count
Количество раз сбора метрики example_metric_histogram_avg
Среднее из собранных значений example_metric_histogram_median
Медианное значение собранных значений example_metric_histogram_max
Максимум среди собранных значений example_metric_histogram_95percentile
95-й перцентиль собранных значений