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