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);
101 fformat (stream,
"%s{thread=\"0\"} %lld\n",
108 res[i].scalar_value);
112 fformat (stderr,
"Unknown value %d\n", res[i].type);
121 #define ROOTPAGE "<html><head><title>Metrics exporter</title></head><body><ul><li><a href=\"/metrics\">metrics</a></li></ul></body></html>" 122 #define NOT_FOUND_ERROR "<html><head><title>Document not found</title></head><body><h1>404 - Document not found</h1></body></html>" 127 char status[80] = { 0 };
128 if (fgets (status,
sizeof (status) - 1, stream) == 0)
130 fprintf (stderr,
"fgets error: %s %s\n", status, strerror (errno));
134 char *method = strtok_r (status,
" \t\r\n", &saveptr);
135 if (method == 0 || strncmp (method,
"GET", 4) != 0)
137 fputs (
"HTTP/1.0 405 Method Not Allowed\r\n", stream);
140 char *request_uri = strtok_r (
NULL,
" \t", &saveptr);
141 char *protocol = strtok_r (
NULL,
" \t\r\n", &saveptr);
142 if (protocol == 0 || strncmp (protocol,
"HTTP/1.", 7) != 0)
144 fputs (
"HTTP/1.0 400 Bad Request\r\n", stream);
151 if (fgets (header,
sizeof (header) - 1, stream) == 0)
153 fprintf (stderr,
"fgets error: %s\n", strerror (errno));
156 if (header[0] ==
'\n' || header[1] ==
'\n')
161 if (strcmp (request_uri,
"/") == 0)
163 fprintf (stream,
"HTTP/1.0 200 OK\r\nContent-Length: %lu\r\n\r\n",
168 if (strcmp (request_uri,
"/metrics") != 0)
171 "HTTP/1.0 404 Not Found\r\nContent-Length: %lu\r\n\r\n",
176 fputs (
"HTTP/1.0 200 OK\r\nContent-Type: text/plain\r\n\r\n", stream);
183 struct sockaddr_in6 serveraddr;
184 int addrlen =
sizeof (serveraddr);
187 int listenfd = socket (AF_INET6, SOCK_STREAM, 0);
190 perror (
"Failed opening socket");
195 setsockopt (listenfd, SOL_SOCKET, SO_REUSEADDR, &enable,
sizeof (
int));
198 perror (
"Failed setsockopt");
204 serveraddr.sin6_family = AF_INET6;
205 serveraddr.sin6_port = htons (port);
206 serveraddr.sin6_addr = in6addr_any;
208 if (bind (listenfd, (
struct sockaddr *) &serveraddr, addrlen) < 0)
210 fprintf (stderr,
"bind() error %s\n", strerror (errno));
214 if (listen (listenfd, 1000000) != 0)
216 fprintf (stderr,
"listen() error for %s\n", strerror (errno));
238 u8 *stat_segment_name, *pattern = 0, **patterns = 0;
250 if (
unformat (a,
"socket-name %s", &stat_segment_name))
252 else if (
unformat (a,
"%s", &pattern))
259 "%s: usage [socket-name <name>] <patterns> ...\n",
268 "%s: usage [socket-name <name>] <patterns> ...\n", argv[0]);
275 fformat (stderr,
"Couldn't connect to vpp, does %s exist?\n",
287 int conn_sock = accept (fd,
NULL,
NULL);
290 fprintf (stderr,
"Accept failed: %s", strerror (errno));
295 struct sockaddr_in6 clientaddr = { 0 };
296 char address[INET6_ADDRSTRLEN];
298 getpeername (conn_sock, (
struct sockaddr *) &clientaddr, &addrlen);
300 (AF_INET6, &clientaddr.sin6_addr, address, sizeof (address)))
302 fprintf (stderr,
"Client address is [%s]:%d\n", address,
303 ntohs (clientaddr.sin6_port));
307 FILE *stream = fdopen (conn_sock,
"r+");
310 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)
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