ASP MagicPerf Component  

MagicPerf component provides easy application integration with NT Performance Monitor functionality. Now with couple lines of code you can connect your ASP page, COM object, MTS package or any other application written in any language that supports COM model to NT Performance Monitor to report your metrics in real-time.


 

Couple examples where MagicPerf could be used:

  • To monitor how many simultaneous users you have on a specific ASP page
  • How many users hit your specific page
  • How long does your transaction takes to execute and under what conditions.

All the information gets reported real time and could be viewed using NT Performance Monitor Charts locally or remotely. MagicPerf supports most of the counters within NT Performance Monitor.

 

Evaluation of MagicPerf Component
Click here to download a 30-days evaluation copy of MagicPerf Component.

Purchasing MagicPerf Component
You can get MagicPerf online or by phone from The Registration Network

  • 1-CPU Licence $1299
  • 2-CPU Licence $1899
  • 4-CPU Licence $2299
Also, you may order by sending check to: Dana Consulting Inc.
(in the memo field specify MagicPerf)

Send it to:
Dana Consulting Inc.
14936 CreditView Drive
Savage, MN 55378

Please, print, fill out and enclose Order Form located in OrderForm.html file

Installation
Installation is done in four easy steps.
You need to be logged on as Administrator to the machine where you are installing component.

    Step 1:
    To install MagicPerf copy the following files in one directory of your choice:

    MagicPef.sys
    MagicLib.exe
    MagicPef.dll
    MagicLic.exe
    MagicLic.dat

    Step 2:
    In the "Command Prompt" window type the following command: regsvr32.exe MagicPef.dll.

    Step 3:
    In the the "Command Prompt" window type the following command: net start MagicPef On success the message will appear: "The magicpef service was started successfully."

    Step 4:
    In the "Command Prompt" window type the following command: MagicLic.exe. On success you will see the message: "OK: Licence has been successfully updated"

    Step 5:
    By default MagicPerf installed in the "Manual Start" mode. It means that every time you restart your computer you will need to execute command "net start magicpef" to start MagicPerf services. To set MagicPerf to start automatically, go to "Control Pane" -> "Devices". Find "Magic Performance Driver" and select start up option. Set it to "Automatic". Do the same for "Magic performance Library". After the above steps are completed MagicPerf will start automatically every time you restart your computer.

    Now you are ready to start using component.

 

Working with MagicPerf
Definitions
Methods
DefineObjectType
AddPredefinedCounterDefinition
RegisterObjectType
UnregisterObjectType
CalcOperationTime
ObtainTimeMark
ClearCounter
UpdateOneValueCounter
UpdateTwoValueCounter
Constants

Definitions:

