Utilisation de prometheus-cpp-dev

This commit is contained in:
2025-12-03 23:20:46 +01:00
parent 3b9d229559
commit 8c23e6b8f9
6 changed files with 170 additions and 77 deletions

View File

@@ -12,17 +12,22 @@ RUN set -eux; \
apt-get update; \ apt-get update; \
apt-get install -y \ apt-get install -y \
libncurses-dev \ libncurses-dev \
libmicrohttpd-dev;\ libmicrohttpd-dev \
apt-get clean libcurl4-openssl-dev \
zlib1g-dev \
prometheus-cpp-dev
RUN set -eux; \ RUN set -eux; \
git clone https://github.com/jelmd/libprom.git; \ apt-get update; \
cd libprom; \ apt-get install -y \
make build; \ libpaho-mqtt-dev
cd prom/build; \
make install; \ RUN set -eux; \
cd ../../promhttp/build; \ apt-get update; \
make install; apt-get install -y \
librabbitmq4 \
librabbitmq-dev;\
apt-get clean
WORKDIR /root WORKDIR /root

2
.gitignore vendored
View File

@@ -1 +1 @@
/output/ /build/

26
.vscode/launch.json vendored Normal file
View File

@@ -0,0 +1,26 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug geii_exporter",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/build/geii_exporter",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "Activer les pretty-printers pour gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
],
"preLaunchTask": "CMake: build"
}
]
}

38
.vscode/tasks.json vendored
View File

@@ -1,33 +1,21 @@
{ {
"version": "2.0.0",
"tasks": [ "tasks": [
{ {
"type": "cppbuild", "label": "CMake: build",
"label": "C/C++: gcc build active file", "type": "shell",
"command": "/usr/bin/gcc", "command": "cmake --build build --config Debug",
"args": [
"-fdiagnostics-color=always",
"-g",
"${workspaceFolder}${pathSeparator}main.cpp",
"-lm",
"-lncursesw",
"-lprom",
"-lpromhttp",
"-lmicrohttpd",
"-o",
"${fileDirname}/${fileBasenameNoExtension}"
],
"options": {
"cwd": "${fileDirname}"
},
"problemMatcher": [
"$gcc"
],
"group": { "group": {
"kind": "build", "kind": "build",
"isDefault": true "isDefault": true
}, },
"detail": "Task generated by Debugger." "problemMatcher": ["$gcc"]
},
{
"label": "CMake: configure",
"type": "shell",
"command": "cmake -S . -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=ON",
"problemMatcher": ["$gcc"]
} }
], ]
"version": "2.0.0" }
}

57
CMakeLists.txt Normal file
View File

