~dpiddy/ubuntu/lucid/syslog-ng/connection-logging

« back to all changes in this revision

Viewing changes to tests/loggen/loggen.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Hahler
  • Date: 2008-04-21 21:00:45 UTC
  • mfrom: (1.1.10 upstream)
  • Revision ID: james.westby@ubuntu.com-20080421210045-vvzvv1a6tkrlfek3
Tags: 2.0.9-1ubuntu1
* Sync from Debian, freeze exception granted in LP: #220031
* Fix build of syslog-ng.xml:
  - doc/reference/syslog-ng.xml:
    Fix reference to docbookx.dtd
  - debian/control:
    Build-Depend on docbook-xml
* doc/reference/README.syslog-ng-anon:
  Add missing last sample and link to sample config file; taken
  from http://dev.riseup.net/privacy/syslog-ng-anon/
* Modify Maintainer value to match the DebianMaintainerField
  specification.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <config.h>
 
2
#include <stdio.h>
 
3
#include <sys/types.h>
 
4
#include <sys/socket.h>
 
5
#include <netinet/in.h>
 
6
#include <sys/un.h>
 
7
#include <stdlib.h>
 
8
#include <errno.h>
 
9
#include <sys/time.h>
 
10
#include <time.h>
 
11
#include <unistd.h>
 
12
#include <netdb.h>
 
13
#include <string.h>
 
14
 
 
15
#if HAVE_GETOPT_H
 
16
#include <getopt.h>
 
17
#endif
 
18
 
 
19
#define POS_TIMESTAMP1   4
 
20
#define POS_SEQ          49
 
21
#define POS_TIMESTAMP2   87
 
22
 
 
23
#define MAX_MESSAGE_LENGTH 8192
 
24
 
 
25
#define USEC_PER_SEC     10e6
 
26
#define MIN(a, b)    ((a) < (b) ? (a) : (b))
 
27
 
 
28
static inline unsigned long
 
29
time_val_diff(struct timeval *t1, struct timeval *t2)
 
30
{
 
31
  return (t1->tv_sec - t2->tv_sec) * USEC_PER_SEC + (t1->tv_usec - t2->tv_usec);
 
32
}
 
33
 
 
34
void
 
35
gen_messages(int sock, int rate, int message_length, int interval)
 
36
{
 
37
  struct timeval now, start, last_ts_format, last_throttle_check;
 
38
  char linebuf[MAX_MESSAGE_LENGTH + 1];
 
39
  char stamp[32];
 
40
  char intbuf[16];
 
41
  int linelen;
 
42
  int i, run_id;
 
43
  unsigned long count = 0, last_count = 0;
 
44
  char padding[] = "PADD";
 
45
  long buckets = rate - (rate / 10);
 
46
  double diff;
 
47
  
 
48
  gettimeofday(&start, NULL);
 
49
  now = start;
 
50
  last_throttle_check = now;
 
51
  run_id = start.tv_sec;
 
52
 
 
53
  /* force reformat of the timestamp */
 
54
  last_ts_format = now;
 
55
  last_ts_format.tv_sec--;
 
56
  
 
57
  linelen = snprintf(linebuf, sizeof(linebuf), "<38>2007-12-24T12:28:51 localhost localprg: seq: %010d, runid: %-10d, stamp: %-19s ", 0, run_id, "");
 
58
  
 
59
  for (i = linelen; i < message_length - 1; i++)
 
60
    {
 
61
      linebuf[i] = padding[(i - linelen) % (sizeof(padding) - 1)];
 
62
    }
 
63
  linebuf[message_length - 1] = '\n';
 
64
  linebuf[message_length] = 0;
 
65
  linelen = strlen(linebuf);
 
66
  
 
67
  while (now.tv_sec - start.tv_sec < interval)
 
68
    {
 
69
      gettimeofday(&now, NULL);
 
70
      
 
71
      if (now.tv_sec != last_ts_format.tv_sec)
 
72
        {
 
73
          int len;
 
74
          struct tm *tm;
 
75
          
 
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);
 
80
 
 
81
          diff = time_val_diff(&now, &last_ts_format);
 
82
          
 
83
          fprintf(stderr, "rate = %.2lf msg/sec              \r", ((double) (count - last_count) * USEC_PER_SEC) / diff);
 
84
          last_ts_format = now;
 
85
          last_count = count;
 
86
 
 
87
        }
 
88
 
 
89
      diff = time_val_diff(&now, &last_throttle_check);
 
90
      if (buckets == 0 || diff > 10e5)
 
91
        {
 
92
          /* check rate every 0.1sec */
 
93
          long new_buckets;
 
94
          
 
95
          new_buckets = (rate * diff) / USEC_PER_SEC;
 
96
          if (new_buckets)
 
97
            {
 
98
              buckets = MIN(rate, buckets + new_buckets);
 
99
              last_throttle_check = now;
 
100
            }
 
101
        }
 
102
 
 
103
      if (buckets == 0)
 
104
        {
 
105
          struct timespec tspec, trem;
 
106
          long msec = (1000 / rate) + 1;
 
107
 
 
108
          tspec.tv_sec = msec / 1000;
 
109
          tspec.tv_nsec = (msec % 1000) * 10e6;
 
110
          while (nanosleep(&tspec, &trem) < 0 && errno == EINTR)
 
111
            {
 
112
              tspec = trem;
 
113
            }
 
114
          /* recalculate buckets */
 
115
          continue;
 
116
        }
 
117
 
 
118
      /* add sequence number */
 
119
      snprintf(intbuf, sizeof(intbuf), "%010ld", count);
 
120
      memcpy(&linebuf[POS_SEQ], intbuf, 10);
 
121
          
 
122
      if (write(sock, linebuf, linelen) < 0)
 
123
        {
 
124
          fprintf(stderr, "Send error %s\n", strerror(errno));
 
125
          break;
 
126
        }
 
127
      buckets--;
 
128
      count++;
 
129
    }
 
