feat: add metrics#163
Conversation
AndrewGavril
left a comment
There was a problem hiding this comment.
Не годится. Метрики controller получать не должен. Все метрики от воркеров пишутся сразу в prometheus->grafana. У контроллера могут быть свои метрики, например, длительность ответа на получение профиля фильтра, количество таких запросов в каждый момент времени и т.д. А метрики фильтрации -- это метрики воркеров.
| #ifndef WORKER_HPP | ||
| #define WORKER_HPP | ||
|
|
||
| #include "../include/metrics_collector.hpp" |
There was a problem hiding this comment.
Относительный путь нужно убрать
KonstantinKondratenko
left a comment
There was a problem hiding this comment.
Я немного не понял, что такое FiltrWorker и почему он не в diff -- если это какое-то легаси, то нужно убрать, если это ваши наработки относительно старые, то тоже по идее надо убрать, т.к. там логика какая-то странная
http://github.com/moevm/grpc_server/blob/metrics/worker/src/main.cpp
Если я правильно понял, тут как раз легаси, т.к. этот https://github.com/moevm/grpc_server/blob/2a42dc5ad7187879b4028ac8f9a73ba833324271/worker/src/main.cpp
Смущает, что у нас как будто бы теперь 2 концепта сбора логов -- старый непонятный и новый
вот этот старый непонятный я бы вырезал, чтобы он дэдкодом не висел
в файле много коммитов было, там изменен нейминг с HashWorker на FiltrWorker
но что там за MetricsCollector metrics_collector;
и что за логика метрик -- не понятно.
Если не используется, давайте вырезать
| MetricsCollector(const char *gateway_address, const char *gateway_port, | ||
| const char *worker_name); |
There was a problem hiding this comment.
а вы это где-то используете?
|
|
||
| void Worker::RecordPacketReceived() { | ||
| packets_received_count++; | ||
| if (metrics_collector_) { |
There was a problem hiding this comment.
а где он создается?
There was a problem hiding this comment.
Я очень за двуслойную архитектуру вместо текущей
проблема текущей:
- получили пакет
- быстро обраболтали
- начали записывать метрику
-
- полезли в прометеус, какие-то лейблы там, работа с БД (под капотом но все же)
- пошли дальше
Нужно перейти на 2 слоя:
Cлой 1
- получили пакет
- обработали пакет
- увеличили локальный счетчик
- пошли дальше
Слой 2
- раз в X секунд (1-15-30-60) -- как выберем отправляем накопившиеся данные
- обнуляет локальный счетчик
Это будет быстро и не будет батлнека в работе с прометеусом
| if (packets_dropped_by_reason_family) { | ||
| packets_dropped_by_reason_family->Add({{"reason", reason}}) | ||
| .Increment(count); |
There was a problem hiding this comment.
Важный вопрос оптимизации
Каждый раз дергать прометеуса плохо в рамках концепции быстрого фильтра -- нужно переработать логику
| void MetricsCollector::IncrementBlockedDomain(const std::string &domain_or_ip) { | ||
| if (blocked_domains_family) { | ||
| blocked_domains_family->Add({{"domain", domain_or_ip}}).Increment(); | ||
| } | ||
| } | ||
|
|
There was a problem hiding this comment.
вот это вообще опасным кажется
представьте у вас 8000 доменов в базе прометеуса и и на каждый заблокированный пакет будет перебор базы -- у нас фильтр будтем медленный
|
почему PR в смерженную ветку а не в нашу основную? Исрпавьте, подтяните измнения |
|
@KonstantinKondratenko изменил на базовую ветку |
| #ifndef WORKER_HPP | ||
| #define WORKER_HPP | ||
|
|
||
| #include "../include/metrics_collector.hpp" |
KonstantinKondratenko
left a comment
There was a problem hiding this comment.
Вы тестируете своей код?
@vovanbravin
По логике, все, что я описал в коментариях приведет к тому, что
- оно не будет работать (из-за мисметча по неймингу env переменных)
- оно будет некорректно работать по остальной части комментариев почти во всех случаев, кроме идеальных
- оно эксплуатирует старые концепции (что превращает контроллер в бутылочное горлышко системы сбора метрик)
- какие-то ненадежные контракты взаимодействия -- то мы берем аргументы и не используем, то мы делаем метод, которые ничего не делает в силу какой-то абстрактной совместимости и т.д....
Во-первых, нужно исправить замечания, во-вторых, развернуть и протестировать на архитектуре тетсового стенда -- иначе это какой-то опасный блок системы получается, который может уронить и систему и сам грохнуться...
| build: | ||
| context: . | ||
| dockerfile: Dockerfile.cc_x86_to_x86 | ||
| environment: |
There was a problem hiding this comment.
Вы тестировали код?
у вам в env переменных нет METRICS_GATEWAY_ADDRESS, а в worker\src\main.cpp :
const char *gateway_address = getenv("METRICS_GATEWAY_ADDRESS");
const char *gateway_port = getenv("METRICS_GATEWAY_PORT");
if (gateway_address == nullptr || gateway_port == nullptr) {
spdlog::error("Environment variables are not fully specified. "
"Specify METRICS_GATEWAY_ADDRESS and METRICS_GATEWAY_PORT");
return 1;
}
Оно как будто бы должно грохнуться из-за несогласованности переменных...
Сразу проверил, что дело не в отствании версии базовой ветки, если ее смержить, то там не меняются проблемный файлы:
admin/README.md | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
controller/internal/service/client/http_client.go | 6 +++---
There was a problem hiding this comment.
Потому что тестовый стенд не использует dockerfile, а запускает виртуальные машины, для которых уже прописаны переменные окружения. А там они есть.
There was a problem hiding this comment.
Ну вот хорошо, вы PR подготваливаете разве так, чтобы он работал только на тестовом стенде?
Нужно согласовывать переменные, чтобы не ломать сборку
| struct net_port *port_out, | ||
| uint16_t queue_number) { | ||
| if (solution_is_send) { | ||
| record_packet_passed(); |
There was a problem hiding this comment.
Перенесите в область после rte_eth_tx_burst -- иначе, если не отправится, то расхождение статистики будет
плюс еще важно было бы проверять, сколько пакетов де-факто отправилось, если я доку правильно понял, то функция как раз это и возвращает -> полезно это куда-то принимать и как-то анализировать
https://doc.dpdk.org/api/rte__ethdev_8h.html#a83e56cabbd31637efd648e3fc010392b
| #ifndef WORKER_HPP | ||
| #define WORKER_HPP | ||
|
|
||
| #include "metrics_collector.hpp" |
There was a problem hiding this comment.
линтер ругается поправьте
|
|
||
| for (int i = 0; i < nb_rx; i++) { | ||
|
|
||
| record_packet_received(); |
There was a problem hiding this comment.
вы тут считает пакет, а дальше идут логические ветки, которые ловят ошибки, например, Failed to search a key-value pair in the hash table -- а у вас такой пакет уже посчитан и пакет не считается ни passed, ни dropped
из-за этого ломается концепция метрик, что мы считаем:
received != passed + dropped -- нужно везде добавить такую обработку, чтобы расхождения не было, например добавлять
record_packet_droped(); и rte_pktmbuf_free(pkts[i]);
|
|
||
| bool Worker::classify(const std::string &type, const std::string &target, | ||
| struct requested_classification *out_req) { | ||
| RecordTaskStart(); |
There was a problem hiding this comment.
у вас в classify вызываются RecordTaskStart и RecordTaskEnd, которые принудительно пушат метрики, а если я правильно понимаю, то классифкация запускается при миссе кэша.
что получаем -- что каждый мисс кэша генерирует 2 синхронные операции, что ломает концепт двух слоев -- горячего (пайплайн обработки) и холодного (фоновая выгрузка метрик)
я бы убрал принудительный синхронный пуш из RecordTaskStart и RecordTaskEnd
| void IncrementPacketsReceived(int count = 1); | ||
| void IncrementPacketsPassed(int count = 1); | ||
| void IncrementPacketsDropped(const std::string &reason, int count = 1); | ||
| void IncrementBlockedDomain(const std::string &domain_or_ip); |
There was a problem hiding this comment.
где реализация?
Если забыли -- допишите
Если нет ее (почему?) -- то уберите объявление
|
|
||
| void GetCPUUsage(); | ||
| void MainLoop(); | ||
| prometheus::Histogram *metrics_collection_duration; |
There was a problem hiding this comment.
поле объявлено и не используется
| PushMetrics(); | ||
| } | ||
|
|
||
| void MetricsCollector::ObserveCollectionDuration(double seconds) { |
There was a problem hiding this comment.
какой совместимости?
Выглядит как велосипед какой-то...
Если нам он не нужен, то уберите, или реализуйте логику, в которой он используется...
| } | ||
| } | ||
|
|
||
| void MetricsCollector::IncrementPacketsDropped(const std::string &reason, |
There was a problem hiding this comment.
reason не используется нигде и никак -- почему?
так не должно быть, у нас конракты какие-то ненадежные
| } | ||
| } | ||
|
|
||
| void Worker::statsReport() { |
There was a problem hiding this comment.
почему эта функция все еще есть???
Посмотрите по контрактам что функция делает -- она шлет пустые метрики
тем более мы же отошли от схемы воркер->контроллер->метрики , чтобы не делать ботлнек из контроллера, а у вас это как раз эта схема сейчас
у вас в controller\pkg\proto\communication\communication.proto контракт:
message StatsReport {
uint64 worker_id = 1;
uint64 time = 2;
uint64 total_blocked = 3;
uint64 total_allowed = 4;
repeated ResourceStats resources = 5;
}
вы заполняете
report.set_worker_id(worker_id);
report.set_time(time(nullptr));
т.е. функция делает примерно следующее "я воркер, вот время" -- итого:
- полезной нагрузки 0
- эксплуатирует старую концепцию взаимодействия по метрикам воркера и контроллера
- в Worker::MainLoop вы дергаете этот метод, а зачем???
Зачем оно все еще в коде и все еще вызывается??????
|
Линтер поправьте |
|
Не исправлена IP ветка обработки пакета -- аналогично #163 (comment) |
| uint64_t dropped = local_packets_dropped.exchange(0); | ||
|
|
||
| if (received > 0) | ||
| metrics_collector_->IncrementPacketsReceived(received); |
There was a problem hiding this comment.
передаете тип uint64_t , а принимаете int в metrics_collector.hpp и metrics_collector.cpp
There was a problem hiding this comment.
сделайте везде uint64_t
|
|
||
| std::unordered_map<std::string, CPUInfo> cpu_usage; | ||
| prometheus::Gauge *memory_used_gauge; | ||
| prometheus::Gauge *task_processing_time_gauge; |
There was a problem hiding this comment.
вы с этими полями не работаете, как я понимаю -- это легаси какое-то, нужно убрать
tasks_completed_counter
tasks_completed_counter
std::atomic is_task_running{false};
std::chrono::time_pointstd::chrono::high_resolution_clock task_start;
| std::atomic<uint64_t> local_packets_dropped{0}; | ||
|
|
||
| std::chrono::steady_clock::time_point last_metrics_push_time; | ||
| const int METRICS_PUSH_INTERVAL_SEC = 5; |
There was a problem hiding this comment.
мы же отошли от кривого нейминга, когда у нас push назван, а идейно это не push
|
|
||
| extern void record_packet_received(); | ||
| extern void record_packet_passed(); | ||
| extern void record_packet_droped(); |
There was a problem hiding this comment.
record_packet_droped -> record_packet_dropped
|
@KonstantinKondratenko проверьте поправки |
No description provided.