sadf.c
来自「linux下查看系统工具原码,如IOSTAT等」· C语言 代码 · 共 2,002 行 · 第 1/4 页
C
2,002 行
void write_xml_stats(short curr, short *tab){ int i, j, k; unsigned long long dt, itv, g_itv; char cur_time[64]; struct file_stats *fsi = &file_stats[curr], *fsj = &file_stats[!curr]; /* Set timestamp for current data */ set_loc_time(curr); /* Get interval values */ get_itv_value(&file_stats[curr], &file_stats[!curr], file_hdr.sa_proc, &itv, &g_itv); dt = itv / HZ; /* Correct rounding error for dt */ if ((itv % HZ) >= (HZ / 2)) dt++; strftime(cur_time, 64, "date=\"%Y-%m-%d\" time=\"%H:%M:%S\"", &loc_time); xprintf(*tab, "<timestamp %s interval=\"%llu\">", cur_time, dt); (*tab)++; /* proc/s */ xprintf(*tab, "<processes per=\"second\" proc=\"%.2f\"/>", S_VALUE(fsj->processes, fsi->processes, itv)); /* cswch/s */ xprintf(*tab, "<context-switch per=\"second\" cswch=\"%.2f\"/>", ll_s_value(fsj->context_swtch, fsi->context_swtch, itv)); /* cpu */ xprintf(*tab, "<cpu-load>"); xprintf(++(*tab), "<cpu number=\"all\" user=\"%.2f\" nice=\"%.2f\" " "system=\"%.2f\" iowait=\"%.2f\" steal=\"%.2f\" idle=\"%.2f\"/>", ll_sp_value(fsj->cpu_user, fsi->cpu_user, g_itv), ll_sp_value(fsj->cpu_nice, fsi->cpu_nice, g_itv), ll_sp_value(fsj->cpu_system, fsi->cpu_system, g_itv), ll_sp_value(fsj->cpu_iowait, fsi->cpu_iowait, g_itv), ll_sp_value(fsj->cpu_steal, fsi->cpu_steal, g_itv), (fsi->cpu_idle < fsj->cpu_idle) ? 0.0 : ll_sp_value(fsj->cpu_idle, fsi->cpu_idle, g_itv)); if (file_hdr.sa_proc) { unsigned long long pc_itv; struct stats_one_cpu *sci = st_cpu[curr], *scj = st_cpu[!curr]; for (i = 0; i <= file_hdr.sa_proc; i++, sci++, scj++) { /* Recalculate itv for current proc */ pc_itv = get_per_cpu_interval(sci, scj); xprintf(*tab, "<cpu number=\"%d\" user=\"%.2f\" nice=\"%.2f\" " "system=\"%.2f\" iowait=\"%.2f\" steal=\"%.2f\" idle=\"%.2f\"/>", i, ll_sp_value(scj->per_cpu_user, sci->per_cpu_user, pc_itv), ll_sp_value(scj->per_cpu_nice, sci->per_cpu_nice, pc_itv), ll_sp_value(scj->per_cpu_system, sci->per_cpu_system, pc_itv), ll_sp_value(scj->per_cpu_iowait, sci->per_cpu_iowait, pc_itv), ll_sp_value(scj->per_cpu_steal, sci->per_cpu_steal, pc_itv), (sci->per_cpu_idle < scj->per_cpu_idle) ? 0.0 : ll_sp_value(scj->per_cpu_idle, sci->per_cpu_idle, pc_itv)); } } xprintf(--(*tab), "</cpu-load>"); /* Interrupts */ xprintf(*tab, "<interrupts>"); xprintf(++(*tab), "<int-global per=\"second\">"); xprintf(++(*tab), "<irq intr=\"sum\" value=\"%.2f\"/>", ll_s_value(fsj->irq_sum, fsi->irq_sum, itv)); /* Display individual interrupts stats only if they are available in file */ if (GET_ONE_IRQ(file_hdr.sa_actflag)) { for (i = 0; i < NR_IRQS; i++) { xprintf(*tab, "<irq intr=\"%d\" value=\"%.2f\"/>", i, S_VALUE(interrupts[!curr][i], interrupts[curr][i], itv)); } } xprintf(--(*tab), "</int-global>"); if (file_hdr.sa_irqcpu) { int offset; struct stats_irq_cpu *p, *q, *p0, *q0; xprintf(*tab, "<int-proc per=\"second\">"); (*tab)++; for (k = 0; k <= file_hdr.sa_proc; k++) { for (j = 0; j < file_hdr.sa_irqcpu; j++) { p0 = st_irq_cpu[curr] + j; /* irq field set only for proc #0 */ /* * A value of ~0 means it is a remaining interrupt * which is no longer used, for example because the * number of interrupts has decreased in /proc/interrupts * or because we are appending data to an old sa file * with more interrupts than are actually available now. */ if (p0->irq == ~0) continue; q0 = st_irq_cpu[!curr] + j; offset = j; if (p0->irq != q0->irq) { if (j) offset = j - 1; q0 = st_irq_cpu[!curr] + offset; if ((p0->irq != q0->irq) && (j + 1 < file_hdr.sa_irqcpu)) offset = j + 1; q0 = st_irq_cpu[!curr] + offset; } if (p0->irq != q0->irq) continue; p = st_irq_cpu[curr] + k * file_hdr.sa_irqcpu + j; q = st_irq_cpu[!curr] + k * file_hdr.sa_irqcpu + offset; xprintf(*tab, "<irqcpu cpu=\"%d\" intr=\"%d\" value=\"%.2f\"/>", k, p0->irq, S_VALUE(q->interrupt, p->interrupt, itv)); } } xprintf(--(*tab), "</int-proc>"); } xprintf(--(*tab), "</interrupts>"); /* swap */ xprintf(*tab, "<swap-pages per=\"second\" pswpin=\"%.2f\" pswpout=\"%.2f\"/>", S_VALUE(fsj->pswpin, fsi->pswpin, itv), S_VALUE(fsj->pswpout, fsi->pswpout, itv)); /* io */ xprintf(*tab, "<io per=\"second\">"); xprintf(++(*tab), "<tps>%.2f</tps>", S_VALUE(fsj->dk_drive, fsi->dk_drive, itv)); xprintf(*tab, "<io-reads rtps=\"%.2f\" bread=\"%.2f\"/>", S_VALUE(fsj->dk_drive_rio, fsi->dk_drive_rio, itv), S_VALUE(fsj->dk_drive_rblk, fsi->dk_drive_rblk, itv)); xprintf(*tab, "<io-writes wtps=\"%.2f\" bwrtn=\"%.2f\"/>", S_VALUE(fsj->dk_drive_wio, fsi->dk_drive_wio, itv), S_VALUE(fsj->dk_drive_wblk, fsi->dk_drive_wblk, itv)); xprintf(--(*tab), "</io>"); /* Disks */ if (file_hdr.sa_nr_disk) { double tput, util, await, svctm, arqsz; struct disk_stats *sdi = st_disk[curr], *sdj; xprintf(*tab, "<disk per=\"second\">"); (*tab)++; for (i = 0; i < file_hdr.sa_nr_disk; i++, ++sdi) { if (!(sdi->major + sdi->minor)) continue; j = check_disk_reg(&file_hdr, st_disk, curr, !curr, i); sdj = st_disk[!curr] + j; tput = ((double) (sdi->nr_ios - sdj->nr_ios)) * HZ / itv; util = S_VALUE(sdj->tot_ticks, sdi->tot_ticks, itv); svctm = tput ? util / tput : 0.0; await = (sdi->nr_ios - sdj->nr_ios) ? ((sdi->rd_ticks - sdj->rd_ticks) + (sdi->wr_ticks - sdj->wr_ticks)) / ((double) (sdi->nr_ios - sdj->nr_ios)) : 0.0; arqsz = (sdi->nr_ios - sdj->nr_ios) ? ((sdi->rd_sect - sdj->rd_sect) + (sdi->wr_sect - sdj->wr_sect)) / ((double) (sdi->nr_ios - sdj->nr_ios)) : 0.0; xprintf(*tab, "<disk-device dev=\"%s\" tps=\"%.2f\" rd_sec=\"%.2f\" " "wr_sec=\"%.2f\" avgrq-sz=\"%.2f\" avgqu-sz=\"%.2f\" " "await=\"%.2f\" svctm=\"%.2f\" util-percent=\"%.2f\"/>", /* Confusion possible here between index and minor numbers */ get_devname(sdi->major, sdi->minor, USE_PRETTY_OPTION(flags)), S_VALUE(sdj->nr_ios, sdi->nr_ios, itv), ll_s_value(sdj->rd_sect, sdi->rd_sect, itv), ll_s_value(sdj->wr_sect, sdi->wr_sect, itv), /* See iostat for explanations */ arqsz, S_VALUE(sdj->rq_ticks, sdi->rq_ticks, itv) / 1000.0, await, svctm, util / 10.0); } xprintf(--(*tab), "</disk>"); } /* Serial lines */ if (file_hdr.sa_serial) { struct stats_serial *ssi = st_serial[curr], *ssj = st_serial[!curr]; xprintf(*tab, "<serial per=\"second\">"); (*tab)++; for (i = 0; i < file_hdr.sa_serial; i++, ssi++, ssj++) { if (ssi->line == ~0) continue; if (ssi->line == ssj->line) { xprintf(*tab, "<tty line=\"%d\" rcvin=\"%.2f\" xmtin=\"%.2f\" " "framerr=\"%.2f\" prtyerr=\"%.2f\" brk=\"%.2f\" " "ovrun=\"%.2f\"/>", ssi->line, S_VALUE(ssj->rx, ssi->rx, itv), S_VALUE(ssj->tx, ssi->tx, itv), S_VALUE(ssj->frame, ssi->frame, itv), S_VALUE(ssj->parity, ssi->parity, itv), S_VALUE(ssj->brk, ssi->brk, itv), S_VALUE(ssj->overrun, ssi->overrun, itv)); } } xprintf(--(*tab), "</serial>"); } /* Network */ xprintf(*tab, "<network per=\"second\">"); (*tab)++; if (file_hdr.sa_iface) { struct stats_net_dev *sndi = st_net_dev[curr], *sndj; for (i = 0; i < file_hdr.sa_iface; i++, sndi++) { if (!strcmp(sndi->interface, "?")) continue; j = check_iface_reg(&file_hdr, st_net_dev, curr, !curr, i); sndj = st_net_dev[!curr] + j; xprintf((*tab)++, "<net-device iface=\"%s\">", sndi->interface); xprintf(*tab, "<net-dev rxpck=\"%.2f\" txpck=\"%.2f\" rxbyt=\"%.2f\" " "txbyt=\"%.2f\" rxcmp=\"%.2f\" txcmp=\"%.2f\" rxmcst=\"%.2f\"/>", S_VALUE(sndj->rx_packets, sndi->rx_packets, itv), S_VALUE(sndj->tx_packets, sndi->tx_packets, itv), S_VALUE(sndj->rx_bytes, sndi->rx_bytes, itv), S_VALUE(sndj->tx_bytes, sndi->tx_bytes, itv), S_VALUE(sndj->rx_compressed, sndi->rx_compressed, itv), S_VALUE(sndj->tx_compressed, sndi->tx_compressed, itv), S_VALUE(sndj->multicast, sndi->multicast, itv)); xprintf(*tab, "<net-edev rxerr=\"%.2f\" txerr=\"%.2f\" coll=\"%.2f\" " "rxdrop=\"%.2f\" txdrop=\"%.2f\" txcarr=\"%.2f\" " "rxfram=\"%.2f\" rxfifo=\"%.2f\" txfifo=\"%.2f\"/>", S_VALUE(sndj->rx_errors, sndi->rx_errors, itv), S_VALUE(sndj->tx_errors, sndi->tx_errors, itv), S_VALUE(sndj->collisions, sndi->collisions, itv), S_VALUE(sndj->rx_dropped, sndi->rx_dropped, itv), S_VALUE(sndj->tx_dropped, sndi->tx_dropped, itv), S_VALUE(sndj->tx_carrier_errors, sndi->tx_carrier_errors, itv), S_VALUE(sndj->rx_frame_errors, sndi->rx_frame_errors, itv), S_VALUE(sndj->rx_fifo_errors, sndi->rx_fifo_errors, itv), S_VALUE(sndj->tx_fifo_errors, sndi->tx_fifo_errors, itv)); xprintf(--(*tab), "</net-device>"); } } xprintf(*tab, "<net-nfs call=\"%.2f\" retrans=\"%.2f\" read=\"%.2f\" " "write=\"%.2f\" access=\"%.2f\" getatt=\"%.2f\"/>", S_VALUE(fsj->nfs_rpccnt, fsi->nfs_rpccnt, itv), S_VALUE(fsj->nfs_rpcretrans, fsi->nfs_rpcretrans, itv), S_VALUE(fsj->nfs_readcnt, fsi->nfs_readcnt, itv), S_VALUE(fsj->nfs_writecnt, fsi->nfs_writecnt, itv), S_VALUE(fsj->nfs_accesscnt, fsi->nfs_accesscnt, itv), S_VALUE(fsj->nfs_getattcnt, fsi->nfs_getattcnt, itv)); xprintf(*tab, "<net-nfsd scall=\"%.2f\" badcall=\"%.2f\" packet=\"%.2f\" " "udp=\"%.2f\" tcp=\"%.2f\" hit=\"%.2f\" miss=\"%.2f\" " "sread=\"%.2f\" swrite=\"%.2f\" saccess=\"%.2f\" sgetatt=\"%.2f\"/>", S_VALUE(fsj->nfsd_rpccnt, fsi->nfsd_rpccnt, itv), S_VALUE(fsj->nfsd_rpcbad, fsi->nfsd_rpcbad, itv), S_VALUE(fsj->nfsd_netcnt, fsi->nfsd_netcnt, itv), S_VALUE(fsj->nfsd_netudpcnt, fsi->nfsd_netudpcnt, itv), S_VALUE(fsj->nfsd_nettcpcnt, fsi->nfsd_nettcpcnt, itv), S_VALUE(fsj->nfsd_rchits, fsi->nfsd_rchits, itv), S_VALUE(fsj->nfsd_rcmisses, fsi->nfsd_rcmisses, itv), S_VALUE(fsj->nfsd_readcnt, fsi->nfsd_readcnt, itv), S_VALUE(fsj->nfsd_writecnt, fsi->nfsd_writecnt, itv), S_VALUE(fsj->nfsd_accesscnt, fsi->nfsd_accesscnt, itv), S_VALUE(fsj->nfsd_getattcnt, fsi->nfsd_getattcnt, itv)); xprintf(*tab, "<net-sock totsck=\"%u\" tcpsck=\"%u\" udpsck=\"%u\" " "rawsck=\"%u\" ip-frag=\"%u\"/>", fsi->sock_inuse, fsi->tcp_inuse, fsi->udp_inuse, fsi->raw_inuse, fsi->frag_inuse); xprintf(--(*tab), "</network>"); /* paging */ xprintf(*tab, "<paging per=\"second\" pgpgin=\"%.2f\" pgpgout=\"%.2f\" " "fault=\"%.2f\" majflt=\"%.2f\"/>", S_VALUE(fsj->pgpgin, fsi->pgpgin, itv), S_VALUE(fsj->pgpgout, fsi->pgpgout, itv), S_VALUE(fsj->pgfault, fsi->pgfault, itv), S_VALUE(fsj->pgmajfault, fsi->pgmajfault, itv)); /* memory */ xprintf(*tab, "<memory per=\"second\" unit=\"kB\">"); xprintf(++(*tab), "<memfree>%lu</memfree>", fsi->frmkb); xprintf(*tab, "<memused>%lu</memused>", fsi->tlmkb - fsi->frmkb); xprintf(*tab, "<memused-percent>%.2f</memused-percent>", fsi->tlmkb ? SP_VALUE(fsi->frmkb, fsi->tlmkb, fsi->tlmkb) : 0.0); xprintf(*tab, "<swpfree>%lu</swpfree>", fsi->frskb); xprintf(*tab, "<swpused>%lu</swpused>", fsi->tlskb - fsi->frskb); xprintf(*tab, "<swpused-percent>%.2f</swpused-percent>", fsi->tlskb ? SP_VALUE(fsi->frskb, fsi->tlskb, fsi->tlskb) : 0.0); xprintf(*tab, "<swpcad>%lu</swpcad>", fsi->caskb); xprintf(*tab, "<buffers>%lu</buffers>", fsi->bufkb); xprintf(*tab, "<cached>%lu</cached>", fsi->camkb); xprintf(*tab, "<frmpg>%.2f</frmpg>", S_VALUE((double) PG(fsj->frmkb), (double) PG(fsi->frmkb), itv)); xprintf(*tab, "<bufpg>%.2f</bufpg>", S_VALUE((double) PG(fsj->bufkb), (double) PG(fsi->bufkb), itv)); xprintf(*tab, "<campg>%.2f</campg>", S_VALUE((double) PG(fsj->camkb), (double) PG(fsi->camkb), itv)); xprintf(--(*tab), "</memory>"); /* kernel */ xprintf(*tab, "<kernel per=\"second\">"); xprintf(++(*tab), "<dentunusd>%u</dentunusd>", fsi->dentry_stat); xprintf(*tab, "<file-sz>%u</file-sz>", fsi->file_used); xprintf(*tab, "<inode-sz>%u</inode-sz>", fsi->inode_used); xprintf(*tab, "<super-sz>%u</super-sz>", fsi->super_used); xprintf(*tab, "<super-sz-percent>%.2f</super-sz-percent>", fsi->super_max ? ((double) (fsi->super_used * 100)) / fsi->super_max : 0.0); xprintf(*tab, "<dquot-sz>%u</dquot-sz>", fsi->dquot_used); xprintf(*tab, "<dquot-sz-percent>%.2f</dquot-sz-percent>", fsi->dquot_max ? ((double) (fsi->dquot_used * 100)) / fsi->dquot_max : 0.0); xprintf(*tab, "<rtsig-sz>%u</rtsig-sz>", fsi->rtsig_queued); xprintf(*tab, "<rtsig-sz-percent>%.2f</rtsig-sz-percent>", fsi->rtsig_max ? ((double) (fsi->rtsig_queued * 100)) / fsi->rtsig_max : 0.0); xprintf(--(*tab), "</kernel>"); /* queue */ xprintf(*tab, "<queue runq-sz=\"%lu\" plist-sz=\"%u\" ldavg-1=\"%.2f\" " "ldavg-5=\"%.2f\" ldavg-15=\"%.2f\"/>", fsi->nr_running, fsi->nr_threads, (double) fsi->load_avg_1 / 100, (double) fsi->load_avg_5 / 100, (double) fsi->load_avg_15 / 100); xprintf(--(*tab), "</timestamp>");}/* *************************************************************************** * Display XML restart records *************************************************************************** */void write_xml_restarts(short curr, short *tab){ char cur_time[64]; /* Set timestamp for current data */ set_loc_time(curr); strftime(cur_time, 64, "date=\"%Y-%m-%d\" time=\"%H:%M:%S\"", &loc_time); xprintf(*tab, "<boot %s/>", cur_time);}/* *************************************************************************** * Print a Linux restart message (contents of a DUMMY record) *************************************************************************** */void write_dummy(short curr, int use_tm_start, int use_tm_end){ char cur_time[26]; set_timestamp(curr, cur_time, 26); /* The RESTART message must be in the interval specified by -s/-e options */ if ((use_tm_start && (datecmp(&loc_time, &tm_start) < 0)) || (use_tm_end && (datecmp(&loc_time, &tm_end) > 0))) return; if (format == S_O_PPC_OPTION) printf("%s\t-1\t%ld\tLINUX-RESTART\n", file_hdr.sa_nodename, file_stats[curr].ust_time); else if (format == S_O_DB_OPTION) printf("%s;-1;%s;LINUX-RESTART\n", file_hdr.sa_nodename, cur_time);}/* *************************************************************************** * Display data file header *************************************************************************** */void display_file_header(char *dfile, struct file_hdr *file_hdr){ printf("File: %s (%#x)\n", dfile, file_hdr->sa_magic); print_gal_header(localtime(&(file_hdr->sa_ust_time)), file_hdr->sa_sysname, file_hdr->sa_release, file_hdr->sa_nodename); printf("Activity flag: %#x\n", file_hdr->sa_actflag); printf("Sizeof(long): %d\n", file_hdr->sa_sizeof_long); printf("#CPU: %u\n", file_hdr->sa_proc + 1); printf("#IrqCPU: %u\n", file_hdr->sa_irqcpu); printf("#Disks: %u\n", file_hdr->sa_nr_disk); printf("#Serial: %u\n", file_hdr->sa_serial); printf("#Ifaces: %u\n", file_hdr->sa_iface);}/* *************************************************************************** * Display XML header and host data *************************************************************************** */void display_xml_header(short *tab){ printf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); printf("<!DOCTYPE Configure PUBLIC \"DTD v%s sysstat //EN\"\n", XML_DTD_VERSION); printf("\"http://perso.wanadoo.fr/sebastien.godard/sysstat.dtd\">\n"); xprintf(*tab, "<sysstat>"); xprintf(++(*tab), "<sysdata-version>%s</sysdata-version>", XML_DTD_VERSION); xprintf(*tab, "<host nodename=\"%s\">", file_hdr.sa_nodename); xprintf(++(*tab), "<sysname>%s</sysname>", file_hdr.sa_sysname); xprintf(*tab, "<release>%s</release>", file_hdr.sa_release);}/* *************************************************************************** * Allocate structures *************************************************************************** */void allocate_structures(int stype){ if (file_hdr.sa_proc > 0) salloc_cpu_array(st_cpu, file_hdr.sa_proc + 1); if (file_hdr.sa_serial) salloc_serial_array(st_serial, file_hdr.sa_serial); if (file_hdr.sa_irqcpu) salloc_irqcpu_array(st_irq_cpu, file_hdr.sa_proc + 1, file_hdr.sa_irqcpu); if (file_hdr.sa_iface) salloc_net_dev_array(st_net_dev, file_hdr.sa_iface); if (file_hdr.sa_nr_disk) salloc_disk_array(st_disk, file_hdr.sa_nr_disk);}/* *************************************************************************** * Move structures data *************************************************************************** */void copy_structures(int dest, int src){ memcpy(&file_stats[dest], &file_stats[src], FILE_STATS_SIZE); if (file_hdr.sa_proc > 0) memcpy(st_cpu[dest], st_cpu[src], STATS_ONE_CPU_SIZE * (file_hdr.sa_proc + 1)); if (GET_ONE_IRQ(file_hdr.sa_actflag)) memcpy(interrupts[dest], interrupts[src], STATS_ONE_IRQ_SIZE); if (file_hdr.sa_serial) memcpy(st_serial[dest], st_serial[src], STATS_SERIAL_SIZE * file_hdr.sa_serial); if (file_hdr.sa_irqcpu) memcpy(st_irq_cpu[dest], st_irq_cpu[src], STATS_IRQ_CPU_SIZE * (file_hdr.sa_proc + 1) * file_hdr.sa_irqcpu); if (file_hdr.sa_iface) memcpy(st_net_dev[dest], st_net_dev[src], STATS_NET_DEV_SIZE * file_hdr.sa_iface); if (file_hdr.sa_nr_disk) memcpy(st_disk[dest], st_disk[src], DISK_STATS_SIZE * file_hdr.sa_nr_disk);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?