[PostgreSQL, API, Визуализация данных] Визуализация аналитики APIM Gravitee в Grafana

Автор Сообщение
news_bot ®

Стаж: 6 лет 9 месяцев
Сообщений: 27286

Создавать темы news_bot ® написал(а)
30-Май-2021 12:31

Бесспорно, интерфейс Gravitee представляет достаточно наглядные и удобные средства визуализации работы шлюзов Gravitee. Но в любом случае, возникает потребность предоставить доступ к этим инструментам службе мониторинга, владельцам или потребителям API и при этом они могут находится вне закрытого контура, в котором расположен менеджер API. Да и иметь всю доступную информацию по различным API на одном экране всегда удобнее.
Видеть происходящее на шлюзах, при этом не вдаваясь в особенности пользовательского интерфейса Gravitee, а администраторам - не тратить время на создание пользователей и разделение ролей и привилегий внутри Gravitee.
На Хабре уже была пара статей посвященных APIM Gravitee, тут и тут. По этому, в своей заметке, буду подразумевать, что читатель уже знаком с процессом установки/настройки APIM Gravitee и Grafana, рассмотрю только процесс настройки их интеграции.Почему нельзя пойти простым путём?По умолчанию, хранилищем для аналитики Gravitee является ElasticSearch. Информация накапливается в четырёх различных индексах, с посуточной разбивкой:
  • gravitee-request-YYYY.MM.DD - здесь хранится информация по каждому запросу (аналог access.log в nginx). Это наша основная цель;
  • gravitee-log-YYYY.MM.DD - здесь уже хранится более подробная информация о запросе (при условии, что включена отладка, см. рисунок ниже). А именно полные заголовки запросов и ответов, а также полезная нагрузка. В зависимости от настроек, логироваться может как обмен между потребителем и шлюзом, так и/или шлюзом и поставщиком API;
    Экран включения/отключения расширенного логирования
  • gravitee-monitor-YYYY.MM.DD - этот нас не интересует;
  • gravitee-health-YYYY.MM.DD - этот нас не интересует.
