Skip to content

Instantly share code, notes, and snippets.

@higebu
Last active August 29, 2015 14:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save higebu/72f23dbef572122f9448 to your computer and use it in GitHub Desktop.
Save higebu/72f23dbef572122f9448 to your computer and use it in GitHub Desktop.
diff -ur zabbix-2.4.1.orig/conf/zabbix_proxy.conf zabbix-2.4.1/conf/zabbix_proxy.conf
--- zabbix-2.4.1.orig/conf/zabbix_proxy.conf 2014-10-08 15:58:58.000000000 +0900
+++ zabbix-2.4.1/conf/zabbix_proxy.conf 2014-10-28 19:19:43.501952068 +0900
@@ -312,6 +312,14 @@
# Default:
# VMwareFrequency=60
+### Option: VMwarePerfFrequency
+# How often Zabbix will connect to VMware service to obtain performance data.
+#
+# Mandatory: no
+# Range: 10-86400
+# Default:
+# VMwarePerfFrequency=60
+
### Option: VMwareCacheSize
# Size of VMware cache, in bytes.
# Shared memory size for storing VMware data.
diff -ur zabbix-2.4.1.orig/conf/zabbix_server.conf zabbix-2.4.1/conf/zabbix_server.conf
--- zabbix-2.4.1.orig/conf/zabbix_server.conf 2014-10-08 15:58:58.000000000 +0900
+++ zabbix-2.4.1/conf/zabbix_server.conf 2014-10-28 19:19:43.501952068 +0900
@@ -229,6 +229,14 @@
# Default:
# VMwareFrequency=60
+### Option: VMwarePerfFrequency
+# How often Zabbix will connect to VMware service to obtain performance data.
+#
+# Mandatory: no
+# Range: 10-86400
+# Default:
+# VMwarePerfFrequency=60
+
### Option: VMwareCacheSize
# Size of VMware cache, in bytes.
# Shared memory size for storing VMware data.
diff -ur zabbix-2.4.1.orig/src/zabbix_proxy/proxy.c zabbix-2.4.1/src/zabbix_proxy/proxy.c
--- zabbix-2.4.1.orig/src/zabbix_proxy/proxy.c 2014-10-08 15:58:58.000000000 +0900
+++ zabbix-2.4.1/src/zabbix_proxy/proxy.c 2014-11-11 10:21:32.891773793 +0900
@@ -149,6 +149,7 @@
int CONFIG_VMWARE_FORKS = 0;
int CONFIG_VMWARE_FREQUENCY = 60;
+int CONFIG_VMWARE_PERF_FREQUENCY = 60;
zbx_uint64_t CONFIG_CONF_CACHE_SIZE = 8 * ZBX_MEBIBYTE;
zbx_uint64_t CONFIG_HISTORY_CACHE_SIZE = 8 * ZBX_MEBIBYTE;
@@ -582,6 +583,8 @@
PARM_OPT, 0, 250},
{"VMwareFrequency", &CONFIG_VMWARE_FREQUENCY, TYPE_INT,
PARM_OPT, 10, SEC_PER_DAY},
+ {"VMwarePerfFrequency", &CONFIG_VMWARE_PERF_FREQUENCY, TYPE_INT,
+ PARM_OPT, 10, SEC_PER_DAY},
{"VMwareCacheSize", &CONFIG_VMWARE_CACHE_SIZE, TYPE_UINT64,
PARM_OPT, 256 * ZBX_KIBIBYTE, __UINT64_C(2) * ZBX_GIBIBYTE},
{"AllowRoot", &CONFIG_ALLOW_ROOT, TYPE_INT,
diff -ur zabbix-2.4.1.orig/src/zabbix_server/poller/checks_simple.c zabbix-2.4.1/src/zabbix_server/poller/checks_simple.c
--- zabbix-2.4.1.orig/src/zabbix_server/poller/checks_simple.c 2014-10-08 15:58:58.000000000 +0900
+++ zabbix-2.4.1/src/zabbix_server/poller/checks_simple.c 2014-10-28 19:22:36.405933757 +0900
@@ -70,6 +70,7 @@
{"hv.datastore.discovery", VMCHECK_FUNC(check_vcenter_hv_datastore_discovery)},
{"hv.datastore.read", VMCHECK_FUNC(check_vcenter_hv_datastore_read)},
{"hv.datastore.write", VMCHECK_FUNC(check_vcenter_hv_datastore_write)},
+ {"hv.perfcounter", VMCHECK_FUNC(check_vcenter_hv_perfcounter)},
{"vm.cluster.name", VMCHECK_FUNC(check_vcenter_vm_cluster_name)},
{"vm.cpu.num", VMCHECK_FUNC(check_vcenter_vm_cpu_num)},
@@ -97,6 +98,7 @@
{"vm.vfs.dev.write", VMCHECK_FUNC(check_vcenter_vm_vfs_dev_write)},
{"vm.vfs.fs.discovery", VMCHECK_FUNC(check_vcenter_vm_vfs_fs_discovery)},
{"vm.vfs.fs.size", VMCHECK_FUNC(check_vcenter_vm_vfs_fs_size)},
+ {"vm.perfcounter", VMCHECK_FUNC(check_vcenter_vm_perfcounter)},
{NULL, NULL}
};
diff -ur zabbix-2.4.1.orig/src/zabbix_server/poller/checks_simple_vmware.c zabbix-2.4.1/src/zabbix_server/poller/checks_simple_vmware.c
--- zabbix-2.4.1.orig/src/zabbix_server/poller/checks_simple_vmware.c 2014-10-08 15:58:58.000000000 +0900
+++ zabbix-2.4.1/src/zabbix_server/poller/checks_simple_vmware.c 2014-10-28 19:23:12.257930174 +0900
@@ -179,30 +179,74 @@
return cluster;
}
-
-static int vmware_counter_get(const char *stats, const char *instance, zbx_uint64_t counterid, int coeff,
- AGENT_RESULT *result)
+static int vmware_service_counter_get(zbx_vmware_service_t *service, const char *type, const char *id,
+ const char *path, const char *instance, int coeff, AGENT_RESULT *result)
{
- const char *__function_name = "vmware_counter_get";
-
- int ret = SYSINFO_RET_FAIL;
- char xpath[MAX_STRING_LEN], *value;
+ const char *__function_name = "vmware_service_counter_get";
+ int ret = SYSINFO_RET_FAIL;
+ zbx_uint64_t counterid;
+ int i;
+ zbx_vmware_perf_entity_t *entity;
+ zbx_vmware_perf_counter_t *perfcounter;
+ zbx_ptr_pair_t *perfvalue;
- zabbix_log(LOG_LEVEL_DEBUG, "In %s() %s: " ZBX_FS_UI64, __function_name, instance, counterid);
+ zabbix_log(LOG_LEVEL_DEBUG, "In %s() type:%s id:%s path:%s instance:%s", __function_name, type, id, path,
+ instance);
- zbx_snprintf(xpath, sizeof(xpath), ZBX_XPATH_LN3("value", "id", "counterId") "[.='" ZBX_FS_UI64 "']/.."
- ZBX_XPATH_LN("instance") "[.='%s']/../.." ZBX_XPATH_LN("value"), counterid, instance);
-
- if (NULL == (value = zbx_xml_read_value(stats, xpath)))
+ if (FAIL == zbx_vmware_service_get_perfcounterid(service, path, &counterid))
{
SET_MSG_RESULT(result, zbx_strdup(NULL, "Performance counter is not available."));
goto out;
}
- if (SUCCEED == set_result_type(result, ITEM_VALUE_TYPE_UINT64, ITEM_DATA_TYPE_DECIMAL, value))
+ if (NULL == (entity = zbx_vmware_service_get_perf_entity(service, type, id)))
+ {
+ /* the requested counter has not been queried yet */
+ zabbix_log(LOG_LEVEL_DEBUG, "performance data is not yet ready, ignoring request");
ret = SYSINFO_RET_OK;
+ goto out;
+ }
- zbx_free(value);
+ for (i = 0; i < entity->counters.values_num; i++)
+ {
+ perfcounter = (zbx_vmware_perf_counter_t *)entity->counters.values[i];
+
+ if (perfcounter->counterid == counterid)
+ break;
+ }
+
+ if (i == entity->counters.values_num)
+ {
+ SET_MSG_RESULT(result, zbx_strdup(NULL, "Performance counter data was not found."));
+ goto out;
+ }
+
+ for (i = 0; i < perfcounter->values.values_num; i++)
+ {
+ perfvalue = (zbx_ptr_pair_t *)&perfcounter->values.values[i];
+
+ if (NULL == perfvalue->first)
+ {
+ if ('\0' == *instance)
+ break;
+ continue;
+ }
+
+ if (0 == strcmp(perfvalue->first, instance))
+ break;
+ }
+
+ if (i == perfcounter->values.values_num)
+ {
+ SET_MSG_RESULT(result, zbx_strdup(NULL, "Performance counter instance was not found."));
+ goto out;
+ }
+
+ if (SUCCEED == set_result_type(result, ITEM_VALUE_TYPE_UINT64, ITEM_DATA_TYPE_DECIMAL, perfvalue->second))
+ {
+ result->ui64 *= coeff;
+ ret = SYSINFO_RET_OK;
+ }
out:
zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, sysinfo_ret_string(ret));
@@ -210,7 +254,7 @@
}
static int vmware_service_get_vm_counter(zbx_vmware_service_t *service, const char *uuid, const char *instance,
- zbx_uint64_t counterid, int coeff, AGENT_RESULT *result)
+ const char *path, int coeff, AGENT_RESULT *result)
{
const char *__function_name = "vmware_service_get_vm_counter";
@@ -218,7 +262,7 @@
zbx_vmware_vm_t *vm = NULL;
zbx_vmware_dev_t *dev;
- zabbix_log(LOG_LEVEL_DEBUG, "In %s() uuid:'%s' %s: " ZBX_FS_UI64, __function_name, uuid, instance, counterid);
+ zabbix_log(LOG_LEVEL_DEBUG, "In %s() uuid:%s instance:%s path:%s", __function_name, uuid, instance, path);
if (NULL == (vm = service_vm_get(service, uuid)))
{
@@ -240,7 +284,7 @@
goto out;
}
- ret = vmware_counter_get(vm->stats, instance, counterid, coeff, result);
+ ret = vmware_service_counter_get(service, "VirtualMachine", vm->id, path, instance, coeff, result);
out:
zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, sysinfo_ret_string(ret));
@@ -251,90 +295,111 @@
{
const char *__function_name = "vmware_get_events";
- zbx_vector_str_t keys;
zbx_uint64_t key;
- char *value, xpath[MAX_STRING_LEN];
+ char *value, *error = NULL;
int i, ret = SYSINFO_RET_FAIL;
zbx_log_t *log;
struct tm tm;
time_t t;
+ xmlDoc *doc;
+ xmlXPathContext *xpathCtx;
+ xmlXPathObject *xpathObj;
+ xmlNodeSetPtr nodeset;
zabbix_log(LOG_LEVEL_DEBUG, "In %s() lastlogsize:" ZBX_FS_UI64, __function_name, lastlogsize);
- zbx_vector_str_create(&keys);
-
- if (SUCCEED != zbx_xml_read_values(events, ZBX_XPATH_LN2("Event", "key"), &keys))
+ if (NULL == (doc = xmlReadMemory(events, strlen(events), "noname.xml", NULL, 0)))
{
- SET_MSG_RESULT(result, zbx_strdup(NULL, "No event key found."));
- zbx_vector_str_destroy(&keys);
+ error = zbx_strdup(error, "Cannot parse event data.");
goto out;
}
- for (i = keys.values_num - 1; i >= 0; i--)
- {
- if (SUCCEED != is_uint64(keys.values[i], &key))
- continue;
+ xpathCtx = xmlXPathNewContext(doc);
- if (key <= lastlogsize)
- continue;
+ if (NULL == (xpathObj = xmlXPathEvalExpression((xmlChar *)ZBX_VMWARE_EVENTS(), xpathCtx)))
+ {
+ error = zbx_strdup(error, "Cannot make event parsing query.");
+ goto clean;
+ }
- /* value */
+ if (xmlXPathNodeSetIsEmpty(xpathObj->nodesetval))
+ {
+ error = zbx_strdup(error, "Cannot find event keys in event data.");
+ goto clean;
+ }
- zbx_snprintf(xpath, sizeof(xpath), ZBX_XPATH_LN2("Event", "key") "[.='" ZBX_FS_UI64 "']/.."
- ZBX_XPATH_LN("fullFormattedMessage"), key);
+ nodeset = xpathObj->nodesetval;
- if (NULL == (value = zbx_xml_read_value(events, xpath)))
+ for (i = 0; i < nodeset->nodeNr; i++)
+ {
+ if (NULL == (value = zbx_xml_read_node_value(doc, nodeset->nodeTab[i], "*[local-name()='key']")))
continue;
- zbx_replace_invalid_utf8(value);
- log = add_log_result(result, value);
- log->logeventid = key;
- log->lastlogsize = key;
-
- zbx_free(value);
-
- /* timestamp */
+ if (SUCCEED == is_uint64(value, &key) && key > lastlogsize)
+ {
+ zbx_free(value);
- zbx_snprintf(xpath, sizeof(xpath), ZBX_XPATH_LN2("Event", "key") "[.='" ZBX_FS_UI64 "']/.."
- ZBX_XPATH_LN("createdTime"), key);
+ value = zbx_xml_read_node_value(doc, nodeset->nodeTab[i],
+ "*[local-name()='fullFormattedMessage']");
- if (NULL == (value = zbx_xml_read_value(events, xpath)))
- continue;
+ if (NULL != value)
+ {
+ zbx_replace_invalid_utf8(value);
+ log = add_log_result(result, value);
+ log->logeventid = key;
+ log->lastlogsize = key;
- /* 2013-06-04T14:19:23.406298Z */
- if (6 == sscanf(value, "%d-%d-%dT%d:%d:%d.%*s", &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour,
- &tm.tm_min, &tm.tm_sec))
+ zbx_free(value);
+ value = zbx_xml_read_node_value(doc, nodeset->nodeTab[i],
+ "*[local-name()='createdTime']");
- {
- int tz_offset;
+ if (NULL != value)
+ {
+ if (6 == sscanf(value, "%d-%d-%dT%d:%d:%d.%*s", &tm.tm_year, &tm.tm_mon,
+ &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec))
+ {
+ int tz_offset;
#if defined(HAVE_TM_TM_GMTOFF)
- struct tm *ptm;
- time_t now;
+ struct tm *ptm;
+ time_t now;
- now = time(NULL);
- ptm = localtime(&now);
- tz_offset = ptm->tm_gmtoff;
+ now = time(NULL);
+ ptm = localtime(&now);
+ tz_offset = ptm->tm_gmtoff;
#else
- tz_offset = -timezone;
+ tz_offset = -timezone;
#endif
- tm.tm_year -= 1900;
- tm.tm_mon--;
- tm.tm_isdst = -1;
+ tm.tm_year -= 1900;
+ tm.tm_mon--;
+ tm.tm_isdst = -1;
+
+ if (0 < (t = mktime(&tm)))
+ log->timestamp = (int)t + tz_offset;
+ }
- if (0 < (t = mktime(&tm)))
- log->timestamp = (int)t + tz_offset;
+ }
+ }
}
+
zbx_free(value);
}
if (!ISSET_LOG(result))
set_log_result_empty(result);
- zbx_vector_str_clean(&keys);
- zbx_vector_str_destroy(&keys);
-
ret = SYSINFO_RET_OK;
+
+clean:
+ if (NULL != xpathObj)
+ xmlXPathFreeObject(xpathObj);
+
+ xmlXPathFreeContext(xpathCtx);
+ xmlFreeDoc(doc);
+ xmlCleanupParser();
out:
+ if (NULL != error)
+ SET_MSG_RESULT(result, error);
+
zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, sysinfo_ret_string(ret));
return ret;
@@ -388,7 +453,7 @@
if (0 != (service->state & ZBX_VMWARE_STATE_FAILED))
{
SET_MSG_RESULT(result, zbx_strdup(NULL, NULL != service->data->error ? service->data->error :
- "Unknown VMware service error"));
+ "Unknown VMware service error."));
zabbix_log(LOG_LEVEL_DEBUG, "failed to query VMware service: %s",
NULL != service->data->error ? service->data->error : "unknown error");
@@ -500,7 +565,7 @@
SET_UI64_RESULT(result, hv->vms.values_num);
break;
case ZBX_OPT_MEM_BALLOONED:
- xpath = ZBX_XPATH_LN2("quickStats", "balloonedMemory");
+ xpath = ZBX_VM_QUICKSTATS("balloonedMemory");
value_uint64_sum = 0;
for (i = 0; i < hv->vms.values_num; i++)
@@ -691,7 +756,7 @@
else if (0 == strcmp(status, "red"))
SET_UI64_RESULT(result, 3);
else
- ret = SYSINFO_RET_FAIL;
+ ret = SYSINFO_RET_FAIL;
zbx_free(status);
unlock:
@@ -759,7 +824,7 @@
if (NULL == (service = get_vmware_service(url, username, password, result, &ret)))
goto unlock;
- if (NULL == (version = zbx_xml_read_value(service->contents, ZBX_XPATH_LN2("about", "version"))))
+ if (NULL == (version = zbx_xml_read_value(service->contents, ZBX_VMWARE_ABOUT("version"))))
goto unlock;
SET_STR_RESULT(result, version);
@@ -797,7 +862,7 @@
if (NULL == (service = get_vmware_service(url, username, password, result, &ret)))
goto unlock;
- if (NULL == (fullname = zbx_xml_read_value(service->contents, ZBX_XPATH_LN2("about", "fullName"))))
+ if (NULL == (fullname = zbx_xml_read_value(service->contents, ZBX_VMWARE_ABOUT("fullName"))))
goto unlock;
SET_STR_RESULT(result, fullname);
@@ -874,7 +939,7 @@
zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
ret = get_vcenter_stat(request, username, password, ZBX_OPT_XPATH,
- ZBX_XPATH_LN2("quickStats", "overallCpuUsage"), result);
+ ZBX_HV_QUICKSTATS("overallCpuUsage"), result);
if (SYSINFO_RET_OK == ret && NULL != GET_UI64_RESULT(result))
result->ui64 = result->ui64 * 1000000;
@@ -917,7 +982,7 @@
zbx_vmware_cluster_t *cluster = NULL;
zbx_vmware_hv_t *hv = (zbx_vmware_hv_t *)service->data->hvs.values[i];
- if (NULL == (name = zbx_xml_read_value(hv->details, ZBX_XPATH_LN2("config", "name"))))
+ if (NULL == (name = zbx_xml_read_value(hv->details, ZBX_HV_CONFIG("name"))))
continue;
if (NULL != hv->clusterid)
@@ -958,7 +1023,7 @@
zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
- ret = get_vcenter_stat(request, username, password, ZBX_OPT_XPATH, ZBX_XPATH_LN2("product", "fullName"),
+ ret = get_vcenter_stat(request, username, password, ZBX_OPT_XPATH, ZBX_HV_CONFIG_PRODUCT("fullName"),
result);
zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, sysinfo_ret_string(ret));
@@ -975,7 +1040,7 @@
zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
- ret = get_vcenter_stat(request, username, password, ZBX_OPT_XPATH, ZBX_XPATH_LN2("hardware", "numCpuCores"),
+ ret = get_vcenter_stat(request, username, password, ZBX_OPT_XPATH, ZBX_HV_HARDWARE("numCpuCores"),
result);
zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, sysinfo_ret_string(ret));
@@ -992,7 +1057,7 @@
zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
- ret = get_vcenter_stat(request, username, password, ZBX_OPT_XPATH, ZBX_XPATH_LN2("hardware", "cpuMhz"),
+ ret = get_vcenter_stat(request, username, password, ZBX_OPT_XPATH, ZBX_HV_HARDWARE("cpuMhz"),
result);
if (SYSINFO_RET_OK == ret && NULL != GET_UI64_RESULT(result))
@@ -1012,7 +1077,7 @@
zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
- ret = get_vcenter_stat(request, username, password, ZBX_OPT_XPATH, ZBX_XPATH_LN2("hardware", "cpuModel"),
+ ret = get_vcenter_stat(request, username, password, ZBX_OPT_XPATH, ZBX_HV_HARDWARE("cpuModel"),
result);
zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, sysinfo_ret_string(ret));
@@ -1029,8 +1094,7 @@
zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
- ret = get_vcenter_stat(request, username, password, ZBX_OPT_XPATH,
- ZBX_XPATH_LN2("hardware", "numCpuThreads"), result);
+ ret = get_vcenter_stat(request, username, password, ZBX_OPT_XPATH, ZBX_HV_HARDWARE("numCpuThreads"), result);
zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, sysinfo_ret_string(ret));
@@ -1046,8 +1110,7 @@
zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
- ret = get_vcenter_stat(request, username, password, ZBX_OPT_XPATH, ZBX_XPATH_LN2("hardware", "memorySize"),
- result);
+ ret = get_vcenter_stat(request, username, password, ZBX_OPT_XPATH, ZBX_HV_HARDWARE("memorySize"), result);
zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, sysinfo_ret_string(ret));
@@ -1063,7 +1126,7 @@
zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
- ret = get_vcenter_stat(request, username, password, ZBX_OPT_XPATH, ZBX_XPATH_LN2("hardware", "model"),
+ ret = get_vcenter_stat(request, username, password, ZBX_OPT_XPATH, ZBX_HV_HARDWARE("model"),
result);
zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, sysinfo_ret_string(ret));
@@ -1080,7 +1143,7 @@
zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
- ret = get_vcenter_stat(request, username, password, ZBX_OPT_XPATH, ZBX_XPATH_LN2("hardware", "uuid"),
+ ret = get_vcenter_stat(request, username, password, ZBX_OPT_XPATH, ZBX_HV_HARDWARE("uuid"),
result);
zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, sysinfo_ret_string(ret));
@@ -1097,7 +1160,7 @@
zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
- ret = get_vcenter_stat(request, username, password, ZBX_OPT_XPATH, ZBX_XPATH_LN2("hardware", "vendor"),
+ ret = get_vcenter_stat(request, username, password, ZBX_OPT_XPATH, ZBX_HV_HARDWARE("vendor"),
result);
zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, sysinfo_ret_string(ret));
@@ -1134,7 +1197,7 @@
zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
ret = get_vcenter_stat(request, username, password, ZBX_OPT_XPATH,
- ZBX_XPATH_LN2("quickStats", "overallMemoryUsage"), result);
+ ZBX_HV_QUICKSTATS("overallMemoryUsage"), result);
if (SYSINFO_RET_OK == ret && NULL != GET_UI64_RESULT(result))
result->ui64 = result->ui64 * ZBX_MEBIBYTE;
@@ -1153,8 +1216,7 @@
zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
- ret = get_vcenter_stat(request, username, password, ZBX_OPT_XPATH, ZBX_XPATH_LN2("val", "overallStatus"),
- result);
+ ret = get_vcenter_stat(request, username, password, ZBX_OPT_XPATH, ZBX_HV_STATUS(), result);
if (SYSINFO_RET_OK == ret && NULL != GET_STR_RESULT(result))
{
@@ -1186,7 +1248,7 @@
zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
- ret = get_vcenter_stat(request, username, password, ZBX_OPT_XPATH, ZBX_XPATH_LN2("quickStats", "uptime"),
+ ret = get_vcenter_stat(request, username, password, ZBX_OPT_XPATH, ZBX_HV_QUICKSTATS("uptime"),
result);
zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, sysinfo_ret_string(ret));
@@ -1203,8 +1265,7 @@
zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
- ret = get_vcenter_stat(request, username, password, ZBX_OPT_XPATH, ZBX_XPATH_LN2("product", "version"),
- result);
+ ret = get_vcenter_stat(request, username, password, ZBX_OPT_XPATH, ZBX_HV_CONFIG_PRODUCT("version"), result);
zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, sysinfo_ret_string(ret));
@@ -1266,7 +1327,8 @@
goto unlock;
}
- ret = vmware_counter_get(hv->stats, "", service->counters.nic_received, ZBX_KIBIBYTE, result);
+ ret = vmware_service_counter_get(service, "HostSystem", hv->id, "net/received[average]", "", ZBX_KIBIBYTE,
+ result);
unlock:
zbx_vmware_unlock();
out:
@@ -1314,7 +1376,9 @@
goto unlock;
}
- ret = vmware_counter_get(hv->stats, "", service->counters.nic_transmitted, ZBX_KIBIBYTE, result);
+ ret = vmware_service_counter_get(service, "HostSystem", hv->id, "net/transmitted[average]", "", ZBX_KIBIBYTE,
+ result);
+
unlock:
zbx_vmware_unlock();
out:
@@ -1432,8 +1496,8 @@
if (NULL == datastore->uuid)
break;
- ret = vmware_counter_get(hv->stats, datastore->uuid,
- service->counters.datastore_read_latency, 1, result);
+ ret = vmware_service_counter_get(service, "HostSystem", hv->id,
+ "datastore/totalReadLatency[average]", datastore->uuid, 1, result);
goto unlock;
}
}
@@ -1496,8 +1560,8 @@
if (NULL == datastore->uuid)
break;
- ret = vmware_counter_get(hv->stats, datastore->uuid,
- service->counters.datastore_write_latency, 1, result);
+ ret = vmware_service_counter_get(service, "HostSystem", hv->id,
+ "datastore/totalWriteLatency[average]", datastore->uuid, 1, result);
goto unlock;
}
}
@@ -1511,6 +1575,67 @@
return ret;
}
+int check_vcenter_hv_perfcounter(AGENT_REQUEST *request, const char *username, const char *password,
+ AGENT_RESULT *result)
+{
+ const char *__function_name = "check_vcenter_hv_perfcounter";
+ int ret = SYSINFO_RET_FAIL;
+ char *url, *uuid, *path, *instance;
+ zbx_vmware_service_t *service;
+ zbx_vmware_hv_t *hv;
+ zbx_uint64_t counterid;
+
+ zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
+
+ if (3 > request->nparam || request->nparam > 4)
+ {
+ SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters."));
+ goto out;
+ }
+
+ url = get_rparam(request, 0);
+ uuid = get_rparam(request, 1);
+ path = get_rparam(request, 2);
+ instance = get_rparam(request, 3);
+
+ if (NULL == instance)
+ instance = "";
+
+ zbx_vmware_lock();
+
+ if (NULL == (service = get_vmware_service(url, username, password, result, &ret)))
+ goto unlock;
+
+ if (NULL == (hv = hv_get(&service->data->hvs, uuid)))
+ {
+ SET_MSG_RESULT(result, zbx_strdup(NULL, "Unknown hypervisor uuid."));
+ goto unlock;
+ }
+
+ if (FAIL == zbx_vmware_service_get_perfcounterid(service, path, &counterid))
+ {
+ SET_MSG_RESULT(result, zbx_strdup(NULL, "Performance counter is not available."));
+ goto unlock;
+ }
+
+ if (SUCCEED == zbx_vmware_service_start_monitoring(service, "HostSystem", hv->id, counterid))
+ {
+ ret = SYSINFO_RET_OK;
+ goto unlock;
+ }
+
+ /* the performance counter is already being monitored, try to get the results from statistics */
+ ret = vmware_service_counter_get(service, "HostSystem", hv->id, path, instance, 1, result);
+
+unlock:
+ zbx_vmware_unlock();
+out:
+ zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, sysinfo_ret_string(ret));
+
+ return ret;
+}
+
+
int check_vcenter_vm_cpu_num(AGENT_REQUEST *request, const char *username, const char *password,
AGENT_RESULT *result)
{
@@ -1520,7 +1645,7 @@
zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
- ret = get_vcenter_vmstat(request, username, password, ZBX_XPATH_LN2("config", "numCpu"), result);
+ ret = get_vcenter_vmstat(request, username, password, ZBX_VM_CONFIG("numCpu"), result);
zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, sysinfo_ret_string(ret));
@@ -1593,7 +1718,7 @@
zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
- ret = get_vcenter_vmstat(request, username, password, ZBX_XPATH_LN2("quickStats", "overallCpuUsage"), result);
+ ret = get_vcenter_vmstat(request, username, password, ZBX_VM_QUICKSTATS("overallCpuUsage"), result);
if (SYSINFO_RET_OK == ret && NULL != GET_UI64_RESULT(result))
result->ui64 = result->ui64 * 1000000;
@@ -1646,10 +1771,10 @@
{
vm = (zbx_vmware_vm_t *)hv->vms.values[k];
- if (NULL == (vm_name = zbx_xml_read_value(vm->details, ZBX_XPATH_LN2("config", "name"))))
+ if (NULL == (vm_name = zbx_xml_read_value(vm->details, ZBX_VM_CONFIG("name"))))
continue;
- if (NULL == (hv_name = zbx_xml_read_value(hv->details, ZBX_XPATH_LN2("config", "name"))))
+ if (NULL == (hv_name = zbx_xml_read_value(hv->details, ZBX_HV_CONFIG("name"))))
{
zbx_free(vm_name);
continue;
@@ -1727,7 +1852,7 @@
if (i != service->data->hvs.values_num)
{
- name = zbx_xml_read_value(hv->details, ZBX_XPATH_LN2("config", "name"));
+ name = zbx_xml_read_value(hv->details, ZBX_HV_CONFIG("name"));
SET_STR_RESULT(result, name);
ret = SYSINFO_RET_OK;
@@ -1751,7 +1876,7 @@
zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
- ret = get_vcenter_vmstat(request, username, password, ZBX_XPATH_LN2("config", "memorySizeMB"), result);
+ ret = get_vcenter_vmstat(request, username, password, ZBX_VM_CONFIG("memorySizeMB"), result);
if (SYSINFO_RET_OK == ret && NULL != GET_UI64_RESULT(result))
result->ui64 = result->ui64 * ZBX_MEBIBYTE;
@@ -1770,7 +1895,7 @@
zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
- ret = get_vcenter_vmstat(request, username, password, ZBX_XPATH_LN2("quickStats", "balloonedMemory"), result);
+ ret = get_vcenter_vmstat(request, username, password, ZBX_VM_QUICKSTATS("balloonedMemory"), result);
if (SYSINFO_RET_OK == ret && NULL != GET_UI64_RESULT(result))
result->ui64 = result->ui64 * ZBX_MEBIBYTE;
@@ -1789,7 +1914,7 @@
zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
- ret = get_vcenter_vmstat(request, username, password, ZBX_XPATH_LN2("quickStats", "compressedMemory"), result);
+ ret = get_vcenter_vmstat(request, username, password, ZBX_VM_QUICKSTATS("compressedMemory"), result);
if (SYSINFO_RET_OK == ret && NULL != GET_UI64_RESULT(result))
result->ui64 = result->ui64 * ZBX_MEBIBYTE;
@@ -1808,7 +1933,7 @@
zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
- ret = get_vcenter_vmstat(request, username, password, ZBX_XPATH_LN2("quickStats", "swappedMemory"), result);
+ ret = get_vcenter_vmstat(request, username, password, ZBX_VM_QUICKSTATS("swappedMemory"), result);
if (SYSINFO_RET_OK == ret && NULL != GET_UI64_RESULT(result))
result->ui64 = result->ui64 * ZBX_MEBIBYTE;
@@ -1827,7 +1952,7 @@
zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
- ret = get_vcenter_vmstat(request, username, password, ZBX_XPATH_LN2("quickStats", "guestMemoryUsage"), result);
+ ret = get_vcenter_vmstat(request, username, password, ZBX_VM_QUICKSTATS("guestMemoryUsage"), result);
if (SYSINFO_RET_OK == ret && NULL != GET_UI64_RESULT(result))
result->ui64 = result->ui64 * ZBX_MEBIBYTE;
@@ -1846,7 +1971,7 @@
zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
- ret = get_vcenter_vmstat(request, username, password, ZBX_XPATH_LN2("quickStats", "hostMemoryUsage"), result);
+ ret = get_vcenter_vmstat(request, username, password, ZBX_VM_QUICKSTATS("hostMemoryUsage"), result);
if (SYSINFO_RET_OK == ret && NULL != GET_UI64_RESULT(result))
result->ui64 = result->ui64 * ZBX_MEBIBYTE;
@@ -1865,7 +1990,7 @@
zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
- ret = get_vcenter_vmstat(request, username, password, ZBX_XPATH_LN2("quickStats", "privateMemory"), result);
+ ret = get_vcenter_vmstat(request, username, password, ZBX_VM_QUICKSTATS("privateMemory"), result);
if (SYSINFO_RET_OK == ret && NULL != GET_UI64_RESULT(result))
result->ui64 = result->ui64 * ZBX_MEBIBYTE;
@@ -1884,7 +2009,7 @@
zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
- ret = get_vcenter_vmstat(request, username, password, ZBX_XPATH_LN2("quickStats", "sharedMemory"), result);
+ ret = get_vcenter_vmstat(request, username, password, ZBX_VM_QUICKSTATS("sharedMemory"), result);
if (SYSINFO_RET_OK == ret && NULL != GET_UI64_RESULT(result))
result->ui64 = result->ui64 * ZBX_MEBIBYTE;
@@ -1903,7 +2028,7 @@
zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
- ret = get_vcenter_vmstat(request, username, password, ZBX_XPATH_LN2("runtime", "powerState"), result);
+ ret = get_vcenter_vmstat(request, username, password, ZBX_VM_RUNTIME("powerState"), result);
if (SYSINFO_RET_OK == ret)
ret = vmware_set_powerstate_result(result);
@@ -1993,8 +2118,8 @@
char *url, *uuid, *instance, *mode;
zbx_vmware_service_t *service;
- zbx_uint64_t counterid;
int coeff, ret = SYSINFO_RET_FAIL;
+ const char *path;
zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
@@ -2028,12 +2153,12 @@
if (NULL == mode || '\0' == *mode || 0 == strcmp(mode, "bps"))
{
- counterid = service->counters.nic_received;
+ path = "net/received[average]";
coeff = ZBX_KIBIBYTE;
}
else if (0 == strcmp(mode, "pps"))
{
- counterid = service->counters.nic_packets_rx;
+ path = "net/packetsRx[summation]";
coeff = 1;
}
else
@@ -2042,7 +2167,7 @@
goto unlock;
}
- ret = vmware_service_get_vm_counter(service, uuid, instance, counterid, coeff, result);
+ ret = vmware_service_get_vm_counter(service, uuid, instance, path, coeff, result);
unlock:
zbx_vmware_unlock();
out:
@@ -2058,8 +2183,8 @@
char *url, *uuid, *instance, *mode;
zbx_vmware_service_t *service;
- zbx_uint64_t counterid;
int coeff, ret = SYSINFO_RET_FAIL;
+ const char *path;
zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
@@ -2093,12 +2218,12 @@
if (NULL == mode || '\0' == *mode || 0 == strcmp(mode, "bps"))
{
- counterid = service->counters.nic_transmitted;
+ path = "net/transmitted[average]";
coeff = ZBX_KIBIBYTE;
}
else if (0 == strcmp(mode, "pps"))
{
- counterid = service->counters.nic_packets_tx;
+ path = "net/packetsTx[summation]";
coeff = 1;
}
else
@@ -2107,7 +2232,7 @@
goto unlock;
}
- ret = vmware_service_get_vm_counter(service, uuid, instance, counterid, coeff, result);
+ ret = vmware_service_get_vm_counter(service, uuid, instance, path, coeff, result);
unlock:
zbx_vmware_unlock();
out:
@@ -2125,7 +2250,7 @@
zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
- ret = get_vcenter_vmstat(request, username, password, ZBX_XPATH_LN2("storage", "committed"), result);
+ ret = get_vcenter_vmstat(request, username, password, ZBX_VM_STORAGE("committed"), result);
zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, sysinfo_ret_string(ret));
@@ -2141,7 +2266,7 @@
zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
- ret = get_vcenter_vmstat(request, username, password, ZBX_XPATH_LN2("storage", "unshared"), result);
+ ret = get_vcenter_vmstat(request, username, password, ZBX_VM_STORAGE("unshared"), result);
zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, sysinfo_ret_string(ret));
@@ -2157,7 +2282,7 @@
zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
- ret = get_vcenter_vmstat(request, username, password, ZBX_XPATH_LN2("storage", "uncommitted"), result);
+ ret = get_vcenter_vmstat(request, username, password, ZBX_VM_STORAGE("uncommitted"), result);
zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, sysinfo_ret_string(ret));
@@ -2173,7 +2298,7 @@
zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
- ret = get_vcenter_vmstat(request, username, password, ZBX_XPATH_LN2("quickStats", "uptimeSeconds"), result);
+ ret = get_vcenter_vmstat(request, username, password, ZBX_VM_QUICKSTATS("uptimeSeconds"), result);
zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, sysinfo_ret_string(ret));
@@ -2259,8 +2384,8 @@
char *url, *uuid, *instance, *mode;
zbx_vmware_service_t *service;
- zbx_uint64_t counterid;
int coeff, ret = SYSINFO_RET_FAIL;
+ const char *path;
zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
@@ -2294,12 +2419,12 @@
if (NULL == mode || '\0' == *mode || 0 == strcmp(mode, "bps"))
{
- counterid = service->counters.disk_read;
+ path = "virtualDisk/read[average]";
coeff = ZBX_KIBIBYTE;
}
else if (0 == strcmp(mode, "ops"))
{
- counterid = service->counters.disk_number_read_averaged;
+ path = "virtualDisk/numberReadAveraged[average]";
coeff = 1;
}
else
@@ -2308,7 +2433,7 @@
goto unlock;
}
- ret = vmware_service_get_vm_counter(service, uuid, instance, counterid, coeff, result);
+ ret = vmware_service_get_vm_counter(service, uuid, instance, path, coeff, result);
unlock:
zbx_vmware_unlock();
out:
@@ -2324,8 +2449,8 @@
char *url, *uuid, *instance, *mode;
zbx_vmware_service_t *service;
- zbx_uint64_t counterid;
int coeff, ret = SYSINFO_RET_FAIL;
+ const char *path;
zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
@@ -2359,12 +2484,12 @@
if (NULL == mode || '\0' == *mode || 0 == strcmp(mode, "bps"))
{
- counterid = service->counters.disk_write;
+ path = "virtualDisk/write[average]";
coeff = ZBX_KIBIBYTE;
}
else if (0 == strcmp(mode, "ops"))
{
- counterid = service->counters.disk_number_write_averaged;
+ path = "virtualDisk/numberWriteAveraged[average]";
coeff = 1;
}
else
@@ -2373,7 +2498,7 @@
goto unlock;
}
- ret = vmware_service_get_vm_counter(service, uuid, instance, counterid, coeff, result);
+ ret = vmware_service_get_vm_counter(service, uuid, instance, path, coeff, result);
unlock:
zbx_vmware_unlock();
out:
@@ -2544,4 +2669,65 @@
return ret;
}
+int check_vcenter_vm_perfcounter(AGENT_REQUEST *request, const char *username, const char *password,
+ AGENT_RESULT *result)
+{
+ const char *__function_name = "check_vcenter_vm_perfcounter";
+ int ret = SYSINFO_RET_FAIL;
+ char *url, *uuid, *path, *instance;
+ zbx_vmware_service_t *service;
+ zbx_vmware_vm_t *vm;
+ zbx_uint64_t counterid;
+
+ zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
+
+ if (3 > request->nparam || request->nparam > 4)
+ {
+ SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid number of parameters."));
+ goto out;
+ }
+
+ url = get_rparam(request, 0);
+ uuid = get_rparam(request, 1);
+ path = get_rparam(request, 2);
+ instance = get_rparam(request, 3);
+
+ if (NULL == instance)
+ instance = "";
+
+ zbx_vmware_lock();
+
+ if (NULL == (service = get_vmware_service(url, username, password, result, &ret)))
+ goto unlock;
+
+ if (NULL == (vm = service_vm_get(service, uuid)))
+ {
+ SET_MSG_RESULT(result, zbx_strdup(NULL, "Unknown virtual machine uuid."));
+ goto unlock;
+ }
+
+ if (FAIL == zbx_vmware_service_get_perfcounterid(service, path, &counterid))
+ {
+ SET_MSG_RESULT(result, zbx_strdup(NULL, "Performance counter is not available."));
+ goto unlock;
+ }
+
+ if (SUCCEED == zbx_vmware_service_start_monitoring(service, "VirtualMachine", vm->id, counterid))
+ {
+ ret = SYSINFO_RET_OK;
+ goto unlock;
+ }
+
+ /* the performance counter is already being monitored, try to get the results from statistics */
+ ret = vmware_service_counter_get(service, "VirtualMachine", vm->id, path, instance, 1, result);
+
+unlock:
+ zbx_vmware_unlock();
+out:
+ zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, sysinfo_ret_string(ret));
+
+ return ret;
+}
+
+
#endif /* defined(HAVE_LIBXML2) && defined(HAVE_LIBCURL) */
diff -ur zabbix-2.4.1.orig/src/zabbix_server/poller/checks_simple_vmware.h zabbix-2.4.1/src/zabbix_server/poller/checks_simple_vmware.h
--- zabbix-2.4.1.orig/src/zabbix_server/poller/checks_simple_vmware.h 2014-10-08 15:58:58.000000000 +0900
+++ zabbix-2.4.1/src/zabbix_server/poller/checks_simple_vmware.h 2014-10-28 19:23:12.257930174 +0900
@@ -81,6 +81,8 @@
AGENT_RESULT *result);
int check_vcenter_hv_datastore_write(AGENT_REQUEST *request, const char *username, const char *password,
AGENT_RESULT *result);
+int check_vcenter_hv_perfcounter(AGENT_REQUEST *request, const char *username, const char *password,
+ AGENT_RESULT *result);
int check_vcenter_vm_cluster_name(AGENT_REQUEST *request, const char *username, const char *password,
AGENT_RESULT *result);
@@ -134,6 +136,8 @@
AGENT_RESULT *result);
int check_vcenter_vm_vfs_fs_size(AGENT_REQUEST *request, const char *username, const char *password,
AGENT_RESULT *result);
+int check_vcenter_vm_perfcounter(AGENT_REQUEST *request, const char *username, const char *password,
+ AGENT_RESULT *result);
#endif /* defined(HAVE_LIBXML2) && defined(HAVE_LIBCURL) */
#endif
diff -ur zabbix-2.4.1.orig/src/zabbix_server/server.c zabbix-2.4.1/src/zabbix_server/server.c
--- zabbix-2.4.1.orig/src/zabbix_server/server.c 2014-10-08 15:58:58.000000000 +0900
+++ zabbix-2.4.1/src/zabbix_server/server.c 2014-11-11 10:21:55.275770955 +0900
@@ -144,6 +144,7 @@
int CONFIG_VMWARE_FORKS = 0;
int CONFIG_VMWARE_FREQUENCY = 60;
+int CONFIG_VMWARE_PERF_FREQUENCY = 60;
zbx_uint64_t CONFIG_CONF_CACHE_SIZE = 8 * ZBX_MEBIBYTE;
zbx_uint64_t CONFIG_HISTORY_CACHE_SIZE = 8 * ZBX_MEBIBYTE;
@@ -547,6 +548,8 @@
PARM_OPT, 0, 250},
{"VMwareFrequency", &CONFIG_VMWARE_FREQUENCY, TYPE_INT,
PARM_OPT, 10, SEC_PER_DAY},
+ {"VMwarePerfFrequency", &CONFIG_VMWARE_PERF_FREQUENCY, TYPE_INT,
+ PARM_OPT, 10, SEC_PER_DAY},
{"VMwareCacheSize", &CONFIG_VMWARE_CACHE_SIZE, TYPE_UINT64,
PARM_OPT, 256 * ZBX_KIBIBYTE, __UINT64_C(2) * ZBX_GIBIBYTE},
{"AllowRoot", &CONFIG_ALLOW_ROOT, TYPE_INT,
diff -ur zabbix-2.4.1.orig/src/zabbix_server/vmware/vmware.c zabbix-2.4.1/src/zabbix_server/vmware/vmware.c
--- zabbix-2.4.1.orig/src/zabbix_server/vmware/vmware.c 2014-10-08 15:58:58.000000000 +0900
+++ zabbix-2.4.1/src/zabbix_server/vmware/vmware.c 2014-10-28 20:29:02.369507494 +0900
@@ -30,7 +30,7 @@
/*
* The VMware data (zbx_vmware_service_t structure) are stored in shared memory.
* This data can be accessed with zbx_vmware_get_service() function and is regularly
- * updated by VMware collector processess.
+ * updated by VMware collector processes.
*
* When a new service is requested by poller the zbx_vmware_get_service() function
* creates a new service object, marks it as new, but still returns NULL object.
@@ -40,16 +40,24 @@
* as updating.
*
* The service object is updated by creating a new data object, initializing it
- * with the latest data from VMware vCenter (or vSphere), destroying the old data
+ * with the latest data from VMware vCenter (or Hypervisor), destroying the old data
* object and replacing it with the new one.
*
* The collector must be locked only when accessing service object list and working with
* a service object. It is not locked for new data object creation during service update,
* which is the most time consuming task.
+ *
+ * As the data retrieved by VMware collector can be quite big (for example 1 Hypervisor
+ * with 500 Virtual Machines will result in approximately 20 MB of data), VMware collector
+ * updates performance data (which is only 10% of the structure data) separately
+ * with CONFIG_VMWARE_PERF_FREQUENCY period. The performance data are stored directly
+ * in VMware service object entities vector - so the structure data is not affected by
+ * performance data updates.
*/
extern char *CONFIG_FILE;
extern int CONFIG_VMWARE_FREQUENCY;
+extern int CONFIG_VMWARE_PERF_FREQUENCY;
extern zbx_uint64_t CONFIG_VMWARE_CACHE_SIZE;
extern unsigned char process_type, daemon_type;
extern int server_num, process_num;
@@ -58,6 +66,7 @@
__vm_mem_realloc_func, __vm_mem_free_func)
#define ZBX_VMWARE_CACHE_TTL CONFIG_VMWARE_FREQUENCY
+#define ZBX_VMWARE_PERF_TTL CONFIG_VMWARE_PERF_FREQUENCY
#define ZBX_VMWARE_SERVICE_TTL SEC_PER_DAY
static ZBX_MUTEX vmware_lock;
@@ -75,6 +84,8 @@
#if defined(HAVE_LIBXML2) && defined(HAVE_LIBCURL)
+#define ZBX_VMWARE_COUNTERS_INIT_SIZE 500
+
/* VMware service object name mapping for vcenter and vsphere installations */
typedef struct
{
@@ -92,13 +103,13 @@
{"PerfMgr", "SessionManager", "EventManager", "propertyCollector"}
};
-/* key - performance counter reference mapping */
+/* mapping of performance counter group/key[rollup type] to its id (net/transmitted[average] -> <id>) */
typedef struct
{
- const char *key;
- zbx_uint64_t *pcounter;
+ char *path;
+ zbx_uint64_t id;
}
-zbx_perfcounter_mapping_t;
+zbx_vmware_counter_t;
/*
* SOAP support
@@ -120,6 +131,24 @@
"</ns1:Body>" \
"</SOAP-ENV:Envelope>"
+#define ZBX_VMWARE_FAULTSTRING() "/*/*/*[local-name()='Fault']/*[local-name()='faultstring']"
+
+
+#define ZBX_PERFMGR_REFRESHRATE() "/*/*/*/*/*[local-name()='refreshRate']"
+#define ZBX_PERFMGR_COUNTERS() \
+ "/*/*/*/*/*[local-name()='propSet']/*[local-name()='val']/*[local-name()='PerfCounterInfo']"
+
+#define ZBX_DATASTORE(property) "/*/*/*/*/*/*[local-name()='propSet']/*[local-name()='val']" \
+ "/*[local-name()='" property "']"
+
+#define ZBX_HV_DATASTORES() \
+ "/*/*/*/*/*[local-name()='propSet'][*[local-name()='name'][text()='datastore']]" \
+ "/*[local-name()='val']/*[@type='Datastore']"
+
+#define ZBX_HV_VMS() \
+ "/*/*/*/*/*[local-name()='propSet'][*[local-name()='name'][text()='vm']]" \
+ "/*[local-name()='val']/*[@type='VirtualMachine']"
+
typedef struct
{
char *data;
@@ -130,7 +159,7 @@
static ZBX_HTTPPAGE page;
-static size_t WRITEFUNCTION2(void *ptr, size_t size, size_t nmemb, void *userdata)
+static size_t curl_write_cb(void *ptr, size_t size, size_t nmemb, void *userdata)
{
size_t r_size = size * nmemb;
@@ -139,13 +168,33 @@
return r_size;
}
-static size_t HEADERFUNCTION2(void *ptr, size_t size, size_t nmemb, void *userdata)
+static size_t curl_header_cb(void *ptr, size_t size, size_t nmemb, void *userdata)
{
return size * nmemb;
}
/******************************************************************************
* *
+ * performance counter hashset support functions *
+ * *
+ ******************************************************************************/
+zbx_hash_t vmware_counter_hash_func(const void *data)
+{
+ zbx_vmware_counter_t *counter = (zbx_vmware_counter_t *)data;
+
+ return ZBX_DEFAULT_STRING_HASH_ALGO(counter->path, strlen(counter->path), ZBX_DEFAULT_HASH_SEED);
+}
+
+int vmware_counter_compare_func(const void *d1, const void *d2)
+{
+ zbx_vmware_counter_t *c1 = (zbx_vmware_counter_t *)d1;
+ zbx_vmware_counter_t *c2 = (zbx_vmware_counter_t *)d2;
+
+ return strcmp(c1->path, c2->path);
+}
+
+/******************************************************************************
+ * *
* Function: vmware_shared_strdup *
* *
* Purpose: duplicates the specified string into shared memory *
@@ -175,6 +224,98 @@
/******************************************************************************
* *
+ * Function: vmware_counters_shared_copy *
+ * *
+ * Purpose: copies performance counter vector into shared memory hashset *
+ * *
+ * Parameters: dst - [IN] the destination hashset *
+ * src - [IN] the source vector *
+ * *
+ ******************************************************************************/
+static void vmware_counters_shared_copy(zbx_hashset_t *dst, const zbx_vector_ptr_t *src)
+{
+ int i;
+ zbx_vmware_counter_t *csrc, *cdst;
+
+ for (i = 0; i < src->values_num; i++)
+ {
+ csrc = src->values[i];
+
+ cdst = zbx_hashset_insert(dst, csrc, sizeof(zbx_vmware_counter_t));
+ cdst->path = vmware_shared_strdup(csrc->path);
+ }
+}
+
+/******************************************************************************
+ * *
+ * Function: vmware_vector_ptr_pair_shared_clean *
+ * *
+ * Purpose: frees shared resources allocated to store instance performance *
+ * counter values *
+ * *
+ * Parameters: instance - [IN] the performance counter instance value *
+ * *
+ ******************************************************************************/
+static void vmware_vector_ptr_pair_shared_clean(zbx_vector_ptr_pair_t *pairs)
+{
+ int i;
+
+ for (i = 0; i < pairs->values_num; i++)
+ {
+ zbx_ptr_pair_t *pair = &pairs->values[i];
+
+ if (NULL != pair->first)
+ __vm_mem_free_func(pair->first);
+
+ __vm_mem_free_func(pair->second);
+ }
+
+ pairs->values_num = 0;
+}
+
+/******************************************************************************
+ * *
+ * Function: vmware_perf_counter_shared_free *
+ * *
+ * Purpose: frees shared resources allocated to store performance counter *
+ * data *
+ * *
+ * Parameters: counter - [IN] the performance counter data *
+ * *
+ ******************************************************************************/
+static void vmware_perf_counter_shared_free(zbx_vmware_perf_counter_t *counter)
+{
+ vmware_vector_ptr_pair_shared_clean(&counter->values);
+ __vm_mem_free_func(counter);
+}
+
+/******************************************************************************
+ * *
+ * Function: vmware_entities_shared_clean_stats *
+ * *
+ * Purpose: removes statistics data from vmware entities *
+ * *
+ ******************************************************************************/
+static void vmware_entities_shared_clean_stats(zbx_vector_ptr_t *entities)
+{
+ int i, j;
+ zbx_vmware_perf_entity_t *entity;
+ zbx_vmware_perf_counter_t *counter;
+
+ for (i = 0; i < entities->values_num; i++)
+ {
+ entity = (zbx_vmware_perf_entity_t *)entities->values[i];
+
+ for (j = 0; j < entity->counters.values_num; j++)
+ {
+ counter = (zbx_vmware_perf_counter_t *)entity->counters.values[j];
+ vmware_vector_ptr_pair_shared_clean(&counter->values);
+ }
+ }
+}
+
+/******************************************************************************
+ * *
* Function: vmware_datastore_shared_free *
* *
* Purpose: frees shared resources allocated to store datastore data *
@@ -232,9 +373,6 @@
if (NULL != vm->uuid)
__vm_mem_free_func(vm->uuid);
- if (NULL != vm->stats)
- __vm_mem_free_func(vm->stats);
-
if (NULL != vm->details)
__vm_mem_free_func(vm->details);
@@ -270,9 +408,6 @@
if (NULL != hv->clusterid)
__vm_mem_free_func(hv->clusterid);
- if (NULL != hv->stats)
- __vm_mem_free_func(hv->stats);
-
__vm_mem_free_func(hv);
}
@@ -330,7 +465,41 @@
/******************************************************************************
* *
- * Function: vmware_service_free *
+ * Function: vmware_shared_perf_entity_free *
+ * *
+ * Purpose: frees shared memory vmware peformance entity and the resources *
+ * allocated by it *
+ * *
+ * Parameters: entity - [IN] the entity to free *
+ * *
+ ******************************************************************************/
+static void vmware_shared_perf_entity_free(zbx_vmware_perf_entity_t *entity)
+{
+ zbx_vector_ptr_clean(&entity->counters, (zbx_mem_free_func_t)vmware_perf_counter_shared_free);
+ zbx_vector_ptr_destroy(&entity->counters);
+
+ __vm_mem_free_func(entity->type);
+ __vm_mem_free_func(entity->id);
+ __vm_mem_free_func(entity);
+}
+
+/******************************************************************************
+ * *
+ * Function: vmware_counter_shared_clean *
+ * *
+ * Purpose: frees resources allocated by vmware performance counter *
+ * *
+ * Parameters: counter - [IN] the performance counter to free *
+ * *
+ ******************************************************************************/
+static void vmware_counter_shared_clean(zbx_vmware_counter_t *counter)
+{
+ __vm_mem_free_func(counter->path);
+}
+
+/******************************************************************************
+ * *
+ * Function: vmware_service_shared_free *
* *
* Purpose: frees shared resources allocated to store vmware service *
* *
@@ -339,6 +508,9 @@
******************************************************************************/
static void vmware_service_shared_free(zbx_vmware_service_t *service)
{
+ zbx_hashset_iter_t iter;
+ zbx_vmware_counter_t *counter;
+
__vm_mem_free_func(service->url);
__vm_mem_free_func(service->username);
__vm_mem_free_func(service->password);
@@ -348,6 +520,16 @@
vmware_data_shared_free(service->data);
+ zbx_vector_ptr_clean(&service->entities, (zbx_mem_free_func_t)vmware_shared_perf_entity_free);
+ zbx_vector_ptr_destroy(&service->entities);
+
+ zbx_hashset_iter_reset(&service->counters, &iter);
+
+ while (NULL != (counter = zbx_hashset_iter_next(&iter)))
+ vmware_counter_shared_clean(counter);
+
+ zbx_hashset_destroy(&service->counters);
+
__vm_mem_free_func(service);
}
@@ -442,7 +624,6 @@
vm->id = vmware_shared_strdup(src->id);
vm->uuid = vmware_shared_strdup(src->uuid);
vm->details = vmware_shared_strdup(src->details);
- vm->stats = vmware_shared_strdup(src->stats);
for (i = 0; i < src->devs.values_num; i++)
zbx_vector_ptr_append(&vm->devs, vmware_dev_shared_dup(src->devs.values[i]));
@@ -474,7 +655,6 @@
hv->uuid = vmware_shared_strdup(src->uuid);
hv->id = vmware_shared_strdup(src->id);
hv->details = vmware_shared_strdup(src->details);
- hv->stats = vmware_shared_strdup(src->stats);
hv->clusterid = vmware_shared_strdup(src->clusterid);
for (i = 0; i < src->datastores.values_num; i++)
@@ -567,7 +747,6 @@
zbx_free(vm->id);
zbx_free(vm->uuid);
- zbx_free(vm->stats);
zbx_free(vm->details);
zbx_free(vm);
}
@@ -593,7 +772,6 @@
zbx_free(hv->id);
zbx_free(hv->details);
zbx_free(hv->clusterid);
- zbx_free(hv->stats);
zbx_free(hv);
}
@@ -638,6 +816,39 @@
/******************************************************************************
* *
+ * Function: vmware_perf_entity_free *
+ * *
+ * Purpose: frees vmware peformance entity and the resources allocated by it *
+ * *
+ * Parameters: entity - [IN] the entity to free *
+ * *
+ ******************************************************************************/
+static void vmware_perf_entity_free(zbx_vmware_perf_entity_t *entity)
+{
+ /* entities allocated on heap do not use counters vector */
+ zbx_free(entity->type);
+ zbx_free(entity->id);
+ zbx_free(entity);
+}
+
+/******************************************************************************
+ * *
+ * Function: vmware_counter_free *
+ * *
+ * Purpose: frees vmware performance counter and the resources allocated by *
+ * it *
+ * *
+ * Parameters: counter - [IN] the performance counter to free *
+ * *
+ ******************************************************************************/
+static void vmware_counter_free(zbx_vmware_counter_t *counter)
+{
+ zbx_free(counter->path);
+ zbx_free(counter);
+}
+
+/******************************************************************************
+ * *
* Function: vmware_service_authenticate *
* *
* Purpose: authenticates vmware service *
@@ -674,15 +885,16 @@
if (CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_COOKIEFILE, "")) ||
CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_FOLLOWLOCATION, 1L)) ||
- CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_WRITEFUNCTION, WRITEFUNCTION2)) ||
- CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_HEADERFUNCTION, HEADERFUNCTION2)) ||
+ CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_WRITEFUNCTION, curl_write_cb)) ||
+ CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_HEADERFUNCTION,
+ curl_header_cb)) ||
CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_SSL_VERIFYPEER, 0L)) ||
CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_POST, 1L)) ||
CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_URL, service->url)) ||
CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_TIMEOUT, (long)timeout)) ||
CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_SSL_VERIFYHOST, 0L)))
{
- *error = zbx_dsprintf(*error, "Cannot set cURL option [%d]: %s", opt, curl_easy_strerror(err));
+ *error = zbx_dsprintf(*error, "Cannot set cURL option %d: %s.", opt, curl_easy_strerror(err));
goto out;
}
@@ -695,7 +907,7 @@
if (CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_POSTFIELDS, xml)))
{
- *error = zbx_dsprintf(*error, "Cannot set cURL option [%d]: %s", opt, curl_easy_strerror(err));
+ *error = zbx_dsprintf(*error, "Cannot set cURL option %d: %s.", opt, curl_easy_strerror(err));
goto out;
}
@@ -709,7 +921,7 @@
zabbix_log(LOG_LEVEL_TRACE, "%s() SOAP response: %s", __function_name, page.data);
- if (NULL == (*error = zbx_xml_read_value(page.data, ZBX_XPATH_LN1("faultstring"))))
+ if (NULL == (*error = zbx_xml_read_value(page.data, ZBX_VMWARE_FAULTSTRING())))
{
/* Successfully authenticated with vcenter service manager. */
/* Set the service type and return with success. */
@@ -737,7 +949,7 @@
if (CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_POSTFIELDS, xml)))
{
- *error = zbx_dsprintf(*error, "Cannot set cURL option [%d]: %s", opt, curl_easy_strerror(err));
+ *error = zbx_dsprintf(*error, "Cannot set cURL option %d: %s.", opt, curl_easy_strerror(err));
goto out;
}
@@ -745,13 +957,13 @@
if (CURLE_OK != (err = curl_easy_perform(easyhandle)))
{
- *error = zbx_dsprintf(*error, "Cannot set cURL option [%d]: %s", opt, curl_easy_strerror(err));
+ *error = zbx_dsprintf(*error, "Cannot set cURL option %d: %s.", opt, curl_easy_strerror(err));
goto out;
}
zabbix_log(LOG_LEVEL_TRACE, "%s() SOAP response: %s", __function_name, page.data);
- if (NULL != (*error = zbx_xml_read_value(page.data, ZBX_XPATH_LN1("faultstring"))))
+ if (NULL != (*error = zbx_xml_read_value(page.data, ZBX_VMWARE_FAULTSTRING())))
goto out;
ret = SUCCEED;
@@ -793,7 +1005,7 @@
if (CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_POSTFIELDS, ZBX_POST_VMWARE_CONTENTS)))
{
- *error = zbx_dsprintf(*error, "Cannot set cURL option [%d]: %s", opt, curl_easy_strerror(err));
+ *error = zbx_dsprintf(*error, "Cannot set cURL option %d: %s.", opt, curl_easy_strerror(err));
goto out;
}
@@ -807,7 +1019,7 @@
zabbix_log(LOG_LEVEL_TRACE, "%s() SOAP response: %s", __function_name, page.data);
- if (NULL != (*error = zbx_xml_read_value(page.data, ZBX_XPATH_LN1("faultstring"))))
+ if (NULL != (*error = zbx_xml_read_value(page.data, ZBX_VMWARE_FAULTSTRING())))
goto out;
*contents = zbx_strdup(*contents, page.data);
@@ -819,31 +1031,6 @@
/******************************************************************************
* *
- * Function: vmware_add_perfcounter_metric *
- * *
- * Purpose: adds performance counter metric to the soap request *
- * *
- * Parameters: tmp - [IN/OUT] the request body *
- * tmp_alloc - [IN/OUT] the size of allocated memory for request *
- * tmp_offset - [IN/OUT] the size of used memory in request *
- * instance - [IN] the device instance id *
- * counterid - [IN] the performance counter id *
- * *
- ******************************************************************************/
-static void vmware_add_perfcounter_metric(char **tmp, size_t *tmp_alloc, size_t *tmp_offset, const char *instance,
- zbx_uint64_t counterid)
-{
- if (0 == counterid)
- return;
-
- zbx_strcpy_alloc(tmp, tmp_alloc, tmp_offset, "<ns0:metricId>");
- zbx_snprintf_alloc(tmp, tmp_alloc, tmp_offset, "<ns0:counterId>" ZBX_FS_UI64 "</ns0:counterId>", counterid);
- zbx_snprintf_alloc(tmp, tmp_alloc, tmp_offset, "<ns0:instance>%s</ns0:instance>", instance);
- zbx_strcpy_alloc(tmp, tmp_alloc, tmp_offset, "</ns0:metricId>");
-}
-
-/******************************************************************************
- * *
* Function: vmware_service_get_perfcounter_refreshrate *
* *
* Purpose: get the performance counter refreshrate for the specified entity *
@@ -884,7 +1071,7 @@
if (CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_POSTFIELDS, tmp)))
{
- *error = zbx_dsprintf(*error, "Cannot set cURL option [%d]: %s", opt, curl_easy_strerror(err));
+ *error = zbx_dsprintf(*error, "Cannot set cURL option %d: %s.", opt, curl_easy_strerror(err));
goto out;
}
@@ -898,19 +1085,19 @@
zabbix_log(LOG_LEVEL_TRACE, "%s() SOAP response: %s", __function_name, page.data);
- if (NULL != (*error = zbx_xml_read_value(page.data, ZBX_XPATH_LN1("faultstring"))))
+ if (NULL != (*error = zbx_xml_read_value(page.data, ZBX_VMWARE_FAULTSTRING())))
goto out;
- if (NULL == (value = zbx_xml_read_value(page.data, ZBX_XPATH_LN2("returnval", "refreshRate"))))
+ if (NULL == (value = zbx_xml_read_value(page.data, ZBX_PERFMGR_REFRESHRATE())))
{
- *error = zbx_strdup(*error, "Cannot get refreshRate");
+ *error = zbx_strdup(*error, "Cannot find refreshRate.");
goto out;
}
zabbix_log(LOG_LEVEL_DEBUG, "%s() refresh_rate:%s", __function_name, value);
if (SUCCEED != (ret = is_uint31(value, refresh_rate)))
- *error = zbx_strdup(*error, "Cannot get refreshRate");
+ *error = zbx_dsprintf(*error, "Cannot convert refreshRate from %s.", value);
zbx_free(value);
out:
@@ -921,102 +1108,6 @@
/******************************************************************************
* *
- * Function: vmware_get_group_perfcounters *
- * *
- * Purpose: read the specified performance counter ids filtered by a group *
- * *
- * Parameters: data - [IN] XML data *
- * size - [IN] the size of XML data *
- * group - [IN] the group name *
- * counters - [IN/OUT] mapping of counter keys to output values *
- * *
- * Return: Upon successful completion the function return SUCCEED. *
- * Otherwise, FAIL is returned. *
- * *
- ******************************************************************************/
-static int vmware_get_group_perfcounters(const char *data, int size, const char *group,
- zbx_perfcounter_mapping_t *counters)
-{
- xmlDoc *doc;
- xmlXPathContext *xpathCtx;
- xmlXPathObject *xpathObj;
- xmlNodeSetPtr nodeset;
- char *xpath = NULL, *key, *counterId;
- int i, ret = FAIL;
- zbx_perfcounter_mapping_t *counter;
-
- if (NULL == (doc = xmlReadMemory(data, size, "noname.xml", NULL, 0)))
- goto out;
-
- xpathCtx = xmlXPathNewContext(doc);
-
- xpath = zbx_dsprintf(xpath, "//*[local-name()='PerfCounterInfo'][*[local-name()='groupInfo']"
- "/*[local-name()='key']/text()='%s']", group);
-
- if (NULL == (xpathObj = xmlXPathEvalExpression((xmlChar *)xpath, xpathCtx)))
- goto clean;
-
- if (xmlXPathNodeSetIsEmpty(xpathObj->nodesetval))
- goto clean;
-
- nodeset = xpathObj->nodesetval;
-
- for (i = 0; i < nodeset->nodeNr; i++)
- {
- if (NULL == (key = zbx_xml_read_node_value(doc, nodeset->nodeTab[i],
- "*[local-name()='nameInfo']/*[local-name()='key']")))
- {
- continue;
- }
-
- for (counter = counters; NULL != counter->key; counter++)
- {
- if (0 != strcmp(counter->key, key))
- continue;
-
- if (NULL == (counterId = zbx_xml_read_node_value(doc, nodeset->nodeTab[i],
- "*[local-name()='key']")))
- {
- continue;
- }
-
- is_uint64(counterId, counter->pcounter);
- zbx_free(counterId);
- }
-
- zbx_free(key);
- }
-
- for (counter = counters; NULL != counter->key; counter++)
- {
- if (0 == *counter->pcounter)
- {
- zabbix_log(LOG_LEVEL_WARNING, "failed to retrieve VMware performance counter: %s/%s",
- group, counter->key);
- }
- else
- {
- zabbix_log(LOG_LEVEL_DEBUG, "found VMware performance counter %s/%s: " ZBX_FS_UI64,
- group, counter->key, *counter->pcounter);
- }
- }
-
- ret = SUCCEED;
-clean:
- if (NULL != xpathObj)
- xmlXPathFreeObject(xpathObj);
-
- zbx_free(xpath);
-
- xmlXPathFreeContext(xpathCtx);
- xmlFreeDoc(doc);
- xmlCleanupParser();
-out:
- return ret;
-}
-
-/******************************************************************************
- * *
* Function: vmware_service_get_perfcounters *
* *
* Purpose: get the performance counter ids *
@@ -1029,7 +1120,8 @@
* FAIL - the operation has failed *
* *
******************************************************************************/
-static int vmware_service_get_perfcounters(zbx_vmware_service_t *service, CURL *easyhandle, char **error)
+static int vmware_service_get_perfcounters(zbx_vmware_service_t *service, CURL *easyhandle,
+ zbx_vector_ptr_t *counters, char **error)
{
# define ZBX_POST_VMWARE_GET_PERFCOUTNER \
ZBX_POST_VSPHERE_HEADER \
@@ -1049,27 +1141,13 @@
const char *__function_name = "vmware_service_get_perf_counters";
- char tmp[MAX_STRING_LEN];
- int opts, err, ret = SUCCEED;
-
- zbx_perfcounter_mapping_t disk_counters[] = {
- {"read", &service->counters.disk_read},
- {"write", &service->counters.disk_write},
- {"numberReadAveraged", &service->counters.disk_number_read_averaged},
- {"numberWriteAveraged", &service->counters.disk_number_write_averaged},
- {NULL, NULL}};
-
- zbx_perfcounter_mapping_t nic_counters[] = {
- {"packetsRx", &service->counters.nic_packets_rx},
- {"packetsTx", &service->counters.nic_packets_tx},
- {"received", &service->counters.nic_received},
- {"transmitted", &service->counters.nic_transmitted},
- {NULL, NULL}};
-
- zbx_perfcounter_mapping_t datastore_counters[] = {
- {"totalReadLatency", &service->counters.datastore_read_latency},
- {"totalWriteLatency", &service->counters.datastore_write_latency},
- {NULL, NULL}};
+ char tmp[MAX_STRING_LEN], *group = NULL, *key = NULL, *rollup = NULL,
+ *counterid = NULL;
+ int opts, err, ret = SUCCEED, i;
+ xmlDoc *doc;
+ xmlXPathContext *xpathCtx;
+ xmlXPathObject *xpathObj;
+ xmlNodeSetPtr nodeset;
zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
@@ -1081,7 +1159,7 @@
if (CURLE_OK != (err = curl_easy_setopt(easyhandle, opts = CURLOPT_POSTFIELDS, tmp)))
{
- *error = zbx_dsprintf(*error, "Cannot set cURL option [%d]: %s", opts, curl_easy_strerror(err));
+ *error = zbx_dsprintf(*error, "Cannot set cURL option %d: %s.", opts, curl_easy_strerror(err));
goto out;
}
@@ -1095,25 +1173,60 @@
zabbix_log(LOG_LEVEL_TRACE, "%s() SOAP response: %s", __function_name, page.data);
- if (NULL != (*error = zbx_xml_read_value(page.data, ZBX_XPATH_LN1("faultstring"))))
+ if (NULL != (*error = zbx_xml_read_value(page.data, ZBX_VMWARE_FAULTSTRING())))
goto out;
- if (SUCCEED != vmware_get_group_perfcounters(page.data, page.offset, "virtualDisk", disk_counters))
+ if (NULL == (doc = xmlReadMemory(page.data, page.offset, "noname.xml", NULL, 0)))
{
- *error = zbx_strdup(*error, "Cannot find performance counters for virtualDisk group");
+ *error = zbx_strdup(*error, "Cannot parse performance counter list.");
goto out;
}
- if (SUCCEED != vmware_get_group_perfcounters(page.data, page.offset, "net", nic_counters))
+ xpathCtx = xmlXPathNewContext(doc);
+
+ if (NULL == (xpathObj = xmlXPathEvalExpression((xmlChar *)ZBX_PERFMGR_COUNTERS(), xpathCtx)))
{
- *error = zbx_strdup(*error, "Cannot find performance counters for net group");
- goto out;
+ *error = zbx_strdup(*error, "Cannot make performance counter list parsing query.");
+ goto clean;
+ }
+
+ if (xmlXPathNodeSetIsEmpty(xpathObj->nodesetval))
+ {
+ *error = zbx_strdup(*error, "Cannot find items in performance counter list.");
+ goto clean;
}
- if (SUCCEED != vmware_get_group_perfcounters(page.data, page.offset, "datastore", datastore_counters))
+ nodeset = xpathObj->nodesetval;
+
+ for (i = 0; i < nodeset->nodeNr; i++)
{
- *error = zbx_strdup(*error, "Cannot find performance counters for datastore group");
- goto out;
+ zbx_vmware_counter_t *counter;
+
+ group = zbx_xml_read_node_value(doc, nodeset->nodeTab[i],
+ "*[local-name()='groupInfo']/*[local-name()='key']");
+
+ key = zbx_xml_read_node_value(doc, nodeset->nodeTab[i],
+ "*[local-name()='nameInfo']/*[local-name()='key']");
+
+ rollup = zbx_xml_read_node_value(doc, nodeset->nodeTab[i], "*[local-name()='rollupType']");
+ counterid = zbx_xml_read_node_value(doc, nodeset->nodeTab[i], "*[local-name()='key']");
+
+ if (NULL != group && NULL != key && NULL != rollup && NULL != counterid)
+ {
+ counter = zbx_malloc(NULL, sizeof(zbx_vmware_counter_t));
+ counter->path = zbx_dsprintf(NULL, "%s/%s[%s]", group, key, rollup);
+ ZBX_STR2UINT64(counter->id, counterid);
+
+ zbx_vector_ptr_append(counters, counter);
+
+ zabbix_log(LOG_LEVEL_DEBUG, "adding performance counter %s:" ZBX_FS_UI64, counter->path,
+ counter->id);
+ }
+
+ zbx_free(counterid);
+ zbx_free(rollup);
+ zbx_free(key);
+ zbx_free(group);
}
/* The counter data uses a lot of memory which is needed only once during initialization. */
@@ -1123,6 +1236,13 @@
page.offset = 0;
ret = SUCCEED;
+clean:
+ if (NULL != xpathObj)
+ xmlXPathFreeObject(xpathObj);
+
+ xmlXPathFreeContext(xpathCtx);
+ xmlFreeDoc(doc);
+ xmlCleanupParser();
out:
zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret));
@@ -1131,207 +1251,34 @@
/******************************************************************************
* *
- * Function: vmware_service_hv_get_stats *
+ * Function: wmware_vm_get_nic_devices *
* *
- * Purpose: retrieves hypervisor performance statistics *
+ * Purpose: gets virtual machine network interface devices *
* *
- * Parameters: service - [IN] the vmware service *
- * easyhandle - [IN] the CURL handle *
- * hv - [IN] the vmware hypervisor *
- * error - [OUT] the error message in the case of failure *
+ * Parameters: vm - [IN] the virtual machine *
* *
- * Return value: SUCCEED - the operation has completed successfully *
- * FAIL - the operation has failed *
+ * Comments: The network interface devices are taken from vm device list *
+ * filtered by macAddress key. *
* *
******************************************************************************/
-static int vmware_service_hv_get_stats(const zbx_vmware_service_t *service, CURL *easyhandle,
- zbx_vmware_hv_t *hv, char **error)
+static void wmware_vm_get_nic_devices(zbx_vmware_vm_t *vm)
{
- const char *__function_name = "vmware_service_hv_get_stats";
-
- int err, opt, ret = FAIL, refresh_rate;
- char *tmp = NULL;
- size_t tmp_alloc = 0, tmp_offset = 0;
+ const char *__function_name = "wmware_vm_get_nic_devices";
+ xmlDoc *doc;
+ xmlXPathContext *xpathCtx;
+ xmlXPathObject *xpathObj;
+ xmlNodeSetPtr nodeset;
+ int i, nics = 0;
zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
- if (SUCCEED != vmware_service_get_perfcounter_refreshrate(service, easyhandle, "HostSystem", hv->id,
- &refresh_rate, error))
- {
+ if (NULL == (doc = xmlReadMemory(vm->details, strlen(vm->details), "noname.xml", NULL, 0)))
goto out;
- }
-
- zbx_strcpy_alloc(&tmp, &tmp_alloc, &tmp_offset, ZBX_POST_VSPHERE_HEADER);
- zbx_strcpy_alloc(&tmp, &tmp_alloc, &tmp_offset, "<ns0:QueryPerf>");
- zbx_snprintf_alloc(&tmp, &tmp_alloc, &tmp_offset, "<ns0:_this type=\"PerformanceManager\">%s</ns0:_this>",
- vmware_service_objects[service->type].performance_manager);
- zbx_strcpy_alloc(&tmp, &tmp_alloc, &tmp_offset, "<ns0:querySpec>");
- zbx_snprintf_alloc(&tmp, &tmp_alloc, &tmp_offset, "<ns0:entity type=\"HostSystem\">%s</ns0:entity>",
- hv->id);
- zbx_strcpy_alloc(&tmp, &tmp_alloc, &tmp_offset, "<ns0:maxSample>1</ns0:maxSample>");
-
- /* add total host networking stats */
- vmware_add_perfcounter_metric(&tmp, &tmp_alloc, &tmp_offset, "", service->counters.nic_received);
- vmware_add_perfcounter_metric(&tmp, &tmp_alloc, &tmp_offset, "", service->counters.nic_transmitted);
-
- /* add datastore stats */
- vmware_add_perfcounter_metric(&tmp, &tmp_alloc, &tmp_offset, "*", service->counters.datastore_read_latency);
- vmware_add_perfcounter_metric(&tmp, &tmp_alloc, &tmp_offset, "*", service->counters.datastore_write_latency);
- zbx_snprintf_alloc(&tmp, &tmp_alloc, &tmp_offset, "<ns0:intervalId>%d</ns0:intervalId>", refresh_rate);
- zbx_strcpy_alloc(&tmp, &tmp_alloc, &tmp_offset, "</ns0:querySpec>");
- zbx_strcpy_alloc(&tmp, &tmp_alloc, &tmp_offset, "</ns0:QueryPerf>");
- zbx_strcpy_alloc(&tmp, &tmp_alloc, &tmp_offset, ZBX_POST_VSPHERE_FOOTER);
+ xpathCtx = xmlXPathNewContext(doc);
- if (CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_POSTFIELDS, tmp)))
- {
- *error = zbx_dsprintf(*error, "Cannot set cURL option [%d]: %s", opt, curl_easy_strerror(err));
- goto out;
- }
-
- page.offset = 0;
-
- if (CURLE_OK != (err = curl_easy_perform(easyhandle)))
- {
- *error = zbx_strdup(*error, curl_easy_strerror(err));
- goto out;
- }
-
- zabbix_log(LOG_LEVEL_TRACE, "%s() SOAP response: %s", __function_name, page.data);
-
- if (NULL != (*error = zbx_xml_read_value(page.data, ZBX_XPATH_LN1("faultstring"))))
- goto out;
-
- hv->stats = zbx_strdup(NULL, page.data);
-
- ret = SUCCEED;
-out:
- zbx_free(tmp);
-
- zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret));
-
- return ret;
-}
-
-/******************************************************************************
- * *
- * Function: vmware_service_vm_get_stats *
- * *
- * Purpose: retrieves virtual machine statistics *
- * *
- * Parameters: service - [IN] the vmware service *
- * easyhandle - [IN] the CURL handle *
- * vm - [IN] the virtual machine *
- * error - [OUT] the error message in the case of failure *
- * *
- * Return value: SUCCEED - the operation has completed successfully *
- * FAIL - the operation has failed *
- * *
- ******************************************************************************/
-static int vmware_service_vm_get_stats(const zbx_vmware_service_t *service, CURL *easyhandle, zbx_vmware_vm_t *vm,
- char **error)
-{
- const char *__function_name = "vmware_service_get_vm_stats";
-
- int err, o, ret = FAIL, refresh_rate;
- char *tmp = NULL;
- size_t tmp_alloc = 0, tmp_offset = 0;
-
- zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
-
- if (SUCCEED != vmware_service_get_perfcounter_refreshrate(service, easyhandle, "VirtualMachine", vm->id,
- &refresh_rate, error))
- {
- goto out;
- }
-
- zbx_strcpy_alloc(&tmp, &tmp_alloc, &tmp_offset, ZBX_POST_VSPHERE_HEADER);
- zbx_strcpy_alloc(&tmp, &tmp_alloc, &tmp_offset, "<ns0:QueryPerf>");
- zbx_snprintf_alloc(&tmp, &tmp_alloc, &tmp_offset, "<ns0:_this type=\"PerformanceManager\">%s</ns0:_this>",
- vmware_service_objects[service->type].performance_manager);
- zbx_strcpy_alloc(&tmp, &tmp_alloc, &tmp_offset, "<ns0:querySpec>");
- zbx_snprintf_alloc(&tmp, &tmp_alloc, &tmp_offset, "<ns0:entity type=\"VirtualMachine\">%s</ns0:entity>",
- vm->id);
- zbx_strcpy_alloc(&tmp, &tmp_alloc, &tmp_offset, "<ns0:maxSample>1</ns0:maxSample>");
-
- /* add network interface performance counters */
- vmware_add_perfcounter_metric(&tmp, &tmp_alloc, &tmp_offset, "*", service->counters.nic_packets_rx);
- vmware_add_perfcounter_metric(&tmp, &tmp_alloc, &tmp_offset, "*", service->counters.nic_packets_tx);
- vmware_add_perfcounter_metric(&tmp, &tmp_alloc, &tmp_offset, "*", service->counters.nic_received);
- vmware_add_perfcounter_metric(&tmp, &tmp_alloc, &tmp_offset, "*", service->counters.nic_transmitted);
-
- /* then add all virtual disk devices */
- vmware_add_perfcounter_metric(&tmp, &tmp_alloc, &tmp_offset, "*", service->counters.disk_read);
- vmware_add_perfcounter_metric(&tmp, &tmp_alloc, &tmp_offset, "*", service->counters.disk_write);
- vmware_add_perfcounter_metric(&tmp, &tmp_alloc, &tmp_offset, "*", service->counters.disk_number_read_averaged);
- vmware_add_perfcounter_metric(&tmp, &tmp_alloc, &tmp_offset, "*", service->counters.disk_number_write_averaged);
-
- zbx_snprintf_alloc(&tmp, &tmp_alloc, &tmp_offset, "<ns0:intervalId>%d</ns0:intervalId>", refresh_rate);
- zbx_strcpy_alloc(&tmp, &tmp_alloc, &tmp_offset, "</ns0:querySpec>");
- zbx_strcpy_alloc(&tmp, &tmp_alloc, &tmp_offset, "</ns0:QueryPerf>");
- zbx_strcpy_alloc(&tmp, &tmp_alloc, &tmp_offset, ZBX_POST_VSPHERE_FOOTER);
-
- if (CURLE_OK != (err = curl_easy_setopt(easyhandle, o = CURLOPT_POSTFIELDS, tmp)))
- {
- *error = zbx_dsprintf(*error, "Cannot set cURL option [%d]: %s", o, curl_easy_strerror(err));
- goto out;
- }
-
- page.offset = 0;
-
- if (CURLE_OK != (err = curl_easy_perform(easyhandle)))
- {
- *error = zbx_strdup(*error, curl_easy_strerror(err));
- goto out;
- }
-
- zabbix_log(LOG_LEVEL_TRACE, "%s() SOAP response: %s", __function_name, page.data);
-
- if (NULL != (*error = zbx_xml_read_value(page.data, ZBX_XPATH_LN1("faultstring"))))
- goto out;
-
- vm->stats = zbx_strdup(NULL, page.data);
-
- ret = SUCCEED;
-out:
- zbx_free(tmp);
-
- zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret));
-
- return ret;
-}
-
-/******************************************************************************
- * *
- * Function: wmware_vm_get_nic_devices *
- * *
- * Purpose: gets virtual machine network interface devices *
- * *
- * Parameters: vm - [IN] the virtual machine *
- * *
- * Comments: The network interface devices are taken from vm device list *
- * filtered by macAddress key. *
- * *
- ******************************************************************************/
-static void wmware_vm_get_nic_devices(zbx_vmware_vm_t *vm)
-{
- const char *__function_name = "wmware_vm_get_nic_devices";
-
- xmlDoc *doc;
- xmlXPathContext *xpathCtx;
- xmlXPathObject *xpathObj;
- xmlNodeSetPtr nodeset;
- int i, nics = 0;
-
- zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
-
- if (NULL == (doc = xmlReadMemory(vm->details, strlen(vm->details), "noname.xml", NULL, 0)))
- goto out;
-
- xpathCtx = xmlXPathNewContext(doc);
-
- if (NULL == (xpathObj = xmlXPathEvalExpression((xmlChar *)"//*[local-name()='hardware']/"
- "*[local-name()='device'][*[local-name()='macAddress']]", xpathCtx)))
+ if (NULL == (xpathObj = xmlXPathEvalExpression((xmlChar *)ZBX_VM_HARDWARE("device")
+ "[*[local-name()='macAddress']]", xpathCtx)))
{
goto clean;
}
@@ -1399,8 +1346,8 @@
xpathCtx = xmlXPathNewContext(doc);
/* select all hardware devices of VirtualDisk type */
- if (NULL == (xpathObj = xmlXPathEvalExpression((xmlChar *)"//*[local-name()='hardware']/"
- "*[local-name()='device'][string(@*[local-name()='type'])='VirtualDisk']", xpathCtx)))
+ if (NULL == (xpathObj = xmlXPathEvalExpression((xmlChar *)ZBX_VM_HARDWARE("device")
+ "[string(@*[local-name()='type'])='VirtualDisk']", xpathCtx)))
{
goto clean;
}
@@ -1432,7 +1379,7 @@
}
/* find the controller (parent) device */
- xpath = zbx_dsprintf(xpath, "//*[local-name()='hardware']/*[local-name()='device']"
+ xpath = zbx_dsprintf(xpath, ZBX_VM_HARDWARE("device")
"[*[local-name()='key']/text()='%s']", controllerKey);
if (NULL == (xpathObjController = xmlXPathEvalExpression((xmlChar *)xpath, xpathCtx)))
@@ -1510,7 +1457,7 @@
* FAIL - the operation has failed *
* *
******************************************************************************/
-static int vmware_service_get_vm_data(const zbx_vmware_service_t *service, CURL *easyhandle, const char *vmid,
+static int vmware_service_get_vm_data(zbx_vmware_service_t *service, CURL *easyhandle, const char *vmid,
char **data, char **error)
{
# define ZBX_POST_VMWARE_VM_STATUS_EX \
@@ -1544,7 +1491,7 @@
if (CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_POSTFIELDS, tmp)))
{
- *error = zbx_dsprintf(*error, "Cannot set cURL option [%d]: %s", opt, curl_easy_strerror(err));
+ *error = zbx_dsprintf(*error, "Cannot set cURL option %d: %s.", opt, curl_easy_strerror(err));
goto out;
}
@@ -1558,7 +1505,7 @@
zabbix_log(LOG_LEVEL_TRACE, "%s() SOAP response: %s", __function_name, page.data);
- if (NULL != (*error = zbx_xml_read_value(page.data, ZBX_XPATH_LN1("faultstring"))))
+ if (NULL != (*error = zbx_xml_read_value(page.data, ZBX_VMWARE_FAULTSTRING())))
goto out;
*data = zbx_strdup(NULL, page.data);
@@ -1585,7 +1532,7 @@
* detected. *
* *
******************************************************************************/
-static zbx_vmware_vm_t *vmware_service_create_vm(const zbx_vmware_service_t *service, CURL *easyhandle,
+static zbx_vmware_vm_t *vmware_service_create_vm(zbx_vmware_service_t *service, CURL *easyhandle,
const char *id, char **error)
{
const char *__function_name = "vmware_service_create_vm";
@@ -1615,9 +1562,6 @@
wmware_vm_get_nic_devices(vm);
wmware_vm_get_disk_devices(vm);
- if (SUCCEED != vmware_service_vm_get_stats(service, easyhandle, vm, error))
- goto out;
-
ret = SUCCEED;
out:
if (SUCCEED != ret)
@@ -1685,9 +1629,9 @@
zabbix_log(LOG_LEVEL_TRACE, "%s() SOAP response: %s", __function_name, page.data);
- name = zbx_xml_read_value(page.data, ZBX_XPATH_LN2("val", "name"));
+ name = zbx_xml_read_value(page.data, ZBX_DATASTORE("name"));
- if (NULL != (url = zbx_xml_read_value(page.data, ZBX_XPATH_LN2("val", "url"))))
+ if (NULL != (url = zbx_xml_read_value(page.data, ZBX_DATASTORE("url"))))
{
if ('\0' != *url)
{
@@ -1767,7 +1711,7 @@
if (CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_POSTFIELDS, tmp)))
{
- *error = zbx_dsprintf(*error, "Cannot set cURL option [%d]: %s", opt, curl_easy_strerror(err));
+ *error = zbx_dsprintf(*error, "Cannot set cURL option %d: %s", opt, curl_easy_strerror(err));
goto out;
}
@@ -1781,7 +1725,7 @@
zabbix_log(LOG_LEVEL_TRACE, "%s() SOAP response: %s", __function_name, page.data);
- if (NULL != (*error = zbx_xml_read_value(page.data, ZBX_XPATH_LN1("faultstring"))))
+ if (NULL != (*error = zbx_xml_read_value(page.data, ZBX_VMWARE_FAULTSTRING())))
goto out;
*data = zbx_strdup(NULL, page.data);
@@ -1808,7 +1752,7 @@
* detected. *
* *
******************************************************************************/
-static zbx_vmware_hv_t *vmware_service_create_hv(const zbx_vmware_service_t *service, CURL *easyhandle,
+static zbx_vmware_hv_t *vmware_service_create_hv(zbx_vmware_service_t *service, CURL *easyhandle,
const char *id, char **error)
{
const char *__function_name = "vmware_service_create_hv";
@@ -1832,7 +1776,7 @@
if (SUCCEED != vmware_service_get_hv_data(service, easyhandle, id, &hv->details, error))
goto out;
- if (NULL == (value = zbx_xml_read_value(hv->details, ZBX_XPATH_LN2("hardware", "uuid"))))
+ if (NULL == (value = zbx_xml_read_value(hv->details, ZBX_HV_HARDWARE("uuid"))))
goto out;
hv->uuid = value;
@@ -1843,7 +1787,7 @@
hv->clusterid = value;
}
- zbx_xml_read_values(hv->details, "//*[@type='Datastore']", &datastores);
+ zbx_xml_read_values(hv->details, ZBX_HV_DATASTORES(), &datastores);
for (i = 0; i < datastores.values_num; i++)
{
@@ -1853,10 +1797,7 @@
zbx_vector_ptr_append(&hv->datastores, datastore);
}
- if (SUCCEED != vmware_service_hv_get_stats(service, easyhandle, hv, error))
- goto out;
-
- zbx_xml_read_values(hv->details, "//*[@type='VirtualMachine']", &vms);
+ zbx_xml_read_values(hv->details, ZBX_HV_VMS(), &vms);
for (i = 0; i < vms.values_num; i++)
{
@@ -2051,9 +1992,10 @@
{
char *token, *token_xpath = NULL;
- if (CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_POSTFIELDS, ZBX_POST_VCENTER_HV_LIST)))
+ if (CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_POSTFIELDS,
+ ZBX_POST_VCENTER_HV_LIST)))
{
- *error = zbx_dsprintf(*error, "Cannot set cURL option [%d]: %s", opt, curl_easy_strerror(err));
+ *error = zbx_dsprintf(*error, "Cannot set cURL option %d: %s.", opt, curl_easy_strerror(err));
goto out;
}
@@ -2103,7 +2045,8 @@
ret = SUCCEED;
out:
- zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s found:%d", __function_name, zbx_result_string(ret), hvs->values_num);
+ zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s found:%d", __function_name, zbx_result_string(ret),
+ hvs->values_num);
return ret;
}
@@ -2146,7 +2089,7 @@
if (CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_POSTFIELDS, tmp)))
{
- *error = zbx_dsprintf(*error, "Cannot set cURL option [%d]: %s", opt, curl_easy_strerror(err));
+ *error = zbx_dsprintf(*error, "Cannot set cURL option %d: %s.", opt, curl_easy_strerror(err));
goto out;
}
@@ -2160,12 +2103,12 @@
zabbix_log(LOG_LEVEL_TRACE, "%s() SOAP response: %s", __function_name, page.data);
- if (NULL != (*error = zbx_xml_read_value(page.data, ZBX_XPATH_LN1("faultstring"))))
+ if (NULL != (*error = zbx_xml_read_value(page.data, ZBX_VMWARE_FAULTSTRING())))
goto out;
- if (NULL == (*event_session = zbx_xml_read_value(page.data, "//*[@type='EventHistoryCollector']")))
+ if (NULL == (*event_session = zbx_xml_read_value(page.data, "/*/*/*/*[@type='EventHistoryCollector']")))
{
- *error = zbx_strdup(*error, "Cannot get EventHistoryCollector session");
+ *error = zbx_strdup(*error, "Cannot get EventHistoryCollector session.");
goto out;
}
@@ -2227,7 +2170,7 @@
if (CURLE_OK != (err = curl_easy_setopt(easyhandle, o = CURLOPT_POSTFIELDS, tmp)))
{
- *error = zbx_dsprintf(*error, "Cannot set cURL option [%d]: %s", o, curl_easy_strerror(err));
+ *error = zbx_dsprintf(*error, "Cannot set cURL option %d: %s.", o, curl_easy_strerror(err));
goto out;
}
@@ -2241,7 +2184,7 @@
zabbix_log(LOG_LEVEL_TRACE, "%s() SOAP response: %s", __function_name, page.data);
- if (NULL != (*error = zbx_xml_read_value(page.data, ZBX_XPATH_LN1("faultstring"))))
+ if (NULL != (*error = zbx_xml_read_value(page.data, ZBX_VMWARE_FAULTSTRING())))
goto out;
*events = zbx_strdup(NULL, page.data);
@@ -2401,7 +2344,7 @@
if (CURLE_OK != (err = curl_easy_setopt(easyhandle, o = CURLOPT_POSTFIELDS, ZBX_POST_VCENTER_CLUSTER)))
{
- *error = zbx_dsprintf(*error, "Cannot set cURL option [%d]: %s", o, curl_easy_strerror(err));
+ *error = zbx_dsprintf(*error, "Cannot set cURL option %d: %s.", o, curl_easy_strerror(err));
goto out;
}
@@ -2415,7 +2358,7 @@
zabbix_log(LOG_LEVEL_TRACE, "%s() SOAP response: %s", __function_name, page.data);
- if (NULL != (*error = zbx_xml_read_value(page.data, ZBX_XPATH_LN1("faultstring"))))
+ if (NULL != (*error = zbx_xml_read_value(page.data, ZBX_VMWARE_FAULTSTRING())))
goto out;
*clusters = zbx_strdup(*clusters, page.data);
@@ -2475,7 +2418,7 @@
if (CURLE_OK != (err = curl_easy_setopt(easyhandle, o = CURLOPT_POSTFIELDS, tmp)))
{
- *error = zbx_dsprintf(*error, "Cannot set cURL option [%d]: %s", o, curl_easy_strerror(err));
+ *error = zbx_dsprintf(*error, "Cannot set cURL option %d: %s.", o, curl_easy_strerror(err));
goto out;
}
@@ -2489,7 +2432,7 @@
zabbix_log(LOG_LEVEL_TRACE, "%s() SOAP response: %s", __function_name, page.data);
- if (NULL != (*error = zbx_xml_read_value(page.data, ZBX_XPATH_LN1("faultstring"))))
+ if (NULL != (*error = zbx_xml_read_value(page.data, ZBX_VMWARE_FAULTSTRING())))
goto out;
*status = zbx_strdup(NULL, page.data);
@@ -2592,28 +2535,205 @@
******************************************************************************/
static int vmware_service_initialize(zbx_vmware_service_t *service, CURL *easyhandle, char **error)
{
- int ret = FAIL;
- char *contents = NULL;
+ int ret = FAIL;
+ char *contents = NULL;
+ zbx_vector_ptr_t counters;
- if (SUCCEED != vmware_service_get_perfcounters(service, easyhandle, error))
+ zbx_vector_ptr_create(&counters);
+
+ if (SUCCEED != vmware_service_get_perfcounters(service, easyhandle, &counters, error))
goto out;
if (SUCCEED != vmware_service_get_contents(service, easyhandle, &contents, error))
goto out;
zbx_vmware_lock();
+
service->contents = vmware_shared_strdup(contents);
+ vmware_counters_shared_copy(&service->counters, &counters);
+
zbx_vmware_unlock();
ret = SUCCEED;
out:
zbx_free(contents);
+ zbx_vector_ptr_clean(&counters, (zbx_mem_free_func_t)vmware_counter_free);
+ zbx_vector_ptr_destroy(&counters);
+
return ret;
}
/******************************************************************************
* *
+ * Function: zbx_vmware_service_get_perf_entity *
+ * *
+ * Purpose: gets performance entity by type and id *
+ * *
+ * Parameters: service - [IN] the vmware service *
+ * type - [IN] the performance entity type *
+ * id - [IN] the performance entity id *
+ * *
+ * Return value: the performance entity or NULL if not found *
+ * *
+ ******************************************************************************/
+zbx_vmware_perf_entity_t *zbx_vmware_service_get_perf_entity(zbx_vmware_service_t *service, const char *type,
+ const char *id)
+{
+ const char *__function_name = "zbx_vmware_service_get_perf_entity";
+ int i;
+ zbx_vmware_perf_entity_t *entity;
+
+ zabbix_log(LOG_LEVEL_DEBUG, "In %s() type:%s id:%s", __function_name, type, id);
+
+ for (i = 0; i < service->entities.values_num; i++)
+ {
+ entity = service->entities.values[i];
+
+ if (0 == strcmp(entity->type, type) && 0 == strcmp(entity->id, id))
+ goto out;
+ }
+
+ entity = NULL;
+out:
+ zabbix_log(LOG_LEVEL_DEBUG, "End of %s() entity:%p", __function_name, entity);
+
+ return entity;
+}
+
+/******************************************************************************
+ * *
+ * Function: vmware_service_add_perf_entity *
+ * *
+ * Purpose: adds entity to vmware service performance entity list *
+ * *
+ * Parameters: service - [IN] the vmware service *
+ * uuid - [IN] the entity uuid *
+ * counters - [IN] NULL terminated list of performance counters *
+ * to be monitored for this entity *
+ * now - [IN] the current timestamp *
+ * *
+ * Comments: The performance counters are specified by their path: *
+ * <group>/<key>[<rollup type>] *
+ * *
+ ******************************************************************************/
+static void vmware_service_add_perf_entity(zbx_vmware_service_t *service, const char *type, const char *id,
+ const char **counters, int now)
+{
+ const char *__function_name = "vmware_service_add_perf_entity";
+
+ zbx_vmware_perf_entity_t *entity;
+ zbx_uint64_t counterid;
+ int i;
+
+ zabbix_log(LOG_LEVEL_DEBUG, "In %s() type:%s id:%s", __function_name, type, id);
+
+ if (NULL == (entity = zbx_vmware_service_get_perf_entity(service, type, id)))
+ {
+ entity = __vm_mem_malloc_func(NULL, sizeof(zbx_vmware_perf_entity_t));
+ entity->refresh = 0;
+ entity->type = vmware_shared_strdup(type);
+ entity->id = vmware_shared_strdup(id);
+
+ zbx_vector_ptr_create_ext(&entity->counters, __vm_mem_malloc_func, __vm_mem_realloc_func,
+ __vm_mem_free_func);
+
+ for (i = 0; NULL != counters[i]; i++)
+ {
+ if(FAIL == zbx_vmware_service_get_perfcounterid(service, counters[i], &counterid))
+ {
+ zabbix_log(LOG_LEVEL_DEBUG, "cannot find performance counter %s", counters[i]);
+ }
+ else
+ {
+ zbx_vmware_perf_counter_t *counter;
+
+ counter = __vm_mem_malloc_func(NULL, sizeof(zbx_vmware_perf_counter_t));
+ counter->counterid = counterid;
+ zbx_vector_ptr_pair_create_ext(&counter->values, __vm_mem_malloc_func,
+ __vm_mem_realloc_func, __vm_mem_free_func);
+
+ zbx_vector_ptr_append(&entity->counters, counter);
+ }
+ }
+
+ zbx_vector_ptr_append(&service->entities, entity);
+ }
+
+ entity->last_seen = now;
+
+ zabbix_log(LOG_LEVEL_DEBUG, "End of %s() perfcounters:%d", __function_name, entity->counters.values_num);
+}
+
+/******************************************************************************
+ * *
+ * Function: vmware_service_update_perf_entities *
+ * *
+ * Purpose: adds new or remove old entities (hypervisors, virtual machines) *
+ * from service performance entity list *
+ * *
+ * Parameters: service - [IN] the vmware service *
+ * *
+ ******************************************************************************/
+static void vmware_service_update_perf_entities(zbx_vmware_service_t *service)
+{
+ const char *__function_name = "vmware_service_add_perf_entity";
+
+ int now, i, j;
+ zbx_vmware_perf_entity_t *entity;
+ zbx_vmware_hv_t *hv;
+ zbx_vmware_vm_t *vm;
+
+ const char *hv_perfcounters[] = {
+ "net/packetsRx[summation]", "net/packetsTx[summation]",
+ "net/received[average]", "net/transmitted[average]",
+ "datastore/totalReadLatency[average]",
+ "datastore/totalWriteLatency[average]", NULL
+ };
+ const char *vm_perfcounters[] = {
+ "virtualDisk/read[average]", "virtualDisk/write[average]",
+ "virtualDisk/numberReadAveraged[average]",
+ "virtualDisk/numberWriteAveraged[average]",
+ "net/packetsRx[summation]", "net/packetsTx[summation]",
+ "net/received[average]", "net/transmitted[average]", NULL
+ };
+
+ zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
+
+ now = time(NULL);
+
+ /* update current performance entities */
+ for (i = 0; i < service->data->hvs.values_num; i++)
+ {
+ hv = service->data->hvs.values[i];
+ vmware_service_add_perf_entity(service, "HostSystem", hv->id, hv_perfcounters, now);
+
+ for (j = 0; j < hv->vms.values_num; j++)
+ {
+ vm = hv->vms.values[j];
+ vmware_service_add_perf_entity(service, "VirtualMachine", vm->id, vm_perfcounters, now);
+ }
+ }
+
+ /* remove old entities */
+ for (i = 0; i < service->entities.values_num;)
+ {
+ entity = service->entities.values[i];
+
+ if (0 != entity->last_seen && entity->last_seen < now)
+ {
+ vmware_shared_perf_entity_free(entity);
+ zbx_vector_ptr_remove_noorder(&service->entities, i);
+ continue;
+ }
+ i++;
+ }
+
+ zabbix_log(LOG_LEVEL_DEBUG, "End of %s() entities:%d", __function_name, service->entities.values_num);
+}
+
+/******************************************************************************
+ * *
* Function: vmware_service_update *
* *
* Purpose: updates object with a new data from vmware service *
@@ -2643,7 +2763,7 @@
if (NULL == (easyhandle = curl_easy_init()))
{
- zabbix_log(LOG_LEVEL_WARNING, "Cannot init cURL library");
+ zabbix_log(LOG_LEVEL_WARNING, "Cannot initialize cURL library");
goto out;
}
@@ -2652,7 +2772,7 @@
if (CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_HTTPHEADER, headers)))
{
- zabbix_log(LOG_LEVEL_WARNING, "Cannot set cURL option [%d]: %s", opt, curl_easy_strerror(err));
+ zabbix_log(LOG_LEVEL_WARNING, "Cannot set cURL option %d: %s", opt, curl_easy_strerror(err));
goto clean;
}
@@ -2695,7 +2815,9 @@
out:
zbx_vmware_lock();
- service->state = (SUCCEED == ret) ? ZBX_VMWARE_STATE_READY : ZBX_VMWARE_STATE_FAILED;
+ /* remove UPDATING flag and set READY or FAILED flag */
+ service->state &= ~(ZBX_VMWARE_STATE_MASK | ZBX_VMWARE_STATE_UPDATING);
+ service->state |= (SUCCEED == ret) ? ZBX_VMWARE_STATE_READY : ZBX_VMWARE_STATE_FAILED;
vmware_data_shared_free(service->data);
service->data = vmware_data_shared_dup(data);
@@ -2703,11 +2825,343 @@
service->lastcheck = time(NULL);
+ vmware_service_update_perf_entities(service);
+
zbx_vmware_unlock();
zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret));
}
+/******************************************************************************
+ * *
+ * Function: vmware_service_process_perf_entity_data *
+ * *
+ * Purpose: updates vmware performance statistics data *
+ * *
+ * Parameters: service - [IN] the vmware service *
+ * type - [IN] the performance entity type (HostSystem, *
+ * (VirtualMachine...) *
+ * id - [IN] the performance entity id *
+ * doc - [IN] the XML document containing performance counter *
+ * values for all entities *
+ * node - [IN] the XML node containing performance counter *
+ * values for the specified entity *
+ * *
+ ******************************************************************************/
+static void vmware_service_process_perf_entity_data(zbx_vmware_service_t *service, const char *type, const char *id,
+ xmlDoc *doc, xmlNode *node)
+{
+ const char *__function_name = "vmware_service_process_perf_entity_data";
+ xmlXPathContext *xpathCtx;
+ xmlXPathObject *xpathObj;
+ xmlNodeSetPtr nodeset;
+ char *instance, *counter, *value;
+ int i, j, values = 0;
+ zbx_vmware_perf_entity_t *entity;
+ zbx_uint64_t counterid;
+ zbx_vmware_perf_counter_t *perfcounter;
+
+ zabbix_log(LOG_LEVEL_DEBUG, "In %s() type:%s id:%s", __function_name, type, id);
+
+ xpathCtx = xmlXPathNewContext(doc);
+ xpathCtx->node = node;
+
+ if (NULL == (xpathObj = xmlXPathEvalExpression((xmlChar *)"*[local-name()='value']", xpathCtx)))
+ goto out;
+
+ if (xmlXPathNodeSetIsEmpty(xpathObj->nodesetval))
+ goto out;
+
+ if (NULL == (entity = zbx_vmware_service_get_perf_entity(service, type, id)))
+ goto out;
+
+ nodeset = xpathObj->nodesetval;
+
+ for (i = 0; i < nodeset->nodeNr; i++)
+ {
+ value = zbx_xml_read_node_value(doc, nodeset->nodeTab[i], "*[local-name()='value']");
+ instance = zbx_xml_read_node_value(doc, nodeset->nodeTab[i], "*[local-name()='id']"
+ "/*[local-name()='instance']");
+ counter = zbx_xml_read_node_value(doc, nodeset->nodeTab[i], "*[local-name()='id']"
+ "/*[local-name()='counterId']");
+
+ if (NULL != value && NULL != counter)
+ {
+ ZBX_STR2UINT64(counterid, counter);
+
+ for (j = 0; j < entity->counters.values_num; j++)
+ {
+ perfcounter = (zbx_vmware_perf_counter_t *)entity->counters.values[j];
+ if (perfcounter->counterid == counterid)
+ {
+ zbx_ptr_pair_t perfvalue;
+
+ perfvalue.first = vmware_shared_strdup(instance);
+ perfvalue.second = vmware_shared_strdup(value);
+
+ zbx_vector_ptr_pair_append_ptr(&perfcounter->values, &perfvalue);
+ values++;
+
+ break;
+ }
+ }
+ }
+
+ zbx_free(counter);
+ zbx_free(instance);
+ zbx_free(value);
+ }
+out:
+ if (NULL != xpathObj)
+ xmlXPathFreeObject(xpathObj);
+
+ xmlXPathFreeContext(xpathCtx);
+
+ zabbix_log(LOG_LEVEL_DEBUG, "End of %s() values:%d", __function_name, values);
+}
+
+/******************************************************************************
+ * *
+ * Function: vmware_service_parse_perf_data *
+ * *
+ * Purpose: updates vmware performance statistics data *
+ * *
+ * Parameters: service - [IN] the vmware service *
+ * data - [IN] the performance data *
+ * *
+ ******************************************************************************/
+static void vmware_service_parse_perf_data(zbx_vmware_service_t *service, const char *data)
+{
+ const char *__function_name = "vmware_service_parse_perf_data";
+ xmlDoc *doc;
+ xmlXPathContext *xpathCtx;
+ xmlXPathObject *xpathObj;
+ xmlNodeSetPtr nodeset;
+ int i;
+ char *id, *type;
+
+ zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
+
+ if (NULL == (doc = xmlReadMemory(data, strlen(data), "noname.xml", NULL, 0)))
+ goto out;
+
+ xpathCtx = xmlXPathNewContext(doc);
+
+ if (NULL == (xpathObj = xmlXPathEvalExpression((xmlChar *)"/*/*/*/*", xpathCtx)))
+ goto clean;
+
+ if (xmlXPathNodeSetIsEmpty(xpathObj->nodesetval))
+ goto clean;
+
+ nodeset = xpathObj->nodesetval;
+
+ for (i = 0; i < nodeset->nodeNr; i++)
+ {
+ id = zbx_xml_read_node_value(doc, nodeset->nodeTab[i], "*[local-name()='entity']");
+ type = zbx_xml_read_node_value(doc, nodeset->nodeTab[i], "*[local-name()='entity']/@type");
+
+ if (NULL != type && NULL != id)
+ vmware_service_process_perf_entity_data(service, type, id, doc, nodeset->nodeTab[i]);
+
+ zbx_free(type);
+ zbx_free(id);
+ }
+clean:
+ if (NULL != xpathObj)
+ xmlXPathFreeObject(xpathObj);
+
+ xmlXPathFreeContext(xpathCtx);
+ xmlFreeDoc(doc);
+ xmlCleanupParser();
+out:
+ zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);
+}
+
+/******************************************************************************
+ * *
+ * Function: vmware_service_update_perf *
+ * *
+ * Purpose: updates vmware statistics data *
+ * *
+ * Parameters: service - [IN] the vmware service *
+ * *
+ ******************************************************************************/
+static void vmware_service_update_perf(zbx_vmware_service_t *service)
+{
+ const char *__function_name = "vmware_service_update_perf";
+
+ CURL *easyhandle = NULL;
+ struct curl_slist *headers = NULL;
+ int err, opt, i, j;
+ char *error = NULL, *tmp = NULL;
+ size_t tmp_alloc = 0, tmp_offset = 0;
+ zbx_vector_ptr_t entities;
+ zbx_vmware_perf_entity_t *entity, *local_entity;
+ zbx_vmware_perf_counter_t *counter;
+
+ zabbix_log(LOG_LEVEL_DEBUG, "In %s() %s@%s", __function_name, service->username, service->url);
+
+ if (NULL == (easyhandle = curl_easy_init()))
+ {
+ zabbix_log(LOG_LEVEL_WARNING, "Cannot initialize cURL library");
+ goto out;
+ }
+
+ zbx_vector_ptr_create(&entities);
+
+ headers = curl_slist_append(headers, ZBX_XML_HEADER1);
+ headers = curl_slist_append(headers, ZBX_XML_HEADER2);
+
+ if (CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_HTTPHEADER, headers)))
+ {
+ error = zbx_dsprintf(error, "Cannot set cURL option %d: %s.", opt, curl_easy_strerror(err));
+ goto clean;
+ }
+
+ if (SUCCEED != vmware_service_authenticate(service, easyhandle, &error))
+ goto clean;
+
+ /* update performance counter refresh rate for entities */
+
+ /* create a local list of entities with zero refresh rate */
+ zbx_vector_ptr_create(&entities);
+
+ zbx_vmware_lock();
+
+ for (i = 0; i < service->entities.values_num; i++)
+ {
+ entity = service->entities.values[i];
+
+ if (0 != entity->refresh)
+ continue;
+
+ local_entity = zbx_malloc(NULL, sizeof(zbx_vmware_perf_entity_t));
+ local_entity->type = zbx_strdup(NULL, entity->type);
+ local_entity->id = zbx_strdup(NULL, entity->id);
+ local_entity->refresh = 0;
+
+ zbx_vector_ptr_append(&entities, local_entity);
+ }
+
+ zbx_vmware_unlock();
+
+ /* get refresh rates */
+ for (i = 0; i < entities.values_num; i++)
+ {
+ local_entity = entities.values[i];
+
+ vmware_service_get_perfcounter_refreshrate(service, easyhandle, local_entity->type, local_entity->id,
+ &local_entity->refresh, &error);
+
+ if (NULL != error)
+ {
+ zabbix_log(LOG_LEVEL_DEBUG, "cannot get refresh rate for performance entity type:%s id:%s "
+ "error:%s", local_entity->type, local_entity->id, error);
+ zbx_free(error);
+ }
+ }
+
+ /* update refresh rates and create performance query request */
+ zbx_strcpy_alloc(&tmp, &tmp_alloc, &tmp_offset, ZBX_POST_VSPHERE_HEADER);
+ zbx_strcpy_alloc(&tmp, &tmp_alloc, &tmp_offset, "<ns0:QueryPerf>");
+ zbx_snprintf_alloc(&tmp, &tmp_alloc, &tmp_offset, "<ns0:_this type=\"PerformanceManager\">%s</ns0:_this>",
+ vmware_service_objects[service->type].performance_manager);
+
+ zbx_vmware_lock();
+
+ for (i = 0; i < service->entities.values_num; i++)
+ {
+ entity = service->entities.values[i];
+
+ if (0 == entity->refresh)
+ {
+ /* udpate entity refresh rate */
+ for (j = 0; j < entities.values_num; j++)
+ {
+ local_entity = entities.values[j];
+
+ if (0 == strcmp(local_entity->type, entity->type) &&
+ 0 == strcmp(local_entity->id, entity->id))
+ {
+ break;
+ }
+ }
+
+ if (j == entities.values_num)
+ {
+ zabbix_log(LOG_LEVEL_DEBUG, "skipping performance entity with zero refresh rate "
+ "type:%s id:%d", entity->type, entity->id);
+ continue;
+ }
+
+ entity->refresh = local_entity->refresh;
+ }
+
+ /* add entity performance counter request */
+ zbx_snprintf_alloc(&tmp, &tmp_alloc, &tmp_offset, "<ns0:querySpec>"
+ "<ns0:entity type=\"%s\">%s</ns0:entity><ns0:maxSample>1</ns0:maxSample>",
+ entity->type, entity->id);
+
+ for (j = 0; j < entity->counters.values_num; j++)
+ {
+ counter = (zbx_vmware_perf_counter_t *)entity->counters.values[j];
+
+ zbx_snprintf_alloc(&tmp, &tmp_alloc, &tmp_offset, "<ns0:metricId><ns0:counterId>" ZBX_FS_UI64
+ "</ns0:counterId><ns0:instance>*</ns0:instance></ns0:metricId>",
+ counter->counterid);
+ }
+
+ zbx_snprintf_alloc(&tmp, &tmp_alloc, &tmp_offset, "<ns0:intervalId>%d</ns0:intervalId></ns0:querySpec>",
+ entity->refresh);
+ }
+
+ zbx_vmware_unlock();
+
+ zbx_strcpy_alloc(&tmp, &tmp_alloc, &tmp_offset, "</ns0:QueryPerf>");
+ zbx_strcpy_alloc(&tmp, &tmp_alloc, &tmp_offset, ZBX_POST_VSPHERE_FOOTER);
+
+ zbx_vector_ptr_clean(&entities, (zbx_mem_free_func_t)vmware_perf_entity_free);
+ zbx_vector_ptr_destroy(&entities);
+
+ if (CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_POSTFIELDS, tmp)))
+ {
+ error = zbx_dsprintf(error, "Cannot set cURL option %d: %s.", opt, curl_easy_strerror(err));
+ goto clean;
+ }
+
+ page.offset = 0;
+
+ if (CURLE_OK != (err = curl_easy_perform(easyhandle)))
+ error = zbx_strdup(error, curl_easy_strerror(err));
+
+clean:
+ zbx_free(tmp);
+
+ curl_slist_free_all(headers);
+ curl_easy_cleanup(easyhandle);
+out:
+ zbx_vmware_lock();
+
+ if (NULL != error)
+ {
+ zabbix_log(LOG_LEVEL_DEBUG, "cannot update vmware service performance statistics: %s", error);
+ zbx_free(error);
+ }
+ else
+ {
+ vmware_entities_shared_clean_stats(&service->entities);
+ vmware_service_parse_perf_data(service, page.data);
+ }
+
+ service->state &= ~(ZBX_VMWARE_STATE_UPDATING_PERF);
+ service->lastperfcheck = time(NULL);
+
+ zbx_vmware_unlock();
+
+ zabbix_log(LOG_LEVEL_DEBUG, "End of %s(): processed " ZBX_FS_SIZE_T " bytes of data", __function_name,
+ (zbx_fs_size_t)page.offset);
+}
+
/*
* Public API
*/
@@ -2779,6 +3233,11 @@
service->state = ZBX_VMWARE_STATE_NEW;
service->lastaccess = now;
+ zbx_vector_ptr_create_ext(&service->entities, __vm_mem_malloc_func, __vm_mem_realloc_func,
+ __vm_mem_free_func);
+ zbx_hashset_create_ext(&service->counters, ZBX_VMWARE_COUNTERS_INIT_SIZE, vmware_counter_hash_func,
+ vmware_counter_compare_func, __vm_mem_malloc_func, __vm_mem_realloc_func, __vm_mem_free_func);
+
zbx_vector_ptr_append(&vmware->services, service);
/* new service does not have any data - return NULL */
@@ -2855,7 +3314,8 @@
#define ZBX_VMWARE_SERVICE_NONE 0
#define ZBX_VMWARE_SERVICE_IDLE 1
#define ZBX_VMWARE_SERVICE_UPDATE 2
-#define ZBX_VMWARE_SERVICE_REMOVE 3
+#define ZBX_VMWARE_SERVICE_UPDATE_PERF 3
+#define ZBX_VMWARE_SERVICE_REMOVE 4
/******************************************************************************
* *
@@ -2909,18 +3369,19 @@
{
service = vmware->services.values[i];
- if (0 != (service->state & ZBX_VMWARE_STATE_UPDATING))
- continue;
-
- if (now - service->lastaccess > ZBX_VMWARE_SERVICE_TTL)
+ if (0 == (service->state & ZBX_VMWARE_STATE_UPDATING_PERF) &&
+ 0 != (service->state & ZBX_VMWARE_STATE_READY) &&
+ now - service->lastperfcheck >= ZBX_VMWARE_PERF_TTL)
{
- zbx_vector_ptr_remove(&vmware->services, i);
- vmware_service_shared_free(service);
- state = ZBX_VMWARE_SERVICE_REMOVE;
- removed_services++;
+ service->state |= ZBX_VMWARE_STATE_UPDATING_PERF;
+ state = ZBX_VMWARE_SERVICE_UPDATE_PERF;
+ updated_services++;
break;
}
+ if (0 != (service->state & ZBX_VMWARE_STATE_UPDATING))
+ continue;
+
if (now - service->lastcheck >= ZBX_VMWARE_CACHE_TTL)
{
service->state |= ZBX_VMWARE_STATE_UPDATING;
@@ -2929,16 +3390,31 @@
break;
}
+ if (now - service->lastaccess > ZBX_VMWARE_SERVICE_TTL)
+ {
+ zbx_vector_ptr_remove(&vmware->services, i);
+ vmware_service_shared_free(service);
+ state = ZBX_VMWARE_SERVICE_REMOVE;
+ removed_services++;
+ break;
+ }
+
if (service->lastcheck + ZBX_VMWARE_CACHE_TTL < next_update)
next_update = service->lastcheck + ZBX_VMWARE_CACHE_TTL;
+
+ if (service->lastperfcheck + ZBX_VMWARE_PERF_TTL < next_update)
+ next_update = service->lastperfcheck + ZBX_VMWARE_PERF_TTL;
+
}
zbx_vmware_unlock();
if (ZBX_VMWARE_SERVICE_UPDATE == state)
vmware_service_update(service);
- }
- while (ZBX_VMWARE_SERVICE_IDLE != state);
+ else if (ZBX_VMWARE_SERVICE_UPDATE_PERF == state)
+ vmware_service_update_perf(service);
+
+ } while (ZBX_VMWARE_SERVICE_IDLE != state);
total_sec += zbx_time() - sec;
now = time(NULL);
@@ -2977,6 +3453,98 @@
}
/******************************************************************************
+ * *
+ * Function: zbx_vmware_service_get_perfcounterid *
+ * *
+ * Purpose: gets vmware performance counter id by the path *
+ * *
+ * Parameters: counters - [IN] the counters hashset *
+ * path - [IN] the path of counter to retrieve in format *
+ * <group>/<key>[<rollup type>] *
+ * counterid - [OUT] the counter id *
+ * *
+ * Return value: SUCCEED if the counter was found, FAIL otherwise *
+ * *
+ ******************************************************************************/
+int zbx_vmware_service_get_perfcounterid(zbx_vmware_service_t *service, const char *path,
+ zbx_uint64_t *counterid)
+{
+ const char *__function_name = "zbx_vmware_service_get_perfcounterid";
+ zbx_vmware_counter_t *counter;
+ int ret = FAIL;
+
+ zabbix_log(LOG_LEVEL_DEBUG, "In %s() path:%s", __function_name, path);
+
+ if (NULL != (counter = zbx_hashset_search(&service->counters, &path)))
+ {
+ *counterid = counter->id;
+ ret = SUCCEED;
+ }
+
+ zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s counterid:" ZBX_FS_UI64, __function_name, zbx_result_string(ret),
+ *counterid);
+
+ return ret;
+}
+
+/******************************************************************************
+ * *
+ * Function: zbx_vmware_service_start_monitoring *
+ * *
+ * Purpose: start monitoring performance counter of the specified entity *
+ * *
+ * Parameters: service - [IN] the vmware service *
+ * type - [IN] the entity type *
+ * id - [IN] the entity id *
+ * counterid - [IN] the performance counter id *
+ * *
+ * Return value: SUCCEED - the entity counter was added to monitoring list. *
+ * FAIL - the performance counter of the specified entity *
+ * is already being monitored. *
+ * *
+ ******************************************************************************/
+int zbx_vmware_service_start_monitoring(zbx_vmware_service_t *service, const char *type, const char *id,
+ zbx_uint64_t counterid)
+{
+ const char *__function_name = "zbx_vmware_service_start_monitoring";
+ int ret = FAIL;
+ zbx_vmware_perf_entity_t *entity;
+
+ zabbix_log(LOG_LEVEL_DEBUG, "In %s() type:%s id:%s counterid:" ZBX_FS_UI64, __function_name, type, id,
+ counterid);
+
+ if (NULL == (entity = zbx_vmware_service_get_perf_entity(service, type, id)))
+ {
+ entity = __vm_mem_malloc_func(NULL, sizeof(zbx_vmware_perf_entity_t));
+ entity->refresh = 0;
+ entity->last_seen = 0;
+ entity->type = vmware_shared_strdup(type);
+ entity->id = vmware_shared_strdup(id);
+ zbx_vector_ptr_create_ext(&entity->counters, __vm_mem_malloc_func, __vm_mem_realloc_func,
+ __vm_mem_free_func);
+
+ zbx_vector_ptr_append(&service->entities, entity);
+ }
+
+ if (FAIL == zbx_vector_ptr_search(&entity->counters, &counterid, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC))
+ {
+ zbx_vmware_perf_counter_t *counter;
+
+ counter = __vm_mem_malloc_func(NULL, sizeof(zbx_vmware_perf_counter_t));
+ counter->counterid = counterid;
+ zbx_vector_ptr_pair_create_ext(&counter->values, __vm_mem_malloc_func, __vm_mem_realloc_func,
+ __vm_mem_free_func);
+ zbx_vector_ptr_append(&entity->counters, counter);
+
+ ret = SUCCEED;
+ }
+
+ zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret));
+
+ return ret;
+}
+
+/******************************************************************************
* *
* Function: zbx_vmware_lock *
* *
diff -ur zabbix-2.4.1.orig/src/zabbix_server/vmware/vmware.h zabbix-2.4.1/src/zabbix_server/vmware/vmware.h
--- zabbix-2.4.1.orig/src/zabbix_server/vmware/vmware.h 2014-10-08 15:58:58.000000000 +0900
+++ zabbix-2.4.1/src/zabbix_server/vmware/vmware.h 2014-10-28 20:33:20.421479239 +0900
@@ -27,24 +27,42 @@
#define ZBX_VMWARE_STATE_READY 0x002
#define ZBX_VMWARE_STATE_FAILED 0x004
+#define ZBX_VMWARE_STATE_MASK 0x0FF
+
#define ZBX_VMWARE_STATE_UPDATING 0x100
+#define ZBX_VMWARE_STATE_UPDATING_PERF 0x200
+/* performance counter data */
typedef struct
{
- zbx_uint64_t nic_packets_rx;
- zbx_uint64_t nic_packets_tx;
- zbx_uint64_t nic_received;
- zbx_uint64_t nic_transmitted;
-
- zbx_uint64_t disk_read;
- zbx_uint64_t disk_write;
- zbx_uint64_t disk_number_read_averaged;
- zbx_uint64_t disk_number_write_averaged;
+ /* the counter id */
+ zbx_uint64_t counterid;
- zbx_uint64_t datastore_read_latency;
- zbx_uint64_t datastore_write_latency;
+ /* the counter values for various instances */
+ /* pair->first - instance (can be NULL for aggregate values) */
+ /* pair->second - value */
+ zbx_vector_ptr_pair_t values;
+} zbx_vmware_perf_counter_t;
+
+/* an entity monitored with performance counters */
+typedef struct
+{
+ /* entity type: HostSystem or VirtualMachine */
+ char *type;
+
+ /* entity id */
+ char *id;
+
+ /* the performance counter refresh rate */
+ int refresh;
+
+ /* timestamp when the entity was queried last time */
+ int last_seen;
+
+ /* the performance counters to monitor */
+ zbx_vector_ptr_t counters;
}
-zbx_vmware_counters_t;
+zbx_vmware_perf_entity_t;
typedef struct
{
@@ -69,7 +87,6 @@
char *uuid;
char *id;
char *details;
- char *stats;
zbx_vector_ptr_t devs;
}
zbx_vmware_vm_t;
@@ -81,7 +98,6 @@
char *id;
char *details;
char *clusterid;
- char *stats;
zbx_vector_ptr_t datastores;
zbx_vector_ptr_t vms;
}
@@ -120,10 +136,8 @@
/* the service state - see ZBX_VMWARE_STATE_* defines */
int state;
- /* the performance counters */
- zbx_vmware_counters_t counters;
-
int lastcheck;
+ int lastperfcheck;
/* The last vmware service access time. If a service is not accessed for a day it is removed */
int lastaccess;
@@ -131,6 +145,15 @@
/* the vmware service instance contents */
char *contents;
+ /* the performance counter values */
+ zbx_hashset_t stats;
+
+ /* the performance counters */
+ zbx_hashset_t counters;
+
+ /* list of entities to monitor with performance counters */
+ zbx_vector_ptr_t entities;
+
/* The service data object that is swapped with a new one during service update */
zbx_vmware_data_t *data;
}
@@ -162,6 +185,62 @@
zbx_vmware_service_t *zbx_vmware_get_service(const char* url, const char* username, const char* password);
int zbx_vmware_get_statistics(zbx_vmware_stats_t *stats);
+int zbx_vmware_service_get_perfcounterid(zbx_vmware_service_t *service, const char *path, zbx_uint64_t *counterid);
+int zbx_vmware_service_start_monitoring(zbx_vmware_service_t *service, const char *type, const char *id,
+ zbx_uint64_t counterid);
+zbx_vmware_perf_entity_t *zbx_vmware_service_get_perf_entity(zbx_vmware_service_t *service, const char *type,
+ const char *id);
+
+#define ZBX_VM_QUICKSTATS(property) \
+ "/*/*/*/*/*/*[local-name()='propSet'][*[local-name()='name'][text()='summary']]" \
+ "/*[local-name()='val']/*[local-name()='quickStats']/*[local-name()='" property "']"
+
+#define ZBX_VM_RUNTIME(property) \
+ "/*/*/*/*/*/*[local-name()='propSet'][*[local-name()='name'][text()='summary']]" \
+ "/*[local-name()='val']/*[local-name()='runtime']/*[local-name()='" property "']"
+
+#define ZBX_VM_CONFIG(property) \
+ "/*/*/*/*/*/*[local-name()='propSet'][*[local-name()='name'][text()='summary']]" \
+ "/*[local-name()='val']/*[local-name()='config']/*[local-name()='" property "']"
+
+#define ZBX_VM_STORAGE(property) \
+ "/*/*/*/*/*/*[local-name()='propSet'][*[local-name()='name'][text()='summary']]" \
+ "/*[local-name()='val']/*[local-name()='storage']/*[local-name()='" property "']"
+
+#define ZBX_VM_HARDWARE(property) \
+ "/*/*/*/*/*/*[local-name()='propSet'][*[local-name()='name'][text()='config']]" \
+ "/*[local-name()='val']/*[local-name()='hardware']/*[local-name()='" property "']"
+
+#define ZBX_HV_QUICKSTATS(property) \
+ "/*/*/*/*/*[local-name()='propSet'][*[local-name()='name'][text()='summary']]" \
+ "/*[local-name()='val']/*[local-name()='quickStats']/*[local-name()='" property "']"
+
+#define ZBX_HV_CONFIG(property) \
+ "/*/*/*/*/*[local-name()='propSet'][*[local-name()='name'][text()='summary']]" \
+ "/*[local-name()='val']/*[local-name()='config']/*[local-name()='" property "']"
+
+#define ZBX_HV_CONFIG(property) \
+ "/*/*/*/*/*[local-name()='propSet'][*[local-name()='name'][text()='summary']]" \
+ "/*[local-name()='val']/*[local-name()='config']/*[local-name()='" property "']"
+
+#define ZBX_HV_HARDWARE(property) \
+ "/*/*/*/*/*[local-name()='propSet'][*[local-name()='name'][text()='summary']]" \
+ "/*[local-name()='val']/*[local-name()='hardware']/*[local-name()='" property "']"
+
+#define ZBX_HV_CONFIG_PRODUCT(property) \
+ "/*/*/*/*/*[local-name()='propSet'][*[local-name()='name'][text()='summary']]" \
+ "/*[local-name()='val']/*[local-name()='config']/*[local-name()='product']" \
+ "/*[local-name()='" property "']"
+
+#define ZBX_HV_STATUS() \
+ "/*/*/*/*/*[local-name()='propSet'][*[local-name()='name'][text()='summary']]" \
+ "/*[local-name()='val']/*[local-name()='overallStatus']"
+
+#define ZBX_VMWARE_EVENTS() "/*/*/*/*/*/*[local-name()='propSet'][*[local-name()='name'][text()='latestPage']]" \
+ "/*/*[local-name()='Event']"
+
+#define ZBX_VMWARE_ABOUT(property) "/*/*/*/*/*[local-name()='about']/*[local-name()='" property "']"
+
/*
* XML support
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment