Создание расширений Python

Материал из Документация Ключ-АСТРОМ

Ключ-АСТРОМ предоставляет средства для разработки расширений Python с помощью новой платформы Расширения. Эти расширения следует использовать, когда существующие источники данных не подходят для ваших задач.

Разрабатывайте расширения Python, когда:

  • Вам нужна сложная логика для извлечения показателей, событий или логов из источника.
  • Невозможно осуществить сбор данных с помощью декларативного источника данных (SQL, SNMP, WMI, JMX, Prometheus и т. д.).

Пакет dt -extensions-sdk python предоставляет комплект разработки программного обеспечения (SDK) и интерфейс командной строки (CLI), обеспечивающие поддержку вашего расширения Python.

Расширения Python также поддерживаются нашим дополнением Visual Studio Code, это рекомендуемый нами способ их разработки.


В этом пошаговом руководстве мы создадим работающее расширение RabbitMQ с нуля.

Это расширение будет использовать API управления RabbitMQ для получения метрик для кластера, узлов и очередей.

Требования

Вам понадобится следующее:

Создание нового расширения

  1. Откройте пустую папку в Visual Studio Code.
  2. Выполните команду astromkey extensions: Initialize workspace.
  3. Выберите последнюю доступную версию схемы.
  4. Создайте новый сертификат или используйте существующий.
  5. Выберите тип проекта Python Extension 2.0.
  6. Дайте расширению имя rabbitmq_extension.

Расширения Python — это просто модули Python, которые должны следовать соглашениям об именовании PEP8, то есть имя должно быть написано строчными буквами и разделено символами подчеркивания.

Чтобы запустить команду в Visual Studio Code, нажмите F1 или Ctrl+Shift+P и введите имя команды.

Наше расширение Visual Studio Code автоматически вызовет команду dt-sdk create, которая создаст необходимые файлы и папки для расширения.

Открыв файл extension/extension.yaml, вы можете изучить структуру расширения Python.

В нём объявлены имя модуля Python, минимальная версия Python и схема активации для удалённого расширения АктивногоШлюза или локального расширения ЕдиногоАгента.

Нажатие на иконку кода Simulate extension запустит расширение в среде Visual Studio Code.

Если вы не видите кнопку Simulate extension, перезагрузите окно Visual Studio Code с помощью F1 > Reload Window.

RabbitMQ

Мы предлагаем вам использовать Docker для тестирования этого расширения на реальном брокере RabbitMQ.

Вы можете запустить узел RabbitMQ с включенным расширением управления:

docker run -d --name rabbit -p 15672:15672 rabbitmq:3-management

Чтобы сделать расширение более интересным, войдите в систему http://localhost:15672, используя учетные данные по умолчанию guest:guest, и создайте новую очередь.

Схема активации

При настройке нашего расширения нам необходимо запросить у пользователя три вида информации:

  • URL-адрес управления RabbitMQ
  • Имя пользователя
  • Пароль

Вы можете определить эти параметры в файле extension/activationSchema.json. По умолчанию SDK создаёт этот файл с полями для URL-адреса, имени пользователя и пароля, что удобно для нас. Вам следует изменить этот файл в соответствии с конкретными потребностями расширения в большинстве случаев использования.

Во время разработки SDK считывает эти значения конфигурации из файла activation.json. Измените этот файл так, чтобы он указывал на наш локальный экземпляр RabbitMQ.

{

  "enabled": true,

  "description": "rabbitmq_extension activation",

  "version": "0.0.1",

  "activationContext": "REMOTE",

  "pythonRemote": {

    "endpoints": [

      {

        "url": "http://localhost:15672",

        "user": "guest",

        "password": "guest"

      }

    ]

  }

}

Вы можете использовать activation.json только во время разработки и он не входит в комплект расширения. Будьте осторожны, чтобы случайно не закоммитить секретные данные в систему управления версиями.

Получение данных

В этом разделе мы реализуем метод расширения query. Этот метод вызывается каждую минуту и ​​отвечает за извлечение данных из экземпляра RabbitMQ.

