//============================================================================= // // Task: WEBFSMON.TSK // (Generates an .HTML page with Server Status information/graphs) // Author: Avanti Technology, Inc. // http://www.avanti-tech.com // Version: 1.03 - Updated Release (13 Mar 2009) - Fix for v4.20 issue // 1.02 - Updated Release (04 Apr 2008) - NW v6.5 SP7 // 1.01 - Updated Release (15 Mar 2005) // // Description: // ============ // Generates an .HTML page showing the Server Status information with // simple graphs, automatically updated every minute, for any NetWare // v5.0 (or later) Server (does not require WEB Server software or IP). // The task runs continuously, updating the WEBFSMON.HTML Page every // minute, until the task is terminated or TaskMaster is unloaded. // Percentage statistics (i.e., CPU Utilization, Cache Buffers, etc. // with ranges of 0-100%) are graphed in Green (0-50%), Yellow (51-89%), // and Red (90-100%). Volume Space is graphed similarly with Green used // for Free Space, Yellow for Purgeable Space, and Red for Used Space. // // This use of colors is intended to provide quick information at a glance. // // The WEBFSMON.HTML file can be directed to any directory on the Server, // including the SYS:LOGIN directory, thus allowing general access to // Server Status information by any network user able to attach to the // Server (no Login required). For Servers with WEB Server software // loaded or with directories accessible via generic IP means, the // file can be directed to any directory that allows sufficient access. // // Objective: // ========== // Provide general access to generic Server Status information without // concerns for security or account management. // // Usage: // ====== // Script can be manually executed using the TaskMaster TMRUN command // at the TMConsole (Shell) Screen: // // Example: TMRUN [vol:path\]WEBFSMON.TSK // // Note: [vol:path\] is not required if the task resides either // in SYS:SYSTEM or the TaskMaster NLM load directory. // // Script can be scheduled for automatic execution using Client interface or // using the TaskMaster TMSCHEDULE command at the TMConsole (Shell) Screen: // // Examples: TMSCHEDULE ADD WEBFSMON.TSK 01 02:00 // (Executes the 1st of each month at 2:00am) // // TMSCHEDULE ADD WEBFSMON.TSK YNNNNNN 02:00 // (Executes every Sunday [SMTWTFS] at 2:00am) // // Note: Scheduled tasks must reside either in SYS:SYSTEM or the // TaskMaster NLM load directory for security reasons. // // Note: Logic has been incorporated to avoid multiple concurrent executions. // Therefore, it can be scheduled as frequently as desired to insure // continuous operation. // // Compatibility: // ============== // This task has been tested on the following platforms without demonstrating // any compatibility issues or any other reported/confirmed conflicts: // TaskMaster v3.13 (or later), TaskMaster Lite v3.15 (or later) // NetWare v5.x / v6.x / OESx (NetWare kernel) // // Warning: // ======== // AS WITH ANY NEW SOFTWARE PROGRAM, BATCH SCRIPT, OR AUTOMATED PROCESSING // PROCEDURE, CAUTION SHOULD BE EXERCISED AND DUE DILIGENCE OBSERVED DURING // INITIAL IMPLEMENTATION. WHERE POSSIBLE, TESTING SHOULD BE PERFORMED ON // NON-PRODUCTION SYSTEMS PRIOR TO FULL IMPLEMENTATION. // // Comments: // ========= // This task script is provided free of charge and without any warranty or // guarantee of fitness of purpose or performance. // // For additional TaskMaster script examples, visit the Sample Tasks page // on the Avanti Technology, Inc. WEB Site: http://www.avanti-tech.com // // Note: The .HTML output is designed so that the page will automatically // refresh (reload) approximately once per minute, in support of the // sample task design which re-cycles (re-executes) the task and // generates an updated .HTML page of information every minute. // // To remove the refresh cycle, delete the following line from the task: // WRITE // // Note: Search for {MODIFY} comments indicating items which need // to be modified or renamed (as appropriate). // //============================================================================= // Check that the version of TaskMaster loaded is compatible (3.13 or later) IF "%TM_VERSION%.%TM_SUBVERSION%"<"3.13" // Echo the problem message to the screen ECHO. ECHO Error: Incompatible TaskMaster release (requires v3.13 or later)! ECHO. ABORT ENDIF // Check if already active. Terminate this copy if already active. IF ACTIVE_TASK %TASK% ECHO. ECHO %TASK%: Already active! Terminating... ECHO. EXIT ENDIF // Set %0 for use as OPEN WRITE error counter // Note: Must also be reset before restart (i.e., goto START) DEFINE %0 0 :START // {MODIFY} Destination (output) HTML file // Create the output HTML page (TRUNCATE overwrites an existing copy) OPEN WRITE SYS:\LOGIN\%TASK_FILE%.html TRUNCATE // Check for error (WEB browser refresh conflict?) and re-try up to 3 times IF ERRORLEVEL IF %0<3 // Increment the error counter and re-try DEFINE %0 %0+=1 goto START ENDIF ECHO. ECHO %TASK%: Unable to create/open OPEN WRITE file for .HTML output... ECHO Check file status and re-start task. ECHO. ABORT ENDIF // Output basic HTML template WRITE WRITE WRITE WRITE %SERVER%: Status Page WRITE WRITE WRITE WRITE WRITE // Output Server Status information WRITE
WRITE WRITE %DAY_OF_WEEK%, %MONTH_NAME% %DAY%, %YEAR%
IF %HOUR24%>12 DEFINE %1 (%HOUR24%:%MINUTE%:%SECOND%) ELSE DEFINE %1 ENDIF WRITE %HOUR%:%MINUTE%:%SECOND%%AM_PM% %1
WRITE
WRITE

WRITE %SERVER%
IF "%NW_SUPPORTPACK%">"" WRITE (NetWare v%NW_VERSION%.%NW_SUBVERSION% %NW_SUPPORTPACK%) ELSE WRITE (NetWare v%NW_VERSION%.%NW_SUBVERSION%) ENDIF WRITE

:STAT_TABLE WRITE

WRITE WRITE WRITE WRITE WRITE WRITE WRITE WRITE WRITE WRITE WRITE WRITE IF SCREEN_LOCKED DEFINE %1 [Locked] ELSE DEFINE %1 ENDIF WRITE WRITE WRITE WRITE WRITE
WRITE Up-Time: WRITE WRITE     WRITE %UPTIME_STRING% WRITE
WRITE Cache LRU: WRITE WRITE     WRITE %CACHE_LRU_STRING% WRITE
WRITE
WRITE
WRITE Active Screen: WRITE WRITE     WRITE %SCREEN_NAME% %1 WRITE
WRITE
WRITE

WRITE

WRITE // ROW: Table Headings WRITE WRITE WRITE WRITE WRITE // ROW: Utilization // Set the text/graph color by value (0-50=Green, 51-89=Yellow, 90+=Red) IF %CPU_UTIL%<=050 DEFINE %0 green ELSEIF %CPU_UTIL%>=090 DEFINE %0 red ELSE DEFINE %0 yellow ENDIF // This logic trick strips the leading zeros from fixed format fields DEFINE %1 0+=%CPU_UTIL% DEFINE %4 100-=%CPU_UTIL% WRITE WRITE WRITE WRITE WRITE // ROW: Cache Ratio // Set the text/graph color by value (0-50=Red, 51-74=Yellow, 75+=Green) IF %CACHE_RATIO%>=075 DEFINE %0 green ELSEIF %CACHE_RATIO%<=050 DEFINE %0 red ELSE DEFINE %0 yellow ENDIF // This logic trick strips the leading zeros from fixed format fields DEFINE %1 0+=%CACHE_RATIO% DEFINE %4 100-=%CACHE_RATIO% WRITE WRITE WRITE WRITE WRITE // ROW: Packet Receive Buffers (PRBs) // Pre-format %3 for fixed 3 digit result DEFINE %3 000 // Determine the % of PRBs In Use CALC %3 (%RECV_BUFFS_IN_USE% * 100) / %RECV_BUFFS_MAX% // Set the text/graph color by value (0-75=Green, 76-89=Yellow, 90+=Red) IF %3<=075 DEFINE %0 green ELSEIF %3>=090 DEFINE %0 red ELSE DEFINE %0 yellow ENDIF // This logic trick strips the leading zeros from fixed format fields DEFINE %1 0+=%RECV_BUFFS_IN_USE% DEFINE %2 0+=%RECV_BUFFS_MAX% DEFINE %4 100-=%3 WRITE WRITE WRITE WRITE WRITE // ROW: Licenses // Note: Only applies to NetWare v4+ (each NWv3 conn equals a license) IF %NW_VERSION%>3 // Pre-format %3 for fixed 3 digit result DEFINE %3 000 // Determine the % of Licenses In Use (MLA returns -1 value) IF "%LICENSES_MAX%">"0000" CALC %3 (%LICENSES_IN_USE% * 100) / %LICENSES_MAX% ENDIF // Set the text/graph color by value (0-75=Green, 76-89=Yellow, 90+=Red) IF %3<=075 DEFINE %0 green ELSEIF %3>=090 DEFINE %0 red ELSE DEFINE %0 yellow ENDIF // This logic trick strips the leading zeros from fixed format fields DEFINE %1 0+=%LICENSES_IN_USE% IF NOT "%LICENSES_MAX%"=="-1" DEFINE %2 0+=%LICENSES_MAX% ELSE DEFINE %2 MLA ENDIF DEFINE %4 100-=%3 WRITE WRITE WRITE WRITE WRITE ENDIF // ROW: Connections // Pre-format %3 for fixed 3 digit result DEFINE %3 000 IF %NW_VERSION%==3 // Determine the % of Connections (i.e., Licenses) In Use CALC %3 (%CONNS_IN_USE% * 100) / %CONNS_MAX% // Set the text/graph color by value (0-75=Green, 76-89=Yellow, 90+=Red) IF %3<=075 DEFINE %0 green ELSEIF %3>=090 DEFINE %0 red ELSE DEFINE %0 yellow ENDIF ELSE DEFINE %0 green ENDIF // This logic trick strips the leading zeros from fixed format fields DEFINE %1 0+=%CONNS_IN_USE% DEFINE %4 100-=%3 WRITE WRITE WRITE WRITE WRITE WRITE
WRITE   Statistic WRITE WRITE Current WRITE WRITE WRITE WRITE
0% WRITE Graph100% WRITE
WRITE
WRITE   Utilization WRITE WRITE %1% WRITE WRITE IF %1>000 WRITE ENDIF IF %4>000 WRITE ENDIF WRITE
WRITE
WRITE
WRITE
WRITE
WRITE
WRITE   Cache Ratio WRITE WRITE %1% WRITE WRITE IF %1>000 WRITE ENDIF IF %4>000 WRITE ENDIF WRITE
WRITE
WRITE
WRITE
WRITE
WRITE
WRITE   PktRxBuffs WRITE WRITE %1 / %2 WRITE WRITE IF %3>000 WRITE ENDIF IF %4>000 WRITE ENDIF WRITE
WRITE
WRITE
WRITE
WRITE
WRITE
WRITE   Licenses WRITE WRITE %1 / %2 WRITE WRITE IF %3>000 WRITE ENDIF IF %4>000 WRITE ENDIF WRITE
WRITE
WRITE
WRITE
WRITE
WRITE
WRITE   Connections WRITE WRITE %1 // For NetWare v3, Max Conns is important (though irrelevant for NWv4+) IF %NW_VERSION%==3 DEFINE %2 0+=%CONNS_MAX% WRITE / %2 ENDIF WRITE WRITE IF %3>000 WRITE ENDIF IF %4>000 WRITE ENDIF WRITE
WRITE
WRITE
WRITE
WRITE
WRITE
WRITE
WRITE

