[comment {-*- tcl -*- doctools manpage}]
[manpage_begin "Performance Counters" n ""]
[copyright "2014 Ashok P. Nadkarni"]
[moddesc "Performance Counters"]
[titledesc "Commands related to retrieving performance counters"]
[require twapi_pdh]
[description]
[para]

This package provides procedures related to retrieving Windows
performance counters.

This documentation is reference material for related commands.
For more introductory material
and a guide with examples, see the [emph "Performance Monitoring"]
chapter in the
[uri http://www.magicsplat.com/book "Tcl on Windows"] online book.

[section "Performance Objects"]
To get a list of performance objects on a system, call
[uri #pdh_enumerate_objects [cmd pdh_enumerate_objects]].
Commands
[uri #pdh_enumerate_object_counters [cmd pdh_enumerate_object_counters]],
[uri #pdh_enumerate_object_instances [cmd pdh_enumerate_object_instances]] and
[uri #pdh_enumerate_object_items [cmd pdh_enumerate_object_items]] return
the counters and instances for a particular performance object.

[section "Counter Paths"]

Similar to files in a file system, performance counters are identified
by a counter path. A counter path is of the form
[example {\\Computer\PerfObject(ParentInstance/ObjectInstance#InstanceIndex)\Counter}]

Not all components in a counter path need to be specified.
See [uri "http://msdn.microsoft.com/en-us/library/windows/desktop/aa373193(v=vs.85).aspx" "Windows SDK documentation"]
for a detailed description and examples.
[emph {Note that \ and / are not interchangeable in a counter path}]

[para]
To construct a counter path, call 
[uri #pdh_counter_path [cmd pdh_counter_path]]. The break down a 
counter path into its components, call
[uri #pdh_parse_counter_path [cmd pdh_parse_counter_path]].

[section "Retrieving Counter Values"]
To retrieve values for a counter, use the following sequence of commands
[list_begin opt]
[opt_def [uri #pdh_query_open [cmd pdh_query_open]]] 
Opens a query object to which counters can be added.
[opt_def [uri #pdh_counter_path [cmd pdh_counter_path]]]
Constructs a counter path for the performance object and instance
of interest. Call for each counter of interest.
[opt_def [uri #pdh_add_counter [cmd pdh_add_counter]]]
Adds a counter (specified by its counter path as returned in the previous step)
to a query and returns a handle to it. Call for each counter of interest.
[opt_def [uri #pdh_query_refresh [cmd pdh_query_refresh]]]
Updates all counters in the query to their current values. For rate
based counters, this must be called at least twice before retrieving
the value of a counter.
[opt_def [uri #pdh_get_scalar [cmd pdh_get_scalar]]]
Returns the scalar value of a counter as updated in the last
call to [uri #pdh_query_refresh [cmd pdh_query_refresh]].
[opt_def [uri #pdh_get_array [cmd pdh_get_array]]]
Returns a counter that is an array of values (for example, one
for each process) as updated in the last call
call to [uri #pdh_query_refresh [cmd pdh_query_refresh]].
[opt_def [uri #pdh_query_get [cmd pdh_query_get]]]
Returns values for multiple counters from a query. Internally does
the equivalent of [uri #pdh_query_refresh [cmd pdh_query_refresh]].
[opt_def [uri #pdh_query_close [cmd pdh_query_close]]]
Closes a query. This should be called to release resources associated
with a query once the contained counters are no longer required.
[list_end]

The [uri #pdh_system_performance_query [cmd pdh_system_performance_query]]
is a wrapper around [uri #pdh_query_open [cmd pdh_query_open]] that
includes some commonly used system counters.

[example_begin]
set queryh [lb]pdh_system_performance_query processor_utilization memory_free_kb[rb]
proc print_counters {queryh} {
    pdh_query_refresh $queryh
    puts [lb]pdh_query_get $queryh[rb]
    after 1000 [lb]info level 0[rb]
}
print_counters $queryh
vwait forever
[example_end]

[section Commands]

[list_begin definitions]

[call [cmd pdh_add_counter] [arg HPERF] [arg CTRPATH] [opt [arg options]]]
Adds a counter specified by its path [arg CTRPATH] to a performance query.
[arg HPERF] is a query handle previously returned by
[uri #pdh_query_open [cmd pdh_query_open]].
[arg CTRPATH] is a counter path normally constructed through
[uri #pdh_counter_path [cmd pdh_counter_path]].
Subsequent calls to [uri #pdh_query_refresh [cmd pdh_query_refresh]]
for that query will update the counter.
[nl]
The command returns a handle to the counter which can then
be passed to [uri #pdh_get_scalar [cmd pdh_get_scalar]] or
[uri #pdh_get_array [cmd pdh_get_array]] to retrieve its value. Alternatively,
the [uri #pdh_query_get [cmd pdh_query_get]] command can be used
to get values of multiple counters from a query.
[nl]
The counter is automatically released when the query is closed. However,
if a counter is no longer required while the other counters in the query
are still in use, it can be removed from the query by calling
[uri #pdh_remove_counter [cmd pdh_remove_counter]].
[nl]
The following options may be specified with the command. They impact
how values from the counter are returned from the
[uri #pdh_query_get [cmd pdh_query_get]] command.
[list_begin opt]
[opt_def [cmd -array] [arg BOOLEAN]] If [const true] ,the counter is treated as
an array of values. If [const false] (default), it will be returned as a scalar.
[opt_def [cmd -format] [arg FORMAT]]
Specifies how the counter value should be formatted. [arg FORMAT]
may be on of [const long], [const large] or [const double]
for a 32-bit integer, a 64-bit integer or a floating point double.
[opt_def [cmd -name] [arg NAME]]
Specifies the mnemonic name by which the counter will be identified when
multiple counter values are retrieved with
[uri #pdh_query_get [cmd pdh_query_get]]. If unspecified, defaults
to the full counter path [arg CTRPATH].
[opt_def [cmd -scale] [arg SCALE]]
By default, each counter has a default scaling factor.
If [arg SCALE] is [const none], the counter value is
returned without the default scaling. If [arg SCALE] is [const x1000],
the returned value is scaled up by a factor of 1000. If [arg SCALE]
is [const nocap100], the counter value is not capped at 100 as is the scale
for some counters like processor utilization.

[list_end]

[call [cmd pdh_counter_path] [arg PERFOBJ] [arg CTRNAME] [opt [arg options]]]
Returns a path to a performance counter that can then be passed to
[uri #pdh_add_counter [cmd pdh_add_counter]]. [arg PERFOBJ] should
be the name of the performance object, such as [const TCPv4].
[arg CTRNAME] should be the name of the performance counter in the
object, such as [const "Connection Failures"]. The following
additional options may be passed:
[list_begin opt]
[opt_def [cmd -instance] [arg INSTANCE]]
When there are many instances of a performance object, as is true
for the [const Process] object for example, this option allows specification
of a particular instance by specifying its name as [arg INSTANCE].
Many performance objects allow [arg INSTANCE] to be specified as [const *]
to indicate counters for all instances are to be returned.
[opt_def [cmd -instanceindex] [arg INSTANCEINDEX]]
When there is more than one instance of a performance object with the
same name, this option allows selection of a particular one
by specifying its numeric instance index.
[opt_def [cmd -localized] [arg BOOLEAN]]
Performance object and counter names
are localized based on the system languages. Using [const Process]
as the object name on a French localized system will result in a failure.
By default the command assumes the passed names are in English and
localizes them for the local system. If [cmd -localized] is passed
as [const true], the command assumes that the names being passed
are already appropriately localized.
[opt_def [cmd -parent] [arg PARENTINSTANCE]]
Some performance objects, like [const Thread], are contained within
another parent object, [const Process] in the case of [arg Thread].
In such cases [arg PARENTINSTANCE] specifies the context for
the target object.
[list_end]
See [uri "http://msdn.microsoft.com/en-us/library/windows/desktop/aa373193(v=vs.85).aspx" "Windows SDK documentation"]
for more details on counter path syntax and components.

[call [cmd pdh_enumerate_objects] [opt [arg options]]]
Returns a list of the names of the performance objects on a system.
The following options may be specified:
[list_begin opt]
[opt_def [cmd -detail] [arg DETAILLEVEL]]
Controls which detail levels are to be returned. [arg DETAILLEVEL]
may be one of [const novice], [const advanced], [const expert] and
[const wizard] (default) which return performance objects at
an increasing level of detail.
[opt_def [cmd -refresh]]
The list of performance objects is returned from a cache.
Performance objects may be added by any application at any time.
Specifying [cmd -refresh] causes the cache to be refreshed
before being returned.
[list_end]

[call [cmd pdh_enumerate_object_counters] [arg PERFOBJ] [opt [arg options]]]
Returns a list of the names of counters present in the performance
object [arg PERFOBJ]. See 
[uri #pdh_enumerate_object_items [cmd pdh_enumerate_object_items]]
for valid options.

[call [cmd pdh_enumerate_object_instances] [arg PERFOBJ] [opt [arg options]]]
Returns a list of the names of instances of the performance
object [arg PERFOBJ]. The list may be empty if the object supports
instances but none are present. The command raises an error
if [arg PERFOBJ] does not support instances at all.
See [uri #pdh_enumerate_object_items [cmd pdh_enumerate_object_items]]
for valid options.

[call [cmd pdh_enumerate_object_items] [arg PERFOBJ] [opt [arg options]]]
Returns a list of one or two elements, the first being a list of counter names
for the performance object [arg PERFOBJ]. If the performance object
does not support instances, the returned list contains only that element.
Otherwise, the second element is the
list of instance names for object. This may be empty in the case
the performance object supports instances but none are present.
The following options may be specified:
[list_begin opt]
[opt_def [cmd -detail] [arg DETAILLEVEL]]
Controls which detail levels are to be returned. [arg DETAILLEVEL]
may be one of [const novice], [const advanced], [const expert] and
[const wizard] (default) which return performance objects at
an increasing level of detail.
[opt_def [cmd -refresh]]
The list of performance objects is returned from a cache.
Performance objects may be added by any application at any time.
The command will fail if [arg PERFOBJ] is not in the cache.
Specifying [cmd -refresh] causes the cache to be refreshed
before attempting to access the information for [arg PERFOBJ].
[list_end]

[call [cmd pdh_get_array] [arg HCOUNTER] [opt [arg options]]]
Returns a flat list of instance name and value pairs for a counter
that covers multiple objects, such as one containing wildcards.
Refer to [uri #pdh_get_scalar [cmd pdh_get_scalar]] for options.
[nl]
Note that the command does not refresh the counter value. Caller must
do that with [uri #pdh_query_refresh [cmd pdh_query_refresh]] before
calling this command if so desired.

[call [cmd pdh_get_scalar] [arg HCOUNTER] [opt [arg options]]]
Returns the value of the specified counter as of the last call
to [uri #pdh_query_refresh [cmd pdh_query_refresh]]. [arg HCOUNTER]
is a handle to a counter as returned by a prior call to
[uri #pdh_add_counter [cmd pdh_add_counter]]. If the
counter was specified using a wildcard, use
[uri #pdh_get_array [cmd pdh_get_array]] instead to retrieve
multiple values for all matching instances.
[nl]
The following options may be specified:
[list_begin opt]
[opt_def [cmd -format] [arg FORMAT]]
Specifies how the counter value should be formatted. [arg FORMAT]
may be on of [const long], [const large] or [const double]
for a 32-bit integer, a 64-bit integer or a floating point double.
[opt_def [cmd -scale] SCALE]
By default, each counter has a default scaling factor.
If [arg SCALE] is [const none], the counter value is
returned without the default scaling. If [arg SCALE] is [const x1000],
the returned value is scaled up by a factor of 1000. If [arg SCALE]
is [const nocap100], the counter value is not capped at 100 as is the scale
for some counters like processor utilization.
[opt_def [cmd -var] [arg VARNAME]]
Specifies [arg VARNAME] as the name of a variable in the caller's
context where the counter value is stored instead of being returned
as the result of the command. If specified, the return value of
the command is [const 1] on success and [const 0] if the counter
does not exist. Without this option, the command will raise an error
if the counter does not exist.
[list_end]
Note that the command does not refresh the counter value. Caller must
do that with [uri #pdh_query_refresh [cmd pdh_query_refresh]] before
calling this command if so desired.
[call [cmd pdh_parse_counter_path] [arg CTRPATH]]
Returns a dictionary containing the components of the
counter path [arg CTRPATH]. The dictionary contains the following
keys corresponding to each component of the path: [const machine],
[const object], [const instance], [const instanceindex], [const parent]
and [const counter].

[call [cmd pdh_query_close] [arg HPERF]]
Closes a performance counter query. All counters added to the query
are also released. 
[arg HPERF] is a query handle previously returned by
[uri #pdh_query_open [cmd pdh_query_open]].

[call [cmd pdh_query_get] [arg HPERF] [opt [arg "NAME1 NAME2...."]]]
Returns the values for one or more counters added to the query
with [uri #pdh_add_counter [cmd pdh_add_counter]]. If no arguments
are specified, values for all counters added to the query are returned.
Otherwise, each argument must be the name associated with the counter
with the [cmd -name] option to the [cmd pdh_add_counter] command.
[nl]
The counters are refreshed with their current values from the system
before being returned.
[nl]
The returned value is a dictionary, each key of which is the mnemonic name
associated with the abovementioned [cmd -name] option of [cmd pdh_add_counter].
The corresponding value in the dictionary may be a scalar or an array
(as returned by the [uri #pdh_get_array [cmd pdh_get_array]] command)
depending on whether the [cmd -array] option was specified as true
in the corresponding [cmd pdh_add_counter] call.

[call [cmd pdh_query_open]]
Open a new performance counter query and returns a handle to it.
Counters can be added and removed from the query using
The query must be closed when no longer needed by calling
[uri #pdh_query_close [cmd pdh_query_close]].

[call [cmd pdh_query_refresh] [arg HPERF]]
Refreshes all counters in the specified performance counter query
with their current values from the system.
[arg HPERF] is a query handle previously returned by
[uri #pdh_query_open [cmd pdh_query_open]].
[nl]
In the case of rate-based counters
like processor utilization, the first call only serves to
initialize the counters. Valid data is collected only from the second
call onwards. Microsoft recommends calls be at least one second apart.

[call [cmd pdh_remove_counter] [arg HPERF] [arg CTRNAME]]
Removes a counter from a performance counter query. Counters are
automatically released when a query is closed. However, if a counter
is no longer of use but the other counters in the query are, this command can
be used to remove it.

[call [cmd pdh_system_performance_query] [opt [arg "CTRNAME ...."]]]
This is a wrapper around [uri #pdh_query_open [cmd pdh_query_open]] that
includes some commonly used system counters.
[nl]
Calling the command without any arguments will return a list of 
counter mnemonics that the command understands.
[nl]
If called with arguments, each argument must be the name of a counter
mnemonic. The command then returns a handle to a performance query with
those counters already added. The command also internally
calls [uri #pdh_query_refresh [cmd pdh_query_refresh]].
[nl]
The returned query handle can be used
exactly as a handle from [uri #pdh_query_open [cmd pdh_query_open]]
including addition of more counters, retrieving counter values etc.
It must also be closed in the same manner by calling
[uri #pdh_query_close [cmd pdh_query_close]].

[list_end]

[keywords "performance counters" "counters"]

[manpage_end]
