4
#include <sys/socket.h>
5
#include <netinet/in.h>
19
#define POS_TIMESTAMP1 4
21
#define POS_TIMESTAMP2 87
23
#define MAX_MESSAGE_LENGTH 8192
25
#define USEC_PER_SEC 10e6
26
#define MIN(a, b) ((a) < (b) ? (a) : (b))
28
static inline unsigned long
29
time_val_diff(struct timeval *t1, struct timeval *t2)
31
return (t1->tv_sec - t2->tv_sec) * USEC_PER_SEC + (t1->tv_usec - t2->tv_usec);
35
gen_messages(int sock, int rate, int message_length, int interval)
37
struct timeval now, start, last_ts_format, last_throttle_check;
38
char linebuf[MAX_MESSAGE_LENGTH + 1];
43
unsigned long count = 0, last_count = 0;
44
char padding[] = "PADD";
45
long buckets = rate - (rate / 10);
48
gettimeofday(&start, NULL);
50
last_throttle_check = now;
51
run_id = start.tv_sec;
53
/* force reformat of the timestamp */
55
last_ts_format.tv_sec--;
57
linelen = snprintf(linebuf, sizeof(linebuf), "<38>2007-12-24T12:28:51 localhost localprg: seq: %010d, runid: %-10d, stamp: %-19s ", 0, run_id, "");
59
for (i = linelen; i < message_length - 1; i++)
61
linebuf[i] = padding[(i - linelen) % (sizeof(padding) - 1)];
63
linebuf[message_length - 1] = '\n';
64
linebuf[message_length] = 0;
65
linelen = strlen(linebuf);
67
while (now.tv_sec - start.tv_sec < interval)
69
gettimeofday(&now, NULL);
71
if (now.tv_sec != last_ts_format.tv_sec)
76
tm = localtime(&now.tv_sec);
77
len = strftime(stamp, sizeof(stamp), "%Y-%m-%dT%H:%M:%S", tm);
78
memcpy(&linebuf[POS_TIMESTAMP1], stamp, len);
79
memcpy(&linebuf[POS_TIMESTAMP2], stamp, len);
81
diff = time_val_diff(&now, &last_ts_format);
83
fprintf(stderr, "rate = %.2lf msg/sec \r", ((double) (count - last_count) * USEC_PER_SEC) / diff);
89
diff = time_val_diff(&now, &last_throttle_check);
90
if (buckets == 0 || diff > 10e5)
92
/* check rate every 0.1sec */
95
new_buckets = (rate * diff) / USEC_PER_SEC;
98
buckets = MIN(rate, buckets + new_buckets);
99
last_throttle_check = now;
105
struct timespec tspec, trem;
106
long msec = (1000 / rate) + 1;
108
tspec.tv_sec = msec / 1000;
109
tspec.tv_nsec = (msec % 1000) * 10e6;
110
while (nanosleep(&tspec, &trem) < 0 && errno == EINTR)
114
/* recalculate buckets */
118
/* add sequence number */
119
snprintf(intbuf, sizeof(intbuf), "%010ld", count);
120
memcpy(&linebuf[POS_SEQ], intbuf, 10);
122
if (write(sock, linebuf, linelen) < 0)
124
fprintf(stderr, "Send error %s\n", strerror(errno));
132
gettimeofday(&now, NULL);
133
diff = (((double) now.tv_sec) + ((double) now.tv_usec / 10e6)) - ((double) start.tv_sec + ((double) now.tv_usec / 10e6));
134
fprintf(stderr, "average rate = %.2lf msg/sec, count=%ld\n", (double) count / diff, count);
140
printf("loggen [options] target [port]\n"
141
"Generate syslog messages at the specified rate\n\n"
143
" --rate, or -r <msg/sec> Number of messages to generate per second\n"
144
" --inet, or -i Use IP based transport (TCP, UDP)\n"
145
" --unix, or -x Use UNIX domain socket transport\n"
146
" --stream, or -S Use stream socket (TCP and unix-stream)\n"
147
" --dgram, or -D Use datagram socket (UDP and unix-dgram)\n"
148
" --size, or -s <size> Specify the size of the syslog message\n"
149
" --interval, or -I <sec> Number of seconds to run the test for\n");
154
main(int argc, char *argv[])
157
struct option syslog_ng_options[] =
159
{ "rate", required_argument, NULL, 'r' },
160
{ "inet", no_argument, NULL, 'i' },
161
{ "unix", no_argument, NULL, 'x' },
162
{ "stream", no_argument, NULL, 'S' },
163
{ "dgram", no_argument, NULL, 'D' },
164
{ "size", required_argument, NULL, 's' },
165
{ "interval", required_argument, NULL, 'I' },
171
int sock_type = SOCK_STREAM;
173
int message_length = 256;
178
while ((opt = getopt_long(argc, argv, "r:I:ixs:SDh", syslog_ng_options, NULL)) != -1)
180
while ((opt = getopt(argc, argv, "r:I:ixs:SDh")) != -1)
189
interval = atoi(optarg);
198
sock_type = SOCK_DGRAM;
201
sock_type = SOCK_STREAM;
204
message_length = atoi(optarg);
214
if (argc - optind < 2)
216
fprintf(stderr, "No target server specified\n");
223
struct addrinfo hints;
224
struct addrinfo *res, *rp;
226
memset(&hints, 0, sizeof(hints));
227
hints.ai_family = AF_UNSPEC;
228
hints.ai_socktype = sock_type;
229
hints.ai_flags = AI_ADDRCONFIG;
230
hints.ai_protocol = 0;
231
if (getaddrinfo(argv[optind], argv[optind + 1], &hints, &res) != 0)
233
fprintf(stderr, "Name lookup error\n");
237
for (rp = res; rp != NULL; rp = rp->ai_next)
239
sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
243
if (connect(sock, rp->ai_addr, rp->ai_addrlen) != -1)
253
struct sockaddr_in s_in;
255
he = gethostbyname(argv[optind]);
258
fprintf(stderr, "Name lookup error\n");
261
s_in.sin_family = AF_INET;
262
s_in.sin_addr = *(struct in_addr *) he->h_addr;
264
se = getservbyname(argv[optind + 1], sock_type == SOCK_STREAM ? "tcp" : "udp");
266
s_in.sin_port = se->s_port;
268
s_in.sin_port = htons(atoi(argv[optind + 1]));
271
sock = socket(AF_INET, sock_type, 0);
274
fprintf(stderr, "Error creating socket: %s\n", strerror(errno));
278
if (connect(sock, (struct sockaddr *) &s_in, sizeof(s_in)) < 0)
288
fprintf(stderr, "Error connecting to target server: %s\n", strerror(errno));
294
struct sockaddr_un saun;
296
sock = socket(AF_UNIX, sock_type, 0);
297
saun.sun_family = AF_UNIX;
298
strncpy(saun.sun_path, argv[optind], sizeof(saun.sun_path));
299
if (connect(sock, (struct sockaddr *) &saun, sizeof(saun)) < 0)
301
fprintf(stderr, "Error connecting to target server: %s\n", strerror(errno));
306
gen_messages(sock, rate, message_length, interval);