diff --git a/autolib/build.sh b/autolib/build.sh index 42ec7de..19eb5eb 100644 --- a/autolib/build.sh +++ b/autolib/build.sh @@ -19,7 +19,7 @@ autolib_build() { pushd ${lib}/build > /dev/null || return $? autolib_output_banner "${lib}: CMake Build Stage" # YOU MUST set TEST to 1 in order to build the tests - TEST=$build_test cmake -v .. || { + TEST=$build_test cmake --log-level=VERBOSE .. || { autolib_output_error "${lib}: CMake Failure" return 1 } @@ -29,4 +29,4 @@ autolib_build() { return 1 } popd > /dev/null || return $? -} \ No newline at end of file +} diff --git a/prom/CMakeLists.txt b/prom/CMakeLists.txt index 6ed20b6..41665c0 100644 --- a/prom/CMakeLists.txt +++ b/prom/CMakeLists.txt @@ -120,7 +120,11 @@ target_sources( PRIVATE ${private_files} ) -target_link_libraries(prom PUBLIC Threads::Threads) +if(UNIX AND NOT APPLE) + target_link_libraries(prom PUBLIC Threads::Threads -latomic) +else() + target_link_libraries(prom PUBLIC Threads::Threads ) +endif() if ($ENV{TEST}) include(test/CMakeLists.txt) diff --git a/prom/include/prom_counter.h b/prom/include/prom_counter.h index cd3d20a..6fff563 100644 --- a/prom/include/prom_counter.h +++ b/prom/include/prom_counter.h @@ -100,4 +100,23 @@ int prom_counter_inc(prom_counter_t *self, const char **label_values); */ int prom_counter_add(prom_counter_t *self, double r_value, const char **label_values); +/** + * @brief Set the value to the prom_counter_t*. A non-zero integer value will be returned on failure. + * @param self The target prom_counter_t* + * @param r_value The double to set to the prom_counter_t passed as self. The value MUST be greater than or equal to 0. + * @param label_values The label values associated with the metric sample being updated. The number of labels must + * match the value passed to label_key_count in the counter's constructor. If no label values are + * necessary, pass NULL. Otherwise, It may be convenient to pass this value as a literal. + * @return A non-zero integer value upon failure. + * + * *Example* + * + * // An example with labels + * prom_counter_set(foo_counter, 22, (const char**) { "bar", "bang" }); + * + * // An example without labels + * prom_counter_set(foo_counter, 22, NULL); + */ +int prom_counter_set(prom_counter_t *self, double r_value, const char **label_values); + #endif // PROM_COUNTER_H diff --git a/prom/src/prom_counter.c b/prom/src/prom_counter.c index 01dc438..1977522 100644 --- a/prom/src/prom_counter.c +++ b/prom/src/prom_counter.c @@ -64,3 +64,15 @@ int prom_counter_add(prom_counter_t *self, double r_value, const char **label_va if (sample == NULL) return 1; return prom_metric_sample_add(sample, r_value); } + +int prom_counter_set(prom_counter_t *self, double r_value, const char **label_values) { + PROM_ASSERT(self != NULL); + if (self == NULL) return 1; + if (self->type != PROM_COUNTER) { + PROM_LOG(PROM_METRIC_INCORRECT_TYPE); + return 1; + } + prom_metric_sample_t *sample = prom_metric_sample_from_labels(self, label_values); + if (sample == NULL) return 1; + return prom_metric_sample_set(sample, r_value); +} diff --git a/prom/src/prom_metric_sample.c b/prom/src/prom_metric_sample.c index 6862548..6a2e171 100644 --- a/prom/src/prom_metric_sample.c +++ b/prom/src/prom_metric_sample.c @@ -63,7 +63,7 @@ int prom_metric_sample_add(prom_metric_sample_t *self, double r_value) { if (r_value < 0) { return 1; } - _Atomic double old = atomic_load(&self->r_value); + double old = atomic_load(&self->r_value); for (;;) { _Atomic double new = ATOMIC_VAR_INIT(old + r_value); if (atomic_compare_exchange_weak(&self->r_value, &old, new)) { @@ -78,7 +78,7 @@ int prom_metric_sample_sub(prom_metric_sample_t *self, double r_value) { PROM_LOG(PROM_METRIC_INCORRECT_TYPE); return 1; } - _Atomic double old = atomic_load(&self->r_value); + double old = atomic_load(&self->r_value); for (;;) { _Atomic double new = ATOMIC_VAR_INIT(old - r_value); if (atomic_compare_exchange_weak(&self->r_value, &old, new)) { @@ -88,10 +88,11 @@ int prom_metric_sample_sub(prom_metric_sample_t *self, double r_value) { } int prom_metric_sample_set(prom_metric_sample_t *self, double r_value) { - if (self->type != PROM_GAUGE) { + if ((self->type == PROM_COUNTER) && (r_value < self->r_value)) { PROM_LOG(PROM_METRIC_INCORRECT_TYPE); return 1; } + atomic_store(&self->r_value, r_value); return 0; } diff --git a/promhttp/include/promhttp.h b/promhttp/include/promhttp.h index fc47523..91ac040 100644 --- a/promhttp/include/promhttp.h +++ b/promhttp/include/promhttp.h @@ -36,6 +36,16 @@ */ void promhttp_set_active_collector_registry(prom_collector_registry_t *active_registry); +#if MHD_VERSION >= 0x00097002 +#define PROM_MHD_RESULT enum MHD_Result +#else +#define PROM_MHD_RESULT int +#endif + +PROM_MHD_RESULT promhttp_handler(void *cls, struct MHD_Connection *connection, const char *url, const char *method, + const char *version, const char *upload_data, size_t *upload_data_size, void **con_cls); + + /** * @brief Starts a daemon in the background and returns a pointer to an HMD_Daemon. * diff --git a/promhttp/src/promhttp.c b/promhttp/src/promhttp.c index d94a53e..9a1327a 100644 --- a/promhttp/src/promhttp.c +++ b/promhttp/src/promhttp.c @@ -18,6 +18,7 @@ #include "microhttpd.h" #include "prom.h" +#include "promhttp.h" prom_collector_registry_t *PROM_ACTIVE_REGISTRY; @@ -29,7 +30,7 @@ void promhttp_set_active_collector_registry(prom_collector_registry_t *active_re } } -int promhttp_handler(void *cls, struct MHD_Connection *connection, const char *url, const char *method, +PROM_MHD_RESULT promhttp_handler(void *cls, struct MHD_Connection *connection, const char *url, const char *method, const char *version, const char *upload_data, size_t *upload_data_size, void **con_cls) { if (strcmp(method, "GET") != 0) { char *buf = "Invalid HTTP Method\n";