summaryrefslogtreecommitdiffstats
path: root/src/vlib/stats/stats.h
blob: ef43510b2551b70baa56b67005354aec59a32120 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
/* SPDX-License-Identifier: Apache-2.0
 * Copyright(c) 2022 Cisco Systems, Inc.
 */

#ifndef included_stats_stats_h
#define included_stats_stats_h

#include <vppinfra/socket.h>
#include <vppinfra/lock.h>
#include <vlib/stats/shared.h>

/* Default stat segment 32m */
#define STAT_SEGMENT_DEFAULT_SIZE (32 << 20)

/* Shared segment memory layout version */
#define STAT_SEGMENT_VERSION 2

#define STAT_SEGMENT_INDEX_INVALID UINT32_MAX

typedef enum
{
  STAT_COUNTER_HEARTBEAT = 0,
  STAT_COUNTER_LAST_STATS_CLEAR,
  STAT_COUNTER_NODE_CLOCKS,
  STAT_COUNTER_NODE_VECTORS,
  STAT_COUNTER_NODE_CALLS,
  STAT_COUNTER_NODE_SUSPENDS,
  STAT_COUNTER_NODE_NAMES,
  STAT_COUNTERS
} stat_segment_counter_t;

#define foreach_stat_segment_node_counter_name                                \
  _ (NODE_CLOCKS, COUNTER_VECTOR_SIMPLE, clocks, "/sys/node")                 \
  _ (NODE_VECTORS, COUNTER_VECTOR_SIMPLE, vectors, "/sys/node")               \
  _ (NODE_CALLS, COUNTER_VECTOR_SIMPLE, calls, "/sys/node")                   \
  _ (NODE_SUSPENDS, COUNTER_VECTOR_SIMPLE, suspends, "/sys/node")

#define foreach_stat_segment_counter_name                                     \
  _ (LAST_STATS_CLEAR, SCALAR_INDEX, last_stats_clear, "/sys")                \
  _ (HEARTBEAT, SCALAR_INDEX, heartbeat, "/sys")                              \
  _ (NODE_NAMES, NAME_VECTOR, names, "/sys/node")                             \
  foreach_stat_segment_node_counter_name

typedef struct
{
  u32 entry_index;
  u32 vector_index;
  u64 private_data;
  vlib_stats_entry_t *entry;
} vlib_stats_collector_data_t;

typedef void (*vlib_stats_collector_fn_t) (vlib_stats_collector_data_t *);

typedef struct
{
  vlib_stats_collector_fn_t collect_fn;
  u32 entry_index;
  u32 vector_index;
  u64 private_data;
} vlib_stats_collector_reg_t;

typedef struct
{
  vlib_stats_collector_fn_t fn;
  u32 entry_index;
  u32 vector_index;
  u64 private_data;
} vlib_stats_collector_t;

typedef struct
{
  /* internal, does not point to shared memory */
  vlib_stats_collector_t *collectors;

  /* statistics segment */
  uword *directory_vector_by_name;
  vlib_stats_entry_t *directory_vector;
  u8 **nodes;

  /* Update interval */
  f64 update_interval;

  clib_spinlock_t *stat_segment_lockp;
  u32 locking_thread_index;
  u32 n_locks;
  clib_socket_t *socket;
  u8 *socket_name;
  ssize_t memory_size;
  clib_mem_page_sz_t log2_page_sz;
  u8 node_counters_enabled;
  void *heap;
  vlib_stats_shared_header_t
    *shared_header; /* pointer to shared memory segment */
  int memfd;

} vlib_stats_segment_t;

typedef struct
{
  vlib_stats_segment_t segment;
} vlib_stats_main_t;

extern vlib_stats_main_t vlib_stats_main;

static_always_inline vlib_stats_segment_t *
vlib_stats_get_segment ()
{
  return &vlib_stats_main.segment;
}

static_always_inline vlib_stats_entry_t *
vlib_stats_get_entry (vlib_stats_segment_t *sm, u32 entry_index)
{
  vlib_stats_entry_t *e;
  ASSERT (entry_index < vec_len (sm->directory_vector));
  e = sm->directory_vector + entry_index;
  ASSERT (e->type != STAT_DIR_TYPE_EMPTY && e->type != STAT_DIR_TYPE_ILLEGAL);
  return e;
}

static_always_inline void *
vlib_stats_get_entry_data_pointer (u32 entry_index)
{
  vlib_stats_segment_t *sm = vlib_stats_get_segment ();
  vlib_stats_entry_t *e = vlib_stats_get_entry (sm, entry_index);
  return e->data;
}

clib_error_t *vlib_stats_init (vlib_main_t *vm);
void *vlib_stats_set_heap ();
void vlib_stats_segment_lock (void);
void vlib_stats_segment_unlock (void);
void vlib_stats_register_mem_heap (clib_mem_heap_t *);
f64 vlib_stats_get_segment_update_rate (void);

/* gauge */
u32 vlib_stats_add_gauge (char *fmt, ...);
void vlib_stats_set_gauge (u32 entry_index, u64 value);

/* timestamp */
u32 vlib_stats_add_timestamp (char *fmt, ...);
void vlib_stats_set_timestamp (u32 entry_index, f64 value);

/* counter vector */
u32 vlib_stats_add_counter_vector (char *fmt, ...);

/* counter pair vector */
u32 vlib_stats_add_counter_pair_vector (char *fmt, ...);

/* string vector */
u32 vlib_stats_add_string_vector (char *fmt, ...);
void vlib_stats_set_string_vector (u32 entry_index, u32 vector_index,
				   char *fmt, ...);

/* symlink */
u32 vlib_stats_add_symlink (u32 entry_index, u32 vector_index, char *fmt, ...);
void vlib_stats_rename_symlink (u64 entry_index, char *fmt, ...);

/* common to all types */
void vlib_stats_validate (u32 entry_index, ...);
int vlib_stats_validate_will_expand (u32 entry_index, ...);
void vlib_stats_remove_entry (u32 entry_index);
u32 vlib_stats_find_entry_index (char *fmt, ...);
void vlib_stats_register_collector_fn (vlib_stats_collector_reg_t *r);

format_function_t format_vlib_stats_symlink;

#endif