Line data Source code
1 : /* Copyright (c) 2020-2021, The Tor Project, Inc. */ 2 : /* See LICENSE for licensing information */ 3 : 4 : /** 5 : * @file metrics_store_entry.c 6 : * @brief Metrics store entry which contains the gathered data. 7 : **/ 8 : 9 : #define METRICS_STORE_ENTRY_PRIVATE 10 : 11 : #include <string.h> 12 : 13 : #include "orconfig.h" 14 : 15 : #include "lib/container/smartlist.h" 16 : #include "lib/log/util_bug.h" 17 : #include "lib/malloc/malloc.h" 18 : 19 : #include "lib/metrics/metrics_store_entry.h" 20 : 21 : /* 22 : * Public API. 23 : */ 24 : 25 : /** Return newly allocated store entry of type COUNTER. */ 26 : metrics_store_entry_t * 27 309 : metrics_store_entry_new(const metrics_type_t type, const char *name, 28 : const char *help) 29 : { 30 309 : metrics_store_entry_t *entry = tor_malloc_zero(sizeof(*entry)); 31 : 32 309 : tor_assert(name); 33 : 34 309 : entry->type = type; 35 309 : entry->name = tor_strdup(name); 36 309 : entry->labels = smartlist_new(); 37 309 : if (help) { 38 309 : entry->help = tor_strdup(help); 39 : } 40 : 41 309 : return entry; 42 : } 43 : 44 : /** Free a store entry. */ 45 : void 46 249 : metrics_store_entry_free_(metrics_store_entry_t *entry) 47 : { 48 249 : if (!entry) { 49 : return; 50 : } 51 512 : SMARTLIST_FOREACH(entry->labels, char *, l, tor_free(l)); 52 249 : smartlist_free(entry->labels); 53 249 : tor_free(entry->name); 54 249 : tor_free(entry->help); 55 249 : tor_free(entry); 56 : } 57 : 58 : /** Update a store entry with value. */ 59 : void 60 60 : metrics_store_entry_update(metrics_store_entry_t *entry, const int64_t value) 61 : { 62 60 : tor_assert(entry); 63 : 64 60 : switch (entry->type) { 65 56 : case METRICS_TYPE_COUNTER: 66 : /* Counter can ONLY be positive. */ 67 56 : if (BUG(value < 0)) { 68 0 : return; 69 : } 70 56 : entry->u.counter.value += value; 71 56 : break; 72 4 : case METRICS_TYPE_GAUGE: 73 : /* Gauge can increment or decrement. And can be positive or negative. */ 74 4 : entry->u.gauge.value += value; 75 4 : break; 76 : } 77 : } 78 : 79 : /** Reset a store entry that is set its metric data to 0. */ 80 : void 81 1 : metrics_store_entry_reset(metrics_store_entry_t *entry) 82 : { 83 1 : tor_assert(entry); 84 : /* Everything back to 0. */ 85 1 : memset(&entry->u, 0, sizeof(entry->u)); 86 1 : } 87 : 88 : /** Return store entry value. */ 89 : int64_t 90 60 : metrics_store_entry_get_value(const metrics_store_entry_t *entry) 91 : { 92 60 : tor_assert(entry); 93 : 94 60 : switch (entry->type) { 95 58 : case METRICS_TYPE_COUNTER: 96 58 : if (entry->u.counter.value > INT64_MAX) { 97 0 : return INT64_MAX; 98 : } 99 : return entry->u.counter.value; 100 2 : case METRICS_TYPE_GAUGE: 101 2 : return entry->u.gauge.value; 102 : } 103 : 104 : // LCOV_EXCL_START 105 : tor_assert_unreached(); 106 : // LCOV_EXCL_STOP 107 : } 108 : 109 : /** Add a label into the given entry.*/ 110 : void 111 365 : metrics_store_entry_add_label(metrics_store_entry_t *entry, 112 : const char *label) 113 : { 114 365 : tor_assert(entry); 115 365 : tor_assert(label); 116 : 117 365 : smartlist_add(entry->labels, tor_strdup(label)); 118 365 : } 119 : 120 : /** Return true iff the given entry has the given label. */ 121 : bool 122 1 : metrics_store_entry_has_label(const metrics_store_entry_t *entry, 123 : const char *label) 124 : { 125 1 : tor_assert(entry); 126 1 : tor_assert(label); 127 : 128 1 : return smartlist_contains_string(entry->labels, label); 129 : }