source: tools/tracertstats/tracertstats.c @ 5261dbd

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivegetfragoffhelplibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since 5261dbd was 65cdb7f, checked in by Perry Lorier <perry@…>, 16 years ago

Add a "realtime" statistics module. This can display stats every "n" seconds,
or every "n" packets.

Has "csv", "html" and "png" output formats currently. (png output module
really should be autoconf'd out if the required modules don't exist).

I'd like to add odoc formats, and I probably should add a "plain text" one
too.

  • Property mode set to 100644
File size: 5.1 KB
Line 
1/*
2 * This file is part of libtrace
3 *
4 * Copyright (c) 2004 The University of Waikato, Hamilton, New Zealand.
5 * Authors: Daniel Lawson
6 *          Perry Lorier
7 *         
8 * All rights reserved.
9 *
10 * This code has been developed by the University of Waikato WAND
11 * research group. For further information please see http://www.wand.net.nz/
12 *
13 * libtrace is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * libtrace is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with libtrace; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26 *
27 * $Id$
28 *
29 */
30
31//
32// This program takes a series of traces and bpf filters and outputs how many
33// bytes/packets every time interval
34
35#include <stdio.h>
36#include <stdlib.h>
37#include <assert.h>
38#include <string.h>
39#include <sys/time.h>
40#include <sys/types.h>
41#include <time.h>
42
43#include <netinet/in.h>
44#include <netinet/in_systm.h>
45#include <netinet/tcp.h>
46#include <netinet/ip.h>
47#include <netinet/ip_icmp.h>
48#include <arpa/inet.h>
49#include <sys/socket.h>
50#include <getopt.h>
51#include <inttypes.h>
52
53#include "libtrace.h"
54#include "output.h"
55
56struct libtrace_t *trace;
57char *output_format=NULL;
58
59struct filter_t {
60        char *expr;
61        struct libtrace_filter_t *filter;
62        uint64_t count;
63        uint64_t bytes;
64} *filters = NULL;
65int filter_count=0;
66uint64_t totcount;
67uint64_t totbytes;
68
69uint64_t packet_count=UINT64_MAX;
70uint64_t packet_interval=UINT64_MAX;
71
72
73struct output_data_t *output;
74
75void report_results(double ts,uint64_t count,uint64_t bytes)
76{
77        int i=0;
78        output_set_data_time(output,0,ts);
79        output_set_data_int(output,1,count);
80        output_set_data_int(output,2,bytes);
81        for(i=0;i<filter_count;++i) {
82                output_set_data_int(output,i*2+3,filters[i].count);
83                output_set_data_int(output,i*2+4,filters[i].bytes);
84                filters[i].count=filters[i].bytes=0;
85        }
86        output_flush_row(output);
87}
88
89/* Process a trace, counting packets that match filter(s) */
90void run_trace(char *uri) 
91{
92        struct libtrace_packet_t packet;
93        int i;
94        uint64_t count = 0;
95        uint64_t bytes = 0;
96        double last_ts = 0;
97
98        output=output_init(uri,output_format?:"csv");
99        output_add_column(output,"unix_time");
100        output_add_column(output,"packets");
101        output_add_column(output,"bytes");
102        for(i=0;i<filter_count;++i) {
103                char buff[1024];
104                snprintf(buff,sizeof(buff),"%s packets",filters[i].expr);
105                output_add_column(output,buff);
106                snprintf(buff,sizeof(buff),"%s bytes",filters[i].expr);
107                output_add_column(output,buff);
108        }
109        output_flush_headings(output);
110
111
112        trace = trace_create(uri);
113
114        for (;;) {
115                int psize;
116                if ((psize = trace_read_packet(trace, &packet)) <1) {
117                        break;
118                }
119
120                for(i=0;i<filter_count;++i) {
121                        if(trace_bpf_filter(filters[i].filter,&packet)) {
122                                ++filters[i].count;
123                                filters[i].bytes+=trace_get_wire_length(&packet);
124                        }
125                }
126
127                ++count;
128                bytes+=trace_get_wire_length(&packet);
129
130                if (packet_interval!=UINT64_MAX
131                  &&(last_ts==0 || last_ts<trace_get_seconds(&packet))) {
132                        if (last_ts==0)
133                                last_ts=trace_get_seconds(&packet);
134                        report_results(trace_get_seconds(&packet),count,bytes);
135                        count=0;
136                        bytes=0;
137                        last_ts+=packet_interval;
138                }
139
140                if (count > packet_count) {
141                        report_results(trace_get_seconds(&packet),count,bytes);
142                        count=0;
143                        bytes=0;
144                }
145        }
146        report_results(trace_get_seconds(&packet),count,bytes);
147
148        trace_destroy(trace);
149        output_destroy(output);
150}
151
152void usage(char *argv0)
153{
154        fprintf(stderr,"Usage: %s [--filter|-f bpf ]... libtraceuri...\n",argv0);
155}
156
157int main(int argc, char *argv[]) {
158
159        int i;
160
161        while(1) {
162                int option_index;
163                struct option long_options[] = {
164                        { "filter",     1, 0, 'f' },
165                        { "interval",   1, 0, 'i' },
166                        { "count",      1, 0, 'c' },
167                        { "output-format",1,0,'o' },
168                        { NULL,         0, 0, 0   },
169                };
170
171                int c=getopt_long(argc, argv, "c:f:i:o:",
172                                long_options, &option_index);
173
174                if (c==-1)
175                        break;
176
177                switch (c) {
178                        case 'f':
179                                ++filter_count;
180                                filters=realloc(filters,filter_count*sizeof(struct filter_t));
181                                filters[filter_count-1].expr=strdup(optarg);
182                                filters[filter_count-1].filter=trace_bpf_setfilter(optarg);
183                                filters[filter_count-1].count=0;
184                                filters[filter_count-1].bytes=0;
185                                break;
186                        case 'i':
187                                packet_interval=atoi(optarg);
188                                break;
189                        case 'c':
190                                packet_interval=atoi(optarg);
191                                break;
192                        case 'o':
193                                if (output_format) free(output_format);
194                                output_format=strdup(optarg);
195                                break;
196                        default:
197                                fprintf(stderr,"Unknown option: %c\n",c);
198                                usage(argv[0]);
199                                return 1;
200                }
201        }
202
203        if (packet_count == UINT64_MAX && packet_interval == UINT64_MAX) {
204                packet_interval = 300; /* every 5 minutes */
205        }
206
207        for(i=optind;i<argc;++i) {
208                run_trace(argv[i]);
209        }
210
211        return 0;
212}
Note: See TracBrowser for help on using the repository browser.