Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

537 lines
13 KiB

  1. package Win32::PerfLib;
  2. use strict;
  3. use Carp;
  4. use vars qw($VERSION @ISA @EXPORT @EXPORT_OK $AUTOLOAD);
  5. require Exporter;
  6. require DynaLoader;
  7. require AutoLoader;
  8. @ISA = qw(Exporter DynaLoader);
  9. @EXPORT = qw(
  10. PERF_100NSEC_MULTI_TIMER
  11. PERF_100NSEC_MULTI_TIMER_INV
  12. PERF_100NSEC_TIMER
  13. PERF_100NSEC_TIMER_INV
  14. PERF_AVERAGE_BASE
  15. PERF_AVERAGE_BULK
  16. PERF_AVERAGE_TIMER
  17. PERF_COUNTER_BASE
  18. PERF_COUNTER_BULK_COUNT
  19. PERF_COUNTER_COUNTER
  20. PERF_COUNTER_DELTA
  21. PERF_COUNTER_ELAPSED
  22. PERF_COUNTER_FRACTION
  23. PERF_COUNTER_HISTOGRAM
  24. PERF_COUNTER_HISTOGRAM_TYPE
  25. PERF_COUNTER_LARGE_DELTA
  26. PERF_COUNTER_LARGE_QUEUELEN_TYPE
  27. PERF_COUNTER_LARGE_RAWCOUNT
  28. PERF_COUNTER_LARGE_RAWCOUNT_HEX
  29. PERF_COUNTER_MULTI_BASE
  30. PERF_COUNTER_MULTI_TIMER
  31. PERF_COUNTER_MULTI_TIMER_INV
  32. PERF_COUNTER_NODATA
  33. PERF_COUNTER_QUEUELEN
  34. PERF_COUNTER_QUEUELEN_TYPE
  35. PERF_COUNTER_RATE
  36. PERF_COUNTER_RAWCOUNT
  37. PERF_COUNTER_RAWCOUNT_HEX
  38. PERF_COUNTER_TEXT
  39. PERF_COUNTER_TIMER
  40. PERF_COUNTER_TIMER_INV
  41. PERF_COUNTER_VALUE
  42. PERF_DATA_REVISION
  43. PERF_DATA_VERSION
  44. PERF_DELTA_BASE
  45. PERF_DELTA_COUNTER
  46. PERF_DETAIL_ADVANCED
  47. PERF_DETAIL_EXPERT
  48. PERF_DETAIL_NOVICE
  49. PERF_DETAIL_WIZARD
  50. PERF_DISPLAY_NOSHOW
  51. PERF_DISPLAY_NO_SUFFIX
  52. PERF_DISPLAY_PERCENT
  53. PERF_DISPLAY_PER_SEC
  54. PERF_DISPLAY_SECONDS
  55. PERF_ELAPSED_TIME
  56. PERF_INVERSE_COUNTER
  57. PERF_MULTI_COUNTER
  58. PERF_NO_INSTANCES
  59. PERF_NO_UNIQUE_ID
  60. PERF_NUMBER_DECIMAL
  61. PERF_NUMBER_DEC_1000
  62. PERF_NUMBER_HEX
  63. PERF_OBJECT_TIMER
  64. PERF_RAW_BASE
  65. PERF_RAW_FRACTION
  66. PERF_SAMPLE_BASE
  67. PERF_SAMPLE_COUNTER
  68. PERF_SAMPLE_FRACTION
  69. PERF_SIZE_DWORD
  70. PERF_SIZE_LARGE
  71. PERF_SIZE_VARIABLE_LEN
  72. PERF_SIZE_ZERO
  73. PERF_TEXT_ASCII
  74. PERF_TEXT_UNICODE
  75. PERF_TIMER_100NS
  76. PERF_TIMER_TICK
  77. PERF_TYPE_COUNTER
  78. PERF_TYPE_NUMBER
  79. PERF_TYPE_TEXT
  80. PERF_TYPE_ZERO
  81. );
  82. $VERSION = '0.05';
  83. sub AUTOLOAD {
  84. my $constname;
  85. ($constname = $AUTOLOAD) =~ s/.*:://;
  86. my $val = constant($constname);
  87. if ($! != 0) {
  88. if ($! =~ /Invalid/) {
  89. $AutoLoader::AUTOLOAD = $AUTOLOAD;
  90. goto &AutoLoader::AUTOLOAD;
  91. }
  92. else {
  93. croak "Your vendor has not defined Win32::PerfLib macro $constname";
  94. }
  95. }
  96. eval "sub $AUTOLOAD { $val }";
  97. goto &$AUTOLOAD;
  98. }
  99. bootstrap Win32::PerfLib $VERSION;
  100. # Preloaded methods go here.
  101. sub new
  102. {
  103. my $proto = shift;
  104. my $class = ref($proto) || $proto;
  105. my $comp = shift;
  106. my $handle;
  107. my $self = {};
  108. if(PerfLibOpen($comp,$handle))
  109. {
  110. $self->{handle} = $handle;
  111. bless $self, $class;
  112. return $self;
  113. }
  114. else
  115. {
  116. return undef;
  117. }
  118. }
  119. sub Close
  120. {
  121. my $self = shift;
  122. return PerfLibClose($self->{handle});
  123. }
  124. sub DESTROY
  125. {
  126. my $self = shift;
  127. if(!PerfLibClose($self->{handle}))
  128. {
  129. croak "Error closing handle!\n";
  130. }
  131. }
  132. sub GetCounterNames
  133. {
  134. my($machine,$href) = @_;
  135. if(ref $href ne "HASH")
  136. {
  137. croak("usage: Win32::PerfLib::GetCounterNames(machine,hashRef)\n");
  138. }
  139. my($data,@data,$num,$name);
  140. my $retval = PerfLibGetNames($machine,$data);
  141. if($retval)
  142. {
  143. @data = split(/\0/, $data);
  144. while(@data)
  145. {
  146. $num = shift @data;
  147. $name = shift @data;
  148. $href->{$num} = $name;
  149. }
  150. }
  151. $retval;
  152. }
  153. sub GetCounterHelp
  154. {
  155. my($machine,$href) = @_;
  156. if(ref $href ne "HASH")
  157. {
  158. croak("usage: Win32::PerfLib::GetCounterHelp(machine,hashRef)\n");
  159. }
  160. my($data,@data,$num,$name);
  161. my $retval = PerfLibGetHelp($machine,$data);
  162. if($retval)
  163. {
  164. @data = split(/\0/, $data);
  165. while(@data)
  166. {
  167. $num = shift @data;
  168. $name = shift @data;
  169. $href->{$num} = $name;
  170. }
  171. }
  172. $retval;
  173. }
  174. sub GetObjectList
  175. {
  176. my $self = shift;
  177. my $object = shift;
  178. my $data = shift;
  179. if(ref $data ne "HASH")
  180. {
  181. croak("reference isn't a hash reference!\n");
  182. }
  183. return PerfLibGetObjects($self->{handle}, $object, $data);
  184. }
  185. sub GetCounterType
  186. {
  187. my $type = shift;
  188. my $retval;
  189. if( &Win32::PerfLib::PERF_100NSEC_MULTI_TIMER == $type )
  190. {
  191. $retval = "PERF_100NSEC_MULTI_TIMER";
  192. }
  193. elsif( &Win32::PerfLib::PERF_100NSEC_MULTI_TIMER_INV == $type )
  194. {
  195. $retval = "PERF_100NSEC_MULTI_TIMER_INV";
  196. }
  197. elsif( &Win32::PerfLib::PERF_100NSEC_TIMER == $type )
  198. {
  199. $retval = "PERF_100NSEC_TIMER";
  200. }
  201. elsif( &Win32::PerfLib::PERF_100NSEC_TIMER_INV == $type )
  202. {
  203. $retval = "PERF_100NSEC_TIMER_INV";
  204. }
  205. elsif( &Win32::PerfLib::PERF_AVERAGE_BASE == $type )
  206. {
  207. $retval = "PERF_AVERAGE_BASE";
  208. }
  209. elsif( &Win32::PerfLib::PERF_AVERAGE_BULK == $type )
  210. {
  211. $retval = "PERF_AVERAGE_BULK";
  212. }
  213. elsif( &Win32::PerfLib::PERF_AVERAGE_TIMER == $type )
  214. {
  215. $retval = "PERF_AVERAGE_TIMER";
  216. }
  217. elsif( &Win32::PerfLib::PERF_COUNTER_BULK_COUNT == $type )
  218. {
  219. $retval = "PERF_COUNTER_BULK_COUNT";
  220. }
  221. elsif( &Win32::PerfLib::PERF_COUNTER_COUNTER == $type )
  222. {
  223. $retval = "PERF_COUNTER_COUNTER";
  224. }
  225. elsif( &Win32::PerfLib::PERF_COUNTER_DELTA == $type )
  226. {
  227. $retval = "PERF_COUNTER_DELTA";
  228. }
  229. elsif( &Win32::PerfLib::PERF_COUNTER_LARGE_DELTA == $type )
  230. {
  231. $retval = "PERF_COUNTER_LARGE_DELTA";
  232. }
  233. elsif( &Win32::PerfLib::PERF_COUNTER_LARGE_QUEUELEN_TYPE == $type )
  234. {
  235. $retval = "PERF_COUNTER_LARGE_QUEUELEN_TYPE";
  236. }
  237. elsif( &Win32::PerfLib::PERF_COUNTER_LARGE_RAWCOUNT == $type )
  238. {
  239. $retval = "PERF_COUNTER_LARGE_RAWCOUNT";
  240. }
  241. elsif( &Win32::PerfLib::PERF_COUNTER_LARGE_RAWCOUNT_HEX == $type )
  242. {
  243. $retval = "PERF_COUNTER_LARGE_RAWCOUNT_HEX";
  244. }
  245. elsif( &Win32::PerfLib::PERF_COUNTER_MULTI_BASE == $type )
  246. {
  247. $retval = "PERF_COUNTER_MULTI_BASE";
  248. }
  249. elsif( &Win32::PerfLib::PERF_COUNTER_MULTI_TIMER == $type )
  250. {
  251. $retval = "PERF_COUNTER_MULTI_TIMER";
  252. }
  253. elsif( &Win32::PerfLib::PERF_COUNTER_MULTI_TIMER_INV == $type )
  254. {
  255. $retval = "PERF_COUNTER_MULTI_TIMER_INV";
  256. }
  257. elsif( &Win32::PerfLib::PERF_COUNTER_NODATA == $type )
  258. {
  259. $retval = "PERF_COUNTER_NODATA";
  260. }
  261. elsif( &Win32::PerfLib::PERF_COUNTER_QUEUELEN_TYPE == $type )
  262. {
  263. $retval = "PERF_COUNTER_QUEUELEN_TYPE";
  264. }
  265. elsif( &Win32::PerfLib::PERF_COUNTER_RAWCOUNT == $type )
  266. {
  267. $retval = "PERF_COUNTER_RAWCOUNT";
  268. }
  269. elsif( &Win32::PerfLib::PERF_COUNTER_RAWCOUNT_HEX == $type )
  270. {
  271. $retval = "PERF_COUNTER_RAWCOUNT_HEX";
  272. }
  273. elsif( &Win32::PerfLib::PERF_COUNTER_TEXT == $type )
  274. {
  275. $retval = "PERF_COUNTER_TEXT";
  276. }
  277. elsif( &Win32::PerfLib::PERF_COUNTER_TIMER == $type )
  278. {
  279. $retval = "PERF_COUNTER_TIMER";
  280. }
  281. elsif( &Win32::PerfLib::PERF_COUNTER_TIMER_INV == $type )
  282. {
  283. $retval = "PERF_COUNTER_TIMER_INV";
  284. }
  285. elsif( &Win32::PerfLib::PERF_ELAPSED_TIME == $type )
  286. {
  287. $retval = "PERF_ELAPSED_TIME";
  288. }
  289. elsif( &Win32::PerfLib::PERF_RAW_BASE == $type )
  290. {
  291. $retval = "PERF_RAW_BASE";
  292. }
  293. elsif( &Win32::PerfLib::PERF_RAW_FRACTION == $type )
  294. {
  295. $retval = "PERF_RAW_FRACTION";
  296. }
  297. elsif( &Win32::PerfLib::PERF_SAMPLE_BASE == $type )
  298. {
  299. $retval = "PERF_SAMPLE_BASE";
  300. }
  301. elsif( &Win32::PerfLib::PERF_SAMPLE_COUNTER == $type )
  302. {
  303. $retval = "PERF_SAMPLE_COUNTER";
  304. }
  305. elsif( &Win32::PerfLib::PERF_SAMPLE_FRACTION == $type )
  306. {
  307. $retval = "PERF_SAMPLE_FRACTION";
  308. }
  309. $retval;
  310. }
  311. 1;
  312. __END__
  313. =head1 NAME
  314. Win32::PerfLib - accessing the Windows NT Performance Counter
  315. =head1 SYNOPSIS
  316. use Win32::PerfLib;
  317. my $server = "";
  318. Win32::PerfLib::GetCounterNames($server, \%counter);
  319. %r_counter = map { $counter{$_} => $_ } keys %counter;
  320. # retrieve the id for process object
  321. $process_obj = $r_counter{Process};
  322. # retrieve the id for the process ID counter
  323. $process_id = $r_counter{'ID Process'};
  324. # create connection to $server
  325. $perflib = new Win32::PerfLib($server);
  326. $proc_ref = {};
  327. # get the performance data for the process object
  328. $perflib->GetObjectList($process_obj, $proc_ref);
  329. $perflib->Close();
  330. $instance_ref = $proc_ref->{Objects}->{$process_obj}->{Instances};
  331. foreach $p (sort keys %{$instance_ref})
  332. {
  333. $counter_ref = $instance_ref->{$p}->{Counters};
  334. foreach $i (keys %{$counter_ref})
  335. {
  336. if($counter_ref->{$i}->{CounterNameTitleIndex} == $process_id)
  337. {
  338. printf( "% 6d %s\n", $counter_ref->{$i}->{Counter},
  339. $instance_ref->{$p}->{Name}
  340. );
  341. }
  342. }
  343. }
  344. =head1 DESCRIPTION
  345. This module allows to retrieve the performance counter of any computer
  346. (running Windows NT) in the network.
  347. =head1 FUNCTIONS
  348. =head2 NOTE
  349. All of the functions return false if they fail, unless otherwise noted.
  350. If the $server argument is undef the local machine is assumed.
  351. =over 10
  352. =item Win32::PerfLib::GetCounterNames($server,$hashref)
  353. Retrieves the counter names and their indices from the registry and stores them
  354. in the hash reference
  355. =item Win32::PerfLib::GetCounterHelp($server,$hashref)
  356. Retrieves the counter help strings and their indices from the registry and
  357. stores them in the hash reference
  358. =item $perflib = Win32::PerfLib->new ($server)
  359. Creates a connection to the performance counters of the given server
  360. =item $perflib->GetObjectList($objectid,$hashref)
  361. retrieves the object and counter list of the given performance object.
  362. =item $perflib->Close($hashref)
  363. closes the connection to the performance counters
  364. =item Win32::PerfLib::GetCounterType(countertype)
  365. converts the counter type to readable string as referenced in L<calc.html> so
  366. that it is easier to find the appropriate formula to calculate the raw counter
  367. data.
  368. =back
  369. =head1 Datastructures
  370. The performance data is returned in the following data structure:
  371. =over 10
  372. =item Level 1
  373. $hashref = {
  374. 'NumObjectTypes' => VALUE
  375. 'Objects' => HASHREF
  376. 'PerfFreq' => VALUE
  377. 'PerfTime' => VALUE
  378. 'PerfTime100nSec' => VALUE
  379. 'SystemName' => STRING
  380. 'SystemTime' => VALUE
  381. }
  382. =item Level 2
  383. The hash reference $hashref->{Objects} has the returned object ID(s) as keys and
  384. a hash reference to the object counter data as value. Even there is only one
  385. object requested in the call to GetObjectList there may be more than one object
  386. in the result.
  387. $hashref->{Objects} = {
  388. <object1> => HASHREF
  389. <object2> => HASHREF
  390. ...
  391. }
  392. =item Level 3
  393. Each returned object ID has object-specific performance information. If an
  394. object has instances like the process object there is also a reference to
  395. the instance information.
  396. $hashref->{Objects}->{<object1>} = {
  397. 'DetailLevel' => VALUE
  398. 'Instances' => HASHREF
  399. 'Counters' => HASHREF
  400. 'NumCounters' => VALUE
  401. 'NumInstances' => VALUE
  402. 'ObjectHelpTitleIndex' => VALUE
  403. 'ObjectNameTitleIndex' => VALUE
  404. 'PerfFreq' => VALUE
  405. 'PerfTime' => VALUE
  406. }
  407. =item Level 4
  408. If there are instance information for the object available they are stored in
  409. the 'Instances' hashref. If the object has no instances there is an 'Counters'
  410. key instead. The instances or counters are numbered.
  411. $hashref->{Objects}->{<object1>}->{Instances} = {
  412. <1> => HASHREF
  413. <2> => HASHREF
  414. ...
  415. <n> => HASHREF
  416. }
  417. or
  418. $hashref->{Objects}->{<object1>}->{Counters} = {
  419. <1> => HASHREF
  420. <2> => HASHREF
  421. ...
  422. <n> => HASHREF
  423. }
  424. =item Level 5
  425. $hashref->{Objects}->{<object1>}->{Instances}->{<1>} = {
  426. Counters => HASHREF
  427. Name => STRING
  428. ParentObjectInstance => VALUE
  429. ParentObjectTitleIndex => VALUE
  430. }
  431. or
  432. $hashref->{Objects}->{<object1>}->{Counters}->{<1>} = {
  433. Counter => VALUE
  434. CounterHelpTitleIndex => VALUE
  435. CounterNameTitleIndex => VALUE
  436. CounterSize => VALUE
  437. CounterType => VALUE
  438. DefaultScale => VALUE
  439. DetailLevel => VALUE
  440. Display => STRING
  441. }
  442. =item Level 6
  443. $hashref->{Objects}->{<object1>}->{Instances}->{<1>}->{Counters} = {
  444. <1> => HASHREF
  445. <2> => HASHREF
  446. ...
  447. <n> => HASHREF
  448. }
  449. =item Level 7
  450. $hashref->{Objects}->{<object1>}->{Instances}->{<1>}->{Counters}->{<1>} = {
  451. Counter => VALUE
  452. CounterHelpTitleIndex => VALUE
  453. CounterNameTitleIndex => VALUE
  454. CounterSize => VALUE
  455. CounterType => VALUE
  456. DefaultScale => VALUE
  457. DetailLevel => VALUE
  458. Display => STRING
  459. }
  460. Depending on the B<CounterType> there are calculations to do (see calc.html).
  461. =back
  462. =head1 AUTHOR
  463. Jutta M. Klebe, jmk@bybyte.de
  464. =head1 SEE ALSO
  465. perl(1).
  466. =cut