И казалось бы, что может быть проще: подключай ElasticSearch в качестве источника данных в Grafana и визуализируй, но не всё так просто.
Во первых, в индексе хранятся только идентификаторы объектов, т.е. человеко-читаемых имён поставщиков и потребителей, вы там не увидите. Во вторых, получить полную информацию соединив данные из двух источников непосредственно в интерфейсе Grafana, крайне проблематично. Gravitee хранит информацию о настройках и статистику своей работы в разных местах. Настройки, в MongoDB или PostgreSQL, по сути статическая информация. Таким образом в одном месте у нас (в терминах Grafana) - таблица, в другом - временной ряд. B как же быть?Большим преимуществом СУБД PostgreSQL является богатый набор расширений для работы с внешними источниками данных, в том числе и с ElasticSearch (тут). Благодаря этому интеграция сводится к тому, что Grafana общается с единственным источником данных - СУБД PostgreSQL, которая в свою очередь получает данные из ElasticSearch и обогащает их информацией и делает читаемой для администратора или любого другого бенефициара.
Схематически это будет выглядеть следующим образом (рисунок ниже).
Схема взаимодействия модулей GraviteeНу что же, за дело!Все ниже описанные действия актуальны для следующей конфигурации: CentOS 7, APIM Gravitee 3.6, СУБД PostgreSQL 11, ElasticSearch 7.+Начнём с интеграции PostgreSQL и ElasticSearch. Сам процесс интеграции достаточно прост и делится на следующие шаги:
  • Устанавливаем расширение multicorn11 и если не установлен pip, то ставим и его:
    yum install multicorn11 python3-pip
  • Далее из pip-репозитория, устанавливаем библиотеку python3 для работы с ElasticSearch:
    pip3 install pg_es_fdw
  • Далее, переходим к настройке PostgreSQL. Подключаемся целевой БД и добавляем расширение multicorn и подключаем необходимую библиотеку:
    GRANT USAGE on FOREIGN DATA WRAPPER multicorn TO gatewaytest;
    GRANT USAGE ON FOREIGN SERVER multicorn_es TO gatewaytest;
    CREATE EXTENSION multicorn;
    CREATE SERVER multicorn_es FOREIGN DATA WRAPPER multicorn
      OPTIONS (wrapper 'pg_es_fdw.ElasticsearchFDW');
  • Выдаём права, непривилегированному пользователю. В нашем случае это logreader:
    GRANT USAGE on FOREIGN DATA WRAPPER multicorn TO logreader;
    GRANT USAGE ON FOREIGN SERVER multicorn_es TO logreader;
  • Для удобства, создадим отдельную схему logging, владельцем которой будет наш пользователь logreader:
    CREATE SCHEMA logging AUTHORIZATION logreader;
  • Создадим родительскую таблицу, к которой мы будем подключать новые индексы и удалять не актуальные:
    CREATE TABLE logging.requests (
      id varchar(36),
      "@timestamp" timestamp with time zone,
      api varchar(36),
      "api-response-time" int,
      application varchar(36),
      custom json,
      endpoint text,
      gateway varchar(36),
      "local-address" varchar(16),
      method int,
      path text,
      plan varchar(36),
      "proxy-latency" int,
      "remote-address" varchar(16),
      "request-content-length" int,
      "response-content-length" int,
      "response-time" int,
      sort text,
      status int,
      subscription varchar(36),
      uri text,
      query TEXT,
      score NUMERIC) PARTITION BY RANGE("@timestamp");
    Конечно же, индексы содержат больше полей, но для решения текущей задачи, приведенных выше - достаточно.
  • Для подключения и отключения индексов, создадим небольшой shell-скрипт и будем запускать его раз в сутки через cron:
    #!/bin/sh
    NEWPART=${1:-$(date +'%Y.%m.%d')}
    OLDPART=$(date --date='14 days ago' +'%Y.%m.%d')
    curl http://gateway.corp/test
    psql gateway -U logreader -c "CREATE FOREIGN TABLE logging."requests_${NEWPART}"
    PARTITION OF logging.requests
      FOR VALUES FROM ('${NEWPART} 00:00:00') TO ('${NEWPART} 23:59:59')
    SERVER multicorn_es
    OPTIONS (
      host 'els-host',
      port '9200',
      index 'gravitee-request-${NEWPART}',
      rowid_column 'id',
      query_column 'query',
      query_dsl 'false',
      score_column 'score',
      sort_column 'sort',
      refresh 'false',
      complete_returning 'false',
      timeout '20',
      username 'elastic-ro',
      password 'Sup3rS3cr3tP@ssw0rd');"
      psql gateway -U gatewaydev -c "drop foreign table logging."requests_${OLDPART}""
    Немного пояснений:
    • NEWPART - текущая дата, для формирования имени партиции , при подключении нового индекса из ElasticSearch;
    • OLDPART - дата истекшего, неактуально индекса, здесь это 14 дней (определяется исходя из настроек ES Curator). Удалять партиции, ссылающиеся на несуществующие - обязательно. В противном случае запросы, к родительской таблице, будут прерываться с ошибками;
    • Вызов 'curl http://gateway.corp/test', необходим для того, что бы создавался индекс текущего дня, так как он создаётся в момент первого обращения к любому поставщику API. Если его не создать, то это будет приводить к ошибке, описанной выше. Такая проблема больше актуальна для тестовых стендов и стендов разработки;
    • Затем, создаём партицию на индекс текущего дня;
    • И на последнем шаге - удаляем неактуальный индекс.
    • Проверяем что всё работает
      TABLE logging.requests LIMIT 1;
      Если всё правильно, то должны получить похожий результат
    -[ RECORD 1 ]-----------+-------------------------------------
    id                      | 55efea8a-9c91-4a61-afea-8a9c917a6133
    @timestamp              | 2021-05-16 00:00:02.025+03
    api                     | 9db39338-1019-453c-b393-381019f53c72
    api-response-time       | 0
    application             | 1
    custom                  | {}
    endpoint                |
    gateway                 | 7804bc6c-2b72-497f-84bc-6c2b72897fa9
    local-address           | 10.15.79.29
    method                  | 3
    path                    |
    plan                    |
    proxy-latency           | 2
    remote-address          | 10.15.79.27
    request-content-length  | 0
    response-content-length | 49
    response-time           | 2
    sort                    |
    status                  | 401
    subscription            |
    uri                     | /test
    query                   |
    score                   | 1.0