WRITE

:CPU_GRAPH WRITE WRITE WRITE WRITE WRITE WRITE WRITE WRITE WRITE WRITE WRITE WRITE WRITE WRITE
WRITE WRITE WRITE WRITE WRITE
WRITE Last Min. WRITE WRITE Utilization: Last Minute (per sec) WRITE WRITE Last Sec. WRITE
WRITE
WRITE WHILE // Get the next CPU Utilization value (%CPU_UTIL% field) PARSE %0 %9 1-3 PACK IF "%0"=="" THEN BREAK IF %0<000 OR %0>100 THEN BREAK // Set %1 to the inverse of the CPU Utilization value for graphing DEFINE %1 100-=%0 // Set the text/graph color by value (0-50=Green, 51-89=Yellow, 90+=Red) IF %0<=050 DEFINE %0 green ELSEIF %0>=090 DEFINE %0 red ELSE DEFINE %0 yellow ENDIF WRITE // Shift the collection left by one entry PARSE %0 %9 4-180 PACK DEFINE %9 %0 LOOP WRITE
WRITE WRITE WRITE
WRITE WRITE WRITE
WRITE
WRITE
WRITE
WRITE WRITE WRITE WRITE WRITE
WRITE Last Hour WRITE WRITE Utilization: Last Hour (avg/min) WRITE WRITE Last Min. WRITE
WRITE
WRITE // Copy cycle average collection entries to temp variable for graphing DEFINE %2 %8 WHILE // Get the next cycle averaged CPU Utilization value PARSE %0 %2 1-3 PACK IF "%0"=="" THEN BREAK IF %0<000 OR %0>100 THEN BREAK // Set %1 to the inverse of the CPU Utilization value for graphing DEFINE %1 100-=%0 // Set the text/graph color by value (0-50=Green, 51-89=Yellow, 90+=Red) IF %0<=050 DEFINE %0 green ELSEIF %0>=090 DEFINE %0 red ELSE DEFINE %0 yellow ENDIF WRITE // Shift the collection left by one entry PARSE %0 %2 4-180 PACK DEFINE %2 %0 LOOP WRITE
WRITE WRITE WRITE
WRITE WRITE WRITE
WRITE
WRITE
WRITE
WRITE Data key: Left (oldest) << Right (recent) WRITE
WRITE

:VOL_TABLE WRITE

