Performance Monitor itself is not the be-all end-all system administration tool. We had hoped to provide a tool that is to bottleneck detection and capacity planning what NotePad is to word processing. To us this meant a basic ability to view system information using real-time charts, logs, reports, and alerts. It also meant providing concurrent monitoring of multiple remote systems. Beyond these basic facilities, we felt it would be better to expose the interfaces we describe in this chapter than to try to solve everyone's problems in one fell swoop.
The structure of Performance Monitor is a trifle involved, and it won't make any sense to you why we did all this unless you have a grasp of what we had hoped to accomplish. We had some rather lofty goals at the start of this project, and these greatly influenced the data structures and mechanisms we chose to use.
A key objective was to not tie Performance Monitor to the counter set in any one system. It was clear that there would be multiple Win32 system implementations, and they might support completely different sets of counters. This consideration permits us to port Performance Monitor to those systems easily, and also lets Performance Monitor collect and display data from non-Windows systems such as Novell NetWare® servers or UNIX® systems.
It seemed to be a good idea to allow device drivers, network protocols, and server applications to add their own objects and counters to Performance Monitor. This was not a difficult addition to the plan, because the Performance Monitor itself was already designed to be independent of the counters in the system. This led to the facility to add extended objects, which is covered in detail in Chapter 13, "Adding Application Performance Counters."
We wanted the overhead of Performance Monitor to be low, and its level to be controlled by the user. This led to letting the user select the time interval for sampling. As the project evolved, we discovered that to really control overhead, we had to let the user select objects as well. A finer level of selection did not seem to buy much.
We wanted monitoring of remote systems to be just as easy as monitoring local systems. Through the magic of remote procedure call (RPC), this was an easy goal to achieve.
We also wanted it to be relatively easy to write performance monitors. This led to a certain amount of redundancy in the data. Structures we had dealt with in prototype monitors were more efficient, but required lots of logic in Performance Monitor and the system in order to achieve what appeared to be somewhat trivial savings. For example, the name of a process is returned with each block of data collected for the process, so the monitor does not have to keep separate track of object instance names and somehow tie them to their collected data. This makes operations like appending log files and relogging at longer time intervals much easier. It also makes it simple to construct performance monitors that limit log file space and reuse space when it becomes full; although ours does not work that way, yours could.
Finally, we wanted Performance Monitor to be language-independent. All strings displayed to the user are in resources that can be edited separately from the program. Because Performance Monitor is independent of the system, the names of the counters are not in the monitor's resources. We nonetheless needed to be able to translate the counters and Explain text into other languages. This text is instead stored in the Registry in the languages supported on the system.