Welcome, guest | Sign In | My Account | Store | Cart
###########################################################
# Check physical memory usage. 
# Email alert if ram usage exceeds 90%.
# Display the top ten processes by memory usage.
###########################################################

puts "\n executing [info script]\n"

# make script drive independent.

set drive [lindex [file split [info nameofexecutable]] 0 ] 

puts "\n proclib = $drive/scripts/TCL/proclib"

########################################################  
# Source utility procs.
########################################################  

source [ file join  $drive scripts/TCL/proclib/checkFile_proc.tcl ]
source [ file join  $drive scripts/TCL/proclib/smtp_proc.tcl ]
source [ file join  $drive scripts/TCL/proclib/reportHeader_proc.tcl ]
source [ file join  $drive scripts/TCL/proclib/printColumns.tcl ]
source [ file join  $drive scripts/TCL/proclib/convertToMb.tcl ]

########################################################  
# Source packages. 
########################################################  

package require twapi
package require winutils
package require Tclx
package require math::fuzzy

######################################
# Proc - check memory usage. 
######################################
proc checkMem {} {

   puts "\n checkMem \n"

   while {1} { 

      # pause for 30 seconds 

      after 30000

      # check physical memory utilization over a ten second interval.
       
      array set meminfo [twapi::get_memory_info -all]

      set totalPhysicalMem $meminfo(-totalphysical)
      set availPhysicalMem $meminfo(-availphysical)
      set totalCommit      $meminfo(-totalcommit)
      set availCommit      $meminfo(-availcommit)
      set swapFiles        $meminfo(-swapfiles)

      set physicalMemUsage [ expr { (double ($totalPhysicalMem - $availPhysicalMem)/$totalPhysicalMem  ) } ] 
      
      set usedPerc [ expr { [math::fuzzy::troundn $physicalMemUsage 2] *100 } ]

#      if memory usage is > 90% and alert has not been generated send error report.

      if { ![ info exist report ] } { 
         
         set report false
         
      }
         
      if { $usedPerc > 90 && [ string is false $report ] } { 

	  set report true
          
          writeReport meminfo $usedPerc

      } else {

	  set continue true 

      }

      # if memory usage is < 90% and alert has been generated send OK report.

      if { $usedPerc < 90 && [ string is true $report ] } { 

	  set report false

          writeReport meminfo $usedPerc

      } else {

	  set continue true 

      }

   }

}
######################################
# Proc - write report
######################################
proc writeReport { meminfo usedPerc } {
  
   global reportFile
   global reportFileId

   upvar $meminfo a

   set header       "$::env(COMPUTERNAME) - Check Memory Usage"

   reportHeader $reportFileId $header $reportFile
 
   set s "*****************************************"
   set t1 [ format "%-15s %s" " " $s ]
   set s "The End"
   set t2 [ format "%-35s    %s" " " $s ]
   set t3 "$::env(COMPUTERNAME) -  Memory utilization is $usedPerc\%\. " 

   puts $reportFileId \n$t3\n

   set s "*****************************************"
   set t1 [ format "%-15s %s" " " $s ]

   foreach e [ memDetails a ] {

       puts $reportFileId [ format "%-15s %s" " " $e ] 

   }

   set t9 "Memory utilization - Top Ten" 

   puts $reportFileId \n$t1
   puts $reportFileId [ format "%-15s %s" " " $t9 ]
   puts $reportFileId $t1\n

   set spaces " "

   set w1 [ string length "ProcessName" ]
   set w2 [ string length "ProcessId"   ]
   set w3 [ string length "WorkingSet"  ]
   set w4 [ string length "WorkingsetPeak" ]

   puts $reportFileId [ format "%-15s %-20s %${w2}s %${w3}s %${w4}s\n" $spaces \
                                                             "ProcessName"   \
                                                             "ProcessId"     \
                                                             "WorkingSet"    \
                                                             "WorkingsetPeak"  ]

   foreach e [ processDetails ] {

      set processName    [ lindex $e 0 ]
      set processId      [ lindex $e 1 ]
      set workingset     [ toMB [ lindex $e 2 ] ]
      set workingsetpeak [ toMB [ lindex $e 3 ] ]

      set width [ string length $processId ]
                                              
      puts $reportFileId [ format "%-15s %-20s %${w2}s %${w3}s %${w4}s" $spaces \
                                                             $processName       \
                                                             "$processId"       \
                                                             "$workingset mb"   \
                                                             "$workingsetpeak mb" ]

   }

   puts  $reportFileId \n$t1
   puts  $reportFileId $t2
   puts  $reportFileId $t1

   emailReport $usedPerc

   ftruncate -fileid $reportFileId 0

}
######################################
# Proc - get memory details. 
######################################
proc memDetails { meminfo } {

   upvar $meminfo a

   set totalPhysicalMem $a(-totalphysical)
   set availPhysicalMem $a(-availphysical)
   set totalCommit      $a(-totalcommit)
   set availCommit      $a(-availcommit)
   set swapFiles        $a(-swapfiles)

   set width 30 

   catch { puts_tabular $width "Physical memory:" "Total [toMB $a(-totalphysical)] MB, Available [toMB $a(-availphysical)] MB" } r 
 
   set t1 $r

   catch { puts_tabular $width "Commit:"  "Total [toMB $a(-totalcommit)] MB, Available [toMB $a(-availcommit)] MB" } r 

   set t2 $r

   catch { puts_tabular $width "Swap files:" "[join $a(-swapfiles) {, }]" } r

   set t3 $r

   # allocated swap file space = (total commit memory - total physical memory)

   set swapFileSpace [ expr { $totalCommit - $totalPhysicalMem } ] 
 
   catch { puts_tabular $width "Allocated swap file space:" "[toMB $swapFileSpace] MB" } r 
   set t4 $r
   
   # available swap file space = (available commit memory - available physical memory)  
   
   set availSwapFileSpace [ expr { $availCommit - $availPhysicalMem } ]

   catch { puts_tabular $width "Available swap file space:" "[toMB $availSwapFileSpace] MB" } r 

   set t5 $r

   return [ list $t1 $t2 $t3 $t4 $t5 ]

}
##################################################
# Proc - get memory usage by top ten processes.
##################################################
proc processDetails {} {

#   puts "\n processDetails \n"

   set processList [ lsort [ winutils::processes ] ]

   # calculate the cpu utilization for each process then sort and select the top ten. 
   
   foreach e $processList {

      set processName [ lindex $e 0 ] 
      set processId   [ lindex $e 1 ] 

      array set meminfo [ twapi::get_process_info $processId -workingset -workingsetpeak]

      lappend usageList [ list $processName $processId $meminfo(-workingset) $meminfo(-workingsetpeak) ] 

   }

   set x      [ lsort -decreasing -integer -index 2 $usageList ]

   set topTen [ lrange [ lsort -decreasing -integer -index 2 $usageList ] 0 9 ] 
  
   return $topTen

}
###########################################
# Email Report 
###########################################

proc emailReport { usedPerc } {

   global reportFile
   global reportFileId

   flush $reportFileId  

   set computerName $::env(COMPUTERNAME)

   if { $usedPerc  < 90 } { 

       set subject "$computerName - Memory Alert Over."   

   } else {

       set subject "$computerName - Memory Alert."   

   }

   sendSimpleMessage you@youremail.com $subject $reportFile

}
######################################
# Control Section.
######################################

######################################
# Set Variables
######################################

set processId [ twapi::get_current_process_id ]

set eventId   [ twapi::eventlog_open -write ]

set data "CHECKMEM STARTING"

twapi::eventlog_write $eventId 1 -type information -loguser -data $data

twapi::eventlog_close $eventId

set reportFile   [ file join $drive reports/notify/checkMem.txt ]

#########################################
# Check if files exist.
#########################################

checkFile [file dirname $reportFile]

######################################
# Open output files.
######################################

set reportFileId  [open $reportFile w]

################################### 
# Global variables.
################################### 

global reportFile
global reportFileId

checkMem 

History