Tor 0.4.9.0-alpha-dev
metrics_store.c
Go to the documentation of this file.
1/* Copyright (c) 2020-2021, The Tor Project, Inc. */
2/* See LICENSE for licensing information */
3
4/**
5 * @file metrics_store.c
6 * @brief Metrics interface to store them based on specific store type and get
7 * their MetricsPort output.
8 **/
9
10#define METRICS_STORE_ENTRY_PRIVATE
11
12#include "orconfig.h"
13
14#include "lib/container/map.h"
15#include "lib/log/util_bug.h"
16#include "lib/malloc/malloc.h"
17
20
21/* Format Drivers. */
23
24/** A metric store which contains a map of entries. */
26 /** Indexed by metrics entry name. An entry is a smartlist_t of one or more
27 * metrics_store_entry_t allowing for multiple metrics of the same name.
28 *
29 * The reason we allow multiple entries is because there are cases where one
30 * metrics can be used twice by the same entity but with different labels.
31 * One example is an onion service with multiple ports, the port specific
32 * metrics will have a port value as a label. */
33 strmap_t *entries;
34};
35
36/** Function pointer to the format function of a specific driver. */
37typedef void (fmt_driver_fn_t)(const metrics_store_entry_t *, buf_t *,
38 bool no_comment);
39
40/** Helper: Free a single entry in a metrics_store_t taking a void pointer
41 * parameter. */
42static void
44{
45 smartlist_t *list = p;
46 SMARTLIST_FOREACH(list, metrics_store_entry_t *, entry,
47 metrics_store_entry_free(entry));
48 smartlist_free(list);
49}
50
51#include <stdio.h>
52
53/** Put the given store output in the buffer data and use the format function
54 * given in fmt to get it for each entry. */
55static void
56get_output(const metrics_store_t *store, buf_t *data, fmt_driver_fn_t fmt)
57{
58 tor_assert(store);
59 tor_assert(data);
60 tor_assert(fmt);
61
62 STRMAP_FOREACH(store->entries, key, const smartlist_t *, entries) {
63 /* Indicate that we've formatted the comment already for the entries. */
64 bool comment_formatted = false;
65 SMARTLIST_FOREACH_BEGIN(entries, const metrics_store_entry_t *, entry) {
66 fmt(entry, data, comment_formatted);
67 comment_formatted = true;
68 } SMARTLIST_FOREACH_END(entry);
69 } STRMAP_FOREACH_END;
70}
71
72/** Return a newly allocated and initialized store of the given type. */
75{
76 metrics_store_t *store = tor_malloc_zero(sizeof(*store));
77
78 store->entries = strmap_new();
79
80 return store;
81}
82
83/** Free the given store including all its entries. */
84void
86{
87 if (store == NULL) {
88 return;
89 }
90
91 strmap_free(store->entries, metrics_store_free_void);
92 tor_free(store);
93}
94
95/** Find all metrics entry in the given store identified by name. If not found,
96 * NULL is returned. */
98metrics_store_get_all(const metrics_store_t *store, const char *name)
99{
100 tor_assert(store);
102
103 return strmap_get(store->entries, name);
104}
105
106/** Add a new metrics entry to the given store and type. The name MUST be the
107 * unique identifier. The help string can be omitted. */
108metrics_store_entry_t *
110 const char *name, const char *help, size_t bucket_count,
111 const int64_t *buckets)
112
113{
114 smartlist_t *entries;
115 metrics_store_entry_t *entry;
116
117 tor_assert(store);
119
120 entries = metrics_store_get_all(store, name);
121 if (!entries) {
122 entries = smartlist_new();
123 strmap_set(store->entries, name, entries);
124 }
125 entry = metrics_store_entry_new(type, name, help, bucket_count, buckets);
126 smartlist_add(entries, entry);
127
128 return entry;
129}
130
131/** Set the output of the given store of the format fmt into the given buffer
132 * data. */
133void
135 const metrics_store_t *store, buf_t *data)
136{
137 tor_assert(store);
138
139 switch (fmt) {
142 break;
143 default:
144 // LCOV_EXCL_START
145 tor_assert_unreached();
146 // LCOV_EXCL_STOP
147 }
148}
149
150/** Reset a store as in free its content. */
151void
153{
154 if (store == NULL) {
155 return;
156 }
157 strmap_free(store->entries, metrics_store_free_void);
158 store->entries = strmap_new();
159}
const char * name
Definition: config.c:2462
Headers for util_malloc.c.
#define tor_free(p)
Definition: malloc.h:56
Headers for map.c.
metrics_type_t
metrics_format_t
@ METRICS_FORMAT_PROMETHEUS
void metrics_store_free_(metrics_store_t *store)
Definition: metrics_store.c:85
static void get_output(const metrics_store_t *store, buf_t *data, fmt_driver_fn_t fmt)
Definition: metrics_store.c:56
metrics_store_t * metrics_store_new(void)
Definition: metrics_store.c:74
void metrics_store_get_output(const metrics_format_t fmt, const metrics_store_t *store, buf_t *data)
smartlist_t * metrics_store_get_all(const metrics_store_t *store, const char *name)
Definition: metrics_store.c:98
metrics_store_entry_t * metrics_store_add(metrics_store_t *store, metrics_type_t type, const char *name, const char *help, size_t bucket_count, const int64_t *buckets)
void() fmt_driver_fn_t(const metrics_store_entry_t *, buf_t *, bool no_comment)
Definition: metrics_store.c:37
static void metrics_store_free_void(void *p)
Definition: metrics_store.c:43
void metrics_store_reset(metrics_store_t *store)
Header for lib/metrics/metrics_store.c.
metrics_store_entry_t * metrics_store_entry_new(const metrics_type_t type, const char *name, const char *help, size_t bucket_count, const int64_t *buckets)
Header for lib/metrics/metrics_store_entry.c.
void prometheus_format_store_entry(const metrics_store_entry_t *entry, buf_t *data, bool no_comment)
Definition: prometheus.c:88
Header for feature/metrics/prometheus.c.
smartlist_t * smartlist_new(void)
void smartlist_add(smartlist_t *sl, void *element)
#define SMARTLIST_FOREACH_BEGIN(sl, type, var)
#define SMARTLIST_FOREACH(sl, type, var, cmd)
strmap_t * entries
Definition: metrics_store.c:33
Macros to manage assertions, fatal and non-fatal.
#define tor_assert(expr)
Definition: util_bug.h:103