20 #include <arpa/inet.h> 21 #include <sys/epoll.h> 30 #include <sys/socket.h> 36 #define SERVER_PORT 9482 56 static u32 *stats = 0;
68 for (i = 0; i <
vec_len (res); i++)
74 for (k = 0; k <
vec_len (res[i].simple_counter_vec); k++)
75 for (j = 0; j <
vec_len (res[i].simple_counter_vec[k]); j++)
76 fformat (stream,
"%s{thread=\"%d\",interface=\"%d\"} %lld\n",
82 fformat (stream,
"# TYPE %s_packets counter\n",
84 fformat (stream,
"# TYPE %s_bytes counter\n",
86 for (k = 0; k <
vec_len (res[i].simple_counter_vec); k++)
87 for (j = 0; j <
vec_len (res[i].combined_counter_vec[k]); j++)
90 "%s_packets{thread=\"%d\",interface=\"%d\"} %lld\n",
92 res[i].combined_counter_vec[k][j].packets);
94 "%s_bytes{thread=\"%d\",interface=\"%d\"} %lld\n",
96 res[i].combined_counter_vec[k][j].bytes);
100 for (j = 0; j <
vec_len (res[i].error_vector); j++)
102 fformat (stream,
"# TYPE %s counter\n",
104 fformat (stream,
"%s{thread=\"%d\"} %lld\n",
105 prom_string (res[i].name), j, res[i].error_vector[j]);
112 res[i].scalar_value);
116 fformat (stderr,
"Unknown value %d\n", res[i].type);
125 #define ROOTPAGE "<html><head><title>Metrics exporter</title></head><body><ul><li><a href=\"/metrics\">metrics</a></li></ul></body></html>" 126 #define NOT_FOUND_ERROR "<html><head><title>Document not found</title></head><body><h1>404 - Document not found</h1></body></html>" 131 char status[80] = { 0 };
132 if (fgets (status,
sizeof (status) - 1, stream) == 0)
134 fprintf (stderr,
"fgets error: %s %s\n", status, strerror (errno));
138 char *method = strtok_r (status,
" \t\r\n", &saveptr);
139 if (method == 0 || strncmp (method,
"GET", 4) != 0)
141 fputs (
"HTTP/1.0 405 Method Not Allowed\r\n", stream);
144 char *request_uri = strtok_r (
NULL,
" \t", &saveptr);
146 if (protocol == 0 || strncmp (protocol,
"HTTP/1.", 7) != 0)
148 fputs (
"HTTP/1.0 400 Bad Request\r\n", stream);
155 if (fgets (header,
sizeof (header) - 1, stream) == 0)
157 fprintf (stderr,
"fgets error: %s\n", strerror (errno));
160 if (header[0] ==
'\n' || header[1] ==
'\n')
165 if (strcmp (request_uri,
"/") == 0)
167 fprintf (stream,
"HTTP/1.0 200 OK\r\nContent-Length: %lu\r\n\r\n",
172 if (strcmp (request_uri,
"/metrics") != 0)
175 "HTTP/1.0 404 Not Found\r\nContent-Length: %lu\r\n\r\n",
180 fputs (
"HTTP/1.0 200 OK\r\nContent-Type: text/plain\r\n\r\n", stream);
187 struct sockaddr_in6 serveraddr;
188 int addrlen =
sizeof (serveraddr);
191 int listenfd = socket (AF_INET6, SOCK_STREAM, 0);
194 perror (
"Failed opening socket");
199 setsockopt (listenfd, SOL_SOCKET, SO_REUSEADDR, &enable,
sizeof (
int));
202 perror (
"Failed setsockopt");
208 serveraddr.sin6_family = AF_INET6;
209 serveraddr.sin6_port = htons (port);
210 serveraddr.sin6_addr = in6addr_any;
212 if (bind (listenfd, (
struct sockaddr *) &serveraddr, addrlen) < 0)
214 fprintf (stderr,
"bind() error %s\n", strerror (errno));
218 if (listen (listenfd, 1000000) != 0)
220 fprintf (stderr,
"listen() error for %s\n", strerror (errno));
242 u8 *stat_segment_name, *pattern = 0, **patterns = 0;
254 if (
unformat (a,
"socket-name %s", &stat_segment_name))
256 else if (
unformat (a,
"%s", &pattern))
263 "%s: usage [socket-name <name>] <patterns> ...\n",
272 "%s: usage [socket-name <name>] <patterns> ...\n", argv[0]);
279 fformat (stderr,
"Couldn't connect to vpp, does %s exist?\n",
291 int conn_sock = accept (fd,
NULL,
NULL);
294 fprintf (stderr,
"Accept failed: %s", strerror (errno));
299 struct sockaddr_in6 clientaddr = { 0 };
300 char address[INET6_ADDRSTRLEN];
302 getpeername (conn_sock, (
struct sockaddr *) &clientaddr, &addrlen);
304 (AF_INET6, &clientaddr.sin6_addr, address, sizeof (address)))
306 fprintf (stderr,
"Client address is [%s]:%d\n", address,
307 ntohs (clientaddr.sin6_port));
311 FILE *stream = fdopen (conn_sock,
"r+");
314 fprintf (stderr,
"fdopen error: %s\n", strerror (errno));
int stat_segment_connect(const char *socket_name)
static int start_listen(u16 port)
Optimized string handling code, including c11-compliant "safe C library" variants.
void stat_segment_data_free(stat_segment_data_t *res)
counter_t ** simple_counter_vec
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
static void dump_metrics(FILE *stream, u8 **patterns)
vl_api_ip_proto_t protocol
int main(int argc, char **argv)
vl_api_fib_path_type_t type
void stat_segment_disconnect(void)
void * clib_mem_init(void *heap, uword size)
#define STAT_SEGMENT_SOCKET_FILE
#define vec_free(V)
Free vector's memory (no header).
uint32_t * stat_segment_ls(uint8_t **patterns)
manual_print typedef address
stat_segment_data_t * stat_segment_dump(uint32_t *stats)
struct sockaddr_in6 sin6_addr
static char * prom_string(char *s)
struct sockaddr_in sin_addr
static void http_handler(FILE *stream, u8 **patterns)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
struct sockaddr_storage storage