summaryrefslogtreecommitdiff
path: root/src/lib/metrics/metrics_store_entry.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/metrics/metrics_store_entry.c')
-rw-r--r--src/lib/metrics/metrics_store_entry.c129
1 files changed, 129 insertions, 0 deletions
diff --git a/src/lib/metrics/metrics_store_entry.c b/src/lib/metrics/metrics_store_entry.c
new file mode 100644
index 0000000000..44ebb5cb84
--- /dev/null
+++ b/src/lib/metrics/metrics_store_entry.c
@@ -0,0 +1,129 @@
+/* Copyright (c) 2020, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * @file metrics_store_entry.c
+ * @brief Metrics store entry which contains the gathered data.
+ **/
+
+#define METRICS_STORE_ENTRY_PRIVATE
+
+#include <string.h>
+
+#include "orconfig.h"
+
+#include "lib/container/smartlist.h"
+#include "lib/log/util_bug.h"
+#include "lib/malloc/malloc.h"
+
+#include "lib/metrics/metrics_store_entry.h"
+
+/*
+ * Public API.
+ */
+
+/** Return newly allocated store entry of type COUNTER. */
+metrics_store_entry_t *
+metrics_store_entry_new(const metrics_type_t type, const char *name,
+ const char *help)
+{
+ metrics_store_entry_t *entry = tor_malloc_zero(sizeof(*entry));
+
+ tor_assert(name);
+
+ entry->type = type;
+ entry->name = tor_strdup(name);
+ entry->labels = smartlist_new();
+ if (help) {
+ entry->help = tor_strdup(help);
+ }
+
+ return entry;
+}
+
+/** Free a store entry. */
+void
+metrics_store_entry_free_(metrics_store_entry_t *entry)
+{
+ if (!entry) {
+ return;
+ }
+ SMARTLIST_FOREACH(entry->labels, char *, l, tor_free(l));
+ smartlist_free(entry->labels);
+ tor_free(entry->name);
+ tor_free(entry->help);
+ tor_free(entry);
+}
+
+/** Update a store entry with value. */
+void
+metrics_store_entry_update(metrics_store_entry_t *entry, const int64_t value)
+{
+ tor_assert(entry);
+
+ switch (entry->type) {
+ case METRICS_TYPE_COUNTER:
+ /* Counter can ONLY be positive. */
+ if (BUG(value < 0)) {
+ return;
+ }
+ entry->u.counter.value += value;
+ break;
+ case METRICS_TYPE_GAUGE:
+ /* Gauge can increment or decrement. And can be positive or negative. */
+ entry->u.gauge.value += value;
+ break;
+ }
+}
+
+/** Reset a store entry that is set its metric data to 0. */
+void
+metrics_store_entry_reset(metrics_store_entry_t *entry)
+{
+ tor_assert(entry);
+ /* Everything back to 0. */
+ memset(&entry->u, 0, sizeof(entry->u));
+}
+
+/** Return store entry value. */
+int64_t
+metrics_store_entry_get_value(const metrics_store_entry_t *entry)
+{
+ tor_assert(entry);
+
+ switch (entry->type) {
+ case METRICS_TYPE_COUNTER:
+ if (entry->u.counter.value > INT64_MAX) {
+ return INT64_MAX;
+ }
+ return entry->u.counter.value;
+ case METRICS_TYPE_GAUGE:
+ return entry->u.gauge.value;
+ }
+
+ // LCOV_EXCL_START
+ tor_assert_unreached();
+ // LCOV_EXCL_STOP
+}
+
+/** Add a label into the given entry.*/
+void
+metrics_store_entry_add_label(metrics_store_entry_t *entry,
+ const char *label)
+{
+ tor_assert(entry);
+ tor_assert(label);
+
+ smartlist_add(entry->labels, tor_strdup(label));
+}
+
+/** Return true iff the given entry has the given label. */
+bool
+metrics_store_entry_has_label(const metrics_store_entry_t *entry,
+ const char *label)
+{
+ tor_assert(entry);
+ tor_assert(label);
+
+ return smartlist_contains_string(entry->labels, label);
+}