aboutsummaryrefslogtreecommitdiffstats
path: root/src/vpp/app
diff options
context:
space:
mode:
authorOle Troan <ot@cisco.com>2018-09-04 13:19:12 +0200
committerDamjan Marion <dmarion@me.com>2018-09-17 10:07:27 +0000
commit58492a83722caf1c49977d73abf931418ce1f8f2 (patch)
tree0e2f7e031fbfa10c35448c9660292146aeb442b1 /src/vpp/app
parent40ea3f59dca497e5f4b5a8440a9c8c2e37396701 (diff)
STATS: Dynamically mapped shared memory segment
Move from using a hash to a vector with offsets into shared memory. Limit exposure of VPP data structures and include files to external stats library and applications. Change-Id: Ic06129f12d10cf4c4946a86d9bc734eacff2c7da Signed-off-by: Ole Troan <ot@cisco.com>
Diffstat (limited to 'src/vpp/app')
-rw-r--r--src/vpp/app/vpp_get_stats.c74
-rw-r--r--src/vpp/app/vpp_prometheus_export.c44
2 files changed, 68 insertions, 50 deletions
diff --git a/src/vpp/app/vpp_get_stats.c b/src/vpp/app/vpp_get_stats.c
index 908e675b062..c1a5acb797c 100644
--- a/src/vpp/app/vpp_get_stats.c
+++ b/src/vpp/app/vpp_get_stats.c
@@ -22,12 +22,17 @@
#include <vpp/stats/stats.h>
static int
-stat_poll_loop (stat_segment_cached_pointer_t * cp)
+stat_poll_loop (u8 ** patterns)
{
struct timespec ts, tsrem;
stat_segment_data_t *res;
int i, j, k, lost_connection = 0;
f64 heartbeat, prev_heartbeat = 0;
+ u32 *stats = stat_segment_ls (patterns);
+ if (!stats)
+ {
+ return -1;
+ }
printf ("\033[2J"); /* clear the screen */
while (1)
@@ -49,7 +54,12 @@ stat_poll_loop (stat_segment_cached_pointer_t * cp)
}
printf ("\033[H"); /* Cursor top left corner */
- res = stat_segment_collect (cp);
+ res = stat_segment_dump (stats);
+ if (!res)
+ {
+ stats = stat_segment_ls (patterns);
+ continue;
+ }
for (i = 0; i < vec_len (res); i++)
{
switch (res[i].type)
@@ -57,24 +67,24 @@ stat_poll_loop (stat_segment_cached_pointer_t * cp)
case STAT_DIR_TYPE_COUNTER_VECTOR_SIMPLE:
for (k = 0; k < vec_len (res[i].simple_counter_vec); k++)
for (j = 0; j < vec_len (res[i].simple_counter_vec[k]); j++)
- fformat (stdout, "[%d]: %lld packets %s\n",
+ fformat (stdout, "[%d]: %llu packets %s\n",
j, res[i].simple_counter_vec[k][j], res[i].name);
break;
case STAT_DIR_TYPE_COUNTER_VECTOR_COMBINED:
for (k = 0; k < vec_len (res[i].simple_counter_vec); k++)
for (j = 0; j < vec_len (res[i].combined_counter_vec[k]); j++)
- fformat (stdout, "[%d]: %lld packets, %lld bytes %s\n",
+ fformat (stdout, "[%d]: %llu packets, %llu bytes %s\n",
j, res[i].combined_counter_vec[k][j].packets,
res[i].combined_counter_vec[k][j].bytes,
res[i].name);
break;
case STAT_DIR_TYPE_ERROR_INDEX:
- fformat (stdout, "%lld %s\n", res[i].error_value, res[i].name);
+ fformat (stdout, "%llu %s\n", res[i].error_value, res[i].name);
break;
- case STAT_DIR_TYPE_SCALAR_POINTER:
+ case STAT_DIR_TYPE_SCALAR_INDEX:
fformat (stdout, "%.2f %s\n", res[i].scalar_value, res[i].name);
break;
@@ -99,6 +109,7 @@ enum stat_client_cmd_e
STAT_CLIENT_CMD_LS,
STAT_CLIENT_CMD_POLL,
STAT_CLIENT_CMD_DUMP,
+ STAT_CLIENT_CMD_TIGHTPOLL,
};
int
@@ -108,10 +119,9 @@ main (int argc, char **argv)
u8 *stat_segment_name, *pattern = 0, **patterns = 0;
int rv;
enum stat_client_cmd_e cmd = STAT_CLIENT_CMD_UNKNOWN;
- void *heap_base;
- heap_base = clib_mem_vm_map ((void *) 0x10000000ULL, 128 << 20);
- clib_mem_init (heap_base, 128 << 20);
+ /* Create a heap of 64MB */
+ clib_mem_init (0, 64 << 20);
unformat_init_command_line (a, argv);
@@ -133,6 +143,10 @@ main (int argc, char **argv)
{
cmd = STAT_CLIENT_CMD_POLL;
}
+ else if (unformat (a, "tightpoll"))
+ {
+ cmd = STAT_CLIENT_CMD_TIGHTPOLL;
+ }
else if (unformat (a, "%s", &pattern))
{
vec_add1 (patterns, pattern);
@@ -154,10 +168,9 @@ reconnect:
exit (1);
}
- u8 **dir;
+ u32 *dir;
int i, j, k;
stat_segment_data_t *res;
- stat_segment_cached_pointer_t *cp;
dir = stat_segment_ls (patterns);
@@ -167,7 +180,9 @@ reconnect:
/* List all counters */
for (i = 0; i < vec_len (dir); i++)
{
- printf ("%s\n", (char *) dir[i]);
+ char *n = stat_segment_index_to_name (dir[i]);
+ printf ("%s\n", n);
+ free (n);
}
break;
@@ -180,7 +195,7 @@ reconnect:
case STAT_DIR_TYPE_COUNTER_VECTOR_SIMPLE:
for (k = 0; k < vec_len (res[i].simple_counter_vec) - 1; k++)
for (j = 0; j < vec_len (res[i].simple_counter_vec[k]); j++)
- fformat (stdout, "[%d @ %d]: %lld packets %s\n",
+ fformat (stdout, "[%d @ %d]: %llu packets %s\n",
j, k, res[i].simple_counter_vec[k][j],
res[i].name);
break;
@@ -188,19 +203,18 @@ reconnect:
case STAT_DIR_TYPE_COUNTER_VECTOR_COMBINED:
for (k = 0; k < vec_len (res[i].combined_counter_vec); k++)
for (j = 0; j < vec_len (res[i].combined_counter_vec[k]); j++)
- fformat (stdout, "[%d @ %d]: %lld packets, %lld bytes %s\n",
+ fformat (stdout, "[%d @ %d]: %llu packets, %llu bytes %s\n",
j, k, res[i].combined_counter_vec[k][j].packets,
res[i].combined_counter_vec[k][j].bytes,
res[i].name);
break;
case STAT_DIR_TYPE_ERROR_INDEX:
- fformat (stdout, "%lld %s\n", res[i].error_value, dir[i]);
+ fformat (stdout, "%llu %s\n", res[i].error_value, res[i].name);
break;
- case STAT_DIR_TYPE_SCALAR_POINTER:
- fformat (stdout, "%.2f %s\n", dir[i], res[i].scalar_value,
- res[i].name);
+ case STAT_DIR_TYPE_SCALAR_INDEX:
+ fformat (stdout, "%.2f %s\n", res[i].scalar_value, res[i].name);
break;
default:
@@ -211,19 +225,27 @@ reconnect:
break;
case STAT_CLIENT_CMD_POLL:
- cp = stat_segment_register (dir);
- if (!cp)
- {
- fformat (stderr,
- "Couldn't register required counters with stat segment\n");
- exit (1);
- }
- stat_poll_loop (cp);
+ stat_poll_loop (patterns);
/* We can only exist the pool loop if we lost connection to VPP */
stat_segment_disconnect ();
goto reconnect;
break;
+ case STAT_CLIENT_CMD_TIGHTPOLL:
+ while (1)
+ {
+ res = stat_segment_dump (dir);
+ if (res == 0)
+ {
+ /* Refresh */
+ vec_free (dir);
+ dir = stat_segment_ls (patterns);
+ continue;
+ }
+ stat_segment_data_free (res);
+ }
+ break;
+
default:
fformat (stderr,
"%s: usage [socket-name <name>] [ls|dump|poll] <patterns> ...\n",
diff --git a/src/vpp/app/vpp_prometheus_export.c b/src/vpp/app/vpp_prometheus_export.c
index 4fd749af24a..65e014783a0 100644
--- a/src/vpp/app/vpp_prometheus_export.c
+++ b/src/vpp/app/vpp_prometheus_export.c
@@ -30,7 +30,6 @@
#include <sys/socket.h>
#include <vpp-api/client/stat_client.h>
#include <vlib/vlib.h>
-#include <vpp/stats/stats.h>
#include <ctype.h>
/* https://github.com/prometheus/prometheus/wiki/Default-port-allocations */
@@ -50,12 +49,22 @@ prom_string (char *s)
}
static void
-dump_metrics (FILE * stream, stat_segment_cached_pointer_t * cp)
+dump_metrics (FILE * stream, u8 ** patterns)
{
stat_segment_data_t *res;
int i, j, k;
+ static u32 *stats = 0;
+
+retry:
+ res = stat_segment_dump (stats);
+ if (res == 0)
+ { /* Memory layout has changed */
+ if (stats)
+ vec_free (stats);
+ stats = stat_segment_ls (patterns);
+ goto retry;
+ }
- res = stat_segment_collect (cp);
for (i = 0; i < vec_len (res); i++)
{
switch (res[i].type)
@@ -93,7 +102,7 @@ dump_metrics (FILE * stream, stat_segment_cached_pointer_t * cp)
prom_string (res[i].name), res[i].error_value);
break;
- case STAT_DIR_TYPE_SCALAR_POINTER:
+ case STAT_DIR_TYPE_SCALAR_INDEX:
fformat (stream, "# TYPE %s counter\n", prom_string (res[i].name));
fformat (stream, "%s %.2f\n", prom_string (res[i].name),
res[i].scalar_value);
@@ -113,7 +122,7 @@ dump_metrics (FILE * stream, stat_segment_cached_pointer_t * cp)
#define NOT_FOUND_ERROR "<html><head><title>Document not found</title></head><body><h1>404 - Document not found</h1></body></html>"
static void
-http_handler (FILE * stream, stat_segment_cached_pointer_t * cp)
+http_handler (FILE * stream, u8 ** patterns)
{
char status[80] = { 0 };
if (fgets (status, sizeof (status) - 1, stream) == 0)
@@ -165,7 +174,7 @@ http_handler (FILE * stream, stat_segment_cached_pointer_t * cp)
return;
}
fputs ("HTTP/1.0 200 OK\r\nContent-Type: text/plain\r\n\r\n", stream);
- dump_metrics (stream, cp);
+ dump_metrics (stream, patterns);
}
static int
@@ -223,10 +232,9 @@ main (int argc, char **argv)
unformat_input_t _argv, *a = &_argv;
u8 *stat_segment_name, *pattern = 0, **patterns = 0;
int rv;
- void *heap_base;
- heap_base = clib_mem_vm_map ((void *) 0x10000000ULL, 128 << 20);
- clib_mem_init (heap_base, 128 << 20);
+ /* Allocating 32MB heap */
+ clib_mem_init (0, 32 << 20);
unformat_init_command_line (a, argv);
@@ -257,18 +265,6 @@ main (int argc, char **argv)
exit (1);
}
- u8 **dir;
- stat_segment_cached_pointer_t *cp;
-
- dir = stat_segment_ls (patterns);
- cp = stat_segment_register (dir);
- if (!cp)
- {
- fformat (stderr,
- "Couldn't register required counters with stat segment\n");
- exit (1);
- }
-
int fd = start_listen (SERVER_PORT);
if (fd < 0)
{
@@ -291,8 +287,8 @@ main (int argc, char **argv)
if (inet_ntop
(AF_INET6, &clientaddr.sin6_addr, address, sizeof (address)))
{
- printf ("Client address is [%s]:%d\n", address,
- ntohs (clientaddr.sin6_port));
+ fprintf (stderr, "Client address is [%s]:%d\n", address,
+ ntohs (clientaddr.sin6_port));
}
}
@@ -304,7 +300,7 @@ main (int argc, char **argv)
continue;
}
/* Single reader at the moment */
- http_handler (stream, cp);
+ http_handler (stream, patterns);
fclose (stream);
}