@@ -0,0 +1,57 @@
cmake_minimum_required(VERSION 3.15)
project(geii_exporter LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
# Activer warnings utiles
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wpedantic")
# Executable principal
add_executable(geii_exporter
main.cpp
)
# -------------------------------
# Librairies systèmes
# -------------------------------
# CURL
find_package(CURL REQUIRED)
# Microhttpd
find_library(MICROHTTPD_LIB microhttpd REQUIRED)
# Threads et compression
find_package(Threads REQUIRED)
find_library(Z_LIB z REQUIRED)
# ncursesw
find_library(NCURSESW_LIB ncursesw REQUIRED)
# RabbitMQ C client
find_library(RABBITMQ_LIB rabbitmq REQUIRED)
# Paho MQTT C client
find_library(PAHO_MQTT3C_LIB paho-mqtt3c REQUIRED)
# -------------------------------
# Prometheus C++
# -------------------------------
find_package(prometheus-cpp REQUIRED)
# -------------------------------
# Lien des bibliothèques
# -------------------------------
target_link_libraries(geii_exporter
prometheus-cpp::core
prometheus-cpp::pull
${CURL_LIBRARIES}
${MICROHTTPD_LIB}
Threads::Threads
${Z_LIB}
${NCURSESW_LIB}
${RABBITMQ_LIB}
${PAHO_MQTT3C_LIB}
)

101
main.cpp
View File

@@ -6,10 +6,10 @@
#include "main.h" #include "main.h"
#include "AutomForArduino.cpp" #include "AutomForArduino.cpp"
extern "C" { #include <prometheus/counter.h>
#include "libprom/prom.h" #include <prometheus/gauge.h>
#include "libprom/promhttp.h" #include <prometheus/registry.h>
} #include <prometheus/exposer.h>
// Constantes de fonctionnement // Constantes de fonctionnement
#define LEVEL_MIN 2 #define LEVEL_MIN 2
@@ -34,14 +34,15 @@ TemporisationRetardMontee tempo4(2000);
// Prometheus // Prometheus
// ************************************************************ // ************************************************************
struct MHD_Daemon *server; using namespace prometheus;
prom_counter_t *pm_pompe; std::shared_ptr<Registry> registry;
prom_gauge_t *pm_debit; Gauge* debit_entree = nullptr;
Gauge* debit_sortie = nullptr;
// ************************************************************ // ************************************************************
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
/* Initialisation */ /* Initialisation */
ConsoleInit(); ConsoleInit();
AffichageWindow(); AffichageWindow();
@@ -56,10 +57,10 @@ int main(int argc, char *argv[])
int ch = getch(); // Lit l'entrée du clavier sans bloquer int ch = getch(); // Lit l'entrée du clavier sans bloquer
// **** Break loop if escape key (27) is pressed // **** Break loop if escape key (27) is pressed
if (ch == 27 || _digital[OUT_END].ivalue) { if (ch == 27 || _digital[OUT_END].ivalue) {
break; break;
} }
// **** Beep // **** Beep
if (_digital[OUT_BEEP].ivalue) if (_digital[OUT_BEEP].ivalue)
{ {
@@ -75,7 +76,7 @@ int main(int argc, char *argv[])
Actions(); Actions();
ProcessPrometheus(); ProcessPrometheus();
ProcessException(); ProcessException();
usleep(100000); usleep(100000);
@@ -83,8 +84,7 @@ int main(int argc, char *argv[])
endwin(); // Termine ncurses et rétablit le terminal endwin(); // Termine ncurses et rétablit le terminal
puts("Fin du programme"); puts("Fin du programme");
pcr_destroy(PROM_COLLECTOR_REGISTRY);
promhttp_stop_daemon(server);
return 0; return 0;
} }
@@ -406,7 +406,7 @@ void ProcessInitValues()
/** /**
* Fonctionnement des moteurs * Fonctionnement des moteurs
*/ */
double ProcessMoteur(int i) double ProcessMoteur(int i)
{ {
double vitesse = 1.0; double vitesse = 1.0;
double t = _digital[i].time / 5000.0; double t = _digital[i].time / 5000.0;
@@ -567,14 +567,14 @@ void Process()
t_backup = t; t_backup = t;
} }
double SimulConsoSinusoidale(long t) double SimulConsoSinusoidale(long t)
{ {
double alea = ((long)(t / 100.0) % 600) * 3 / 1800.0 * PI; double alea = ((long)(t / 100.0) % 600) * 3 / 1800.0 * PI;
//mvprintw(18, 0, "%ld %f", (long)(t / 100.0), alea); //mvprintw(18, 0, "%ld %f", (long)(t / 100.0), alea);
return 100 + cos(alea) * cos(alea) * _digital[OUT_FLOW_OUT_AMPLITUDE].dvalue; return 100 + cos(alea) * cos(alea) * _digital[OUT_FLOW_OUT_AMPLITUDE].dvalue;
} }
// dt : Intervalle de temps // dt : Intervalle de temps
double SimulConsoBrown(double valeur_precedente) double SimulConsoBrown(double valeur_precedente)
{ {
float mu = 0.01 * -((((int)t_elapsed / 30) % 2) * 2 - 1); // Taux de croissance (1%) float mu = 0.01 * -((((int)t_elapsed / 30) % 2) * 2 - 1); // Taux de croissance (1%)
@@ -583,8 +583,8 @@ double SimulConsoBrown(double valeur_precedente)
mvprintw(8, 40, "(µ %.1f %% ; σ %.1f %%) ", mu * 100, sigma * 100); mvprintw(8, 40, "(µ %.1f %% ; σ %.1f %%) ", mu * 100, sigma * 100);
// Nombre aléatoire compris dans [-1 +1] // Nombre aléatoire compris dans [-1 +1]
float rand_std_normal = ((double)rand() / RAND_MAX) * 2.0 - 1.0; float rand_std_normal = ((double)rand() / RAND_MAX) * 2.0 - 1.0;
// Calcule la variation logarithmique pour cette étape // Calcule la variation logarithmique pour cette étape
float drift = (mu - 0.5f * sigma * sigma) * dt; float drift = (mu - 0.5f * sigma * sigma) * dt;
float diffusion = sigma * sqrt(dt) * rand_std_normal; float diffusion = sigma * sqrt(dt) * rand_std_normal;
@@ -597,23 +597,23 @@ double SimulConsoBrown(double valeur_precedente)
*/ */
/** /**
* Initialisation, affichage des parties statiques * Initialisation, affichage des parties statiques
*/ */
void AffichageWindow() void AffichageWindow()
{ {
window = subwin(stdscr, 19, 62, 0, 0); window = subwin(stdscr, 19, 62, 0, 0);
box(window, 0, 0); box(window, 0, 0);
// Titre // Titre
mvwprintw(window, 1, 2, "Château d'eau (11/2024)"); mvwprintw(window, 1, 2, "Château d'eau (11/2024)");
// I/O // I/O
// Ligne du haut // Ligne du haut
mvwaddch(window, 2, 0, ACS_LTEE); mvwaddch(window, 2, 0, ACS_LTEE);
mvwhline(window, 2, 1, 0, 60); mvwhline(window, 2, 1, 0, 60);
mvwaddch(window, 2, 61, ACS_RTEE); mvwaddch(window, 2, 61, ACS_RTEE);
// Ligne du bas // Ligne du bas
mvwaddch(window, 7, 0, ACS_LTEE); mvwaddch(window, 7, 0, ACS_LTEE);
mvwhline(window, 7, 1, 0, 60); mvwhline(window, 7, 1, 0, 60);
@@ -640,14 +640,14 @@ void AffichageWindow()
mvwprintw(window, 8, 2, "Debit en sortie"); mvwprintw(window, 8, 2, "Debit en sortie");
mvwprintw(window, 9, 2, "Debit en entrée"); mvwprintw(window, 9, 2, "Debit en entrée");
mvwprintw(window, 10, 2, "Volume dans le réservoir"); mvwprintw(window, 10, 2, "Volume dans le réservoir");
// Graphe // Graphe
// Ligne du haut // Ligne du haut
mvwaddch(window, 11, 0, ACS_LTEE); mvwaddch(window, 11, 0, ACS_LTEE);
mvwhline(window, 11, 1, 0, 60); mvwhline(window, 11, 1, 0, 60);
mvwaddch(window, 11, 61, ACS_RTEE); mvwaddch(window, 11, 61, ACS_RTEE);
// Ligne du bas // Ligne du bas
mvwaddch(window, 13, 0, ACS_LTEE); mvwaddch(window, 13, 0, ACS_LTEE);
mvwhline(window, 13, 1, 0, 60); mvwhline(window, 13, 1, 0, 60);
@@ -670,14 +670,14 @@ void AffichageWindow()
mvwaddch(window, 16, 0, ACS_LTEE); mvwaddch(window, 16, 0, ACS_LTEE);
mvwhline(window, 16, 1, 0, 60); mvwhline(window, 16, 1, 0, 60);
mvwaddch(window, 16, 61, ACS_RTEE); mvwaddch(window, 16, 61, ACS_RTEE);
mvwprintw(window, 14, 2 * 6 - 1, "min"); mvwprintw(window, 14, 2 * 6 - 1, "min");
mvwprintw(window, 14, 6 * 6 - 2, "low"); mvwprintw(window, 14, 6 * 6 - 2, "low");
mvwprintw(window, 14, 7 * 6, "high"); mvwprintw(window, 14, 7 * 6, "high");
mvwprintw(window, 14, 56, "max"); mvwprintw(window, 14, 56, "max");
// Informations // Informations
mvwprintw(window, 17, 2, "Mode"); mvwprintw(window, 17, 2, "Mode");
mvwaddch(window, 16, 18, ACS_TTEE); mvwaddch(window, 16, 18, ACS_TTEE);
mvwaddch(window, 18, 18, ACS_BTEE); mvwaddch(window, 18, 18, ACS_BTEE);
@@ -750,50 +750,67 @@ void AffichageGraphe(int y, int x, double value)
for (i = 0; i < entier; i++) for (i = 0; i < entier; i++)
{ {
mvwaddwstr(window, y, x + i, L""); // U+2588 mvwaddwstr(window, y, x + i, L""); // U+2588
} }
int frac = (int)((value - entier) * 4); int frac = (int)((value - entier) * 4);
if (frac > 3) // 0.75 -> 0.99 if (frac > 3) // 0.75 -> 0.99
{ {
mvwaddwstr(window, y, x + i, L""); // U+258A mvwaddwstr(window, y, x + i, L""); // U+258A
entier += 1; entier += 1;
} }
if (frac > 2) // 0.5 -> 0.99 if (frac > 2) // 0.5 -> 0.99
{ {
mvwaddwstr(window, y, x + i, L""); // U+258C mvwaddwstr(window, y, x + i, L""); // U+258C
entier += 1; entier += 1;
} }
else if (frac > 1) // 0.25 -> 0.49 else if (frac > 1) // 0.25 -> 0.49
{ {
mvwaddwstr(window, y, x + i, L""); //U+258E mvwaddwstr(window, y, x + i, L""); //U+258E
entier += 1; entier += 1;
} }
for (int i = entier; i < 59; i++) for (int i = entier; i < 59; i++)
{ {
mvwprintw(window, y, x + i, " "); mvwprintw(window, y, x + i, " ");
} }
} }
/** /**
* Prometheus * Prometheus
*/ */
void InitPrometheus() void InitPrometheus()
{ {
static Exposer exposer{"0.0.0.0:8099"};
// Le registre central
registry = std::make_shared<Registry>();
exposer.RegisterCollectable(registry);
// Exemple : gauge (comme votre debit)
auto& gauge_family = BuildGauge()
.Name("geii_debit")
.Help("Débit en l/s")
.Register(*registry);
debit_entree = &gauge_family.Add({{"numero", "entree"}});
debit_sortie = &gauge_family.Add({{"numero", "sortie"}});
/*
int result = pcr_init(0,"geii_"); int result = pcr_init(0,"geii_");
std::array<const char*, 1> labels = { "numero" }; std::array<const char*, 1> labels = { "numero" };
pm_pompe = prom_counter_new("pompe_on", "Mise en marche de la pompe" pm_pompe = prom_counter_new("pompe_on", "Mise en marche de la pompe"
, labels.size(), labels.data()); , labels.size(), labels.data());
pcr_register_metric(pm_pompe); pcr_register_metric(pm_pompe);
pm_debit = prom_gauge_new("debit", "Débit en l/s" pm_debit = prom_gauge_new("debit", "Débit en l/s"
, labels.size(), labels.data()); , labels.size(), labels.data());
pcr_register_metric(pm_debit); pcr_register_metric(pm_debit);
promhttp_set_active_collector_registry(NULL); promhttp_set_active_collector_registry(NULL);
// Serveur web // Serveur web
server = promhttp_start_daemon(MHD_USE_SELECT_INTERNALLY server = promhttp_start_daemon(MHD_USE_SELECT_INTERNALLY
, 8099, NULL, NULL); , 8099, NULL, NULL);
@@ -802,18 +819,18 @@ void InitPrometheus()
printf("Impossible de démarrer le serveur HTTP\n"); printf("Impossible de démarrer le serveur HTTP\n");
exit(1); exit(1);
} }
*/
} }
void ProcessPrometheus() void ProcessPrometheus()
{ {
// raising = 1 => front montant sur la sortie // raising = 1 => front montant sur la sortie
/*
if (_digital[OUT_PUMP_1].raising) { if (_digital[OUT_PUMP_1].raising) {
std::array<const char*, 1> labels1 = { "1" }; std::array<const char*, 1> labels1 = { "1" };
prom_counter_inc(pm_pompe, labels1.data()); prom_counter_inc(pm_pompe, labels1.data());
} }
*/
std::array<const char*, 1> labels1 = { "sortie" }; debit_entree->Set(_digital[IN_FLOW_OUT].dvalue);
std::array<const char*, 1> labels2 = { "entree" }; debit_sortie->Set(_digital[IN_FLOW_IN].dvalue);
prom_gauge_set(pm_debit, _digital[IN_FLOW_OUT].dvalue, labels1.data());
prom_gauge_set(pm_debit, _digital[IN_FLOW_IN].dvalue, labels2.data());
} }