Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

Re: (tye)Re: WinNT CPU & MEM usage

by Trinary (Pilgrim)
on Jan 09, 2001 at 13:49 UTC ( [id://50647]=note: print w/replies, xml ) Need Help??


in reply to (tye)Re: WinNT CPU & MEM usage
in thread WinNT CPU & MEM usage

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

Replies are listed 'Best First'.
Re: Re: (tye)Re: WinNT CPU & MEM usage
by myocom (Deacon) on Jan 09, 2001 at 23:29 UTC

    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";
(tye)Re2: WinNT CPU & MEM usage
by tye (Sage) on Jan 09, 2001 at 21:12 UTC

    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")

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://50647]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others exploiting the Monastery: (6)
As of 2024-04-19 14:32 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found