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);
119 fformat (stderr,
"Unknown value %d\n", res[i].type);
128 #define ROOTPAGE "<html><head><title>Metrics exporter</title></head><body><ul><li><a href=\"/metrics\">metrics</a></li></ul></body></html>" 129 #define NOT_FOUND_ERROR "<html><head><title>Document not found</title></head><body><h1>404 - Document not found</h1></body></html>" 134 char status[80] = { 0 };
135 if (fgets (status,
sizeof (status) - 1, stream) == 0)
137 fprintf (stderr,
"fgets error: %s %s\n", status, strerror (errno));
141 char *method = strtok_r (status,
" \t\r\n", &saveptr);
142 if (method == 0 || strncmp (method,
"GET", 4) != 0)
144 fputs (
"HTTP/1.0 405 Method Not Allowed\r\n", stream);
147 char *request_uri = strtok_r (NULL,
" \t", &saveptr);
148 char *
protocol = strtok_r (NULL,
" \t\r\n", &saveptr);
149 if (protocol == 0 || strncmp (protocol,
"HTTP/1.", 7) != 0)
151 fputs (
"HTTP/1.0 400 Bad Request\r\n", stream);
158 if (fgets (header,
sizeof (header) - 1, stream) == 0)
160 fprintf (stderr,
"fgets error: %s\n", strerror (errno));
163 if (header[0] ==
'\n' || header[1] ==
'\n')
168 if (strcmp (request_uri,
"/") == 0)
170 fprintf (stream,
"HTTP/1.0 200 OK\r\nContent-Length: %lu\r\n\r\n",
175 if (strcmp (request_uri,
"/metrics") != 0)
178 "HTTP/1.0 404 Not Found\r\nContent-Length: %lu\r\n\r\n",
183 fputs (
"HTTP/1.0 200 OK\r\nContent-Type: text/plain\r\n\r\n", stream);
190 struct sockaddr_in6 serveraddr;
191 int addrlen =
sizeof (serveraddr);
194 int listenfd = socket (AF_INET6, SOCK_STREAM, 0);
197 perror (
"Failed opening socket");
202 setsockopt (listenfd, SOL_SOCKET, SO_REUSEADDR, &enable,
sizeof (
int));
205 perror (
"Failed setsockopt");
211 serveraddr.sin6_family = AF_INET6;
212 serveraddr.sin6_port = htons (port);
213 serveraddr.sin6_addr = in6addr_any;
215 if (bind (listenfd, (
struct sockaddr *) &serveraddr, addrlen) < 0)
217 fprintf (stderr,
"bind() error %s\n", strerror (errno));
221 if (listen (listenfd, 1000000) != 0)
223 fprintf (stderr,
"listen() error for %s\n", strerror (errno));
245 u8 *stat_segment_name, *pattern = 0, **patterns = 0;
257 if (
unformat (a,
"socket-name %s", &stat_segment_name))
259 else if (
unformat (a,
"%s", &pattern))
266 "%s: usage [socket-name <name>] <patterns> ...\n",
275 "%s: usage [socket-name <name>] <patterns> ...\n", argv[0]);
282 fformat (stderr,
"Couldn't connect to vpp, does %s exist?\n",
294 int conn_sock = accept (fd, NULL, NULL);
297 fprintf (stderr,
"Accept failed: %s", strerror (errno));
302 struct sockaddr_in6 clientaddr = { 0 };
303 char address[INET6_ADDRSTRLEN];
305 getpeername (conn_sock, (
struct sockaddr *) &clientaddr, &addrlen);
307 (AF_INET6, &clientaddr.sin6_addr, address, sizeof (address)))
309 fprintf (stderr,
"Client address is [%s]:%d\n", address,
310 ntohs (clientaddr.sin6_port));
314 FILE *stream = fdopen (conn_sock,
"r+");
317 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)
int main(int argc, char **argv)
vl_api_fib_path_type_t type
vl_api_ip_proto_t protocol
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)
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