Previous page

Next page

Locate page in Contents

Print this page

Performance Monitoring

To monitor the host or a virtual machine performance on a periodic basis, an event handler (callback function) is required. Within the event handler, first check the type of event. Events of type PET_DSP_EVT_HOST_STATISTICS_UPDATED indicate an event containing statistics data. To access the statistics handle (a handle of type PHT_SYSTEM_STATISTICS ), first extract the event parameter using PrlEvent_GetParam , then convert the result (which will be a handle to an object of type PHT_EVENT_PARAMETER ) to a handle using PrlEvtPrm_ToHandle . The functions that operate on PHT_SYSTEM_STATISTICS references can then be used to obtain statistics data.

For the event handler to be called, it is necessary to register it with PrlSrv_RegEventHandler . Before the event handler will receive statistics events, the application must subscribe to statistics events using PrlSrv_SubscribeToHostStatistics . When statistics data is no longer required, unsubscribe from statistics events using PrlSrv_UnsubscribeFromHostStatistics . When events are no longer required, unregister the event event handler using PrlSrv_UnregEventHandler .

The following is a complete example that demonstrates how to obtain statistics data asynchronously using PrlSrv_SubscribeToHostStatistics . Note that the same code could be used to receive statistics data for a virtual machine, instead of the host computer, by using PrlVm_SubscribeToGuestStatistics instead of PrlSrv_SubscribeToHostStatistics , and passing it a handle to a virtual machine that is running. This would also require using PrlVm_UnsubscribeFromGuestStatistics to stop receiving statistics data for the virtual machine.

#include "Parallels.h"

#include "Wrappers/SdkWrap/SdkWrap.h"

#include <stdio.h>

#ifdef _WIN_

#include <windows.h>

#else

#include <unistd.h>

#endif

const char *szServer = "123.123.123.123";

const char *szUsername = "Your Username";

const char *szPassword = "Your Password";

// -------------------------------------------------------------------------

// Event handler.

// -------------------------------------------------------------------------

// 1. Check for events of type PET_DSP_EVT_HOST_STATISTICS_UPDATES.

// 2. Display a header if first call to this event handler.

// 3. Get the event param (PHT_EVENT_PARAMETER) from the PHT_EVENT handle.

// 4. Convert event param to a handle (will be type PHT_SYSTEM_STATISTICS).

// 5. Use PHT_SYSTEM_STATISTICS handle to obtain CPU usage, memory usage,

//    and disk usage data.

// -------------------------------------------------------------------------

static PRL_RESULT OurCallback(PRL_HANDLE handle, void *pData)

