⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sadf.c

📁 linux下查看系统工具原码,如IOSTAT等
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * sadf: system activity data formatter * (C) 1999-2006 by Sebastien GODARD (sysstat <at> wanadoo.fr) * *************************************************************************** * This program is free software; you can redistribute it and/or modify it * * under the terms of the GNU General Public License as published  by  the * * Free Software Foundation; either version 2 of the License, or (at  your * * option) any later version.                                              * *                                                                         * * This program is distributed in the hope that it  will  be  useful,  but * * WITHOUT ANY WARRANTY; without the implied warranty  of  MERCHANTABILITY * * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * * for more details.                                                       * *                                                                         * * You should have received a copy of the GNU General Public License along * * with this program; if not, write to the Free Software Foundation, Inc., * * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA                   * *************************************************************************** */#include <stdio.h>#include <string.h>#include <stdlib.h>#include <stdarg.h>#include <unistd.h>#include <time.h>#include <errno.h>#include <sys/param.h>	/* for HZ */#include "sadf.h"#include "sa.h"#include "common.h"#ifdef USE_NLS#include <locale.h>#include <libintl.h>#define _(string) gettext(string)#else#define _(string) (string)#endiflong interval = -1, count = 0;unsigned int sadf_actflag = 0;unsigned int flags = 0;unsigned short format = 0;	/* Output format */unsigned char irq_bitmap[(NR_IRQS / 8) + 1];unsigned char cpu_bitmap[(NR_CPUS / 8) + 1];int kb_shift = 0;struct file_hdr file_hdr;struct file_stats file_stats[DIM];struct stats_one_cpu *st_cpu[DIM];struct stats_serial *st_serial[DIM];struct stats_irq_cpu *st_irq_cpu[DIM];struct stats_net_dev *st_net_dev[DIM];struct disk_stats *st_disk[DIM];/* Array members of common types are always packed */unsigned int interrupts[DIM][NR_IRQS];struct tm loc_time;/* Contain the date specified by -s and -e options */struct tstamp tm_start, tm_end;char *args[MAX_ARGV_NR];/* *************************************************************************** * Print usage and exit *************************************************************************** */void usage(char *progname){   fprintf(stderr, _("Usage: %s [ options... ] [ <interval> [ <count> ] ] [ <datafile> ]\n"	           "Options are:\n"	           "[ -d | -H | -p | -x ] [ -t ] [ -V ]\n"		   "[ -P { <cpu> | ALL } ] [ -s [ <hh:mm:ss> ] ] [ -e [ <hh:mm:ss> ] ]\n"		   "[ -- <sar_options...> ]\n"),	   progname);   exit(1);}/* *************************************************************************** * Print tabulations *************************************************************************** */void prtab(int nr_tab){   int i;   for (i = 0; i < nr_tab; i++)     printf("\t");}/* *************************************************************************** * printf() function modified for XML display *************************************************************************** */void xprintf(short nr_tab, const char *fmt, ...){   static char buf[1024];   va_list args;   va_start(args, fmt);   vsprintf(buf, fmt, args);   va_end(args);   prtab(nr_tab);   printf("%s\n", buf);}/* *************************************************************************** * Fill loc_time structure according to time data saved in file. * NB: Option -t is ignored when option -p is used, since option -p * displays its timestamp as a long integer. This is type 'time_t', * which is the number of seconds since 1970 _always_ expressed in UTC. ****************************************************************************/void set_loc_time(short curr){   struct tm *ltm;   /* NOTE: loc_time structure must have been init'ed before! */   if (PRINT_TRUE_TIME(flags) &&       ((format == S_O_DB_OPTION) || (format == S_O_XML_OPTION)))      /* '-d -t' or '-x -t' */      ltm = localtime(&file_stats[curr].ust_time);   else      /* '-p' or '-p -t' or '-d' or '-x' */      ltm = gmtime(&file_stats[curr].ust_time);   loc_time = *ltm;}/* *************************************************************************** * Set timestamp string ****************************************************************************/void set_timestamp(short curr, char *cur_time, int len){   set_loc_time(curr);	   /* Set cur_time date value */   if (format == S_O_DB_OPTION) {      if (PRINT_TRUE_TIME(flags))	 strftime(cur_time, len, "%Y-%m-%d %H:%M:%S", &loc_time);      else	 strftime(cur_time, len, "%Y-%m-%d %H:%M:%S UTC", &loc_time);   }   else if (format == S_O_PPC_OPTION)      sprintf(cur_time, "%ld", file_stats[curr].ust_time);}/* *************************************************************************** * cons() - *   encapsulate a pair of ints or pair of char * into a static Cons and *   return a pointer to it. * * given:   t - type of Cons {iv, sv} *	    arg1 - unsigned long int (if iv), char * (if sv) to become *		   element 'a' *	    arg2 - unsigned long int (if iv), char * (if sv) to become *		   element 'b' * * does:    load a static Cons with values using the t parameter to *	    guide pulling values from the arglist * * return:  the address of it's static Cons.  If you need to keep *	    the contents of this Cons, copy it somewhere before calling *	    cons() against to avoid overwrite. *	    ie. don't do this:  f( cons( iv, i, j ), cons( iv, a, b ) ); *************************************************************************** */static Cons *cons(tcons t, ...){   va_list ap;   static Cons c;   c.t = t;   va_start(ap, t);   if (t == iv) {      c.a.i = va_arg(ap, unsigned long int);      c.b.i = va_arg(ap, unsigned long int);   }   else {      c.a.s = va_arg(ap, char *);      c.b.s = va_arg(ap, char *);   }   va_end(ap);   return(&c);}/* *************************************************************************** * render(): * * given:    isdb - flag, true if db printing, false if ppc printing *	     pre  - prefix string for output entries *	     rflags - PT_.... rendering flags *	     pptxt - printf-format text required for ppc output (may be null) *	     dbtxt - printf-format text required for db output (may be null) *	     mid - pptxt/dbtxt format args as a Cons. *	     luval - %lu printable arg (PT_USEINT must be set) *	     dval  - %.2f printable arg (used unless PT_USEINT is set) * * does:     print [pre<sep>]([dbtxt,arg,arg<sep>]|[pptxt,arg,arg<sep>]) \ *                     (luval|dval)(<sep>|\n) * * return:   void. *************************************************************************** */static void render(int isdb, char *pre, int rflags, const char *pptxt,		   const char *dbtxt, Cons *mid, unsigned long int luval,		   double dval){   static int newline = 1;   const char *txt[]  = {pptxt, dbtxt};   char *sep;   /* Start a new line? */   if (newline)      printf("%s%s", pre, seps[isdb]);   /* Terminate this one ? ppc always gets a newline */   newline = ((rflags & PT_NEWLIN) || !isdb);   if (txt[isdb]) {		/* pp/dbtxt? */      if (mid) {		/* Got format args? */	 switch(mid->t) {	  case iv:	    printf(txt[isdb], mid->a.i, mid->b.i);	    break;	  case sv:	    printf(txt[isdb], mid->a.s, mid->b.s);	    break;	 }      }      else {	 printf(txt[isdb]);	/* No args */      }      printf("%s", seps[isdb]);	/* Only if something actually got printed */   }   sep = (newline) ? "\n" : seps[isdb]; /* How does this rendering end? */   if (rflags & PT_USEINT) {      printf("%lu%s", luval, sep);   }   else {      printf("%.2f%s", dval, sep);   }}/* *************************************************************************** * write_mech_stats() - * Replace the old write_stats_for_ppc() and write_stats_for_db(), * making it easier for them to remain in sync and print the same data. *************************************************************************** */void write_mech_stats(short curr, unsigned int act,		      unsigned long dt, unsigned long long itv,		      unsigned long long g_itv, char *cur_time){   struct file_stats      *fsi = &file_stats[curr],      *fsj = &file_stats[!curr];   char pre[80];	/* Text at beginning of each line */   int wantproc = !WANT_PER_PROC(flags)      || (WANT_PER_PROC(flags) && WANT_ALL_PROC(flags));   int isdb = (format == S_O_DB_OPTION);   /*    * This substring appears on every output line, preformat it here    */   snprintf(pre, 80, "%s%s%ld%s%s",	    file_hdr.sa_nodename, seps[isdb], dt, seps[isdb], cur_time);   if (GET_PROC(act)) {      /* The first one as an example */      render(isdb,		/* db/ppc flag */	     pre,		/* the preformatted line leader */	     PT_NEWLIN,		/* is this the end of a db line? */	     "-\tproc/s",	/* ppc text */	     NULL,		/* db text */	     NULL,		/* db/ppc text format args (Cons *) */	     NOVAL,		/* %lu value (unused unless PT_USEINT) */	     /* and %.2f value, used unless PT_USEINT */	     S_VALUE(fsj->processes, fsi->processes, itv));   }   if (GET_CTXSW(act)) {      render(isdb, pre, PT_NEWLIN,	     "-\tcswch/s", NULL, NULL,	     NOVAL,	     ll_s_value(fsj->context_swtch, fsi->context_swtch, itv));   }   if (GET_CPU(act) && wantproc) {      render(isdb, pre,	     PT_NOFLAG,		/* that's zero but you know what it means */	     "all\t%%user",	/* all ppctext is used as format, thus '%%' */	     "-1",		/* look! dbtext */	     NULL,		/* no args */	     NOVAL,		/* another 0, named for readability */	     ll_sp_value(fsj->cpu_user, fsi->cpu_user, g_itv));      render(isdb, pre, PT_NOFLAG,	     "all\t%%nice", NULL, NULL,	     NOVAL,	     ll_sp_value(fsj->cpu_nice, fsi->cpu_nice, g_itv));      render(isdb, pre, PT_NOFLAG,	     "all\t%%system", NULL, NULL,	     NOVAL,	     ll_sp_value(fsj->cpu_system, fsi->cpu_system, g_itv));      render(isdb, pre, PT_NOFLAG,	     "all\t%%iowait", NULL, NULL,	     NOVAL,	     ll_sp_value(fsj->cpu_iowait, fsi->cpu_iowait, g_itv));      render(isdb, pre, PT_NOFLAG,	     "all\t%%steal", NULL, NULL,	     NOVAL,	     ll_sp_value(fsj->cpu_steal, fsi->cpu_steal, g_itv));      render(isdb, pre, PT_NEWLIN,	     "all\t%%idle", NULL, NULL,	     NOVAL,	     (fsi->cpu_idle < fsj->cpu_idle)	     ? 0.0	     : ll_sp_value(fsj->cpu_idle, fsi->cpu_idle, g_itv));   }   if (GET_CPU(act) && WANT_PER_PROC(flags) && file_hdr.sa_proc) {      int i;      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++) {	 if (cpu_bitmap[i >> 3] & (1 << (i & 0x07))) {	    /* Recalculate itv for current proc */	    pc_itv = get_per_cpu_interval(sci, scj);	    render(isdb, pre, PT_NOFLAG,		   "cpu%d\t%%user",	/* ppc text with formatting */		   "%d",		/* db text with format char */		   cons(iv, i, NOVAL),	/* how we pass format args */		   NOVAL,		   ll_sp_value(scj->per_cpu_user, sci->per_cpu_user, pc_itv));	    render(isdb, pre, PT_NOFLAG,		   "cpu%d\t%%nice", NULL, cons(iv, i, NOVAL),		   NOVAL,		   ll_sp_value(scj->per_cpu_nice, sci->per_cpu_nice, pc_itv));	    render(isdb, pre, PT_NOFLAG,		   "cpu%d\t%%system", NULL, cons(iv, i, NOVAL),		   NOVAL,		   ll_sp_value(scj->per_cpu_system, sci->per_cpu_system, pc_itv));	    render(isdb, pre, PT_NOFLAG,		   "cpu%d\t%%iowait", NULL, cons(iv, i, NOVAL),		   NOVAL,		   ll_sp_value(scj->per_cpu_iowait, sci->per_cpu_iowait, pc_itv));	    render(isdb, pre, PT_NOFLAG,		   "cpu%d\t%%steal", NULL, cons(iv, i, NOVAL),		   NOVAL,		   ll_sp_value(scj->per_cpu_steal, sci->per_cpu_steal, pc_itv));	    render(isdb, pre, PT_NEWLIN,		   "cpu%d\t%%idle", NULL, cons(iv, i, NOVAL),		   NOVAL,		   (sci->per_cpu_idle < scj->per_cpu_idle)		   ? 0.0		   : ll_sp_value(scj->per_cpu_idle, sci->per_cpu_idle, pc_itv));	 }      }   }   if (GET_IRQ(act) && wantproc) {      /* Print number of interrupts per second */      render(isdb, pre, PT_NEWLIN,	     "sum\tintr/s", "-1", NULL,	     NOVAL, ll_s_value(fsj->irq_sum, fsi->irq_sum, itv));   }   if (GET_ONE_IRQ(act)) {      int i;      for (i = 0; i < NR_IRQS; i++) {	 if (irq_bitmap[i >> 3] & (1 << (i & 0x07))) {	    render(isdb, pre, PT_NEWLIN,		   "i%03d\tintr/s", "%d", cons(iv, i, NOVAL),		   NOVAL,		   S_VALUE(interrupts[!curr][i], interrupts[curr][i], itv));	 }      }   }   /* print paging stats */   if (GET_PAGE(act)) {      render(isdb, pre, PT_NOFLAG,	     "-\tpgpgin/s", NULL, NULL,	     NOVAL,	     S_VALUE(fsj->pgpgin, fsi->pgpgin, itv));      render(isdb, pre, PT_NOFLAG,	     "-\tpgpgout/s", NULL, NULL,	     NOVAL,	     S_VALUE(fsj->pgpgout, fsi->pgpgout, itv));      render(isdb, pre, PT_NOFLAG,	     "-\tfault/s", NULL, NULL,	     NOVAL,	     S_VALUE(fsj->pgfault, fsi->pgfault, itv));      render(isdb, pre, PT_NEWLIN,	     "-\tmajflt/s", NULL, NULL,	     NOVAL,	     S_VALUE(fsj->pgmajfault, fsi->pgmajfault, itv));   }   /* Print number of swap pages brought in and out */   if (GET_SWAP(act)) {      render(isdb, pre, PT_NOFLAG,	     "-\tpswpin/s", NULL, NULL,	     NOVAL, S_VALUE(fsj->pswpin, fsi->pswpin, itv));      render(isdb, pre, PT_NEWLIN,	     "-\tpswpout/s", NULL, NULL,	     NOVAL, S_VALUE(fsj->pswpout, fsi->pswpout, itv));   }   /* Print I/O stats (no distinction made between disks) */   if (GET_IO(act)) {      render(isdb, pre, PT_NOFLAG,	     "-\ttps", NULL, NULL,	     NOVAL, S_VALUE(fsj->dk_drive, fsi->dk_drive, itv));      render(isdb, pre, PT_NOFLAG,	     "-\trtps", NULL, NULL,	     NOVAL, S_VALUE(fsj->dk_drive_rio, fsi->dk_drive_rio, itv));      render(isdb, pre, PT_NOFLAG,	     "-\twtps", NULL, NULL,	     NOVAL, S_VALUE(fsj->dk_drive_wio, fsi->dk_drive_wio, itv));      render(isdb, pre, PT_NOFLAG,	     "-\tbread/s", NULL, NULL,	     NOVAL, S_VALUE(fsj->dk_drive_rblk, fsi->dk_drive_rblk, itv));      render(isdb, pre, PT_NEWLIN,	     "-\tbwrtn/s", NULL, NULL,	     NOVAL, S_VALUE(fsj->dk_drive_wblk, fsi->dk_drive_wblk, itv));   }   /* Print memory stats */   if (GET_MEMORY(act)) {      render(isdb, pre, PT_NOFLAG,	     "-\tfrmpg/s", NULL, NULL,	     NOVAL,	     S_VALUE((double) PG(fsj->frmkb),		     (double) PG(fsi->frmkb), itv));      render(isdb, pre, PT_NOFLAG,	     "-\tbufpg/s", NULL, NULL,	     NOVAL, S_VALUE((double) PG(fsj->bufkb),			    (double) PG(fsi->bufkb), itv));      render(isdb, pre, PT_NEWLIN,	     "-\tcampg/s", NULL, NULL,	     NOVAL, S_VALUE((double) PG(fsj->camkb),			    (double) PG(fsi->camkb), itv));   }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -