master
c 151 lines 3.16 KB
Raw
1 /* SPDX-License-Identifier: GPL-3.0-or-later */
2 #include <stdlib.h>
3 #include <arpa/inet.h>
4 #include <netinet/in.h>
5 #include <stdio.h>
6 #include <sys/types.h>
7 #include <sys/socket.h>
8 #include <unistd.h>
9 #include <string.h>
10 #include <time.h>
11 #include <pthread.h>
12
13 void diep(char *s)
14 {
15 perror(s);
16 exit(1);
17 }
18
19 size_t run_threads = 1;
20 size_t metrics = 1024;
21
22 #define SERVER_IP "127.0.0.1"
23 #define PORT 8125
24
25 size_t myrand(size_t max) {
26 size_t loops = max / RAND_MAX;
27 size_t i;
28
29 size_t ret = rand();
30 for(i = 0; i < loops ;i++)
31 ret += rand();
32
33 return ret % max;
34 }
35
36 struct thread_data {
37 size_t id;
38 struct sockaddr_in *si_other;
39 int slen;
40 size_t counter;
41 };
42
43 static void *report_thread(void *__data) {
44 struct thread_data *data = (struct thread_data *)__data;
45
46 size_t last = 0;
47 for (;;) {
48 size_t i;
49 size_t total = 0;
50 for(i = 0; i < run_threads ;i++)
51 total += data[i].counter;
52
53 printf("%zu metrics/s\n", total-last);
54 last = total;
55
56 sleep(1);
57 printf("\033[F\033[J");
58 }
59
60 return NULL;
61 }
62
63 char *types[] = {"g", "c", "m", "ms", "h", "s", NULL};
64 // char *types[] = {"g", "c", "C", "h", "ms", NULL}; // brubeck compatible
65
66 static void *spam_thread(void *__data) {
67 struct thread_data *data = (struct thread_data *)__data;
68
69 int s;
70 char packet[1024];
71
72 if ((s = socket(AF_INET, SOCK_DGRAM, 0))==-1)
73 diep("socket");
74
75 char **packets = malloc(sizeof(char *) * metrics);
76 size_t i, *lengths = malloc(sizeof(size_t) * metrics);
77 size_t t;
78
79 for(i = 0, t = 0; i < metrics ;i++, t++) {
80 if(!types[t]) t = 0;
81 char *type = types[t];
82
83 lengths[i] = sprintf(packet, "stress.%s.t%zu.m%zu:%zu|%s", type, data->id, i, myrand(metrics), type);
84 packets[i] = strdup(packet);
85 // printf("packet %zu, of length %zu: '%s'\n", i, lengths[i], packets[i]);
86 }
87 //printf("\n");
88
89 for (;;) {
90 for(i = 0; i < metrics ;i++) {
91 if (sendto(s, packets[i], lengths[i], 0, (void *)data->si_other, data->slen) < 0) {
92 printf("C ==> DROPPED\n");
93 for(size_t j = 0; j < metrics ;j++)
94 free(packets[j]);
95 free(packets);
96 free(lengths);
97 close(s);
98 return NULL;
99 }
100 data->counter++;
101 }
102 }
103 }
104
105 int main(int argc, char *argv[])
106 {
107 if (argc != 5) {
108 fprintf(stderr, "Usage: '%s THREADS METRICS IP PORT'\n", argv[0]);
109 exit(-1);
110 }
111
112 run_threads = atoi(argv[1]);
113 metrics = atoi(argv[2]);
114 char *ip = argv[3];
115 int port = atoi(argv[4]);
116
117 struct thread_data data[run_threads];
118 struct sockaddr_in si_other;
119 pthread_t threads[run_threads], report;
120 size_t i;
121
122 srand(time(NULL));
123
124 memset(&si_other, 0, sizeof(si_other));
125 si_other.sin_family = AF_INET;
126 si_other.sin_port = htons(port);
127 if (inet_aton(ip, &si_other.sin_addr)==0) {
128 fprintf(stderr, "inet_aton() of ip '%s' failed\n", ip);
129 exit(1);
130 }
131
132 for (i = 0; i < run_threads; ++i) {
133 data[i].id = i;
134 data[i].si_other = &si_other;
135 data[i].slen = sizeof(si_other);
136 data[i].counter = 0;
137 pthread_create(&threads[i], NULL, spam_thread, &data[i]);
138 }
139
140 printf("\n");
141 printf("THREADS : %zu\n", run_threads);
142 printf("METRICS : %zu\n", metrics);
143 printf("DESTINATION : %s:%d\n", ip, port);
144 printf("\n");
145 pthread_create(&report, NULL, report_thread, &data);
146
147 for (i =0; i < run_threads; ++i)
148 pthread_join(threads[i], NULL);
149
150 return 0;
151 }