{

PRL_HANDLE_TYPE nHandleType;

PRL_RESULT ret = PrlHandle_GetType(handle, &nHandleType);

// Check for PrlHandle_GetType error here.

if (nHandleType == PHT_EVENT)

{

PRL_EVENT_TYPE EventType;

PrlEvent_GetType(handle, &EventType);

// Check if the event type is a statistics update.

if (EventType == PET_DSP_EVT_HOST_STATISTICS_UPDATED)

{

// Output a header if first call to this function.

static PRL_BOOL bHeaderHasBeenPrinted = PRL_FALSE;

if (!bHeaderHasBeenPrinted)

{

bHeaderHasBeenPrinted = PRL_TRUE;

printf("CPU (%%) Used RAM (MB) Free RAM (MB) Used Disk Space (MB)"

" Free Disk Space (MB)\n");

printf("---------------------------------------------------------"

"--------------------\n");

}

PRL_HANDLE hEventParameters;

PRL_HANDLE hServerStatistics;

// Get the event parameter (PHT_EVENT_PARAMETER) from the event handle.

PrlEvent_GetParam(handle, 0, &hEventParameters);

// Convert the event parameter to a handle (PHT_SYSTEM_STATISTICS).

PrlEvtPrm_ToHandle(hEventParameters, &hServerStatistics);

// Get CPU statistics (usage in %).

PRL_HANDLE hCpuStatistics;

ret = PrlStat_GetCpuStat(hServerStatistics, 0, &hCpuStatistics);

PRL_UINT32 nCpuUsage = 0;

ret = PrlStatCpu_GetCpuUsage(hCpuStatistics, &nCpuUsage);

// Get RAM statistics.

PRL_UINT64 nUsedRam, nFreeRam;

PrlStat_GetFreeRamSize(hServerStatistics, &nFreeRam);

PrlStat_GetUsageRamSize(hServerStatistics, &nUsedRam);

nUsedRam /= (1024 * 1024);

nFreeRam /= (1024 * 1024);

// Get disk space statistics.

PRL_UINT64 nFreeDiskSpace, nUsedDiskSpace;

PRL_HANDLE hDiskStatistics;

PrlStat_GetDiskStat(hServerStatistics, 0, &hDiskStatistics);

PrlStatDisk_GetFreeDiskSpace(hDiskStatistics, &nFreeDiskSpace);

PrlStatDisk_GetUsageDiskSpace(hDiskStatistics, &nUsedDiskSpace);

nUsedDiskSpace /= (1024 * 1024);

nFreeDiskSpace /= (1024 * 1024);

printf("%7d %10lld %13lld %20lld %20lld\n",

nCpuUsage, nUsedRam, nFreeRam, nUsedDiskSpace, nFreeDiskSpace);

PrlHandle_Free(hDiskStatistics);

PrlHandle_Free(hCpuStatistics);

PrlHandle_Free(hServerStatistics);

PrlHandle_Free(hEventParameters);

}

}

PrlHandle_Free(handle);

return PRL_ERR_SUCCESS;

}

// --------------------------------------------------------------------------

// Program entry point.

// --------------------------------------------------------------------------

// 1. Call SdkWrap_Load(SDK_LIB_NAME).

// 2. Call PrlApi_Init(PARALLELS_API_VER).

// 3. Create a PRL_SERVER handle using PrlSrv_Create.

// 4. Log in using PrlSrv_Login.

// 5. Register our event handler (OurCallback function).

// 6. Subscribe to host statistics events.

// 7. Keep receiving events until user presses <enter> key.

// 8. Unsubscribe from host statistics events.

// 9. Un-register our event handler.

// 10. Logoff using PrlSrv_Logoff.

// 11. Call PrlApi_Uninit.

// 12. Call SdkWrap_Unload.

// --------------------------------------------------------------------------

int main(int argc, char* argv[])

{

PRL_HANDLE hServer;

PRL_RESULT ret;

// Use the correct dynamic library depending on the platform.

#ifdef _WIN_

#define SDK_LIB_NAME "prl_sdk.dll"

#elif defined(_LIN_)

#define SDK_LIB_NAME "libprl_sdk.so"

#elif defined(_MAC_)

#define SDK_LIB_NAME "libprl_sdk.dylib"

#endif

// Try to load the SDK library, terminate on failure to do so.

if (PRL_FAILED(SdkWrap_Load(SDK_LIB_NAME)) &&

PRL_FAILED(SdkWrap_Load("./" SDK_LIB_NAME)))

{

fprintf(stderr, "Failed to load " SDK_LIB_NAME "\n");

return -1;

}

// Initialize the Parallels API.

ret = PrlApi_Init(PARALLELS_API_VER);

if (PRL_FAILED(ret))

{

fprintf(stderr, "PrlApi_Init returned with error: %s.\n",

prl_result_to_string(ret));

PrlApi_Deinit();

SdkWrap_Unload();

return ret;

}

// Create a PHP_SERVER handle.

ret = PrlSrv_Create(&hServer);

if (PRL_FAILED(ret))

{

fprintf(stderr, "PrlSvr_Create failed, error: %s",

prl_result_to_string(ret));

PrlHandle_Free(hServer);

PrlApi_Deinit();

SdkWrap_Unload();

return -1;

}

// Log in (PrlSrv is asynchronous).

PRL_HANDLE hJob = PrlSrv_Login(

hServer,            // PRL_HANDLE of type PHT_SERVER.

szServer,           // Host name or IP address.

szUsername,         // Username.

szPassword,         // Password.

0,                  // Deprecated - UUID of previous session.

0,                  // Optional - port number (0 for default).

0,                  // Optional - timeout value (0 for default).

PSL_LOW_SECURITY);  // Security level (can be PSL_LOW_SECURITY,

PSL_NORMAL_SECURITY, or PSL_HIGH_SECURITY).

