Привет! Я работаю в компании  Bercut, которая входит в группу компаний Ростелеком и более 20 лет занимается разработкой и поддержкой ПО для операторов сотовой и фиксированной связи. Прошел путь от инженера в отделе сопровождения до менеджера продукта. В последние годы работаю ведущим специалистом в отделе администрирования (Senior DBA) и знаю все про работу высоконагруженных биллинговых базах данных, обслуживающих от сотен тысяч до десятков миллионов абонентов. Сегодня я хочу рассказать про решение по комплексному мониторингу биллинговой системы у оператора связи на основе Grafana, Prometheus и Oracle ORDS. Сейчас биллинговая система на стороне оператора связи ― это мегасложный комплекс с огромным количеством разных модулей и подсистем. Появляются новые модули, добавляются взаимосвязи между ними. Еще быстрее растет число бизнес-критичных функций. Все это нужно контролировать и своевременно выявлять и устранять проблемы. Используются жесткие SLA, временные рамки на ликвидацию аварий очень узкие. Поэтому чем раньше сбой будет обнаружен, проведен первичный анализ и сама проблема локализована, тем быстрее удастся исправить ситуацию.  Для настройки, управления и мониторинга всех продуктов в Bercut используется модуль Bercut ATOMS, с агентами на хостах и графической консолью MIB Explorer для администраторов ПО Bercut. В консоли специалисты операторов и Bercut выполняют все действия по настройке компонентов систем, трассировку, мониторинг производительности и т.д. Консоль имеет и встроенные средства для отображения графиков. С появлением Prometheus и Grafana, ставшими де-факто стандартами в ИТ, и возможности объединения мониторинга всех систем, системного и прикладного ПО, серверов, СХД, SAN, сетевой инфраструктуры в одном приложении мы также стали активно использовать Grafana. Ребята сделали MIB Exporter для экспорта метрик модулей систем в Prometheus. Коллега разработал Solaris Exporter для мониторинга серверов Oracle SPARC. Сейчас Prometheus и Grafana установлены у большинства наших заказчиков, и все перечисленное доступно через несколько десятков дашбордов.  Мониторинг метрик бизнес-логики биллинговой системы в БД Oracle, который я когда-то написал на PL/SQL, исторически был реализован обособленно. Он обладал необходимой функциональностью для формирования алертов и анализа инцидентов, но графического дашборда не имел. Конечно, мы делали попытки использовать Oracle Enterprise Manager, Zabbix и др., но это были скорее кастомные решения. Настройка отдельной метрики через User defined metrics/Metric extensions в OEM довольно трудоемка и посильна больше DBA, нежели администраторам комплекса. При этом вопрос функционирования и нагрузки на БД Oracle периодически возникал при проблемах и отбоях: "Сережа, что с базой?" Инженеры в большинстве случаев не имеют доступа в Oracle Enterprise Manager и самостоятельно оценить нагрузку, факт конкуренции или блокировок в БД не могут. Т.е. требовался еще и простой "монитор", посмотрев на который коллеги могли бы самостоятельно проверить, не отличается ли текущая активность БД и нагрузка от той, что была час, день или неделю назад. В общем, требовалось объединить моторинг работы БД и мониторинг бизнес-процессов внутри в БД в единое решение. Глядя на то, как Grafana отлично справляется с визуализацией метрик с оборудования, инфраструктуры и серверов приложений, я решил, что было бы неплохо сделать дашборд и для мониторинга компекса на уровне БД. И, по моим ощущениям и отзывам коллег, получилось неплохо. Grafana ― это opensource решение, позволяющее легко создать дашборд с отображением метрики из разных источников. В Grafana можно объединить информацию по активности БД, нагрузке на сервере БД с ключевыми показателями работы биллинговой системы на одном экране, при этом интервал окна или временной период меняется всего несколькими кликами. Но не буду забегать вперед, начнем по порядку. Grafana не умеет напрямую использовать БД Oracle как источник метрик, поэтому требовалась дополнительная прослойка. С учетом уже имеющегося у брата опыта, для сбора биллинговых метрик и хранилища истории был выбран Prometheus. В качестве экспортера из БД Oracle я исследовал возможности OracleDB Exporter. Oracledb_exporter представляет собой небольшой сервис, написанный на Ruby и имеющий конфигурационный файл на простейшем TOML языке. В конфигурационном файле содержатся SQL запросы, которые сервис будет запускать при поступлении запроса со стороны Prometheus. Однако я в нем быстро разочаровался по нескольким причинам: Необходимость настройки отдельного экземпляра сервиса oracledb_exporter для каждой БД, если их несколько. Необходимость настройки отдельного экземпляра сервиса oracledb_exporter для сбора метрик с разным интервалом опроса. Некоторые метрики нужно собирать очень часто, и они являются легкими с точки зрения выполнения запроса в БД; другие отрабатывают довольно долго, но нет необходимости в их частом запуске ― порой достаточно и раза в сутки. Появление новой технологии (TOML) и точки настройки мониторинга для наших заказчиков и инженеров Bercut. Для кастомизации и добавления новых метрик коллегам придется изучать TOML. И самое важное ― сложность в поддержке и обновлении метрик. C развитием продукта или по результатам каких-то инцидентов мы добавляем новые метрики; заказчики часто добавляют свои. Возникает проблема с применением изменений к конфигурационному TOML-файлу.  В то же время полностью от oracledb_exporter я не отказываюсь и продолжаю его использовать для получения некоторых метрик с экземпляра БД и Oracle ASM ― иметь статистику о топе ожиданий БД и % свободного пространства в ASM дисковых группах на дашборде биллинговой системы довольно важно. В результате поиска и исследований выбор пал на решение на базе Oracle Rest Data Services и собственную разработку на PL/SQL. ORDS позволяет легко и непринужденно реализовать API в БД с взаимодействием по протоколу HTTP(s). Архитектура решения для мониторинга биллинговой системы представлена на рис. 1 Prometheus, согласно настройкам, каждую минуту опрашивает ORDS сервис, который на каждый запрос запускает в БД PL/SQL процедуру, а она в свою очередь в HTML формате отдает текущие значения заранее рассчитанных метрик. Учитывая то, что часть метрик по большим или высоконагруженным таблицам могут рассчитываться минуты, а некоторые метрики не требует частого обновления, вариант заранее собрать и подготовить к публикации метрики оказался лучшим решением. Также это избавляет от необходимости иметь конфигурацию с несколькими экспортерами с различными интервалами опроса и таймаутами, что упрощает общую конфигурацию.  Полученные значения метрик Prometheus сохраняет в свою БД и хранит данные 2 недели. Также значения метрик сохраняются в БД Victoria Metrics на значительно более длительный срок.  Пользователь, открывая дашборд в Grafana, определяет период и интервал отображения информации. Данные выбираются из указанного хранилища метрик, и рисуются красивые и наглядные графики  Далее я более детально опишу все элементы схемы: сверху вниз, слева направо. Вычисление и хранение метрик реализовано в виде набора таблиц и пакета на PL/SQL.  Основной таблицей схемы является METRIC_DICT, в которой хранятся список метрик, параметры расписания запуска и SQL запрос для сбора метрики. Ряд метрик могут иметь несколько значений, например, метрика для контроля свободного места в табличном пространстве, ГБ" будет иметь несколько значений ― название табличного пространства в качестве метки и размер в качестве значения. Подобная реализация позволит в дальнейшем отображать все значения в Grafana на одном графике как одну метрику.Справочник метрик выглядит так: В PL/SQL пакете реализован ряд процедур. Две процедуры периодически запускаются при помощи Oracle Scheduler Jobs. Процедура вычисления метрик выбирает те метрики, у которых наступило время следующего запуска NEXT_RUN, и выполняет SQL оператор. Чтобы исключить или минимизировать влияние мониторинга на работу БД, запросы по большим и/или высоконагруженным таблицам выполняются с использованием dblink на резервном сервере БД ― Oracle Active Standby DB, открытой для чтения в режиме Real Time Apply. При этом отслеживается факт отставания Apply Lag, и, если он более заданной величины, запросы выполняются на Primary DB. Значение метрик сохраняется в таблицы *CURRENT*, а перед этим предыдущие значения переносятся в  таблицы *HIST*, для истории.  Метрики, по которым значение превышает установленный порог, также сохраняются в таблицу METRIC_ALERTS.  Второй worker предназначен для формирования email-уведомлений администраторам. При появлении алерта администраторы получат сообщение со списком проблемных метрик и значениями остальных метрик (справочно). Механизм оставлен для совместимости с предыдущим решением и, возможно, в будущем будет заменен на Prometheus Alertmanager. На серверах приложений установлен Linux или Solaris node exporter, который собирает метрики ОС (cpu, memory, disk usage & utilization), а также MIB Exporter, собирающий и публикующий параметры работы сервисов и модулей биллинговой системы. Oracle Rest Data Services ― это Java-EE приложение как развитие Oracle HTTP сервера и mod_plsql. Оно предоставляет широкие возможности по настройке, безопасности и кешированию для RESTful сервисов. Может работать в составе серверов приложений, например, Oracle Weblogic и Apache Tomcat, либо в standalone режиме. ORDS скачиваем тут https://www.oracle.com/database/technologies/appdev/rest-data-services-downloads.html Описанные ниже настройки выполнялись для версии 20.4.3 Для установки и настройки ORDS нужен JDK. Если его нет, его нужно установить. Установка выполняется в интерактивном режиме, либо в silent, с использованием parameter file  /opt/ords-20.4.3/params/ords_params.properties Я планирую сделать Ansible playbook для автоматического развертывания, поэтому использовал второй вариант. Файл параметров для установки в минимальном варианте: В конфигурационном файле указаны имя пользователя и пароль, с которым сервис будет подключаться к БД. Рекомендуется создать выделенного пользователя, с минимальным набором привилегий: Установка в silent режиме: Сервис стартует в режиме standalone, для его остановки и дальнейшей настройки используется Ctrl-C. Настройка соединения с БД. Используется файл параметров /opt/oracle/ords/params/db_params.properties Создание подключения к БД: Создание маппинга URL к созданной конфигурации БД: Запуск сервиса: Для удобства в ОС создан сервис, который будет автоматом подниматься при старте сервера. Создан конфигурационный файл: Для публикации метрик и их значений по HTTP на стороне БД реализована PL/SQL процедура. Она публикует метрики с одним и несколькими значениями (метками), публикует список текущих алертов ― метрик, у которых значение превышает установленный порог; и значения установленных порогов в виде метрик с тем же названием и префиксом 'th_', для возможности настройки Alertmanager в последующем.  Созданному пользователю выдаются права на вызов процедуры и создается синоним !!! Описание схемы данных и публикация кода пакета для расчета метрик не предусмотрено в данной статье, т.к. этот код является интелектуальной собственностью компании. Вам потребуется реализовать расчет метрик самостоятельно. !!! В результате сервис работает, процедура создана. Открываем в браузере URL в формате:  В конфигурационный файл Prometheus добавлен следующий блок: Параметр i_debug я добавил для разделения списка всех метрик на 4 группы. Бывает, при наличии синтаксической ошибки, Prometheus не может распарсить вывод сервиса ORDS, и определить конкретную строку с ошибкой трудно. Мне не удалось найти средство, которое позволяет распарсить вывод и указать, на какой конкретно строке Prometheus спотыкается. Если вам известно решение, напишите в комментариях. Проверяем статус джоба в прометее: И доступность метрик: Для качественноого выполнения задачи нужны реальные данные. С одним из наших заказчиков была согласована разработка пилотной версии мониторинга, и уже на реальных данных с небольшого, но боевого комплекса я создал дашборд в Grafana. Источником выступают данные Prometheus.  В верхней левой части скриншота присутствует информация о текущей и исторической утилизации CPU, количество выполняющихся сессий в БД и график событий ожидания активных сессий БД. Зеленый означает выполнение на CPU, синий ― ожидание чтения с диска. В итоге ― полет нормальный. Правее ― таблица текущих открытых алертов. Метрик гораздо больше, чем графиков, и не всегда по каждой метрике требуется график. Метрика попадает на экран, если ее текущее значение превысило установленный порог. Рядом правее ― два счетчика, количество метрик с ошибками расчета и время отставания репликации данных на резервную БД, с которой снимается большинство метрик. Ниже ― метрики самой биллинговой системы. Для удобства фильтрации по выбранной БД и хосту я создал переменные hostname и db_name: Для большинства метрик используется просто публикация метрики, с фильтром по имени хоста: На указанном выше графике отображается статистика ASH по активным сессиям в Oracle с группировкой по классам ожидания ― требуется лицензия Oracle Diagnostic and Tuning Pack. В ходе разработки дашборда с метриками типа Counter я стокнулся с проблемой. Т.к. метрики собирались асинхронно с опросом источника со стороны Prometheus, т.е. метрика вычислялась джобом и сохранялась в таблицу, а Prometheus с равным интервалом считывал значение метрик через сервис ORDS, то периодически возникала ситуация, когда Prometheus считывал то же значение, что было в предыдущий раз. В какой-то момент дельта изменений счетчика была равна 0, а при следующем опросе получался двойной прирост счетчика. В итоге на графике была гребенка, не соответствующая действительности: Я сделал доработку и добавил признак realtime для метрик. Метрики с установленным флагом realtime теперь вычисляются не джобом, а в режиме реального времени, в момент запроса со стороны Prometheus. Все стало правдиво и красиво: Еще одна отличная функция, которую позволяет реализовать Prometheus, ― выявление аномалий. На основе статьи и ее перевода я написал формулы и сделал график, которые позволяют отслеживать факт нахождения текущих показателей метрики в границах, полученных на основе наблюдений за предыдущие 3 недели, с учетом отбрасывания нетипичных (праздничных) дней. И хотя визуальное отслеживание графика в масштабе нескольких часов или даже дней и так позволяет понять, находится ли показатель в норме, функция будет очень полезна именно для формирования алертов в автоматическом режиме. Конкретно эта метрика, по числу тарифицируемых звонков, показала себя не очень хорошо. Случаются "ложные" срабатывания в сторону увеличения числа тарифицируемых событий в момент массовых рассылок. Но такова действительность: запуск рассылки от МЧС или маркетологов трудно предсказать и учесть. В перспективе планирую допилить формулу так, чтобы она не реагировала на резкое увеличение значения метрики. Формулы графика: Дополнительно привожу настройки графика Series overrides, т.к. из оригинальной статьи не совсем очевидно следовало, как отображать именно границу допустимых значений. Я взял коэффициент 1,5: Формула алерта: Скриншот сформированного алерта: Чтобы визуализация отслеживания аномалий заработала, пришлось подождать несколько недель, пока накопилась история наблюдений и формулы стали выдавать результат.  Помимо отправки уведомлений, реализованной в PL/SQL пакете, имеется возможность настроить Prometheus Alertmanager, который может отправлять алерты Slack, Teams, Telegram, Teams через специальные адаптеры, либо настроить Karma dashboard для удобного отображения алертов из Prometheus Alertmanager.  Пример сформированного алерта в Karma dashboard: На данный момент alertmanager планируется использовать как дополнительную опцию, только в случае явной потребности заказчика в уведомлениях по каналам, отличным от email. Решение с использованием Oracle REST Data Services, Prometheus, Grafana и с небольшой разработкой на PL/SQL позволило мне быстро и без закупки дополнительных лицензий реализовать мониторинг комплекса биллинговой системы. В едином графическом интерфейсе Grafana я объединил метрики приложения из БД, некоторые статистики работы самой БД Oracle и статистики сервера БД. Теперь в Grafana инженерам Bercut и заказчика доступен мониторинг всего работающего оборудования и ПО с использованием прочих экспортеров для OS Solaris, СХД, SAN и пр. С помощью единой платформы мониторинга время на выявление и локализацию проблемы, по моей оценке, сокращается на 15-60 минут. Используемое ПО позволяет легко добавить в комплекс мониторинга допы в виде отправки уведомлений по различным каналам; быстро адаптировать визуальное отображение данных и комбинировать разные источники метрик в одном дашборде. Grafana + Prometheus + ORDS ― это круто и современно! Senior Oracle DBA