Performance object Object created by the Magic Performance Component through the use of IPerfObject interface.
System's performance database: Place in a system's registry where both objects' and its counters' names and descriptions reside in the form of a text strings with leading numeric indexes. This is a well-known registry path, which points to HKLM\Software\Microsoft\WindowsNT\CurrentVersion\Perflib. In order for any performance object to be through NT Performance Monitor it must register all of its names and corresponding explanation in this database according to the special rules expected by NT PerfMon.
Defined performance object type: Memory based state of a particular component's instance when the call to the DefineObjectType method has succeeded and at least one performance counter definition has been successfully added by the call to the AddPredefinedCounterDefinition method. (See those methods explanations for details)
Registered performance object type: Memory-based state of a particular component's instance when a defined performance object type (see definition above) is successfully registered within a system through the call of interface's RegisterObjectType method. After registration such particular instance of a performance object becomes "alive" (viewable by standard Performance Monitoring application).
"Succeeds once" method's behavior: Behavior of an interface's method when a call through the method will succeed only once (or never if some kind of persistent error occurs) during the time started just after obtaining interface's pointer till the time the pointer is released.
"Succeeds when in valid order" method's behavior: This is a behavior of an interface's method when a call through the method will succeed only when it is called at a proper well-known state of the object this interface is intended to control and there is no any other persistent error (for example in method's parameters). There is no error to call such kind of method more then once if not mentioned otherwise.
Methods:

DefineObjectType Always the first method to be called after obtaining the interface pointer. Besides performance object's name and description special object's run-time behavior must be specified through it.
Method behavior: Succeeds once
AddPredefinedCounterDefinition Always should be the second method to call in the chain of calls through the interface. Intended to add one or more performance counters definitions to the performance object type.
Method behavior: Succeeds when in valid order
RegisterObjectType Registers defined performance object type.
Method behavior: Succeeds when in valid order and Succeeds once.
UnregisterObjectType Performs un-registration of defined performance object type. This means that object's and counters' names and explanations are deleted from system's performance database.
Method behavior: Succeeds when in valid order
UpdateOneValueCounter Any one value counter of a registered performance object type could be updated using this method
UpdateTwoValueCounter Any two-value (average) counter of a registered performance object type could be updated using this method
ClearCounter Any counter of a registered performance object type could be updated using this method
ObtainTimingMark Simple method to obtain a time marks for the further calculation of operation time. Could be called anytime.
CalcOperationTime Method to calculate operation time.
Constants:

Category   Description
DetailLevel
DefineObjectType
  Specifies the level of detail. Applications use this value to control display complexity. This value is the minimum detail level of all the counters for a given object. This member can be one of the following values.
LevelNovice 0 No technical ability is required to understand the counter data.
LevelAdvanced 1 The counter data is provided for advanced users.
LevelExpert 2 The counter data is provided for expert users.
LevelWizard 3 The counter data is provided for system designers.
PredefinedCounter
Used In Function:
AddPredefinedCounterDefinition
   
NumberCounter 1 PERF_COUNTER_RAWCOUNT
Instantaneous counter value. This is the most common counter.
NumberCounterHex 2 PERF_COUNTER_RAWCOUNT_HEX
Instantaneous counter value intended to be displayed as a hexadecimal number.
NumberCounterLarge 3 PERF_COUNTER_LARGE_RAWCOUNT
Instantaneous counter value.
NumberCounterLargeHex 4 PERF_COUNTER_LARGE_RAWCOUNT_HEX Instantaneous counter value intended to be displayed as a hexadecimal number.
RateCounter 5 PERF_COUNTER_COUNTER.
Rate of counts. This is the most common counter.
RateCounterLarge 6 PERF_COUNTER_COUNTER
Rate of counts. This is the most common counter.
DeltaCounter 7 PERF_COUNTER_DELTA
Difference between two counters.
DeltaCounterLarge 8 PERF_COUNTER_LARGE_DELTA
Difference between two counters.
QueueSizeCounter 9 PERF_COUNTER_LARGE_QUEUELEN_TYPE
Count per time interval. Typically used to track number of items queued or waiting.
BusyCounter 10 PERF_COUNTER_TIMER
FreeCounter 11 PERF_COUNTER_TIMER_INV
The inverse of the timer. Used when the object is not in use.
BusyCounter100Ns 12 PERF_100NSEC_TIMER
Timer for when the object is in use.
FreeCounter100Ns 13 PERF_100NSEC_TIMER_INV
The inverse of the timer. Used when the object is not in use.
ElapseTimeCounter 14 PERF_ELAPSED_TIME
The data is the start time of the item being measured. For display, subtract the start time from the snapshot time to yield the elapsed time.
AvgBulkCounter 15 PERF_AVERAGE_BULK
A count that usually gives the bytes per operation when divided by the number of operations. Use only UpdateTwoValueCounter function
AvgTimeCounter 16 PERF_AVERAGE_TIMER
A timer that usually gives time per operation when divided by the number of operations. Use only UpdateTwoValueCounter function
FractionCounter 17 PERF_RAW_FRACTION
Instantaneous value, to be divided by the base data.
Use only UpdateTwoValueCounter function
CounterUpdateCmd
Used In Function:
UpdateOneValueCounter
   
CmdIncrement 0 Increments data for the counter
CmdDecrement 1 Decrements data for the counter
CmdSet 2 Sets data for the counter
CmdGet 3 Retrieves data from the counter
TimingUnit
Used In Function:
ObtainTimeMark
  Sets time mark for counter that are using time
TuFrequency 0 The sampling frequency performance data collection. It is used to convert PerfTime to seconds; for example, PerfTime/PerfFreq = seconds.
TuInterval100ns 1 The performance data sampling time in 100-nanosecond units.
TimeMeasureUnit
Used In Function:
CalcOperationTime
   
TmuFrequency 0 Measures time in frequency
TmuInterval100ns 1 Measures time in 100ns intervals
TmuMilliseconds 2 Measures time in milliseconds intervals
TmuSeconds 3 Measures time in seconds intervals
Method Detailed Information

Function DefineObjectType
(bstrTypeGuid As String, bstrObjectName As String, bstrObjectDesc As String, ObjectDetailLevel As Long, [InstanceNameOrShareFlag]) As Boolean

The first method to call should be done after obtaining the interface. Serves to specify object parameters.

Parameters:
[in]


[in]

[in]

[in]


[in]
bstrTypeGuid
The string representation of GUID should be passed through this parameter.
(GUID string without curly or square brackets around)
bstrObjectName
Object name.
bstrObjectDesc
Object description.
ObjectDetailLevel
Special constant, which could be taken from enumeration type which, resides in the type library for the performance component.
InstanceNameOrShareFlag
See remarks


Remarks:

Each performance object must have object type. This type is represented by GUID string (example: "00001234-5678-9012-3456-78901234ABCD") passed through this method call. You are as developer responsible for generation your own GUID. We also provide tility called magicguid.exe which will generate GUID for you. 
Reason for the GUID: Suppose two different developers from two different companies decided to export a single performance object in his or her application respectively. Further: each of these persons gave the same name to his or her object and each of them added only one counter to his or her object with the same name also. By using unique GUIDs these people irrespectively of each other will give a hint to the component and these objects will be able to co-exist and work on the same machine without conflicts.

In the ObjectDetailLevel variable passed to the method caller could specify one of the constants: (LevelNovice = 0, LevelAdvanced = 1, LevelExpert = 2, LevelWizard = 3), which resides in type library for the component, or the caller could pass just raw constant from the range [0..3]. Detail level doesn't affect any important object characteristics at least from the point of view of today's version of Performance Monitor application, but this could change in the future. Moreover detail level could be used by any custom performance-monitoring application which uses NT's standard performance-monitoring interface through registry API.

The last parameter of this method is very important. The thing must be mentioned first is the variable type which could be passed to this method. The only types, which will be accepted by the component, are Null, Empty, String, Bool. Any other type will be rejected with error. The type of the last parameter and parameter's data controls one important aspect of performance object - instance behavior. See the table below to decide what value to pass through this parameter to the component to get suitable performance object mode.

Type Description
Null Only one instance of given performance object type (based on GUID) will be running on the machine. Any other attempt to create the same object type will give an error. This should be used in NT services or executables that have only one instance per machine.
EMPTY Reserved
False Reserved
True Only one performance object type (based on GUID) will be present on the machine. But any additional attempt to create the same object type will succeed (if no errors occur) and all component instances will share the same performance object and its counter data. (They will update the same counter data). This technique could be useful in Web-based environment such as ASP pages, COM objects and MTS packages, where multiple instances of given object could exist at the same time.
String When component detects that a string is passed in the last parameter of this method, then it will create additional performance object with its own separate counters data. This object's instance could be distinguished by its name in Performance Monitor application. If some application exports several instances of its performance object then it is object's designer responsibility to provide different instance names to them, otherwise there won't be any way to distinguish them in Performance Monitor. Null or empty string passed in the parameter will generate an error. Could be used in NT services or executables that may have more then one instance per machine.

Example:

Call myobj.DefineObjectType("f370c8f0-2031-11d4-ae08-0050dacfb712" , "myObject", "myObjectDesc", LevelExpert, True)



Function AddPredefinedCounterDefinition(bstrCounterName As String, bstrCounterDesc As String, PredefinedCounterType As Long, CounterDetailLevel As Long, CounterScale As Long, [bfDefaultCounterFlag]) As Long

This is a second method that should be done after the call of DefineObjectType in your application. This method needed to add one or more performance counters to the performance object type. It called so many times as many counters are going to be added to the object definition. Those calls could be made only before calling RegisterObjectType. After successful registration of performance object type (through RegisterObjectType) any call to this method will generate an error.


Parameters:
[in]

[in

[in]

[in]


[in]



bstrCounterName
Counter name
bstrCounterDesc
Counter description.
PredefinedCounterType
Counter type. (See Constant Table)
CounterDetailLevel
Special constant, which could be taken from enumeration type which, resides in the type library for the performance component.
CounterScale
Some constant value to specify default counter scale as hint for data visualization in Performance Monitor application. This constant value defines scale factor as a power of 10.
Example: 1 - means scale factor 0.1
2 - means scale factor 0.02
3 - means scale factor 1000

[in]





[out]
Valid value for this parameter belongs to the range [-7..7].
bfDefaultCounterFlag
If "true" value is passed in this parameter then corresponding counter will be treated as default. It means that if somebody adds performance counter for monitoring without selecting one, then default counter will be chosen automatically by Performance Monitor application. Each successive call with a "true" value overwrites previously defined default counter.
pCounterIndex
Counter access index. Must be saved on successful return from the method (See remarks)

Remarks:

When specifying counter name and counter description make sure not to provide empty strings. If any of these parameters are Null or contain empty strings then component will return error code. Strings with blanks are allowed.
In the CounterDetailLevel variable passed to the method caller it is possible to specify one of the constants: (LevelNovice = 0, LevelAdvanced = 1, LevelExpert = 2, LevelWizard = 3), which resides in type library for the component, or the caller could pass just raw constant from the range [0..3]. Detail level doesn't affect any of counter's characteristics at least from the point of view of today's version of Performance Monitor application, but this could change in the future.
On successful return from this method caller must save a value referenced by pCounterIndex pointer. Caller must not make any assumptions about the value being referenced by this pointer. Later this value should be used when updating specific counter's data.

Example:

c1 = myobj.AddPredefinedCounterDefinition("DeltaCounter", "DeltaCounter",
DeltaCounter, 1, 0, Null)

c2 = myobj.AddPredefinedCounterDefinition("NumberCounter", "NumberCounter",
NumberCounter, 1, 0, Null)

c3 = myobj.AddPredefinedCounterDefinition("AvgTimeCounter", "AvgTimeCounter",
AvgTimeCounter, 1, 0, Null)

c4 = myobj.AddPredefinedCounterDefinition("AvgBulkCounter", "AvgBulkCounter",
AvgBulkCounter, 1, 0, Null)

c5 = myobj.AddPredefinedCounterDefinition("RateCounter", "RateCounter",
RateCounter, 1, 0, Null)



Function RegisterObjectType() As Boolean

Through a call of this method any defined performance object type (which contains at least one counter definition) could be exported and become "alive" (viewable). This method should be called only once. If it succeeds then any additional call of it will fail. Each time you change the structure of the object, add/remove or change counters definitions, new GUID needs to be generated. 


Parameters: None

Remarks:

While call is being performed attempt is made to register performance object's name and description and it counters names with descriptions in system's performance database, internal memory-based structure of the object is created also.

Example:
Call myobj.RegisterObjectType



Function UnregisterObjectType() As Boolean


Through a call of this method any defined performance object type could be unregistered from a system's performance database.

Parameters: None

Remarks:

If performance object is registered (via a call to RegisterObjectType), then this method won't work. Moreover this method is not intended to be called often and will succeed only under some circumstances. First thing that should be taken in mind is the fact that performance object's definition data (counters' names and theirs explanations) resides in registry and could be accessed at any particular moment not only by the component itself, but by operating system and performance monitoring applications. That implies some restrictions, since component's code is unaware about such activity. The component checks whether any similar component instances are running at specific instance of un-registration, and whether any standard Performance Monitoring applications are running and use counters' definitions from the system's performance database which is about of being reorganized by the call to this method. If object counters are not locked by any of the above resources, object will be deleted. If counters are in use, this method will fail.

Example:

Call myobj.UnregisterObjectType



Function ObtainTimeMark (typeOfTimeMark As Long)
Obtain operation start time in specified units

Parameters:
[in]

a.
b.
typeOfTimeMark As Long
Specifies type of time measure. Could be
TuFrequency
TuInterval100ns

Remarks:

Both values could be used to obtain current system time. This function is required to be called before calling CalcOperationTime function. The returned value should not be changed and need to be passed into CalcOperationTimefunction as reference.

Example:

dblmark = myobj.ObtainTimeMark(tuInterval100ns)



Function CalcOperationTime (typeOfTimeMark As Long, unitOfMeasure As Long, TimeMark)

Calculate the time for a particular operation in any of 4 possible units of measure

Parameters:
[in]

[in]

a.
b.
c.
d.
typeOfTimeMark
Needs to be the same type as used in ObtainTimeMark function
unitOfMeasure
Specifies unit of time measure. Could be
TmuFrequency
TmuInterval100ns
TmuMilliseconds
TmuSeconds

Example:

OpTime = myobj.CalcOperationTime (tuInterval100ns, tmuMilliseconds, dblmark)



Function ClearCounter (CounterIndex As Long) As Boolean

Clear counter's data of performance object

Parameters:
[in] CounterIndex

Counter index should be returned and stored by previous call to AddPredefinedCounterDefinition function.

Remarks:

Calling ClearCounter function will set specified counter to 0.

Example:

myobj.ClearCounter(c1)



Function UpdateOneValueCounter (CounterIndex As Long, updCmd As Long, pValue) As Boolean

Update one-value counter of performance object

Parameters:
[in]


[in]

a.
b.
c.
[in]

CounterIndex
Counter index should be returned and stored by previous call to AddPredefinedCounterDefinition function.
updCmd
Command specifies operation to perform on the counter. Choices are:

CmdIncrement - increments counter by value pValue
CmdDecrement - decrements counter by value pValue
CmdSet - sets counter to value pValue
pValue

Value to be passed to the counter.

Remarks:

This is one of the main functions that perform all the work. After this function is called the System's performance database is updated and changes became viewable through performance monitor.

Example:

Call myobj.UpdateOneValueCounter(c2, cmdSet, MyValue)



Function UpdateTwoValueCounter(CounterIndex As Long, pValue1,pValue2 ) As Boolean
Update one-value counter of performance object

Parameters:
[in]


[in]
[in]
CounterIndex
Counter index should be returned and stored by previous call to AddPredefinedCounterDefinition function.

pValue1
pValue2

Remarks:

UpdateTwoValueCounter function used to update counters that require two values. Usualy those are an "average" counters. Example of the counters where UpdateTwoValueCounter function needs to be used are: AvgBulkCounter, AvgTimeCounter. Counters themselves are responseible for caulculation proer value and updating System's performance database.

Example:

myobj.UpdateTwoValueCounter(c3, val1,val2)

Examples of the Code:

ASP Examples:

1. Using this snap of code you should be able to monitor real-time number of users visiting your page.

<!--#INCLUDE FILE = "magic_pef.inc" -->
<%
Set myPefObj=Server.CreateObject("MagicPerf")
If Not myPefObj.DefineObjectType("f370c8f0-2031-11d4-ae08-0050dacfb789", myASPApp1","Test MagicPerf application", LevelExpert, True) Then
  Response.Write ("Error in DefineObjectType")
End If
cntNumber = myPefObj.AddPredefinedCounterDefinition("TotalHits", "Displays", NumberCounter, 1, 0, Null)
Call myPefObj.RegisterObjectType
Call myPefObj.UpdateOneValueCounter(cntNumber, cmdIncrement, 1)
%>

2. Using this code should show total number of simultaneous users accessing specific page at the same time.

<!--#INCLUDE FILE = "magic_pef.inc" -->
<%
Set myPefObj=Server.CreateObject("MagicPerf")
If Not myPefObj.DefineObjectType("f370c8f0-2031-11d4-ae08-0050dacfb780", "myASPApp2","Test MagicPerf application", LevelExpert, True) Then
  Response.Write ("Error in DefineObjectType")
End If
cntNumber = myPefObj.AddPredefinedCounterDefinition("PageLoad", "Displays Number of simultanious user on the page", NumberCounter, 1, 0, Null)

Call myPefObj.RegisterObjectType
Call myPefObj.UpdateOneValueCounter(cntNumber, cmdIncrement, 1)
' your ASP and HTML code here --------------------------
for i=0 to 10000    'for loop is just our example
   j=1
next
'-----------------------------------------------
Call myPefObj.UpdateOneValueCounter(cntNumber, cmdDecrement, 1)
%>

3. Examples shows how long does it take for your page to get processed.

<!--#INCLUDE FILE = "magic_pef.inc" -->
<%
Set myPefObj=Server.CreateObject("MagicPerf")
If Not myPefObj.DefineObjectType("f270c8f0-3031-12d4-ae08-0050dacfb773", "myASPApp4","Test MagicPerf application", LevelExpert, True) Then
    Response.Write("Error in DefineObjectType")
End If
cntNumber = myPefObj.AddPredefinedCounterDefinition("PageLoadTime2", "Displays Time ASP code takes to execute", NumberCounter, 1, 0, Null)

Call myPefObj.RegisterObjectType
timeMark = myPefObj.ObtainTimeMark(tuInterval100ns)
'your ASP and HTML code here --------------------------
for i=0 to 10000    'for loop is just our example
     j=1
next
'-----------------------------------------------
optime = myPefObj.CalcOperationTime(tuInterval100ns, tmuMilliseconds, timeMark)
Call myPefObj.UpdateOneValueCounter(cntNumber, cmdSet, optime)
%>

More examples for ASP, Visual Basic and Visual C++ are included in the download package.

     
top


Home | FAQ | News | How to buy | Contacts | ASP MagicPerf Component | ASP MagicShell Component | Website Monitoring Blog