#!mkcmd # $Id: unixstats-HPUX11.m,v 1.9 2008/07/10 18:07:33 ksb Exp $ # unixstats for # HP-UX * B.11.11 U 9000/800 * unlimited-user license # # $Compile: %b -mMkcmd -d hpux11 %f && %b -m%m hpux11.c # $Mkcmd(*): : ${BUD:=../../bin/rrdup} && ${mkcmd-mkcmd} -n %s -I ${BUD} %f && rsync $BUD/machine.h machine.h && perl -pi -e "s/UL,/L,/" %s.c # $Clean: ${rm-rm} hpux11 hpux11.[ch] # comment "%c%kCompile: $%{cc-cc%} %%f -o %%F" from '' from '' from '' from '' from '' # KI instrumentation interface, poorly documented from '' from '' from '' from '' from '' # See the mkcmd -I option for the path to this module, ususally # ../../bin/rrdup or in mkcmd's util directory. require "rrrdupdate.m" require "std_help.m" "std_version.m" basename "unixstats" "" %i static char rcsid[] = "$Id: unixstats-HPUX11.m,v 1.9 2008/07/10 18:07:33 ksb Exp $"; %% type "seconds" 'p' { named "iDelay" "pcDelay" track "fPersist" init "0" param "delay" help "be persistent, rather than running only once, sleeping delay seconds between updates" } %i #if !defined(CP_USER) #define CP_USER 0 /* user time of normal process */ #endif #if !defined(CP_NICE) #define CP_NICE 1 /* user time at nice prio */ #endif #if !defined(CP_SYS) #define CP_SYS 2 /* kernel calls */ #endif #if !defined(CP_IDLE) #define CP_IDLE 3 /* idle time */ #endif #if !defined(CP_WAIT) #define CP_WAIT 4 /* I/O wait */ #endif #if !defined(CP_INTR) #define CP_INTR 7 /* time spent in interrupt code XXX == 0*/ #endif #if !defined(CPUSTATES) #define CPUSTATES 9 #endif #if !defined(MAX_CPU_POLL) #define MAX_CPU_POLL 128 /* super done */ #endif #if !defined(MASK_S) #define MASK_S(Mx) (0x3fffffff & (Mx)) #endif %% integer named 'iErr' { hidden } char* name "pcDest" { init '"peg.sac.fedex.com:31415"' param "[peg:]port" after "iErr = rrrdupdate(%n, 0, 0, 0, 0);if (iErr < 0) {fprintf(stderr, \"%%s: rrrdupdate: %%s: %%d\\n\", %b, %n, iErr);exit(1);}" help "host receiving RRD samples (also allows :port)" } # for compatibility with the perl version char* 'H' { hidden local update "pcDest = %N;" } char* 'N' { named "pcName" param "node" help "override gethostname to force our node's hostname" } boolean 's' { named "fSplit" help "split CPU stats into unix-0.rrd, unix-1.rrd, etc" } char* 'S' { named "pcSuffix" param "suffix" help "add this suffix to the default name" } char* 'O' { named "pcAdminDept" init '"sac"' param "admin" help "remove this suffix after toplevel, if present, default %qi" } char* 'T' { named "pcTopLevel" init '"fedex.com"' param "toplevel" help "remove this from the end of our hostname, default %qi" } augment action 'V' { user "Version();" } left ["pcDest"] { } exit { named "UnixStats" update "%n();" } init 2 "FixPath();" %c /* We are run from cron, and might not have a PATH that makes us (ksb) * happy: try to add the 2 common components we might be missing. */ static void FixPath() { register char *pcPath, *pcMem, *pcHome; register int iLen; static char acAdd[] = ":/usr/local/bin:/usr/local/libexec"; static char acHomeBin[] = "/bin"; static char acSet[] = "PATH"; if ((char *)0 == (pcPath = getenv(acSet)) || '\000' == *pcPath) { pcPath = "/usr/bin:/usr/sbin:/usr/ccs/bin:/sbin"; } /* Build "PATH = $PATH $ADD [ :$HOME/bin]" * (N.B. I know sizeof("") includes the \000 on the end, * but too big is not an issue here. -- ksb) */ iLen = sizeof(acSet)+1+strlen(pcPath)+sizeof(acAdd); if ((char *)0 == (pcHome = getenv("HOME"))) { /* don't bother to find our home with getpwuid(getuid()) */ } else if ('\000' == *pcHome) { pcHome = (char *)0; } else { iLen += 1+strlen(pcHome)+sizeof(acHomeBin); } iLen |=7; if ((char *)0 == (pcMem = malloc(iLen+9))) { return; } sprintf(pcMem, "%s%s", pcPath, acAdd); if ((char *)0 != pcHome) { sprintf(strchr(pcMem, '\000'), ":%s%s", pcHome, acHomeBin); } putenv(pcMem); } /* some clue about where we expect rrdup (ksb) */ static void Version() { printf("%s: rrdup to \"%s\"\n", progname, pcDest); } /* update unix stats for HPUX11 (ksb) */ static void UnixStats() { auto char acMyName[MAXHOSTNAMELEN+2]; static char acRRDFmt[] = "host/%s/unix%s.rrd"; auto char acRRDName[((5+MAXHOSTNAMELEN+4+32+4)|7)+1]; static char acTemplate[] = "sysload:cpu_user:cpu_nice:cpu_sys:cpu_wait:cpu_idle:cpu_int:fork:intr:scall:cswitch:pagein:pageout"; static char acFmt[] = "N:%lf:%lu:%lu:%lu:%lu:%lu:%lu:%lu:%lu:%lu:%lu:%lu:%lu"; auto struct pst_processor aoProc[MAX_CPU_POLL]; auto struct pst_processor oSum; auto struct pst_vminfo VM; auto char acPegCmd[256+1024+1024+32]; register int j, i, iMax; register char *pcDot; register FILE *fpSend; if (CPUSTATES > sizeof(oSum.psp_cpu_time)/sizeof(oSum.psp_cpu_time[0])) { fprintf(stderr, "%s: assert: tick vector too short\n", progname); exit(EX_UNAVAILABLE); } if (-1 == gethostname(acMyName, sizeof(acMyName))) { fprintf(stderr, "%s: gethostname: %s\n", progname, strerror(errno)); exit(EX_OSERR); } /* whittle off "{sac.}{fedex.com}", if we match them */ if ((char *)0 != pcTopLevel && '\000' != *pcTopLevel && strlen(pcTopLevel) < strlen(acMyName)) { register char *pcX; pcX = strchr(acMyName, '\000')-strlen(pcTopLevel); if ('.' == pcX[-1] && 0 == strcasecmp(pcTopLevel, pcX)) *--pcX = '\000'; } if ((char *)0 != pcAdminDept && '\000' != *pcAdminDept && strlen(pcAdminDept) < strlen(acMyName) && !((char *)0 != pcSuffix && 0 == strcmp(pcSuffix, pcAdminDept))) { register char *pcX; pcX = strchr(acMyName, '\000')-strlen(pcAdminDept); if ('.' == pcX[-1] && 0 == strcasecmp(pcAdminDept, pcX)) *--pcX = '\000'; } if ((char *)0 != pcSuffix) { register unsigned u; u = strlen(acMyName); snprintf(acMyName+u, sizeof(acMyName)-u, ".%s", pcSuffix); } if ((char *)0 == pcName) { pcName = acMyName; } do { (void)memset((void *)aoProc, '\000', sizeof(aoProc)); (void)memset((void *)& oSum, '\000', sizeof(oSum)); oSum.psp_avg_1_min = 0.0; oSum.psp_sysexec = 0; if (-1 == pstat_getvminfo(& VM, sizeof(VM), 1, 0)) { fprintf(stderr, "%s: pstat_getvminfo: %s\n", progname, strerror(errno)); exit(EX_OSERR); } if (-1 == (i = pstat_getprocessor(aoProc, sizeof(aoProc[0]), (size_t)MAX_CPU_POLL, 0))) { fprintf(stderr, "%s: pstat_getstatic: %s\n", progname, strerror(errno)); exit(EX_OSERR); } /* The first CPU with 0 idle is the end of the list */ for (iMax = 0; iMax < MAX_CPU_POLL; ++iMax) { if (0 == aoProc[iMax].psp_cpu_time[CP_IDLE]) { break; } } if (0 == iMax) { fprintf(stderr, "%s: no processors on-line?\n", progname); exit(EX_IOERR); } for (i = 0; i < iMax; ++i) { auto char acWhich[64]; if (0 == aoProc[i].psp_cpu_time[CP_IDLE]) { break; } oSum.psp_avg_1_min += aoProc[i].psp_avg_1_min; oSum.psp_sysexec += aoProc[i].psp_sysexec; for (j = 0; j < CPUSTATES; ++j) { oSum.psp_cpu_time[j] += aoProc[i].psp_cpu_time[j]; } if (!fSplit) { continue; } snprintf(acWhich, sizeof(acWhich), "-%d", i); snprintf(acRRDName, sizeof(acRRDName), acRRDFmt, pcName, acWhich); iErr = rrrdupdate(NULL, acRRDName, acTemplate, acFmt, aoProc[i].psp_avg_1_min, MASK_S(aoProc[i].psp_cpu_time[CP_USER]), MASK_S(aoProc[i].psp_cpu_time[CP_NICE]), MASK_S(aoProc[i].psp_cpu_time[CP_SYS]), MASK_S(aoProc[i].psp_cpu_time[CP_WAIT]), MASK_S(aoProc[i].psp_cpu_time[CP_IDLE]), MASK_S(aoProc[i].psp_cpu_time[CP_INTR]), VM.psv_cntfork/iMax, VM.psv_sintr/iMax, VM.psv_ssyscall/iMax, VM.psv_sswtch/iMax, VM.psv_spgin/iMax, VM.psv_spgout/iMax); if (iErr < 0) { fprintf(stderr, "%s: %s: send thread: %d\n", progname, pcDest, iErr); exit(1); } } oSum.psp_avg_1_min /= iMax; #if HACK if (oSum.psp_cpu_time[CP_USER] < 0) oSum.psp_cpu_time[CP_USER] = 0; if (oSum.psp_cpu_time[CP_NICE] < 0) oSum.psp_cpu_time[CP_NICE] = 0; if (oSum.psp_cpu_time[CP_SYS] < 0) oSum.psp_cpu_time[CP_SYS] = 0; if (oSum.psp_cpu_time[CP_WAIT] < 0) oSum.psp_cpu_time[CP_WAIT] = 0; if (oSum.psp_cpu_time[CP_IDLE] < 0) oSum.psp_cpu_time[CP_IDLE] = 0; if (oSum.psp_cpu_time[CP_INTR] < 0) oSum.psp_cpu_time[CP_INTR] = 0; #endif snprintf(acRRDName, sizeof(acRRDName), acRRDFmt, pcName, ""); iErr = rrrdupdate(NULL, acRRDName, acTemplate, acFmt, oSum.psp_avg_1_min, MASK_S(oSum.psp_cpu_time[CP_USER]), MASK_S(oSum.psp_cpu_time[CP_NICE]), MASK_S(oSum.psp_cpu_time[CP_SYS]), MASK_S(oSum.psp_cpu_time[CP_WAIT]), MASK_S(oSum.psp_cpu_time[CP_IDLE]), MASK_S(oSum.psp_cpu_time[CP_INTR]), VM.psv_cntfork, VM.psv_sintr, VM.psv_ssyscall, VM.psv_sswtch, VM.psv_spgin, VM.psv_spgout); if (iErr < 0) { fprintf(stderr, "%s: %s: send consolidated: %d\n", progname, pcDest, iErr); exit(1); } } while (fPersist && 0 == sleep(iDelay)); exit(EX_OK); }