2 *------------------------------------------------------------------
5 * Copyright (c) 2018 Cisco and/or its affiliates.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at:
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *------------------------------------------------------------------
20 #include <vpp-api/client/stat_client.h>
21 #include <vlib/vlib.h>
24 stat_poll_loop (u8 ** patterns)
26 struct timespec ts, tsrem;
27 stat_segment_data_t *res;
28 int i, j, k, lost_connection = 0;
29 f64 heartbeat, prev_heartbeat = 0;
30 u32 *stats = stat_segment_ls (patterns);
36 printf ("\033[2J"); /* clear the screen */
39 heartbeat = stat_segment_heartbeat ();
40 if (heartbeat > prev_heartbeat)
42 prev_heartbeat = heartbeat;
49 if (lost_connection > 10)
51 fformat (stderr, "Lost connection to VPP...\n");
55 printf ("\033[H"); /* Cursor top left corner */
56 res = stat_segment_dump (stats);
59 stats = stat_segment_ls (patterns);
62 for (i = 0; i < vec_len (res); i++)
66 case STAT_DIR_TYPE_COUNTER_VECTOR_SIMPLE:
67 for (k = 0; k < vec_len (res[i].simple_counter_vec); k++)
68 for (j = 0; j < vec_len (res[i].simple_counter_vec[k]); j++)
69 fformat (stdout, "[%d]: %llu packets %s\n",
70 j, res[i].simple_counter_vec[k][j], res[i].name);
73 case STAT_DIR_TYPE_COUNTER_VECTOR_COMBINED:
74 for (k = 0; k < vec_len (res[i].simple_counter_vec); k++)
75 for (j = 0; j < vec_len (res[i].combined_counter_vec[k]); j++)
76 fformat (stdout, "[%d]: %llu packets, %llu bytes %s\n",
77 j, res[i].combined_counter_vec[k][j].packets,
78 res[i].combined_counter_vec[k][j].bytes,
82 case STAT_DIR_TYPE_ERROR_INDEX:
83 for (j = 0; j < vec_len (res[i].error_vector); j++)
84 fformat (stdout, "%llu %s\n", res[i].error_vector[j],
88 case STAT_DIR_TYPE_SCALAR_INDEX:
89 fformat (stdout, "%.2f %s\n", res[i].scalar_value, res[i].name);
92 case STAT_DIR_TYPE_EMPTY:
96 printf ("Unknown value\n");
100 stat_segment_data_free (res);
101 /* Scrape stats every 5 seconds */
104 while (nanosleep (&ts, &tsrem) < 0)
110 enum stat_client_cmd_e
112 STAT_CLIENT_CMD_UNKNOWN,
114 STAT_CLIENT_CMD_POLL,
115 STAT_CLIENT_CMD_DUMP,
116 STAT_CLIENT_CMD_TIGHTPOLL,
120 main (int argc, char **argv)
122 unformat_input_t _argv, *a = &_argv;
123 u8 *stat_segment_name, *pattern = 0, **patterns = 0;
125 enum stat_client_cmd_e cmd = STAT_CLIENT_CMD_UNKNOWN;
127 /* Create a heap of 64MB */
128 clib_mem_init (0, 64 << 20);
130 unformat_init_command_line (a, argv);
132 stat_segment_name = (u8 *) STAT_SEGMENT_SOCKET_FILE;
134 while (unformat_check_input (a) != UNFORMAT_END_OF_INPUT)
136 if (unformat (a, "socket-name %s", &stat_segment_name))
138 else if (unformat (a, "ls"))
140 cmd = STAT_CLIENT_CMD_LS;
142 else if (unformat (a, "dump"))
144 cmd = STAT_CLIENT_CMD_DUMP;
146 else if (unformat (a, "poll"))
148 cmd = STAT_CLIENT_CMD_POLL;
150 else if (unformat (a, "tightpoll"))
152 cmd = STAT_CLIENT_CMD_TIGHTPOLL;
154 else if (unformat (a, "%s", &pattern))
156 vec_add1 (patterns, pattern);
161 "%s: usage [socket-name <name>] [ls|dump|poll] <patterns> ...\n",
167 rv = stat_segment_connect ((char *) stat_segment_name);
170 fformat (stderr, "Couldn't connect to vpp, does %s exist?\n",
177 stat_segment_data_t *res;
179 dir = stat_segment_ls (patterns);
183 case STAT_CLIENT_CMD_LS:
184 /* List all counters */
185 for (i = 0; i < vec_len (dir); i++)
187 char *n = stat_segment_index_to_name (dir[i]);
193 case STAT_CLIENT_CMD_DUMP:
194 res = stat_segment_dump (dir);
195 for (i = 0; i < vec_len (res); i++)
199 case STAT_DIR_TYPE_COUNTER_VECTOR_SIMPLE:
200 if (res[i].simple_counter_vec == 0)
202 for (k = 0; k < vec_len (res[i].simple_counter_vec); k++)
203 for (j = 0; j < vec_len (res[i].simple_counter_vec[k]); j++)
204 fformat (stdout, "[%d @ %d]: %llu packets %s\n",
205 j, k, res[i].simple_counter_vec[k][j],
209 case STAT_DIR_TYPE_COUNTER_VECTOR_COMBINED:
210 if (res[i].combined_counter_vec == 0)
212 for (k = 0; k < vec_len (res[i].combined_counter_vec); k++)
213 for (j = 0; j < vec_len (res[i].combined_counter_vec[k]); j++)
214 fformat (stdout, "[%d @ %d]: %llu packets, %llu bytes %s\n",
215 j, k, res[i].combined_counter_vec[k][j].packets,
216 res[i].combined_counter_vec[k][j].bytes,
220 case STAT_DIR_TYPE_ERROR_INDEX:
221 for (j = 0; j < vec_len (res[i].error_vector); j++)
222 fformat (stdout, "[@%d] %llu %s\n", j, res[i].error_vector[j],
226 case STAT_DIR_TYPE_SCALAR_INDEX:
227 fformat (stdout, "%.2f %s\n", res[i].scalar_value, res[i].name);
230 case STAT_DIR_TYPE_NAME_VECTOR:
231 if (res[i].name_vector == 0)
233 for (k = 0; k < vec_len (res[i].name_vector); k++)
234 if (res[i].name_vector[k])
235 fformat (stdout, "[%d]: %s %s\n", k, res[i].name_vector[k],
239 case STAT_DIR_TYPE_EMPTY:
246 stat_segment_data_free (res);
249 case STAT_CLIENT_CMD_POLL:
250 stat_poll_loop (patterns);
251 /* We can only exist the pool loop if we lost connection to VPP */
252 stat_segment_disconnect ();
256 case STAT_CLIENT_CMD_TIGHTPOLL:
259 res = stat_segment_dump (dir);
264 dir = stat_segment_ls (patterns);
267 stat_segment_data_free (res);
273 "%s: usage [socket-name <name>] [ls|dump|poll] <patterns> ...\n",
277 stat_segment_disconnect ();
283 * fd.io coding-style-patch-verification: ON
286 * eval: (c-set-style "gnu")