Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

I'd like to remotely monitor my WinNT server. I want to gather specifically the CPU and Memory usage statistics. How can I accomplish this with Perl? Or any other command line tool?

Thank You

Replies are listed 'Best First'.
Re: WinNT CPU & MEM usage
by lolindrath (Scribe) on Jan 09, 2001 at 09:20 UTC
    Win32::AdminMisc has some of the stuff you'll need. Use the GetMemoryInfo. It returns a hash with the following info.
    Element Description -------- ------------ Load Percentage load on the available memory RAMTotal Total amount of bytes of physical RAM RAMAvail Total amount of bytes of available physical memory PageTotal Total amount of paged ram PageAvail Total amount of available paged ram VirtTotal Total amount of virtual memory VirtAvail Total amount of available virtual memory


    --=Lolindrath=--
      <shameless plug> You can also use Win32::SystemInfo. It's probably a bit smaller than AdminMisc, and you can get the same memory info from it.</shameless plug>

      Guildenstern
      Negaterd character class uber alles!
(tye)Re: WinNT CPU & MEM usage
by tye (Sage) on Jan 09, 2001 at 05:36 UTC

    I'd probably start with Win32::PerfLib, though I know little about it.

            - tye (but my friends call me "Tye")
      Tye, hate to shoot ya down, but everyone should stay far, far away from Win32::PerfLib if at all possible.

      <quote>What is in the box?
      Pain.</quote>

      The PerfLib structures that are returned are huge, 7 hash refs deep (and not all info is at the same level, depending on vague criteria), obfuscated, horrendously documented, and generally an agonizing process to get to. To get nearly all (but, of course, not consistently all) information back you need to store (at least) 2 calls to each monitoring object and perform a type-specific calculation that is different for each one, using information that can be in some 4 of the 7 hash levels. This is the beast I've been trying to tame for a month or two now, and I'm just now getting to the point where I'm getting useful info back...granted, I had to wrangle a couple other issues (running as a service correctly, etc) but trust me, other things in AdminMisc are far better suited to simple CPU/Mem monitoring, but to get stuff like SQL Server, IIS, and Exchange server usage stats you have to go through PerfLib.

      Read this as well as the calculation section, and pity me. =) Those are the docs I have to go on...if anyone has any pointers to better description of how to get stuff out of PerfLib, I'd love to see em.

      Kind of a rant I guess, but I don't want anyone to waste their time and sanity on this when they don't have to. Posted another rant before, but it got snarfed, probably a browser thing.

      Later all

      Trinary

        For what it's worth, here's an example script for Win32::Perflib that Dave Roth wrote. It could easily be changed to include CPU usage.

        use Win32::PerfLib; my $Server; my $ProcessIndex; $Server = Win32::NodeName unless( $Server = $ARGV[0] ); print "Collecting process info for $Server...\n"; Win32::PerfLib::GetCounterNames( $Server, \%StringIndex ); map { $String{$StringIndex{$_}} = $_; } ( keys( %StringIndex ) ); $ProcessIndex = $String{Process}; # Connect to the server's performance data $Perf = new Win32::PerfLib( $Server ); if( ! $Perf ) { print "Could not obtain the process list.\n"; exit(); } $ProcessList = {}; # get the performance data for the process object $Perf->GetObjectList( $ProcessObject, $ProcessList ); $Perf->Close(); $InstanceHash = $ProcessList->{Objects}->{$ProcessIndex}->{Instances}; foreach my $ProcessObject ( sort( keys( %{$InstanceHash} ) ) ) { my $ProcessCounter = $InstanceHash->{$ProcessObject}->{Counters}; my %ThisProcess; $ThisProcess{Name} = $InstanceHash->{$ProcessObject}->{Name}; foreach my $Attrib ( keys( %$ProcessCounter ) ) { my $AttribName = $StringIndex{$ProcessCounter->{$Attrib}->{Cou +nterNameTitleIndex}}; $ThisProcess{$AttribName} = Format( $ProcessCounter->{$Attrib} +, $ProcessList->{Objects}->{$ProcessIndex} ); } $ProcessList{$ThisProcess{'ID Process'}} = \%ThisProcess; } $~ = PROCESS_HEADER; write; $~ = PROCESS_INFO; foreach $Process ( sort( keys( %ProcessList ) ) ) { # Don't make $Proc lexicaly scoped since it is used in a formatted # write. $Proc = $ProcessList{$Process}; write; } sub Format { my( $Proc, $ObjectList ) = @_; my $Value = $Proc->{Counter}; my $Type = $Proc->{CounterType}; my $TB = $ObjectList->{PerfFreq}; my $Y = $ObjectList->{PerfTime}; if( PERF_100NSEC_TIMER == $Type ) { $Value = 100 * ( $Value / 1000000 ) ; } elsif( PERF_ELAPSED_TIME == $Type ) { my( $Hour, $Min, $Sec ); # Convert the value into seconds... $Value = ( $Y - $Value ) / $TB; $Hour = $Value / ( 60 * 60 ); $Min = ( $Hour - int( $Hour ) ) * 60; $Sec = ( $Min - int( $Min ) ) * 60; $Value = sprintf( "%d:%02d:%02d", int( $Hour ), int( $Min ), i +nt( $Sec ) ); } return( $Value ); } sub FormatNumber { my( $Number ) = @_; my( $Suffix ) = ""; my $K = 1024; if( $K <= $Number ) { $Suffix = " K"; $Number /= $K; } $Number =~ s/(\.\d{0,2})\d*$/$1/; {} while ($Number =~ s/^(-?\d+)(\d{3})/$1,$2/); return( $Number . $Suffix ); } format PROCESS_HEADER = @||| @||||| @|||||||||||||||| @|||||| @|||||||||||| @|||||||||||| @||| +||| PID, Parent, "Process Name", "Threads", "Memory", "Memory Peak", "Hand +les" ---- ------ ----------------- ------- ------------- ------------- ---- +--- . format PROCESS_INFO = @||| @||||| @<<<<<<<<<<<<<<<< @>>>>>> @>>>>>>>>>>>> @>>>>>>>>>>>> @>>> +>>> $Proc->{'ID Process'}, $Proc->{'Creating Process ID'}, $Proc->{Name}, +$Proc->{'Thread Count'}, FormatNumber( $Proc->{'Working Set'} ), Form +atNumber( $Proc->{'Working Set Peak'} ), $Proc->{'Handle Count'} . print "Finished.\n";

        Thanks for the warning.

        Just an FYI, the insanity I see in the documentation pretty much matches the insanity that is Win32 performance counters. It certainly seems that a few helper functions are in order for the more common cases.

        You can also get at this information in its raw form via Win32API::Registry if you'd like to compare the madnesses. :-}

        I see nothing in Win32::AdminMisc that gives CPU usage statistics, BTW.

                - tye (but my friends call me "Tye")