// Wait for a maximum of 10 seconds for

// asynchronous function PrlSrv_Login to complete.

ret = PrlJob_Wait(hJob, 1000);

if (PRL_FAILED(ret))

{

fprintf(stderr, "PrlJob_Wait for PrlSrv_Login returned with error: %s\n",

prl_result_to_string(ret));

PrlHandle_Free(hJob);

PrlHandle_Free(hServer);

PrlApi_Deinit();

SdkWrap_Unload();

return -1;

}

// Analyze the result of PrlSrv_Login.

PRL_RESULT nJobResult;

ret = PrlJob_GetRetCode(hJob, &nJobResult);

if (PRL_FAILED(nJobResult))

{

printf("Login job returned with error: %s\n",

prl_result_to_string(nJobResult));

PrlHandle_Free(hJob);

PrlHandle_Free(hServer);

PrlApi_Deinit();

SdkWrap_Unload();

return -1;

}

else

printf("Login was successful.\n");

// ----------------------------------------------------------------------------

// 1. Register our event handler (OurCallback function).

// 2. Subscribe to host statistics events.

// 3. Keep receiving events until user presses <enter> key.

// 4. Unsubscribe from host statistics events.

// 5. Un-register out event handler.

// ----------------------------------------------------------------------------

PrlSrv_RegEventHandler(hServer, OurCallback, NULL);

PrlSrv_SubscribeToHostStatistics(hServer);

char c;

scanf(&c, 1);

PrlSrv_UnsubscribeFromHostStatistics(hServer);

PrlSrv_UnregEventHandler(hServer, OurCallback, NULL);

// ----------------------------------------------------------------------------

// Log off.

hJob = PrlSrv_Logoff(hServer);

ret = PrlJob_Wait(hJob, 1000);

if (PRL_FAILED(ret))

{

fprintf(stderr, "PrlJob_Wait for PrlSrv_Logoff returned error: %s\n",

prl_result_to_string(ret));

PrlHandle_Free(hJob);

PrlHandle_Free(hServer);

PrlApi_Deinit();

SdkWrap_Unload();

return -1;

}

ret = PrlJob_GetRetCode(hJob, &nJobResult);

if (PRL_FAILED(ret))

{

fprintf(stderr, "PrlJob_GetRetCode failed for PrlSrv_Logoff with error: %s\n",

prl_result_to_string(ret));

PrlHandle_Free(hJob);

PrlHandle_Free(hServer);

PrlApi_Deinit();

SdkWrap_Unload();

return -1;

}

// Report success or failure of PrlSrv_Logoff.

if (PRL_FAILED(nJobResult))

{

fprintf(stderr, "PrlSrv_Logoff failed with error: %s\n",

prl_result_to_string(nJobResult));

PrlHandle_Free(hJob);

PrlHandle_Free(hServer);

PrlApi_Deinit();

SdkWrap_Unload();

return -1;

}

else

printf("Logoff was successful.\n");

// Free handles that are no longer required.

PrlHandle_Free(hJob);

PrlHandle_Free(hServer);

// De-initialize the Parallels API, and unload the SDK.

PrlApi_Deinit();

SdkWrap_Unload();

return 0;

}

Please send us your feedback on this help page