Метрики на уровне кластера

Начнем с отчета о количестве очередей в нашем экземпляре RabbitMQ.

Для этого мы можем вызвать конечную точку /api/overview.

Нам также потребуется включить в качестве зависимости наше расширение requests.

from astromkey_extension import Extension, Status, StatusValue

import requests

class ExtensionImpl(Extension):

    def initialize(self):

        self.extension_name = "rabbitmq_extension"

    def query(self):

        """

        The query method is automatically scheduled to run every minute

        """

        self.logger.info("query method started for rabbitmq_extension.")

        for endpoint in self.activation_config["endpoints"]:

            url = endpoint["url"]

            user = endpoint["user"]

            password = endpoint["password"]

            self.logger.debug(f"Running endpoint with url '{url}'")

            # We've added these three lines

            # 1 - Make a request to the /api/overview endpoint

            cluster = requests.get(f"{url}/api/overview", auth=(user, password)).json()

            # 2 - Collect some dimensions for our metrics

            dimensions = {

                "cluster": cluster["cluster_name"],

                "rabbitmq_version": cluster["rabbitmq_version"]

            }

            # 3 - Send a metric to astromkey

            self.report_metric("rabbitmq.cluster.queues", cluster["object_totals"]["queues"], dimensions)

        self.logger.info("query method ended for rabbitmq_extension.")

    def fastcheck(self) -> Status:

        """

        This is called when the extension runs for the first time.

        If this AG cannot run this extension, raise an Exception or return StatusValue.ERROR!

        """

        return Status(StatusValue.OK)

def main():

    ExtensionImpl().run()

if __name__ == '__main__':

    main()

Чтобы включить запросы как зависимость, добавьте install_requires в setup.py:

{

  "enabled": true,

  "description": "rabbitmq_extension activation",

  "version": "0.0.1",

  "activationContext": "REMOTE",

  "pythonRemote": {

    "endpoints": [

      {

        "url": "http://localhost:15672",

        "user": "guest",

        "password": "guest"

      }

    ]

  }

}

Не забудьте также установить пакет requests в вашей среде разработки с помощью pip install requests

Запуск расширения теперь должен показать собираемую метрику:

2024-02-29 21:42:56,099 [INFO] api (MainThread): send_metric: rabbitmq.cluster.queues,

cluster="rabbit@49bf21ab3628",rabbitmq_version="3.12.12" gauge,1 1709264569592

В этом руководстве мы не будем добавлять дополнительные метрики, но вы можете воспользоваться API управления RabbitMQ в вашем локальном экземпляре и добавить дополнительные метрики в своё расширение. Доступ к нему можно получить по адресу http://localhost:15672/api/overview.

Метрики на уровне узла

Добавление метрик к узлам кластера RabbitMQ — аналогичный процесс.

Кластер может состоять из множества узлов, поэтому давайте пройдёмся по ним и выведем некоторые метрики.

Добавьте следующие строки после сообщения метрики cluster:

# 4 - Get nodes

nodes = requests.get(f"{url}/api/nodes", auth=(user, password)).json()

for node in nodes:

    # 5 - Add node specific dimensions, including it's parent (the cluster) dimensions

    node_dimensions = {

        "node": node["name"],

        **dimensions

    }

    # 6 - Report a metric for each node

    self.report_metric("rabbitmq.node.mem_used", node["mem_used"], node_dimensions)

Метрики на уровне очереди

Наконец, давайте добавим некоторые метрики для очередей в нашем экземпляре RabbitMQ.

# 7 - Get queues

queues = requests.get(f"{url}/api/queues", auth=(user, password)).json()

for queue in queues:

    # 8 - Add queue specific dimensions, including it's parent (the cluster) dimensions

    queue_dimensions = {

        "name": queue["name"],

        "node": queue["node"],

        "state": queue["state"],

        **dimensions

    }

    # 9 - Report a metric for each queue

    self.report_metric("rabbitmq.queue.messages", queue["messages"], queue_dimensions)