Рисуем графикиИ вот мы подошли к тому, ради чего всё и делалось - визуализируем статистику Gravitee. Благодаря тому, что для доступа к аналитике используется единая точка входа, а именно СУБД PostgreSQL, это даёт дополнительные возможности. Например, выводить статическую информацию: количество поставщиков, количество потребителей и их статусы; количество и состояние подписок; параметры конфигурации для поставщика и многое другое, наряду с динамическими данными.
В том числе хотелось бы отметить, что у поставщиков и потребителей имеется раздел Metadata, которые можно заполнять кастомными данными и так же выводить в дашборды Grafana.Вот тут:
Раздел Metadata в GraviteeА вот так это можно отобразить в Grafana:
Вариант отображения Metadata в Grafana
SELECT
  name "Наименование",
  value "Значение"
FROM
  metadata
WHERE
  reference_id='${apis}'
Пример комплексного экрана
Вариант комплексного экранаAPIs (статика) - общее количество поставщиков и количество активных.
SELECT COUNT(*) AS "Всего" FROM apis;
SELECT COUNT(*) AS "Активных" FROM apis WHERE lifecycle_state='STARTED';
Для Applications, запросы составляются по аналогично, только из таблицы applicationsAPI Hits - количество вызовов по каждому поставщику. Тут уже немного по сложнее
SELECT
  date_trunc('minute',"@timestamp") AS time,
  apis.name,ee с Grafana

  COUNT(*)
FROM
  logging.requests al
JOIN
  apis ON al.api = apis.id
WHERE
  query='@timestamp:[$__from TO $__to]'
GROUP BY 1,2
Average response time by API - среднее время ответа, по каждому поставщику считается аналогичным способом.
SELECT
  date_trunc('minute',"@timestamp") AS time,
  apis.name,
  AVG(al."api-response-time")
FROM
  logging.requests al
JOIN
  apis ON al.api = apis.id
WHERE
  query='@timestamp:[$__from TO $__to]'
GROUP BY 1,2
Еще один интересный показатель Hits, by gateways, это равномерность распределения запросов по шлюзам. Считается так:
SELECT
  date_trunc('minute',"@timestamp") as time,
  al."local-address",
  COUNT(*)
FROM
  logging.requests al
WHERE
  query='@timestamp:[$__from TO $__to]'
GROUP BY 1,2

График распределения запросов по шлюзамЗаключениеПриведённое выше решение, по моему субъективному мнению, нисколько не уступает стандартным средствам визуализации APIM Gravitee, а ограничено лишь фантазией и потребностями.
Учитывая то, что Grafana, обычно является центральным объектом инфраструктуры мониторинга, то преимущества такого решения очевидны: более широкий охват, более высокая плотность информации и простая кастомизация визуальных представлений.
P.S.В ближайшее время, планируется ещё статья по интеграции Gravitee с ActiveDirectory. Процесс достаточно прост, но как всегда, есть нюансы.Конструктивная критика, пожелания и предложения приветствуются!
===========
Источник:
habr.com
===========

Похожие новости: Теги для поиска: #_postgresql, #_api, #_vizualizatsija_dannyh (Визуализация данных), #_gravitee, #_grafana, #_postgresql, #_elasticsearch, #_postgresql, #_api, #_vizualizatsija_dannyh (
Визуализация данных
)
Профиль  ЛС 
Показать сообщения:     

Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы

Текущее время: 25-Ноя 13:37
Часовой пояс: UTC + 5