WRITE // ROW: Volume Table Headings WRITE WRITE WRITE WRITE WRITE WRITE WRITE WRITE // Use VOLINFO, redirecting the output to a temporary file, // to determine the mounted volumes // {MODIFY} Specify the destination (temporary file) for the redirected output VOLINFO >%TASK_PATH%\%TASK_FILE%.tmp // {MODIFY} Read the redirected output from VOLINFO (check for errors) OPEN READ %TASK_PATH%\%TASK_FILE%.tmp // Check for OPEN READ errors when attempting to access the temporary file // with the redirected VOLINFO data IF ERRORLEVEL WRITE WRITE WRITE goto EOJ ENDIF // Clear READ variable for WHILE/LOOP DEFINE %0 WHILE NOT SCAN_STRING ":" "%0" // READ first 17 bytes (16 bytes max Volume plus the colon) of next record READ %0 1-17 // Handle a premature EOF condition (there must be at least 1 mounted volume) IF ERRORLEVEL WRITE WRITE WRITE BREAK ENDIF LOOP WHILE SCAN_STRING ":" "%0" // Strip trailing spaces from Volume name REFORMAT %0 PACK TEXT // ROW: Volume %0 // Change the Current Working Directory (CWD) to the Volume to check CD %0 // Handle an error accessing the mounted volume for information retrieval IF NOT SCAN_STRING "%VOL_NAME%" "%0" WRITE WRITE WRITE // READ first 17 bytes (16 bytes max Volume plus the colon) of next record READ %0 1-17 // Check for EOF (i.e., no more records) IF ERRORLEVEL THEN BREAK // Resume WHILE/LOOP processing at top CONTINUE ENDIF // This logic trick strips the leading zeros from fixed format fields DEFINE %1 0+=%VOL_SIZE_MB% DEFINE %2 0+=%VOL_USED% DEFINE %3 0+=%VOL_PURGEABLE% DEFINE %4 0+=%VOL_FREE% DEFINE %4 %4-=%VOL_PURGEABLE% WRITE WRITE WRITE WRITE WRITE WRITE WRITE WRITE // READ first 17 bytes (16 bytes max Volume plus the colon) of next record READ %0 1-17 // Check for EOF (i.e., no more records) IF ERRORLEVEL THEN BREAK LOOP :EOJ WRITE
WRITE   Volume WRITE WRITE Size (MB) WRITE WRITE Used WRITE WRITE Purge WRITE WRITE Free WRITE WRITE Graph WRITE
WRITE WRITE VOLINFO Error: Volume data unavailable WRITE WRITE
WRITE WRITE READ Error: Volume data unavailable WRITE WRITE
WRITE WRITE CHDIR %0 - Error: Volume data unavailable WRITE WRITE
WRITE   %0 WRITE WRITE %1 WRITE WRITE %2% WRITE WRITE %3% WRITE WRITE %4% WRITE WRITE IF %2>000 WRITE ENDIF IF %3>000 WRITE ENDIF IF %4>000 WRITE ENDIF WRITE
WRITE
WRITE
WRITE
WRITE
WRITE
WRITE
WRITE
WRITE
WRITE

WRITE Produced by: %TASK%
WRITE Processed by: TaskMaster v%TM_VERSION%.%TM_SUBVERSION%
WRITE Time Elapsed: %ELAPSED_TIME%
WRITE

WRITE WRITE WRITE WRITE // Close the input/output files CLOSE // Check if collection required prior to initial WHILE/LOOP SLEEP IF %SECOND%>00 DEFINE %0 01 DEFINE %1 0000+=%CPU_UTIL% DEFINE %9 %CPU_UTIL% ELSE DEFINE %0 00 DEFINE %1 0000 DEFINE %9 ENDIF // Pre-format the cumulative variable for cycle averaging // This WHILE/LOOP will put the task to SLEEP for a second then collect the // next CPU Utilization value after which it will check for a 'new' minute // (i.e., %SECOND%==00) at which point it will BREAK out of the WHILE/LOOP // and re-start the task (via the GOTO the label at the top) WHILE SLEEP 1 // Increment the cycle counter DEFINE %0 %0+=01 // Add current value to cumulative for averaging DEFINE %1 %1+=%CPU_UTIL% // Append the current CPU Utilization value to the collection list DEFINE %9 %9%CPU_UTIL% // If it is a new minute (%SECOND%==00) then BREAK out of the WHILE/LOOP IF %SECOND%==00 THEN BREAK LOOP // Pre-format the temp variable to hold the average CPU Utilization collection DEFINE %2 000 // Calculate the average CPU Utilization for this cycle IF %0>00 CALC %2 %1 / %0 ENDIF // Parse previous collection to a max of 59 entries (60 total with this new one) PARSE %3 %8 1-177 PACK // Build new collection, prepending the current average to the collection list DEFINE %8 %2%3 // Reset %0 for subsequent use (OPEN WRITE error counter) DEFINE %0 0 GOTO START