130
  close(sock);
 
131
  
 
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);
 
135
}
 
136
 
 
137
void
 
138
usage()
 
139
{
 
140
  printf("loggen [options] target [port]\n"
 
141
         "Generate syslog messages at the specified rate\n\n"
 
142
         "Options:\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");
 
150
  exit(0);
 
151
}
 
152
 
 
153
int 
 
154
main(int argc, char *argv[])
 
155
{
 
156
#if HAVE_GETOPT_LONG
 
157
  struct option syslog_ng_options[] = 
 
158
    {
 
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' },
 
166
      { NULL, 0, NULL, 0 }
 
167
    };
 
168
#endif
 
169
  int rate = 1000;
 
170
  int unix_socket = 0;
 
171
  int sock_type = SOCK_STREAM;
 
172
  int sock = -1;
 
173
  int message_length = 256;
 
174
  int interval = 10;
 
175
  int opt;
 
176
 
 
177
#if HAVE_GETOPT_LONG
 
178
  while ((opt = getopt_long(argc, argv, "r:I:ixs:SDh", syslog_ng_options, NULL)) != -1)
 
179
#else
 
180
  while ((opt = getopt(argc, argv, "r:I:ixs:SDh")) != -1)
 
181
#endif
 
182
    {
 
183
      switch (opt) 
 
184
        {
 
185
        case 'r':
 
186
          rate = atoi(optarg);
 
187
          break;
 
188
        case 'I':
 
189
          interval = atoi(optarg);
 
190
          break;
 
191
        case 'i':
 
192
          unix_socket = 0;
 
193
          break;
 
194
        case 'x':
 
195
          unix_socket = 1;
 
196
          break;
 
197
        case 'D':
 
198
          sock_type = SOCK_DGRAM;
 
199
          break;
 
200
        case 'S':
 
201
          sock_type = SOCK_STREAM;
 
202
          break;
 
203
        case 's':
 
204
          message_length = atoi(optarg);
 
205
          break;
 
206
        case 'h':
 
207
          usage();
 
208
          break;
 
209
        }
 
210
    }
 
211
  if (!unix_socket)
 
212
    {
 
213
 
 
214
      if (argc - optind < 2)
 
215
        {
 
216
          fprintf(stderr, "No target server specified\n");
 
217
          usage();
 
218
        }
 
219
 
 
220
      if (1)
 
221
        {      
 
222
#if HAVE_GETADDRINFO
 
223
          struct addrinfo hints;
 
224
          struct addrinfo *res, *rp;
 
225
 
 
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)
 
232
            {
 
233
              fprintf(stderr, "Name lookup error\n");
 
234
              return 2;
 
235
            }
 
236
 
 
237
          for (rp = res; rp != NULL; rp = rp->ai_next) 
 
238
            {
 
239
              sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
 
240
              if (sock == -1)
 
241
                continue;
 
242
 
 
243
              if (connect(sock, rp->ai_addr, rp->ai_addrlen) != -1)
 
244
                break;
 
245
 
 
246
              close(sock);
 
247
              sock = -1;
 
248
            }
 
249
          freeaddrinfo(res);
 
250
#else
 
251
          struct hostent *he;
 
252
          struct servent *se;
 
253
          struct sockaddr_in s_in;
 
254
          
 
255
          he = gethostbyname(argv[optind]);
 
256
          if (!he)
 
257
            {
 
258
              fprintf(stderr, "Name lookup error\n");
 
259
              return 2;
 
260
            }
 
261
          s_in.sin_family = AF_INET;
 
262
          s_in.sin_addr = *(struct in_addr *) he->h_addr;
 
263
          
 
264
          se = getservbyname(argv[optind + 1], sock_type == SOCK_STREAM ? "tcp" : "udp");
 
265
          if (se)
 
266
            s_in.sin_port = se->s_port;
 
267
          else
 
268
            s_in.sin_port = htons(atoi(argv[optind + 1]));
 
269
 
 
270
          
 
271
          sock = socket(AF_INET, sock_type, 0);
 
272
          if (sock < 0)
 
273
            {
 
274
              fprintf(stderr, "Error creating socket: %s\n", strerror(errno));
 
275
              return 2;
 
276
            }
 
277
            
 
278
          if (connect(sock, (struct sockaddr *) &s_in, sizeof(s_in)) < 0)
 
279
            {
 
280
              close(sock);
 
281
              sock = -1;
 
282
            }
 
283
#endif
 
284
        }
 
285
      
 
286
      if (sock == -1)
 
287
        {
 
288
          fprintf(stderr, "Error connecting to target server: %s\n", strerror(errno));
 
289
          return 2;
 
290
        }
 
291
    }
 
292
  else
 
293
    {
 
294
      struct sockaddr_un saun;
 
295
      
 
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)
 
300
        {
 
301
          fprintf(stderr, "Error connecting to target server: %s\n", strerror(errno));
 
302
          return 2;
 
303
        }
 
304
    }
 
305
  
 
306
  gen_messages(sock, rate, message_length, interval);
 
307
  return 0;
 
308
}