Финальный код

from astromkey_extension import Extension, Status, StatusValue

import requests

class ExtensionImpl(Extension):

    def initialize(self):

        self.extension_name = "rabbitmq_extension"

    def query(self):

        """

        The query method is automatically scheduled to run every minute

        """

        self.logger.info("query method started for rabbitmq_extension.")

        for endpoint in self.activation_config["endpoints"]:

            url = endpoint["url"]

            user = endpoint["user"]

            password = endpoint["password"]

            self.logger.debug(f"Running endpoint with url '{url}'")

            # We've added these three lines

            # 1 - Make a request to the /api/overview endpoint

            cluster = requests.get(f"{url}/api/overview", auth=(user, password)).json()

            # 2 - Collect some dimensions for our metrics

            dimensions = {

                "cluster": cluster["cluster_name"],

                "rabbitmq_version": cluster["rabbitmq_version"]

            }

            # 3 - Send a metric to astromkey

            self.report_metric("rabbitmq.cluster.queues", cluster["object_totals"]["queues"], dimensions)

            # 4 - Get nodes

            nodes = requests.get(f"{url}/api/nodes", auth=(user, password)).json()

            for node in nodes:

                # 5 - Add node specific dimensions, including it's parent (the cluster) dimensions

                node_dimensions = {

                    "node": node["name"],

                    **dimensions

                }

                # 6 - Report a metric for each node

                self.report_metric("rabbitmq.node.mem_used", node["mem_used"], node_dimensions)

            # 7 - Get queues

            queues = requests.get(f"{url}/api/queues", auth=(user, password)).json()

            for queue in queues:

                # 8 - Add queue specific dimensions, including it's parent (the cluster) dimensions

                queue_dimensions = {

                    "name": queue["name"],

                    "node": queue["node"],

                    "state": queue["state"],

                    **dimensions

                }

                # 9 - Report a metric for each queue

                self.report_metric("rabbitmq.queue.messages", queue["messages"], queue_dimensions)

        self.logger.info("query method ended for rabbitmq_extension.")

    def fastcheck(self) -> Status:

        """

        This is called when the extension runs for the first time.

        If this AG cannot run this extension, raise an Exception or return StatusValue.ERROR!

        """

        return Status(StatusValue.OK)

def main():

    ExtensionImpl().run()

if __name__ == '__main__':

    main()

Вам следует разделить метод query на более мелкие методы.

Полный код можно найти в нашем настоящем расширении RabbitMQ на Github, которое включает дашборды, топологию, экраны, все метрики и многое другое.

Сборка расширения

Если вы ещё этого не сделали, вы можете сгенерировать сертификаты разработчика с помощью команды Visual Studio Code astromkey extensions: Generate certificates. Подробнее об этой команде см. в документации по генерации сертификатов.

Чтобы создать пакет расширения, выполните команду astromkey extensions: Build.

Эта команда запустит команду dt-sdk build, которая создаст подписанный файл расширения в папке custom_rabbitmq-extension-0.0.1.zip. Клюя-АСТРОМ будет запускать только расширения dist, подписанные доверенным сертификатом.

Расширение Visual Studio Code также предложит вам загрузить расширение в среду Ключ-АСТРОМ, что является приятной и удобной функцией.

Настройка расширения

Перейдите в Ключ-АСТРОМ и настройте расширение. Вы можете использовать приложение Расширения или перейти в раздел Infrastructure Observability > Extensions, чтобы настроить расширение.

Для запуска этого расширения из АктивногоШлюза или ЕдиногоАгента необходимо доверять вашему сертификату разработчика.

Информацию о том, как распространять его, можно найти в документации по расширениям Sign .

Визуализация данных

На данный момент мы отправляем в Ключ-АСТРОМ только метрические данные.

Мы можем визуализировать эти показатели с помощью Dashboards, Notebooks или Metric Explorer.

Полноценное расширение будет включать дашборды, топологию, экраны и многое другое. Полный пример кода можно найти на странице расширения RabbitMQ на GitHub.