/* *************************************************************************** * Read statistics sent by sadc, the data collector. *************************************************************************** */ void read_stats(void) { int curr = 1; unsigned long lines; unsigned int rows = 23; int dis_hdr = 0; /* Don't buffer data if redirected to a pipe... */ setbuf(stdout, NULL); /* Read stats header */ read_header_data(); if (!get_activity_nr(act, AO_SELECTED, COUNT_ACTIVITIES)) { fprintf(stderr, _("Requested activities not available\n")); exit(1); } /* Determine if a stat line header has to be displayed */ dis_hdr = check_line_hdr(); lines = rows = get_win_height(); /* Perform required allocations */ allocate_structures(act); /* Print report header */ print_report_hdr(flags, &rectime, &file_hdr, act[get_activity_position(act, A_CPU)]->nr); /* Read system statistics sent by the data collector */ read_sadc_stat_bunch(0); if (!interval) { /* Display stats since boot time and exit */ write_stats_startup(0); } /* Save the first stats collected. Will be used to compute the average */ copy_structures(act, id_seq, record_hdr, 2, 0); /* Set a handler for SIGINT */ memset(&int_act, 0, sizeof(int_act)); int_act.sa_handler = (void *) int_handler; int_act.sa_flags = SA_RESTART; sigaction(SIGINT, &int_act, NULL); /* Main loop */ do { /* Get stats */ read_sadc_stat_bunch(curr); /* Print results */ if (!dis_hdr) { dis = lines / rows; if (dis) { lines %= rows; } lines++; } write_stats(curr, USE_SADC, &count, NO_TM_START, tm_end.use, NO_RESET, ALL_ACTIVITIES); if (record_hdr[curr].record_type == R_LAST_STATS) { /* File rotation is happening: Re-read header data sent by sadc */ read_header_data(); allocate_structures(act); } if (count > 0) { count--; } if (count) { if (sigint_caught) { /* SIGINT signal caught => Display average stats */ count = 0; } else { curr ^= 1; } } } while (count); /* Print statistics average */ dis = dis_hdr; write_stats_avg(curr, USE_SADC, ALL_ACTIVITIES); }
/* *************************************************************************** * Read statistics from a system activity data file. * * IN: * @from_file Input file name. *************************************************************************** */ void read_stats_from_file(char from_file[]) { struct file_magic file_magic; struct file_activity *file_actlst = NULL; int curr = 1, i, p; int ifd, rtype; int rows, eosaf = TRUE, reset = FALSE; long cnt = 1; off_t fpos; /* Get window size */ rows = get_win_height(); /* Read file headers and activity list */ check_file_actlst(&ifd, from_file, act, &file_magic, &file_hdr, &file_actlst, id_seq, FALSE); /* Perform required allocations */ allocate_structures(act); /* Print report header */ print_report_hdr(flags, &rectime, &file_hdr, act[get_activity_position(act, A_CPU)]->nr); /* Read system statistics from file */ do { /* * If this record is a special (RESTART or COMMENT) one, print it and * (try to) get another one. */ do { if (sa_fread(ifd, &record_hdr[0], RECORD_HEADER_SIZE, SOFT_SIZE)) /* End of sa data file */ return; rtype = record_hdr[0].record_type; if ((rtype == R_RESTART) || (rtype == R_COMMENT)) { sar_print_special(0, tm_start.use, tm_end.use, rtype, ifd, from_file, &file_magic); } else { /* * OK: Previous record was not a special one. * So read now the extra fields. */ read_file_stat_bunch(act, 0, ifd, file_hdr.sa_act_nr, file_actlst); if (sar_get_record_timestamp_struct(0)) /* * An error was detected. * The timestamp hasn't been updated. */ continue; } } while ((rtype == R_RESTART) || (rtype == R_COMMENT) || (tm_start.use && (datecmp(&rectime, &tm_start) < 0)) || (tm_end.use && (datecmp(&rectime, &tm_end) >=0))); /* Save the first stats collected. Will be used to compute the average */ copy_structures(act, id_seq, record_hdr, 2, 0); reset = TRUE; /* Set flag to reset last_uptime variable */ /* Save current file position */ if ((fpos = lseek(ifd, 0, SEEK_CUR)) < 0) { perror("lseek"); exit(2); } /* * Read and write stats located between two possible Linux restarts. * Activities that should be displayed are saved in id_seq[] array. */ for (i = 0; i < NR_ACT; i++) { if (!id_seq[i]) continue; if ((p = get_activity_position(act, id_seq[i])) < 0) { /* Should never happen */ PANIC(1); } if (!IS_SELECTED(act[p]->options)) continue; if (!HAS_MULTIPLE_OUTPUTS(act[p]->options)) { handle_curr_act_stats(ifd, fpos, &curr, &cnt, &eosaf, rows, act[p]->id, &reset, file_actlst, from_file, &file_magic); } else { unsigned int optf, msk; optf = act[p]->opt_flags; for (msk = 1; msk < 0x10; msk <<= 1) { if (act[p]->opt_flags & msk) { act[p]->opt_flags &= msk; handle_curr_act_stats(ifd, fpos, &curr, &cnt, &eosaf, rows, act[p]->id, &reset, file_actlst, from_file, &file_magic); act[p]->opt_flags = optf; } } } } if (!cnt) { /* Go to next Linux restart, if possible */ do { eosaf = sa_fread(ifd, &record_hdr[curr], RECORD_HEADER_SIZE, SOFT_SIZE); rtype = record_hdr[curr].record_type; if (!eosaf && (rtype != R_RESTART) && (rtype != R_COMMENT)) { read_file_stat_bunch(act, curr, ifd, file_hdr.sa_act_nr, file_actlst); } else if (!eosaf && (rtype == R_COMMENT)) { /* This was a COMMENT record: print it */ sar_print_special(curr, tm_start.use, tm_end.use, R_COMMENT, ifd, from_file, &file_magic); } } while (!eosaf && (rtype != R_RESTART)); } /* The last record we read was a RESTART one: Print it */ if (!eosaf && (record_hdr[curr].record_type == R_RESTART)) { sar_print_special(curr, tm_start.use, tm_end.use, R_RESTART, ifd, from_file, &file_magic); } } while (!eosaf); close(ifd); free(file_actlst); }
int main(int argc, char *argv[]) { libtrace_t *trace; libtrace_packet_t *packet; libtrace_filter_t *filter=NULL; session_manager_t *sm; uint64_t f; while(1) { int option_index; struct option long_options[] = { { "filter", 1, 0, 'f' }, { "interval", 1, 0, 'i' }, { "count", 1, 0, 'c' }, { "exit", 1, 0, 'e' }, { "relative", 0, 0, 'r' }, { "help", 0, 0, 'h' }, { "libtrace-help",0, 0, 'H' }, { NULL, 0, 0, 0 } }; int c= getopt_long(argc, argv, "c:e:f:i:hHr", long_options, &option_index); if (c==-1) break; switch (c) { case 'f': filter=trace_create_filter(optarg); break; case 'i': packet_interval=atof(optarg); break; case 'c': packet_count=atoi(optarg); packet_interval=UINT32_MAX; // make sure only one is defined break; case 'e': report_periods=atoi(optarg); break; case 'r': report_rel_time = 1; break; case 'H': trace_help(); return 1; default: fprintf(stderr,"Unknown option: %c\n",c); /* FALL THRU */ case 'h': usage(argv[0]); return 1; } } if (optind>=argc) { fprintf(stderr,"Missing input uri\n"); usage(argv[0]); return 1; } while (optind<argc) { // create tcp session manager sm = session_manager_create(); // create and register the data-ack based RTT module session_manager_register_module(sm,rtt_n_sequence_module()); fprintf(stderr, "Processing %s\n",argv[optind]); trace = trace_create(argv[optind]); ++optind; if (trace_is_err(trace)) { trace_perror(trace,"Opening trace file"); return 1; } if (filter && trace_config(trace,TRACE_OPTION_FILTER,filter)==1) { trace_perror(trace,"Configuring filter"); } if (trace_start(trace)) { trace_perror(trace,"Starting trace"); trace_destroy(trace); return 1; } packet = trace_create_packet(); print_report_hdr(); reset_report(); last_report_ts = 0; last_packet_ts = 0; while (trace_read_packet(trace,packet)>0) { per_packet(packet,session_manager_update(sm,packet)); if (report_periods != UINT64_MAX && reported >= report_periods) { break; } } // remaining pkts (or all if no period set) if ((reports[OUT].count+reports[IN].count) > 0 || (packet_interval == UINT32_MAX && packet_count == UINT64_MAX)) { double ts = trace_get_seconds(packet); if (report_rel_time) { print_report(ts-last_report_ts); } else { print_report(ts); } } trace_destroy_packet(packet); if (trace_is_err(trace)) { trace_perror(trace,"Reading packets"); } // some stats f=trace_get_received_packets(trace); if (f!=UINT64_MAX) fprintf(stderr,"%" PRIu64 " packets on input\n",f); f=trace_get_filtered_packets(trace); if (f!=UINT64_MAX) fprintf(stderr,"%" PRIu64 " packets filtered\n",f); f=trace_get_dropped_packets(trace); if (f!=UINT64_MAX) fprintf(stderr,"%" PRIu64 " packets dropped\n",f); f=trace_get_accepted_packets(trace); if (f!=UINT64_MAX) fprintf(stderr,"%" PRIu64 " packets accepted\n",f); trace_destroy(trace); session_manager_destroy(sm); } return 0; }