1 /** 2 * Copyright (C) Mellanox Technologies Ltd. 2001-2013. ALL RIGHTS RESERVED. 3 * 4 * See file LICENSE for terms. 5 */ 6 7 #ifndef UCS_LIBSTATS_H_ 8 #define UCS_LIBSTATS_H_ 9 10 #include <ucs/stats/stats_fwd.h> 11 #include <ucs/datastruct/list.h> 12 #include <ucs/type/status.h> 13 #include <ucs/sys/math.h> 14 #include <stdarg.h> 15 #include <stdint.h> 16 #include <stdio.h> 17 18 19 /* 20 * Serialization options 21 */ 22 enum { 23 UCS_STATS_SERIALIZE_INACTVIVE = UCS_BIT(0), /* Use "inactive" tree */ 24 UCS_STATS_SERIALIZE_BINARY = UCS_BIT(1), /* Binary mode */ 25 UCS_STATS_SERIALIZE_COMPRESS = UCS_BIT(2) /* Compress */ 26 }; 27 28 #define UCS_STATS_DEFAULT_UDP_PORT 37873 29 30 31 #define UCS_STAT_NAME_MAX 39 32 33 #define UCS_STATS_NODE_FMT \ 34 "%s%s" 35 #define UCS_STATS_NODE_ARG(_node) \ 36 (_node)->cls->name, (_node)->name 37 38 #define UCS_STATS_INDENT(_is_sum, _indent) _is_sum ? 0 : (_indent) * 2, "" 39 #define UCS_STATS_IS_LAST_COUNTER(_counters_bits, _current) \ 40 (_counters_bits > ((2ull<<_current) - 1)) 41 42 typedef struct ucs_stats_server *ucs_stats_server_h; /* Handle to server */ 43 typedef struct ucs_stats_client *ucs_stats_client_h; /* Handle to client */ 44 45 46 typedef enum ucs_stats_children_sel { 47 UCS_STATS_INACTIVE_CHILDREN, 48 UCS_STATS_ACTIVE_CHILDREN, 49 UCS_STATS_CHILDREN_LAST 50 } ucs_stats_children_sel_t; 51 52 53 /* Statistics class */ 54 struct ucs_stats_class { 55 const char *name; 56 unsigned num_counters; 57 const char* counter_names[]; 58 }; 59 60 /* 61 * ucs_stats_node is used to hold the counters, their classes and the 62 * relationship between them. 63 * ucs_stats_filter_node is a data structure used to filter the counters 64 * on the report. 65 * Therre are 3 types of filtering: Full, Aggregate, and summary 66 * Following is an example of the data structures in aggregate mode: 67 * 68 * ucs_stats_node ucs_stats_filter_node 69 * -------------- --------------------- 70 * 71 * +-----+ +-----+ 72 * | A-1 |............................> | A-1 | 73 * +-----+ +-----+ 74 * A A A A 75 * | | | | 76 * | | +----------+ | 77 * | | | | 78 * +--+ +--+ +--+--+................. | 79 * | | | B-1 | : | 80 * | | +-----+ : | 81 * | +-----+....|..A................. : | 82 * | | B-2 | | | : : | 83 * | +-----+ <--+ | V V | 84 * +-----+......|..........|.............> +-----+ 85 * | B-3 | || +---------------| B* | 86 * +-----+ <----+ +-----+ 87 * cntr1 cntr1* 88 * cntr2 cntr2* 89 * cntr3 cntr3* 90 * 91 * unfiltered statistics report: 92 * 93 * A-1: 94 * B-1: 95 * cntr1: 11111 96 * cntr2: 22222 97 * cntr3: 33333 98 * B-2: 99 * cntr1: 11111 100 * cntr2: 22222 101 * cntr3: 33333 102 * B-3: 103 * cntr1: 11111 104 * cntr2: 22222 105 * cntr3: 33333 106 * 107 * filtered statistics report: 108 * 109 * A-1: 110 * B*: 111 * cntr1: 33333 112 * cntr2: 66666 113 * cntr3: 99999 114 * 115 */ 116 117 /* In-memory statistics node */ 118 119 struct ucs_stats_node { 120 ucs_stats_class_t *cls; /* Class info */ 121 ucs_stats_node_t *parent; /* Hierachy structure */ 122 char name[UCS_STAT_NAME_MAX + 1]; 123 /* instance name */ 124 ucs_list_link_t list; /* nodes sharing same parent */ 125 ucs_list_link_t children[UCS_STATS_CHILDREN_LAST]; 126 /* children list head */ 127 ucs_list_link_t type_list; /* nodes with same class/es 128 hierarchy */ 129 ucs_stats_filter_node_t *filter_node; /* ptr to type list head */ 130 ucs_stats_counter_t counters[1]; /* instance counters */ 131 }; 132 133 struct ucs_stats_filter_node { 134 ucs_stats_filter_node_t *parent; 135 ucs_list_link_t list; /* nodes sharing same parent.*/ 136 ucs_list_link_t children; 137 ucs_list_link_t type_list_head; /* nodes with same ancestors classes */ 138 int type_list_len; /* length of list */ 139 int ref_count; /* report node when non zero */ 140 uint64_t counters_bitmask; /* which counters to print */ 141 }; 142 143 /** 144 * Initialize statistics node. 145 * 146 * @param node Node to initialize. 147 * @param cls Node class. 148 * @param name Node name format string. 149 * @param ap Name formatting arguments. 150 */ 151 ucs_status_t ucs_stats_node_initv(ucs_stats_node_t *node, ucs_stats_class_t *cls, 152 const char *name, va_list ap); 153 154 155 /** 156 * Serialize statistics. 157 * 158 * @param stream Destination 159 * @param root Statistics node root. 160 * @param options Serialization options. 161 */ 162 ucs_status_t ucs_stats_serialize(FILE *stream, ucs_stats_node_t *root, int options); 163 164 165 /** 166 * De-serialize statistics. 167 * 168 * @param stream Source data. 169 * @param p_roo Filled with tatistics node root. 170 * 171 * @return UCS_ERR_NO_ELEM if hit EOF. 172 */ 173 ucs_status_t ucs_stats_deserialize(FILE *stream, ucs_stats_node_t **p_root); 174 175 176 /** 177 * Release stats returned by ucs_stats_deserialize(). 178 * @param root Stats to release. 179 */ 180 void ucs_stats_free(ucs_stats_node_t *root); 181 182 183 /** 184 * Initialize statistics client. 185 * 186 * @param server_addr Address of server machine. 187 * @param port Port number on server. 188 * @param p_client Filled with handle to the client. 189 */ 190 ucs_status_t ucs_stats_client_init(const char *server_addr, int port, 191 ucs_stats_client_h *p_client); 192 193 194 /** 195 * Destroy statistics client. 196 */ 197 void ucs_stats_client_cleanup(ucs_stats_client_h client); 198 199 200 /** 201 * Send statistics. 202 * 203 * @param client Client handle. 204 * @param root Statistics tree root. 205 * @param timestamp Current statistics timestamp, identifies every "snapshot". 206 */ 207 ucs_status_t ucs_stats_client_send(ucs_stats_client_h client, ucs_stats_node_t *root, 208 uint64_t timestamp); 209 210 211 /** 212 * Start a thread running a server which receives statistics. 213 * 214 * @param port Port number to listen on. 0 - random available port. 215 * @param verbose Verbose level. 216 * @param p_server Filled with handle to the server. 217 */ 218 ucs_status_t ucs_stats_server_start(int port, ucs_stats_server_h *p_server); 219 220 221 /** 222 * Stop statistics server. 223 * @param server Handle to statistics server. 224 */ 225 void ucs_stats_server_destroy(ucs_stats_server_h server); 226 227 228 /** 229 * Get port number used by the server, useful if we started it on a random port. 230 * 231 * @param server Handle to statistics server. 232 * 233 * @return Port number. 234 */ 235 int ucs_stats_server_get_port(ucs_stats_server_h server); 236 237 238 /** 239 * Get current statistics gathered by the server. The data is valid until the next 240 * call to any of the following functions: 241 * - ucs_stats_server_purge_stats 242 * - ucs_stats_server_cleanup 243 * - ucs_stats_server_get_stats 244 * 245 * @param server Handle to statistics server. 246 * @return A list of stat trees for all entities gathered by the server. 247 */ 248 ucs_list_link_t *ucs_stats_server_get_stats(ucs_stats_server_h server); 249 250 251 /** 252 * Clean up existing statistics. 253 */ 254 void ucs_stats_server_purge_stats(ucs_stats_server_h server); 255 256 257 /** 258 * @return Number of packets received by the server. 259 */ 260 unsigned long ucs_stats_server_rcvd_packets(ucs_stats_server_h server); 261 262 263 #endif /* LIBSTATS_H_ */ 264