#ifndef lint static char *RCSid = "$Header: /proj/freeware1.0/nfswatch/nfswatch4.1/RCS/logfile.c,v 1.1 1995/08/08 04:40:28 rck Exp $"; #endif #include "os.h" /* * logfile.c - routines for updating log and snapshot files * * David A. Curry Jeffrey C. Mogul * Purdue University Digital Equipment Corporation * Engineering Computer Network Western Research Laboratory * 1285 Electrical Engineering Building 250 University Avenue * West Lafayette, IN 47907-1285 Palo Alto, CA 94301 * davy@ecn.purdue.edu mogul@decwrl.dec.com * * $Log: logfile.c,v $ * Revision 1.1 1995/08/08 04:40:28 rck * initial checkin * * Revision 4.2 1993/09/22 14:09:28 davy * Added fixes for snapshot code on Solaris 2.x from Gerry Singleton at * OpCom. * * Revision 4.1 1993/09/15 20:52:36 davy * Added "-procs" output. Diffs from Gary Schaps (gls@cirrus.com). * * Revision 4.0 1993/03/01 19:59:00 davy * NFSWATCH Version 4.0. * * Revision 3.3 1993/01/16 19:08:59 davy * Corrected Jeff's address. * * Revision 3.2 1993/01/15 19:33:39 davy * Miscellaneous cleanups. * * Revision 3.1 1993/01/13 20:18:17 davy * Put in OS-specific define scheme, and merged in Tim Hudson's code for * SGI systems (as yet untested). * * Revision 3.0 1991/01/23 08:23:05 davy * NFSWATCH Version 3.0. * * Revision 1.2 90/08/17 15:47:22 davy * NFSWATCH Version 2.0. * * Revision 1.1 88/11/29 11:20:34 davy * NFSWATCH Release 1.0 * */ #include #include #include #include #include "nfswatch.h" #include "externs.h" #include "screen.h" #ifdef SUNOS5 static char *scrncpy(); #endif /* * snapshot - take a snapshot of the screen. */ void snapshot() { FILE *fp; register int x, y; char buffer[BUFSIZ]; /* * We want to append to the snapshot file. */ if ((fp = fopen(snapshotfile, "a")) == NULL) { (void) mvprintw(SCR_PROMPT_Y, SCR_PROMPT_X, "could not open \"%s\"", snapshotfile); (void) refresh(); return; } /* * For all lines but the last one ... */ for (y = 0; y < LINES - 1; y++) { (void) mvprintw(SCR_PROMPT_Y, SCR_PROMPT_X, "dumping line %d", y + 1); (void) clrtoeol(); (void) refresh(); /* * Search backwards on each line for a non-space. * x is the count of significant characters. */ for (x = COLS - 1; x > 0; x--) { /* * Non-space found, increment Z and exit loop */ if (curscr->_y[y][x] != ' ') { x++; break; } } /* * Copy x characters and append a \n and \0 to the * string, then output it. */ #ifdef SUNOS5 (void) scrncpy(buffer, curscr->_y[y], x); #else (void) strncpy(buffer, curscr->_y[y], x); #endif buffer[x++] = '\n'; buffer[x] = '\0'; (void) fputs(buffer, fp); } (void) fputc('\014', fp); (void) fclose(fp); /* * Tell them we're done. */ (void) mvprintw(SCR_PROMPT_Y, SCR_PROMPT_X, "screen dumped to \"%s\"", snapshotfile ); (void) refresh(); } /* * Names of NFS procedures (MUST be kept in the right order) * two leading spaces make things look nicer */ char *local_procs[] = { " CREATE", " GETATTR", " GETROOT", " LINK", " LOOKUP", " MKDIR", " NULLPROC", " READ", " READDIR", " READLINK", " REMOVE", " RENAME", " RMDIR", " SETATTR", " STATFS", " SYMLINK", " WCACHE", " WRITE", 0 }; /* * update_logfile - put out the information to the log file. */ void update_logfile() { char *tstr; char *ctime(); float percent; char buf[BUFSIZ]; struct timeval tv; register int i, j, nfstotal; long count, tot_count; double dcount, sumsqr, sum; static char nfsprocs_header[80] = " Procedure int pct total completed ave.resp var.resp max.resp"; (void) gettimeofday(&tv, (struct timezone *) 0); /* * Start a log entry. */ (void) fprintf(logfp, "#\n# begin\n#\n"); (void) fprintf(logfp, "Date: %.24s\n", ctime(&tv.tv_sec)); tv.tv_sec -= starttime.tv_sec; tstr = prtime(tv.tv_sec); (void) fprintf(logfp, "Cycle Time: %d\n", cycletime); (void) fprintf(logfp, "Elapsed Time: %.8s\n", tstr+11); /* * Print total packet counters. */ (void) fprintf(logfp, "#\n# total packets %8s %8s %8s\n#\n", "network", "to host", "dropped"); (void) fprintf(logfp, "Interval Packets: %8d %8d %8d\n", int_pkt_total, int_dst_pkt_total, int_pkt_drops); (void) fprintf(logfp, "Total Packets: %8d %8d %8d\n", pkt_total, dst_pkt_total, pkt_drops); /* * Put out a header for the packet counters. */ (void) fprintf(logfp, "#\n# packet counters %8s %8s %8s\n#\n", "int", "pct", "total"); /* * Print the packet counters. Percentage is calculated as * this interval counter over total packets this interval. */ for (i = 0; i < PKT_NCOUNTERS; i++) { if (int_dst_pkt_total) { percent = ((float) pkt_counters[i].pc_interval / (float) int_dst_pkt_total) * 100.0; } else { percent = 0.0; } (void) sprintf(buf, "%s:", pkt_counters[i].pc_name); (void) fprintf(logfp, "%-25s %8d %7.0f%% %8d\n", buf, pkt_counters[i].pc_interval, percent, pkt_counters[i].pc_total); } /* * Calculate the total number of NFS packets this * interval. */ nfstotal = pkt_counters[PKT_NFSWRITE].pc_interval + pkt_counters[PKT_NFSREAD].pc_interval; /* * Put out a header for the NFS counters. */ (void) fprintf(logfp, "#\n# nfs counters %8s %8s %8s\n#\n", "int", "pct", "total"); /* * Print the NFS counters. Percentage is calculated as * packets this interval over total NFS packets this * interval. */ for (i = 0; i < nnfscounters; i++) { if (nfstotal) { percent = ((float) nfs_counters[i].nc_interval / (float) nfstotal) * 100.0; } else { percent = 0.0; } (void) sprintf(buf, "%s:", nfs_counters[i].nc_name); (void) fprintf(logfp, "%-25s %8d %7.0f%% %8d\t", buf, nfs_counters[i].nc_interval, percent, nfs_counters[i].nc_total); /* * Print individual proc counters. */ (void) fputc('(', logfp); for (j = 0; j < MAXNFSPROC; j++) { if (j) (void) fputc('/', logfp); (void) fprintf(logfp, "%d", nfs_counters[i].nc_proc[j]); } (void) fprintf(logfp, ")\n"); } /* * Put out a header for the individual file counters. */ (void) fprintf(logfp, "#\n# file counters %8s %8s %8s\n#\n", "int", "pct", "total"); /* * Print the individual file counters. Percentage is * calculated as packets this interval over total NFS * packets this interval. */ for (i = 0; i < nfilecounters; i++) { if (nfstotal) { percent = ((float) fil_counters[i].fc_interval / (float) nfstotal) * 100.0; } else { percent = 0.0; } (void) sprintf(buf, "%s:", fil_counters[i].fc_name); (void) fprintf(logfp, "%-25s %8d %7.0f%% %8d\t", buf, fil_counters[i].fc_interval, percent, fil_counters[i].fc_total); /* * Print individual proc counters. */ (void) fputc('(', logfp); for (j = 0; j < MAXNFSPROC; j++) { if (j) (void) fputc('/', logfp); (void) fprintf(logfp, "%d", fil_counters[i].fc_proc[j]); } (void) fprintf(logfp, ")\n"); } /* * Put out a header for the NFS procs counters. */ if (showwhich == SHOWNFSPROCS) { (void) fprintf(logfp, "#\n# nfs procs \n#\n"); (void) fprintf(logfp, "%s\n", nfsprocs_header); tot_count = 0; for (i = 0; i < MAXNFSPROC; i++) { tot_count += prc_counters[i].pr_interval; } for (i = 0; i < MAXNFSPROC; i++) { if (tot_count) percent = (((float) prc_counters[i].pr_interval) / ((float)tot_count)) * 100.0; else percent = 0.0; (void) fprintf(logfp, "%-17s %5d %3.0f%% %8d", local_procs[i], prc_counters[i].pr_interval, percent, prc_counters[i].pr_total); count = prc_counters[i].pr_complete; if (count != 0) { dcount = (double) count; sum = prc_counters[i].pr_response; sumsqr = prc_counters[i].pr_respsqr; (void) fprintf(logfp, " %8d %8.2f", count, sum /dcount); if (count > 1) { (void) fprintf(logfp, " %8.2f", sqrt((dcount * sumsqr - sum * sum) / (dcount * (dcount - 1.0)))); } else { (void) fprintf(logfp, " "); } (void) fprintf(logfp, " %8.2f", prc_counters[i].pr_maxresp); } (void) fprintf(logfp, "\n"); } } /* * End the log entry. */ (void) fprintf(logfp, "#\n# end\n#\n"); (void) fflush(logfp); } #ifdef SUNOS5 /* * scrncpy - copy a curses array of chtype's (s2) to a character array (s1), * truncating or null padding to always copy n bytes. */ static char * scrncpy(s1, s2, n) chtype *s2; char *s1; int n; { register char *os1; os1 = s1; n++; while ((--n != 0) && ((*s1++ = *s2++) != '\0')) ; if (n != 0) { while (--n != 0) *s1++ = '\0'; } return(os1); } #endif /* SUNOS5 */