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>
22 #include <vpp/stats/stats.h>
25 stat_poll_loop (stat_segment_cached_pointer_t * cp)
27 struct timespec ts, tsrem;
28 stat_segment_data_t *res;
29 int i, j, k, lost_connection = 0;
30 f64 heartbeat, prev_heartbeat = 0;
32 printf ("\033[2J"); /* clear the screen */
35 heartbeat = stat_segment_heartbeat ();
36 if (heartbeat > prev_heartbeat)
38 prev_heartbeat = heartbeat;
45 if (lost_connection > 10)
47 fformat (stderr, "Lost connection to VPP...\n");
51 printf ("\033[H"); /* Cursor top left corner */
52 res = stat_segment_collect (cp);
53 for (i = 0; i < vec_len (res); i++)
57 case STAT_DIR_TYPE_COUNTER_VECTOR_SIMPLE:
58 for (k = 0; k < vec_len (res[i].simple_counter_vec); k++)
59 for (j = 0; j < vec_len (res[i].simple_counter_vec[k]); j++)
60 fformat (stdout, "[%d]: %lld packets %s\n",
61 j, res[i].simple_counter_vec[k][j], res[i].name);
64 case STAT_DIR_TYPE_COUNTER_VECTOR_COMBINED:
65 for (k = 0; k < vec_len (res[i].simple_counter_vec); k++)
66 for (j = 0; j < vec_len (res[i].combined_counter_vec[k]); j++)
67 fformat (stdout, "[%d]: %lld packets, %lld bytes %s\n",
68 j, res[i].combined_counter_vec[k][j].packets,
69 res[i].combined_counter_vec[k][j].bytes,
73 case STAT_DIR_TYPE_ERROR_INDEX:
74 fformat (stdout, "%lld %s\n", res[i].error_value, res[i].name);
77 case STAT_DIR_TYPE_SCALAR_POINTER:
78 fformat (stdout, "%.2f %s\n", res[i].scalar_value, res[i].name);
82 printf ("Unknown value\n");
86 stat_segment_data_free (res);
87 /* Scrape stats every 5 seconds */
90 while (nanosleep (&ts, &tsrem) < 0)
96 enum stat_client_cmd_e
98 STAT_CLIENT_CMD_UNKNOWN,
100 STAT_CLIENT_CMD_POLL,
101 STAT_CLIENT_CMD_DUMP,
105 main (int argc, char **argv)
107 unformat_input_t _argv, *a = &_argv;
108 u8 *stat_segment_name, *pattern = 0, **patterns = 0;
110 enum stat_client_cmd_e cmd = STAT_CLIENT_CMD_UNKNOWN;
113 heap_base = clib_mem_vm_map ((void *) 0x10000000ULL, 128 << 20);
114 clib_mem_init (heap_base, 128 << 20);
116 unformat_init_command_line (a, argv);
118 stat_segment_name = (u8 *) STAT_SEGMENT_SOCKET_FILE;
120 while (unformat_check_input (a) != UNFORMAT_END_OF_INPUT)
122 if (unformat (a, "socket-name %s", &stat_segment_name))
124 else if (unformat (a, "ls"))
126 cmd = STAT_CLIENT_CMD_LS;
128 else if (unformat (a, "dump"))
130 cmd = STAT_CLIENT_CMD_DUMP;
132 else if (unformat (a, "poll"))
134 cmd = STAT_CLIENT_CMD_POLL;
136 else if (unformat (a, "%s", &pattern))
138 vec_add1 (patterns, pattern);
143 "%s: usage [socket-name <name>] [ls|dump|poll] <patterns> ...\n",
149 rv = stat_segment_connect ((char *) stat_segment_name);
152 fformat (stderr, "Couldn't connect to vpp, does %s exist?\n",
159 stat_segment_data_t *res;
160 stat_segment_cached_pointer_t *cp;
162 dir = stat_segment_ls (patterns);
166 case STAT_CLIENT_CMD_LS:
167 /* List all counters */
168 for (i = 0; i < vec_len (dir); i++)
170 printf ("%s\n", (char *) dir[i]);
174 case STAT_CLIENT_CMD_DUMP:
175 res = stat_segment_dump (dir);
176 for (i = 0; i < vec_len (res); i++)
180 case STAT_DIR_TYPE_COUNTER_VECTOR_SIMPLE:
181 for (k = 0; k < vec_len (res[i].simple_counter_vec) - 1; k++)
182 for (j = 0; j < vec_len (res[i].simple_counter_vec[k]); j++)
183 fformat (stdout, "[%d @ %d]: %lld packets %s\n",
184 j, k, res[i].simple_counter_vec[k][j],
188 case STAT_DIR_TYPE_COUNTER_VECTOR_COMBINED:
189 for (k = 0; k < vec_len (res[i].simple_counter_vec); k++)
190 for (j = 0; j < vec_len (res[i].combined_counter_vec[k]); j++)
191 fformat (stdout, "[%d @ %d]: %lld packets, %lld bytes %s\n",
192 j, k, res[i].combined_counter_vec[k][j].packets,
193 res[i].combined_counter_vec[k][j].bytes,
197 case STAT_DIR_TYPE_ERROR_INDEX:
198 fformat (stdout, "%lld %s\n", res[i].error_value, dir[i]);
201 case STAT_DIR_TYPE_SCALAR_POINTER:
202 fformat (stdout, "%.2f %s\n", dir[i], res[i].scalar_value,
210 stat_segment_data_free (res);
213 case STAT_CLIENT_CMD_POLL:
214 cp = stat_segment_register (dir);
218 "Couldn't register required counters with stat segment\n");
222 /* We can only exist the pool loop if we lost connection to VPP */
223 stat_segment_disconnect ();
229 "%s: usage [socket-name <name>] [ls|dump|poll] <patterns> ...\n",
233 stat_segment_disconnect ();
239 * fd.io coding-style-patch-verification: ON
242 * eval: (c-set-style "gnu")