Listing 5: rst.c--reports cumulative time and downtime
/*
* rst - report system time.
*
* SYNOPSIS
* /usr/local/bin/rst < log_file > report_file
*
* DESCRIPTION
* Reports cumulative time and down time.
*
* Reads a log file from standard input, and writes a report
* on standard output.
*
* The input file may be clf(8L)compressed, but need not be;
* rst will operate on any log file, or you can enter data
* by hand.
*/
#include <stdio.h>
#include <time.h>
/* DEC ULTRIX */
#if defined(ULTRIX)
time_t mktime();
#endif
/* SunOS */
#if defined(SUNOS4)
time_t timelocal();
#endif
/* epoch - number of seconds since Jan 1, 1970 00:00:00 GMT. */
time_t epoch(y, m, d, h, n, s)
int y, m, d, h, n, s;
{
struct tm t, *p;
t.tm_sec = s;
t.tm_min = n;
t.tm_hour = h;
t.tm_mday = d;
t.tm_mon = m;
t.tm_year = y;
p = &t;
/* DEC ULTRIX */
#if defined(ULTRIX)
return( mktime(p) );
#endif
/* SunOS */
#if defined(SUNOS4)
return( timelocal(p) );
#endif
}
main()
{
char *p, b[80]; /* record buffer */
char tc, /* current, */
tx, /* intermediate, */
tp; /* & previous records' type */
float f_uptime, /* fraction uptime, */
p_uptime; /* percent uptime */
int yc,mc,dc,hc,nc,sc, /* current, */
yx,mx,dx,hx,nx,sx, /* intermediate, */
yp,mp,dp,hp,np,sp; /* & previous records' date */
int in_stat; /* last line scan status */
time_t cut, /* cumulative uptime, */
cdt, /* cum. downtime, */
cst, /* cum. sched. downtime, */
ctt, /* cum. total time */
cit; /* current interval time */
time_t ts, te, /* epoch time start, --end */
ec, ep; /* for current, previous rec, */
/* Begin. */
/*
* Initialization. Read first line(s); establish epoch start time.
*/
/* Skip initial comments; vet 1st records. */
do {
p = (char *) 0;
if ( (p = gets(b)) == (char *) 0 )
exit(1); /* File devoid of anything meaningful. */
} while ( b[0] == '#' );
if ( b[0] != '+' )
exit(2); /* Can't grok downtime when 1st record is [-*] */
if ( ( in_stat = sscanf(b, "%c%u%u%u%u%u%u",
&tc,&yc,&mc,&dc,&hc,&nc,&sc
) ) < 7 ) {
exit(3); /* 1st non-comment record didn't parse; */
/* likely bad file. */
}/* if */
/* Finally get start chop in epoch notation. */
ts = epoch( yc-1900, mc-1, dc, hc, nc, sc );
te = ts; /* In case there's only one meaningful record. */
ec = ts; /* Prime value of ec. */
printf("Start time - %2d/%2d/%2d %2d:%2d:%2d (%d)\n",
mc, dc, yc-1900, hc, nc, sc, ts );
/*
* Read the rest of the file, calculating the various times as we go.
*/
cut = 0; cdt = 0; cst = 0; ctt = 0; cit = 0;
while ( (p = gets(b)) != (char *) 0 ) {
if ( b[0] != '#' ) {
/* Scan buffer into intermediate record. */
if ( ( in_stat = sscanf(b, "%c%u%u%u%u%u%u",
&tx,&yx,&mx,&dx,&hx,&nx,&sx
) ) >= 7 ) {
/* Scan succeeded. Do righteous stuff. */
/* Make current record previous record. */
tp = tc; yp = yc; mp = mc; dp = dc; hp = hc; np = nc; sp = sc;
ep = ec;
/* Make intermediate record current record. */
tc = tx; yc = yx; mc = mx; dc = dx; hc = hx; nc = nx; sc = sx;
ec = epoch( yc-1900, mc-1, dc, hc, nc, sc );
/* Downtime: +-[...], +*[...]; i.e., if the current */
/* record is a downtime record, and the previous record */
/* is anything, the interval between them is downtime. */
/* NOTE that this includes any junk that got skipped due */
/* to a bogus scan. */
cit = ec - ep;
ctt += cit;
if ( tc == '-' )
cdt += cit; /* cum. unsched. down time */
else if ( tc == '*' )
cst += cit; /* cum. sched. down time */
else
cut += cit; /* cumulative up time */
}/* if scan succeeded */
}/* if not comment */
}/* while */
te = ec; /* The last current record's epoch time */
printf("End time - %2d/%2d/%2d %2d:%2d:%2d (%d)\n",
mc, dc, yc-1900, hc, nc, sc, te );
printf("---\n");
printf("Total time in interval (sec) = %8d\n", te - ts);
printf(" Check cumulative time = %8d\n", ctt);
printf("---\n");
printf("Up time = %8d\n", cut);
printf("Unscheduled down time = %8d\n", cdt);
printf("Scheduled down time = %8d\n", cst);
f_uptime = 1.0 - ( (float) cdt / ( (float) ( cut - cst ) ) );
p_uptime = f_uptime * 100.0;
printf("---\n");
printf("Percent uptime = %8.2f\n", p_uptime);
}/* main */
/* End of File */
|