Skip to content

Instantly share code, notes, and snippets.

@higebu
Last active August 29, 2015 14:10
Show Gist options
  • Save higebu/8a8ac549b3b66c6ffc15 to your computer and use it in GitHub Desktop.
Save higebu/8a8ac549b3b66c6ffc15 to your computer and use it in GitHub Desktop.
diff -ur zabbix-2.4.2.orig/conf/zabbix_proxy.conf zabbix-2.4.2/conf/zabbix_proxy.conf
--- zabbix-2.4.2.orig/conf/zabbix_proxy.conf 2014-11-05 17:01:41.000000000 +0900
+++ zabbix-2.4.2/conf/zabbix_proxy.conf 2014-11-26 19:31:57.845332122 +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.2.orig/conf/zabbix_server.conf zabbix-2.4.2/conf/zabbix_server.conf
--- zabbix-2.4.2.orig/conf/zabbix_server.conf 2014-11-05 17:01:41.000000000 +0900
+++ zabbix-2.4.2/conf/zabbix_server.conf 2014-11-26 19:31:57.845332122 +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.2.orig/src/zabbix_proxy/proxy.c zabbix-2.4.2/src/zabbix_proxy/proxy.c
--- zabbix-2.4.2.orig/src/zabbix_proxy/proxy.c 2014-11-05 17:01:42.000000000 +0900
+++ zabbix-2.4.2/src/zabbix_proxy/proxy.c 2014-11-26 19:31:57.845332122 +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.2.orig/src/zabbix_server/poller/checks_simple.c zabbix-2.4.2/src/zabbix_server/poller/checks_simple.c
--- zabbix-2.4.2.orig/src/zabbix_server/poller/checks_simple.c 2014-11-05 17:01:42.000000000 +0900
+++ zabbix-2.4.2/src/zabbix_server/poller/checks_simple.c 2014-11-26 19:31:57.845332122 +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.2.orig/src/zabbix_server/poller/checks_simple_vmware.c zabbix-2.4.2/src/zabbix_server/poller/checks_simple_vmware.c
--- zabbix-2.4.2.orig/src/zabbix_server/poller/checks_simple_vmware.c 2014-11-05 17:01:42.000000000 +0900
+++ zabbix-2.4.2/src/zabbix_server/poller/checks_simple_vmware.c 2014-11-26 19:51:25.029206185 +0900
@@ -179,30 +179,80 @@
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";
+ 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;
- int ret = SYSINFO_RET_FAIL;
- char xpath[MAX_STRING_LEN], *value;
+ zabbix_log(LOG_LEVEL_DEBUG, "In %s() type:%s id:%s path:%s instance:%s", __function_name, type, id, path,
+ instance);
- zabbix_log(LOG_LEVEL_DEBUG, "In %s() %s: " ZBX_FS_UI64, __function_name, instance, counterid);
+ if (FAIL == zbx_vmware_service_get_perfcounterid(service, path, &counterid))
+ {
+ SET_MSG_RESULT(result, zbx_strdup(NULL, "Performance counter is not available."));
+ goto out;
+ }
- 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 == (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;
+ }
- if (NULL == (value = zbx_xml_read_value(stats, xpath)))
+ for (i = 0; i < entity->counters.values_num; i++)
{
- SET_MSG_RESULT(result, zbx_strdup(NULL, "Performance counter is not available."));
+ 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;
}
- if (SUCCEED == set_result_type(result, ITEM_VALUE_TYPE_UINT64, ITEM_DATA_TYPE_DECIMAL, value))
+ if (0 == perfcounter->values.values_num)
+ {
ret = SYSINFO_RET_OK;
+ goto out;
+ }
- zbx_free(value);
+ 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 +260,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 +268,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 +290,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 +301,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 +459,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 +571,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 +762,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 +830,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 +868,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 +945,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 +988,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 +1029,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 +1046,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 +1063,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 +1083,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 +1100,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 +1116,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 +1132,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 +1149,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 +1166,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 +1203,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 +1222,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 +1254,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 +1271,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 +1333,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 +1382,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 +1502,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 +1566,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 +1581,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 +1651,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 +1724,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 +1777,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 +1858,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 +1882,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 +1901,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 +1920,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 +1939,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 +1958,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 +1977,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 +1996,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 +2015,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 +2034,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 +2124,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 +2159,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 +2173,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 +2189,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 +2224,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 +2238,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 +2256,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 +2272,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 +2288,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 +2304,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 +2390,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 +2425,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 +2439,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 +2455,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 +2490,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 +2504,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 +2675,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.2.orig/src/zabbix_server/poller/checks_simple_vmware.h zabbix-2.4.2/src/zabbix_server/poller/checks_simple_vmware.h
--- zabbix-2.4.2.orig/src/zabbix_server/poller/checks_simple_vmware.h 2014-11-05 17:01:42.000000000 +0900
+++ zabbix-2.4.2/src/zabbix_server/poller/checks_simple_vmware.h 2014-11-26 19:31:57.845332122 +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.2.orig/src/zabbix_server/server.c zabbix-2.4.2/src/zabbix_server/server.c
--- zabbix-2.4.2.orig/src/zabbix_server/server.c 2014-11-05 17:01:42.000000000 +0900
+++ zabbix-2.4.2/src/zabbix_server/server.c 2014-11-26 19:31:57.849332030 +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.2.orig/src/zabbix_server/vmware/vmware.c zabbix-2.4.2/src/zabbix_server/vmware/vmware.c
--- zabbix-2.4.2.orig/src/zabbix_server/vmware/vmware.c 2014-11-05 17:01:42.000000000 +0900
+++ zabbix-2.4.2/src/zabbix_server/vmware/vmware.c 2014-11-26 20:26:04.496983560 +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,63 @@
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);
+}
+
+/******************************************************************************
+ * *
+ * performance entities hashset support functions *
+ * *
+ ******************************************************************************/
+zbx_hash_t vmware_perf_entity_hash_func(const void *data)
+{
+ zbx_hash_t seed;
+
+ zbx_vmware_perf_entity_t *entity = (zbx_vmware_perf_entity_t *)data;
+
+ seed = ZBX_DEFAULT_STRING_HASH_ALGO(entity->type, strlen(entity->type), ZBX_DEFAULT_HASH_SEED);
+
+ return ZBX_DEFAULT_STRING_HASH_ALGO(entity->id, strlen(entity->id), seed);
+}
+
+int vmware_perf_entity_compare_func(const void *d1, const void *d2)
+{
+ int ret;
+
+ zbx_vmware_perf_entity_t *e1 = (zbx_vmware_perf_entity_t *)d1;
+ zbx_vmware_perf_entity_t *e2 = (zbx_vmware_perf_entity_t *)d2;
+
+ ret = strcmp(e1->type, e2->type);
+ if (0 == ret)
+ ret = strcmp(e1->id, e2->id);
+
+ return ret;
+}
+
+/******************************************************************************
+ * *
* Function: vmware_shared_strdup *
* *
* Purpose: duplicates the specified string into shared memory *
@@ -175,6 +254,99 @@
/******************************************************************************
* *
+ * 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_hashset_t *entities)
+{
+ int i;
+ zbx_vmware_perf_entity_t *entity;
+ zbx_vmware_perf_counter_t *counter;
+ zbx_hashset_iter_t iter;
+
+
+ zbx_hashset_iter_reset(entities, &iter);
+ while (NULL != (entity = zbx_hashset_iter_next(&iter)))
+ {
+ for (i = 0; i < entity->counters.values_num; i++)
+ {
+ counter = (zbx_vmware_perf_counter_t *)entity->counters.values[i];
+ vmware_vector_ptr_pair_shared_clean(&counter->values);
+ }
+ }
+}
+
+/******************************************************************************
+ * *
* Function: vmware_datastore_shared_free *
* *
* Purpose: frees shared resources allocated to store datastore data *
@@ -226,14 +398,11 @@
zbx_vector_ptr_clean(&vm->devs, (zbx_mem_free_func_t)vmware_dev_shared_free);
zbx_vector_ptr_destroy(&vm->devs);
- if (NULL != vm->id)
- __vm_mem_free_func(vm->id);
-
if (NULL != vm->uuid)
__vm_mem_free_func(vm->uuid);
- if (NULL != vm->stats)
- __vm_mem_free_func(vm->stats);
+ if (NULL != vm->id)
+ __vm_mem_free_func(vm->id);
if (NULL != vm->details)
__vm_mem_free_func(vm->details);
@@ -270,9 +439,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 +496,40 @@
/******************************************************************************
* *
- * Function: vmware_service_free *
+ * Function: vmware_shared_perf_entity_clean *
+ * *
+ * Purpose: cleans resources allocated by vmware peformance entity in vmware *
+ * cache *
+ * *
+ * Parameters: entity - [IN] the entity to free *
+ * *
+ ******************************************************************************/
+static void vmware_shared_perf_entity_clean(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);
+}
+
+/******************************************************************************
+ * *
+ * 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 +538,10 @@
******************************************************************************/
static void vmware_service_shared_free(zbx_vmware_service_t *service)
{
+ zbx_hashset_iter_t iter;
+ zbx_vmware_counter_t *counter;
+ zbx_vmware_perf_entity_t *entity;
+
__vm_mem_free_func(service->url);
__vm_mem_free_func(service->username);
__vm_mem_free_func(service->password);
@@ -348,6 +551,18 @@
vmware_data_shared_free(service->data);
+ zbx_hashset_iter_reset(&service->entities, &iter);
+ while (NULL != (entity = zbx_hashset_iter_next(&iter)))
+ vmware_shared_perf_entity_clean(entity);
+
+ zbx_hashset_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);
}
@@ -439,10 +654,9 @@
VMWARE_VECTOR_CREATE(&vm->devs, ptr);
- vm->id = vmware_shared_strdup(src->id);
vm->uuid = vmware_shared_strdup(src->uuid);
+ vm->id = vmware_shared_strdup(src->id);
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 +688,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++)
@@ -565,9 +778,8 @@
zbx_vector_ptr_clean(&vm->devs, (zbx_mem_free_func_t)vmware_dev_free);
zbx_vector_ptr_destroy(&vm->devs);
- zbx_free(vm->id);
zbx_free(vm->uuid);
- zbx_free(vm->stats);
+ zbx_free(vm->id);
zbx_free(vm->details);
zbx_free(vm);
}
@@ -593,7 +805,6 @@
zbx_free(hv->id);
zbx_free(hv->details);
zbx_free(hv->clusterid);
- zbx_free(hv->stats);
zbx_free(hv);
}
@@ -638,6 +849,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 +918,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 +940,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 +954,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 +982,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 +990,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_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"))))
+ if (NULL != (*error = zbx_xml_read_value(page.data, ZBX_VMWARE_FAULTSTRING())))
goto out;
ret = SUCCEED;
@@ -793,7 +1038,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 +1052,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 +1064,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 +1104,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 +1118,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 +1141,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 +1153,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 +1174,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 +1192,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 +1206,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 +1269,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,183 +1284,11 @@
/******************************************************************************
* *
- * 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 *
- * *
- * Return value: SUCCEED - the operation has completed successfully *
- * FAIL - the operation has failed *
- * *
- ******************************************************************************/
-static int vmware_service_hv_get_stats(const zbx_vmware_service_t *service, CURL *easyhandle,
- zbx_vmware_hv_t *hv, char **error)
-{
- 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;
-
- zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
-
- if (SUCCEED != vmware_service_get_perfcounter_refreshrate(service, easyhandle, "HostSystem", hv->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=\"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);
-
- 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 *
+ * Parameters: vm - [IN] the virtual machine *
* *
* Comments: The network interface devices are taken from vm device list *
* filtered by macAddress key. *
@@ -1316,7 +1297,6 @@
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;
@@ -1330,8 +1310,8 @@
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 +1379,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 +1412,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 +1490,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 +1524,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 +1538,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 +1565,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";
@@ -1609,15 +1589,11 @@
goto out;
vm->uuid = value;
-
vm->id = zbx_strdup(NULL, id);
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 +1661,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 +1743,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 +1757,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 +1784,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 +1808,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 +1819,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 +1829,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 +2024,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 +2077,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 +2121,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 +2135,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 +2202,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 +2216,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 +2376,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 +2390,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 +2450,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 +2464,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 +2567,193 @@
******************************************************************************/
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";
+ zbx_vmware_perf_entity_t *pentity, entity = {(char *)type, (char *)id};
+
+ zabbix_log(LOG_LEVEL_DEBUG, "In %s() type:%s id:%s", __function_name, type, id);
+
+ pentity = zbx_hashset_search(&service->entities, &entity);
+
+ zabbix_log(LOG_LEVEL_DEBUG, "End of %s() entity:%p", __function_name, entity);
+
+ return pentity;
+}
+
+/******************************************************************************
+ * *
+ * 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, *pentity;
+ zbx_uint64_t counterid;
+ int i;
+
+ zabbix_log(LOG_LEVEL_DEBUG, "In %s() type:%s id:%s", __function_name, type, id);
+
+ if (NULL == (pentity = zbx_vmware_service_get_perf_entity(service, type, id)))
+ {
+ 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);
+ }
+ }
+
+ pentity = zbx_hashset_insert(&service->entities, &entity, sizeof(zbx_vmware_perf_entity_t));
+ }
+
+ pentity->last_seen = now;
+
+ zabbix_log(LOG_LEVEL_DEBUG, "End of %s() perfcounters:%d", __function_name, pentity->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;
+ zbx_hashset_iter_t iter;
+
+ 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 */
+ zbx_hashset_iter_reset(&service->entities, &iter);
+ while (NULL != (entity = zbx_hashset_iter_next(&iter)))
+ {
+ if (0 != entity->last_seen && entity->last_seen < now)
+ {
+ vmware_shared_perf_entity_clean(entity);
+ zbx_hashset_iter_remove(&iter);
+ }
+ }
+
+ zabbix_log(LOG_LEVEL_DEBUG, "End of %s() entities:%d", __function_name, service->entities.num_data);
+}
+
+/******************************************************************************
+ * *
* Function: vmware_service_update *
* *
* Purpose: updates object with a new data from vmware service *
@@ -2643,7 +2783,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 +2792,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 +2835,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 +2845,348 @@
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, valid_data = 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++;
+
+ if (0 == valid_data && 0 != strcmp(value, "-1"))
+ valid_data = 1;
+
+ break;
+ }
+ }
+ }
+
+ zbx_free(counter);
+ zbx_free(instance);
+ zbx_free(value);
+ }
+
+ /* No valid data found - all metrics has -1 value. In this case clear the counter values. */
+ if (0 == valid_data)
+ {
+ for (j = 0; j < entity->counters.values_num; j++)
+ {
+ perfcounter = (zbx_vmware_perf_counter_t *)entity->counters.values[j];
+ vmware_vector_ptr_pair_shared_clean(&perfcounter->values);
+ }
+ }
+
+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;
+ zbx_hashset_iter_t iter;
+
+ 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();
+
+ zbx_hashset_iter_reset(&service->entities, &iter);
+ while (NULL != (entity = zbx_hashset_iter_next(&iter)))
+ {
+ 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();
+
+ /* udpate entity refresh rate */
+ for (i = 0; i < entities.values_num; i++)
+ {
+ if (NULL != (entity = zbx_hashset_search(&service->entities, entities.values[i])))
+ entity->refresh = ((zbx_vmware_perf_entity_t *)entities.values[i])->refresh;
+ }
+
+ /* create performance collector request */
+ zbx_hashset_iter_reset(&service->entities, &iter);
+ while (NULL != (entity = zbx_hashset_iter_next(&iter)))
+ {
+
+ if (0 == entity->refresh)
+ {
+ zabbix_log(LOG_LEVEL_DEBUG, "skipping performance entity with zero refresh rate "
+ "type:%s id:%d", entity->type, entity->id);
+ continue;
+ }
+
+ /* 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 +3258,13 @@
service->state = ZBX_VMWARE_STATE_NEW;
service->lastaccess = now;
+ zbx_hashset_create_ext(&service->entities, 100, vmware_perf_entity_hash_func, vmware_perf_entity_compare_func,
+ NULL, __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, NULL, __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 +3341,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 +3396,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 +3417,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 +3480,97 @@
}
/******************************************************************************
+ * *
+ * 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 *pentity, entity;
+
+ zabbix_log(LOG_LEVEL_DEBUG, "In %s() type:%s id:%s counterid:" ZBX_FS_UI64, __function_name, type, id,
+ counterid);
+
+ if (NULL == (pentity = zbx_vmware_service_get_perf_entity(service, type, id)))
+ {
+ 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);
+
+ pentity = zbx_hashset_insert(&service->entities, &entity, sizeof(zbx_vmware_perf_entity_t));
+ }
+
+ if (FAIL == zbx_vector_ptr_search(&pentity->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(&pentity->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.2.orig/src/zabbix_server/vmware/vmware.h zabbix-2.4.2/src/zabbix_server/vmware/vmware.h
--- zabbix-2.4.2.orig/src/zabbix_server/vmware/vmware.h 2014-11-05 17:01:42.000000000 +0900
+++ zabbix-2.4.2/src/zabbix_server/vmware/vmware.h 2014-11-26 19:50:05.937215838 +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_hashset_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