aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2010-03-29 17:08:24 -0400
committerSteven Rostedt <rostedt@goodmis.org>2010-03-29 17:08:24 -0400
commit47d850792f4e2340cbd53b6cf76bc16125d66fd4 (patch)
treebde31cc35e1490a30b4f5684510aa0a49f326d62
parent3d85518bf58a7052ff18e2c33547ceefac5c1939 (diff)
trace-cmd: Add -l option to trace-cmd listen for log file output
Add a way to pipe log info to another file, especially useful in daemon mode. Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
-rw-r--r--Documentation/trace-cmd-listen.1.txt3
-rw-r--r--trace-listen.c98
-rw-r--r--trace-usage.c3
3 files changed, 83 insertions, 21 deletions
diff --git a/Documentation/trace-cmd-listen.1.txt b/Documentation/trace-cmd-listen.1.txt
index 15014e6..c9bafcd 100644
--- a/Documentation/trace-cmd-listen.1.txt
+++ b/Documentation/trace-cmd-listen.1.txt
@@ -33,6 +33,9 @@ OPTIONS
33 This option overrides the default 'trace' in the 'trace.HOST:PORT.dat' that 33 This option overrides the default 'trace' in the 'trace.HOST:PORT.dat' that
34 is created when a remote host connects. 34 is created when a remote host connects.
35 35
36*-l* 'filename'::
37 This option writes the output messages to a log file instead of standard output.
38
36 39
37SEE ALSO 40SEE ALSO
38-------- 41--------
diff --git a/trace-listen.c b/trace-listen.c
index e12431c..9564620 100644
--- a/trace-listen.c
+++ b/trace-listen.c
@@ -43,6 +43,8 @@ static char *output_dir;
43static char *default_output_file = "trace"; 43static char *default_output_file = "trace";
44static char *output_file; 44static char *output_file;
45 45
46static FILE *logfp;
47
46static int debug; 48static int debug;
47 49
48static int use_tcp; 50static int use_tcp;
@@ -107,6 +109,51 @@ static void finish(int sig)
107 done = 1; 109 done = 1;
108} 110}
109 111
112#define LOG_BUF_SIZE 1024
113static void __plog(const char *prefix, const char *fmt, va_list ap,
114 FILE *fp)
115{
116 static int newline = 1;
117 char buf[LOG_BUF_SIZE];
118 int r;
119
120 r = vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
121
122 if (r > LOG_BUF_SIZE)
123 r = LOG_BUF_SIZE;
124
125 if (logfp) {
126 if (newline)
127 fprintf(logfp, "[%d]%s%.*s", getpid(), prefix, r, buf);
128 else
129 fprintf(logfp, "[%d]%s%.*s", getpid(), prefix, r, buf);
130 newline = buf[r - 1] == '\n';
131 fflush(logfp);
132 return;
133 }
134
135 fprintf(fp, "%.*s", r, buf);
136}
137
138static void plog(const char *fmt, ...)
139{
140 va_list ap;
141
142 va_start(ap, fmt);
143 __plog("", fmt, ap, stdout);
144 va_end(ap);
145}
146
147static void pdie(const char *fmt, ...)
148{
149 va_list ap;
150
151 va_start(ap, fmt);
152 __plog("Error: ", fmt, ap, stderr);
153 va_end(ap);
154 exit(-1);
155}
156
110static void process_udp_child(int sfd, const char *host, const char *port, 157static void process_udp_child(int sfd, const char *host, const char *port,
111 int cpu, int page_size) 158 int cpu, int page_size)
112{ 159{
@@ -124,15 +171,15 @@ static void process_udp_child(int sfd, const char *host, const char *port,
124 tempfile = get_temp_file(host, port, cpu); 171 tempfile = get_temp_file(host, port, cpu);
125 fd = open(tempfile, O_WRONLY | O_TRUNC | O_CREAT, 0644); 172 fd = open(tempfile, O_WRONLY | O_TRUNC | O_CREAT, 0644);
126 if (fd < 0) 173 if (fd < 0)
127 die("creating %s", tempfile); 174 pdie("creating %s", tempfile);
128 175
129 if (use_tcp) { 176 if (use_tcp) {
130 if (listen(sfd, backlog) < 0) 177 if (listen(sfd, backlog) < 0)
131 die("listen"); 178 pdie("listen");
132 peer_addr_len = sizeof(peer_addr); 179 peer_addr_len = sizeof(peer_addr);
133 cfd = accept(sfd, (struct sockaddr *)&peer_addr, &peer_addr_len); 180 cfd = accept(sfd, (struct sockaddr *)&peer_addr, &peer_addr_len);
134 if (cfd < 0) 181 if (cfd < 0)
135 die("accept"); 182 pdie("accept");
136 close(sfd); 183 close(sfd);
137 sfd = cfd; 184 sfd = cfd;
138 } 185 }
@@ -141,7 +188,7 @@ static void process_udp_child(int sfd, const char *host, const char *port,
141 /* TODO, make this copyless! */ 188 /* TODO, make this copyless! */
142 n = read(sfd, buf, page_size); 189 n = read(sfd, buf, page_size);
143 if (n < 0) 190 if (n < 0)
144 die("reading client"); 191 pdie("reading client");
145 if (!n) 192 if (!n)
146 break; 193 break;
147 /* UDP requires that we get the full size in one go */ 194 /* UDP requires that we get the full size in one go */
@@ -178,7 +225,7 @@ static int open_udp(const char *node, const char *port, int *pid,
178 225
179 s = getaddrinfo(NULL, buf, &hints, &result); 226 s = getaddrinfo(NULL, buf, &hints, &result);
180 if (s != 0) 227 if (s != 0)
181 die("getaddrinfo: error opening udp socket"); 228 pdie("getaddrinfo: error opening udp socket");
182 229
183 for (rp = result; rp != NULL; rp = rp->ai_next) { 230 for (rp = result; rp != NULL; rp = rp->ai_next) {
184 sfd = socket(rp->ai_family, rp->ai_socktype, 231 sfd = socket(rp->ai_family, rp->ai_socktype,
@@ -195,7 +242,7 @@ static int open_udp(const char *node, const char *port, int *pid,
195 if (rp == NULL) { 242 if (rp == NULL) {
196 freeaddrinfo(result); 243 freeaddrinfo(result);
197 if (++num_port > MAX_PORT_SEARCH) 244 if (++num_port > MAX_PORT_SEARCH)
198 die("No available ports to bind"); 245 pdie("No available ports to bind");
199 goto again; 246 goto again;
200 } 247 }
201 248
@@ -204,7 +251,7 @@ static int open_udp(const char *node, const char *port, int *pid,
204 *pid = fork(); 251 *pid = fork();
205 252
206 if (*pid < 0) 253 if (*pid < 0)
207 die("creating udp reader"); 254 pdie("creating udp reader");
208 255
209 if (!*pid) 256 if (!*pid)
210 process_udp_child(sfd, node, port, cpu, pagesize); 257 process_udp_child(sfd, node, port, cpu, pagesize);
@@ -242,7 +289,7 @@ static void process_client(const char *node, const char *port, int fd)
242 289
243 cpus = atoi(buf); 290 cpus = atoi(buf);
244 291
245 printf("cpus=%d\n", cpus); 292 plog("cpus=%d\n", cpus);
246 if (cpus < 0) 293 if (cpus < 0)
247 return; 294 return;
248 295
@@ -254,7 +301,7 @@ static void process_client(const char *node, const char *port, int fd)
254 301
255 pagesize = atoi(buf); 302 pagesize = atoi(buf);
256 303
257 printf("pagesize=%d\n", pagesize); 304 plog("pagesize=%d\n", pagesize);
258 if (pagesize <= 0) 305 if (pagesize <= 0)
259 return; 306 return;
260 307
@@ -295,14 +342,14 @@ static void process_client(const char *node, const char *port, int fd)
295 } 342 }
296 343
297 if (use_tcp) 344 if (use_tcp)
298 printf("Using TCP for live connection\n"); 345 plog("Using TCP for live connection\n");
299 346
300 /* Create the client file */ 347 /* Create the client file */
301 snprintf(buf, BUFSIZ, "%s.%s:%s.dat", output_file, node, port); 348 snprintf(buf, BUFSIZ, "%s.%s:%s.dat", output_file, node, port);
302 349
303 ofd = open(buf, O_RDWR | O_CREAT | O_TRUNC, 0644); 350 ofd = open(buf, O_RDWR | O_CREAT | O_TRUNC, 0644);
304 if (ofd < 0) 351 if (ofd < 0)
305 die("Can not create file %s", buf); 352 pdie("Can not create file %s", buf);
306 353
307 port_array = malloc_or_die(sizeof(int) * cpus); 354 port_array = malloc_or_die(sizeof(int) * cpus);
308 pid_array = malloc_or_die(sizeof(int) * cpus); 355 pid_array = malloc_or_die(sizeof(int) * cpus);
@@ -334,7 +381,7 @@ static void process_client(const char *node, const char *port, int fd)
334 do { 381 do {
335 s = write(ofd, buf+s, t); 382 s = write(ofd, buf+s, t);
336 if (s < 0) 383 if (s < 0)
337 die("writing to file"); 384 pdie("writing to file");
338 t -= s; 385 t -= s;
339 s = n - t; 386 s = n - t;
340 } while (t); 387 } while (t);
@@ -410,10 +457,10 @@ static void do_connection(int cfd, struct sockaddr_storage *peer_addr,
410 service, NI_MAXSERV, NI_NUMERICSERV); 457 service, NI_MAXSERV, NI_NUMERICSERV);
411 458
412 if (s == 0) 459 if (s == 0)
413 printf("Connected with %s:%s\n", 460 plog("Connected with %s:%s\n",
414 host, service); 461 host, service);
415 else { 462 else {
416 printf("Error with getnameinfo: %s\n", 463 plog("Error with getnameinfo: %s\n",
417 gai_strerror(s)); 464 gai_strerror(s));
418 close(cfd); 465 close(cfd);
419 return; 466 return;
@@ -425,7 +472,7 @@ static void do_connection(int cfd, struct sockaddr_storage *peer_addr,
425 if (nread > 0) 472 if (nread > 0)
426 nread = read(cfd, buf, BUFSIZ); 473 nread = read(cfd, buf, BUFSIZ);
427 if (cfd < 0) 474 if (cfd < 0)
428 die("client"); 475 pdie("client");
429 if (nread > 0) 476 if (nread > 0)
430 write(1, buf, nread); 477 write(1, buf, nread);
431 } while (nread); 478 } while (nread);
@@ -465,7 +512,7 @@ static void do_listen(char *port)
465 512
466 s = getaddrinfo(NULL, port, &hints, &result); 513 s = getaddrinfo(NULL, port, &hints, &result);
467 if (s != 0) 514 if (s != 0)
468 die("getaddrinfo: error opening %s", port); 515 pdie("getaddrinfo: error opening %s", port);
469 516
470 for (rp = result; rp != NULL; rp = rp->ai_next) { 517 for (rp = result; rp != NULL; rp = rp->ai_next) {
471 sfd = socket(rp->ai_family, rp->ai_socktype, 518 sfd = socket(rp->ai_family, rp->ai_socktype,
@@ -480,19 +527,19 @@ static void do_listen(char *port)
480 } 527 }
481 528
482 if (rp == NULL) 529 if (rp == NULL)
483 die("Could not bind"); 530 pdie("Could not bind");
484 531
485 freeaddrinfo(result); 532 freeaddrinfo(result);
486 533
487 if (listen(sfd, backlog) < 0) 534 if (listen(sfd, backlog) < 0)
488 die("listen"); 535 pdie("listen");
489 536
490 peer_addr_len = sizeof(peer_addr); 537 peer_addr_len = sizeof(peer_addr);
491 538
492 do { 539 do {
493 cfd = accept(sfd, (struct sockaddr *)&peer_addr, &peer_addr_len); 540 cfd = accept(sfd, (struct sockaddr *)&peer_addr, &peer_addr_len);
494 if (cfd < 0) 541 if (cfd < 0)
495 die("connecting"); 542 pdie("connecting");
496 543
497 do_connection(cfd, &peer_addr, peer_addr_len); 544 do_connection(cfd, &peer_addr, peer_addr_len);
498 545
@@ -507,6 +554,7 @@ static void start_daemon(void)
507 554
508void trace_listen(int argc, char **argv) 555void trace_listen(int argc, char **argv)
509{ 556{
557 char *logfile = NULL;
510 char *port = NULL; 558 char *port = NULL;
511 char *iface; 559 char *iface;
512 int daemon = 0; 560 int daemon = 0;
@@ -527,7 +575,7 @@ void trace_listen(int argc, char **argv)
527 {NULL, 0, NULL, 0} 575 {NULL, 0, NULL, 0}
528 }; 576 };
529 577
530 c = getopt_long (argc-1, argv+1, "+hp:o:d:i:D", 578 c = getopt_long (argc-1, argv+1, "+hp:o:d:i:l:D",
531 long_options, &option_index); 579 long_options, &option_index);
532 if (c == -1) 580 if (c == -1)
533 break; 581 break;
@@ -547,6 +595,9 @@ void trace_listen(int argc, char **argv)
547 case 'o': 595 case 'o':
548 output_file = optarg; 596 output_file = optarg;
549 break; 597 break;
598 case 'l':
599 logfile = optarg;
600 break;
550 case 'D': 601 case 'D':
551 daemon = 1; 602 daemon = 1;
552 break; 603 break;
@@ -574,6 +625,13 @@ void trace_listen(int argc, char **argv)
574 if (!output_dir) 625 if (!output_dir)
575 output_dir = default_output_dir; 626 output_dir = default_output_dir;
576 627
628 if (logfile) {
629 /* set the writes to a logfile instead */
630 logfp = fopen(logfile, "w");
631 if (!logfp)
632 die("creating log file %s", logfile);
633 }
634
577 if (chdir(output_dir) < 0) 635 if (chdir(output_dir) < 0)
578 die("Can't access directory %s", output_dir); 636 die("Can't access directory %s", output_dir);
579 637
diff --git a/trace-usage.c b/trace-usage.c
index 828fdd0..e834d44 100644
--- a/trace-usage.c
+++ b/trace-usage.c
@@ -104,11 +104,12 @@ static struct usage_help usage_help[] = {
104 { 104 {
105 "listen", 105 "listen",
106 "listen on a network socket for trace clients", 106 "listen on a network socket for trace clients",
107 " %s listen -p port[-D][-o file][-d dir]\n" 107 " %s listen -p port[-D][-o file][-d dir][-l logfile]\n"
108 " Creates a socket to listen for clients.\n" 108 " Creates a socket to listen for clients.\n"
109 " -D create it in daemon mode.\n" 109 " -D create it in daemon mode.\n"
110 " -o file name to use for clients.\n" 110 " -o file name to use for clients.\n"
111 " -d diretory to store client files.\n" 111 " -d diretory to store client files.\n"
112 " -l logfile to write messages to.\n"
112 }, 113 },
113 { 114 {
114 "list", 115 "list",