diff options
-rw-r--r-- | ChangeLog.d/feature/ZBXNEXT-1287 | 1 | ||||
-rw-r--r-- | include/perfmon.h | 14 | ||||
-rw-r--r-- | include/sysinfo.h | 1 | ||||
-rw-r--r-- | src/libs/zbxsysinfo/win32/pdhmon.c | 21 | ||||
-rw-r--r-- | src/libs/zbxsysinfo/win32/win32.c | 1 | ||||
-rw-r--r-- | src/libs/zbxwin32/perfmon.c | 79 | ||||
-rw-r--r-- | src/zabbix_agent/cpustat.c | 9 | ||||
-rw-r--r-- | src/zabbix_agent/perfstat.c | 48 | ||||
-rw-r--r-- | src/zabbix_agent/perfstat.h | 6 | ||||
-rw-r--r-- | src/zabbix_agent/stats.c | 3 | ||||
-rw-r--r-- | src/zabbix_agent/zabbix_agentd.c | 13 | ||||
-rw-r--r-- | src/zabbix_agent/zbxconf.c | 117 | ||||
-rw-r--r-- | src/zabbix_agent/zbxconf.h | 3 | ||||
-rw-r--r-- | tests/zbxmocktest.c | 1 |
14 files changed, 209 insertions, 108 deletions
diff --git a/ChangeLog.d/feature/ZBXNEXT-1287 b/ChangeLog.d/feature/ZBXNEXT-1287 new file mode 100644 index 00000000000..f0ccdaa6913 --- /dev/null +++ b/ChangeLog.d/feature/ZBXNEXT-1287 @@ -0,0 +1 @@ +...G...... [ZBXNEXT-1287] added support for English performance counters on Windows (kalimulin) diff --git a/include/perfmon.h b/include/perfmon.h index 1221ff459d7..38b15ff691f 100644 --- a/include/perfmon.h +++ b/include/perfmon.h @@ -41,6 +41,13 @@ typedef enum } zbx_perf_counter_status_t; +typedef enum +{ + PERF_COUNTER_LANG_DEFAULT = 0, + PERF_COUNTER_LANG_EN +} +zbx_perf_counter_lang_t; + typedef struct perf_counter_id { struct perf_counter_id *next; @@ -55,6 +62,7 @@ typedef struct perf_counter_data char *name; char *counterpath; int interval; + zbx_perf_counter_lang_t lang; zbx_perf_counter_status_t status; HCOUNTER handle; PDH_RAW_COUNTER rawValues[2]; /* rate counters need two raw values */ @@ -69,12 +77,12 @@ zbx_perf_counter_data_t; PDH_STATUS zbx_PdhMakeCounterPath(const char *function, PDH_COUNTER_PATH_ELEMENTS *cpe, char *counterpath); PDH_STATUS zbx_PdhOpenQuery(const char *function, PDH_HQUERY query); PDH_STATUS zbx_PdhAddCounter(const char *function, zbx_perf_counter_data_t *counter, PDH_HQUERY query, - const char *counterpath, PDH_HCOUNTER *handle); + const char *counterpath, zbx_perf_counter_lang_t lang, PDH_HCOUNTER *handle); PDH_STATUS zbx_PdhCollectQueryData(const char *function, const char *counterpath, PDH_HQUERY query); PDH_STATUS zbx_PdhGetRawCounterValue(const char *function, const char *counterpath, PDH_HCOUNTER handle, PPDH_RAW_COUNTER value); -PDH_STATUS calculate_counter_value(const char *function, const char *counterpath, double *value); +PDH_STATUS calculate_counter_value(const char *function, const char *counterpath, zbx_perf_counter_lang_t lang, double *value); wchar_t *get_counter_name(DWORD pdhIndex); -int check_counter_path(char *counterPath); +int check_counter_path(char *counterPath, int convert_from_numeric); #endif /* ZABBIX_PERFMON_H */ diff --git a/include/sysinfo.h b/include/sysinfo.h index 9607d69bb74..7ca89ae939d 100644 --- a/include/sysinfo.h +++ b/include/sysinfo.h @@ -272,6 +272,7 @@ int VM_MEMORY_SIZE(AGENT_REQUEST *request, AGENT_RESULT *result); #ifdef _WINDOWS int USER_PERF_COUNTER(AGENT_REQUEST *request, AGENT_RESULT *result); int PERF_COUNTER(AGENT_REQUEST *request, AGENT_RESULT *result); +int PERF_COUNTER_EN(AGENT_REQUEST *request, AGENT_RESULT *result); int SERVICE_DISCOVERY(AGENT_REQUEST *request, AGENT_RESULT *result); int SERVICE_INFO(AGENT_REQUEST *request, AGENT_RESULT *result); int SERVICE_STATE(AGENT_REQUEST *request, AGENT_RESULT *result); diff --git a/src/libs/zbxsysinfo/win32/pdhmon.c b/src/libs/zbxsysinfo/win32/pdhmon.c index 1ae11737b92..53602b7ead4 100644 --- a/src/libs/zbxsysinfo/win32/pdhmon.c +++ b/src/libs/zbxsysinfo/win32/pdhmon.c @@ -58,13 +58,14 @@ out: return ret; } -int PERF_COUNTER(AGENT_REQUEST *request, AGENT_RESULT *result) +static int perf_counter_ex(const char *function, AGENT_REQUEST *request, AGENT_RESULT *result, + zbx_perf_counter_lang_t lang) { char counterpath[PDH_MAX_COUNTER_PATH], *tmp, *error = NULL; int interval, ret = SYSINFO_RET_FAIL; double value; - zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__); + zabbix_log(LOG_LEVEL_DEBUG, "In %s()", function); if (2 < request->nparam) { @@ -98,13 +99,13 @@ int PERF_COUNTER(AGENT_REQUEST *request, AGENT_RESULT *result) goto out; } - if (FAIL == check_counter_path(counterpath)) + if (FAIL == check_counter_path(counterpath, PERF_COUNTER_LANG_DEFAULT == lang)) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid performance counter path.")); goto out; } - if (SUCCEED != get_perf_counter_value_by_path(counterpath, interval, &value, &error)) + if (SUCCEED != get_perf_counter_value_by_path(counterpath, interval, lang, &value, &error)) { SET_MSG_RESULT(result, error != NULL ? error : zbx_strdup(NULL, "Cannot obtain performance information from collector.")); @@ -114,7 +115,17 @@ int PERF_COUNTER(AGENT_REQUEST *request, AGENT_RESULT *result) ret = SYSINFO_RET_OK; SET_DBL_RESULT(result, value); out: - zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __func__, zbx_result_string(ret)); + zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", function, zbx_result_string(ret)); return ret; } + +int PERF_COUNTER(AGENT_REQUEST *request, AGENT_RESULT *result) +{ + return perf_counter_ex(__func__, request, result, PERF_COUNTER_LANG_DEFAULT); +} + +int PERF_COUNTER_EN(AGENT_REQUEST *request, AGENT_RESULT *result) +{ + return perf_counter_ex(__func__, request, result, PERF_COUNTER_LANG_EN); +} diff --git a/src/libs/zbxsysinfo/win32/win32.c b/src/libs/zbxsysinfo/win32/win32.c index bf0a324dc65..aa4db6045a6 100644 --- a/src/libs/zbxsysinfo/win32/win32.c +++ b/src/libs/zbxsysinfo/win32/win32.c @@ -59,6 +59,7 @@ ZBX_METRIC parameters_specific[] = {"service_state", CF_HAVEPARAMS, SERVICE_STATE, ZABBIX_SERVICE_NAME}, {"services", CF_HAVEPARAMS, SERVICES, NULL}, {"perf_counter", CF_HAVEPARAMS, PERF_COUNTER, "\\System\\Processes"}, + {"perf_counter_en", CF_HAVEPARAMS, PERF_COUNTER_EN, "\\System\\Processes"}, {"proc_info", CF_HAVEPARAMS, PROC_INFO, "svchost.exe"}, {"__UserPerfCounter", CF_HAVEPARAMS, USER_PERF_COUNTER, ""}, diff --git a/src/libs/zbxwin32/perfmon.c b/src/libs/zbxwin32/perfmon.c index a87debc9524..b735e6ef7b1 100644 --- a/src/libs/zbxwin32/perfmon.c +++ b/src/libs/zbxwin32/perfmon.c @@ -73,18 +73,51 @@ PDH_STATUS zbx_PdhOpenQuery(const char *function, PDH_HQUERY query) * * ******************************************************************************/ PDH_STATUS zbx_PdhAddCounter(const char *function, zbx_perf_counter_data_t *counter, PDH_HQUERY query, - const char *counterpath, PDH_HCOUNTER *handle) + const char *counterpath, zbx_perf_counter_lang_t lang, PDH_HCOUNTER *handle) { + /* pointer type to PdhAddEnglishCounterW() */ + typedef PDH_STATUS (WINAPI *ADD_ENG_COUNTER)(PDH_HQUERY, LPCWSTR, DWORD_PTR, PDH_HCOUNTER); + PDH_STATUS pdh_status = ERROR_SUCCESS; - wchar_t *wcounterPath; + wchar_t *wcounterPath = NULL; + int need_english; + + ZBX_THREAD_LOCAL static ADD_ENG_COUNTER add_eng_counter; + ZBX_THREAD_LOCAL static int first_call = 1; + + need_english = PERF_COUNTER_LANG_DEFAULT != lang || + (NULL != counter && PERF_COUNTER_LANG_DEFAULT != counter->lang); + + /* PdhAddEnglishCounterW() is only available on Windows 2008/Vista and onwards, */ + /* so we need to resolve it dynamically and fail if it's not available */ + if (0 != first_call && 0 != need_english) + { + if (NULL == (add_eng_counter = (ADD_ENG_COUNTER)GetProcAddress(GetModuleHandle(L"PDH.DLL"), + "PdhAddEnglishCounterW"))) + { + zabbix_log(LOG_LEVEL_WARNING, "PdhAddEnglishCounter() is not available, " + "perf_counter_en[] is not supported"); + } - wcounterPath = zbx_utf8_to_unicode(counterpath); + first_call = 0; + } - if (NULL == *handle) - pdh_status = PdhAddCounter(query, wcounterPath, 0, handle); + if (0 != need_english && NULL == add_eng_counter) + { + pdh_status = PDH_NOT_IMPLEMENTED; + } if (ERROR_SUCCESS == pdh_status) - pdh_status = PdhValidatePath(wcounterPath); + { + wcounterPath = zbx_utf8_to_unicode(counterpath); + } + + if (ERROR_SUCCESS == pdh_status && NULL == *handle) + { + pdh_status = need_english ? + add_eng_counter(query, wcounterPath, 0, handle) : + PdhAddCounter(query, wcounterPath, 0, handle); + } if (ERROR_SUCCESS != pdh_status && NULL != *handle) { @@ -149,7 +182,8 @@ PDH_STATUS zbx_PdhGetRawCounterValue(const char *function, const char *counterpa * sleep 1 second to get the second raw value. * * * ******************************************************************************/ -PDH_STATUS calculate_counter_value(const char *function, const char *counterpath, double *value) +PDH_STATUS calculate_counter_value(const char *function, const char *counterpath, + zbx_perf_counter_lang_t lang, double *value) { PDH_HQUERY query; PDH_HCOUNTER handle = NULL; @@ -160,7 +194,7 @@ PDH_STATUS calculate_counter_value(const char *function, const char *counterpath if (ERROR_SUCCESS != (pdh_status = zbx_PdhOpenQuery(function, &query))) return pdh_status; - if (ERROR_SUCCESS != (pdh_status = zbx_PdhAddCounter(function, NULL, query, counterpath, &handle))) + if (ERROR_SUCCESS != (pdh_status = zbx_PdhAddCounter(function, NULL, query, counterpath, lang, &handle))) goto close_query; if (ERROR_SUCCESS != (pdh_status = zbx_PdhCollectQueryData(function, counterpath, query))) @@ -249,11 +283,11 @@ wchar_t *get_counter_name(DWORD pdhIndex) return counterName->name; } -int check_counter_path(char *counterPath) +int check_counter_path(char *counterPath, int convert_from_numeric) { PDH_COUNTER_PATH_ELEMENTS *cpe = NULL; PDH_STATUS status; - int is_numeric, ret = FAIL; + int ret = FAIL; DWORD dwSize = 0; wchar_t *wcounterPath; @@ -278,20 +312,23 @@ int check_counter_path(char *counterPath) goto clean; } - is_numeric = (SUCCEED == _wis_uint(cpe->szObjectName) ? 0x01 : 0); - is_numeric |= (SUCCEED == _wis_uint(cpe->szCounterName) ? 0x02 : 0); - - if (0 != is_numeric) + if (0 != convert_from_numeric) { - if (0x01 & is_numeric) - cpe->szObjectName = get_counter_name(_wtoi(cpe->szObjectName)); - if (0x02 & is_numeric) - cpe->szCounterName = get_counter_name(_wtoi(cpe->szCounterName)); + int is_numeric = (SUCCEED == _wis_uint(cpe->szObjectName) ? 0x01 : 0); + is_numeric |= (SUCCEED == _wis_uint(cpe->szCounterName) ? 0x02 : 0); - if (ERROR_SUCCESS != zbx_PdhMakeCounterPath(__func__, cpe, counterPath)) - goto clean; + if (0 != is_numeric) + { + if (0x01 & is_numeric) + cpe->szObjectName = get_counter_name(_wtoi(cpe->szObjectName)); + if (0x02 & is_numeric) + cpe->szCounterName = get_counter_name(_wtoi(cpe->szCounterName)); - zabbix_log(LOG_LEVEL_DEBUG, "counter path converted to '%s'", counterPath); + if (ERROR_SUCCESS != zbx_PdhMakeCounterPath(__func__, cpe, counterPath)) + goto clean; + + zabbix_log(LOG_LEVEL_DEBUG, "counter path converted to '%s'", counterPath); + } } ret = SUCCEED; diff --git a/src/zabbix_agent/cpustat.c b/src/zabbix_agent/cpustat.c index e63148d8c41..74705d300c1 100644 --- a/src/zabbix_agent/cpustat.c +++ b/src/zabbix_agent/cpustat.c @@ -134,7 +134,7 @@ int init_cpu_collector(ZBX_CPUS_STAT_DATA *pcpus) cpe.szObjectName = get_counter_name(PCI_PROCESSOR); cpe.szInstanceName = cpu; cpe.szParentInstance = NULL; - cpe.dwInstanceIndex = -1; + cpe.dwInstanceIndex = (DWORD)-1; cpe.szCounterName = get_counter_name(PCI_PROCESSOR_TIME); for (idx = 0; idx <= pcpus->count; idx++) @@ -148,7 +148,7 @@ int init_cpu_collector(ZBX_CPUS_STAT_DATA *pcpus) goto clean; if (NULL == (pcpus->cpu_counter[idx] = add_perf_counter(NULL, counterPath, MAX_COLLECTOR_PERIOD, - &error))) + PERF_COUNTER_LANG_DEFAULT, &error))) { goto clean; } @@ -161,8 +161,11 @@ int init_cpu_collector(ZBX_CPUS_STAT_DATA *pcpus) if (ERROR_SUCCESS != zbx_PdhMakeCounterPath(__func__, &cpe, counterPath)) goto clean; - if (NULL == (pcpus->queue_counter = add_perf_counter(NULL, counterPath, MAX_COLLECTOR_PERIOD, &error))) + if (NULL == (pcpus->queue_counter = add_perf_counter(NULL, counterPath, MAX_COLLECTOR_PERIOD, + PERF_COUNTER_LANG_DEFAULT, &error))) + { goto clean; + } ret = SUCCEED; clean: diff --git a/src/zabbix_agent/perfstat.c b/src/zabbix_agent/perfstat.c index b6d7a466514..cb525f6b048 100644 --- a/src/zabbix_agent/perfstat.c +++ b/src/zabbix_agent/perfstat.c @@ -68,7 +68,8 @@ static void deactivate_perf_counter(zbx_perf_counter_data_t *counter) * added, a pointer to that counter is returned, NULL otherwise * * * ******************************************************************************/ -zbx_perf_counter_data_t *add_perf_counter(const char *name, const char *counterpath, int interval, char **error) +zbx_perf_counter_data_t *add_perf_counter(const char *name, const char *counterpath, int interval, + zbx_perf_counter_lang_t lang, char **error) { zbx_perf_counter_data_t *cptr = NULL; PDH_STATUS pdh_status; @@ -97,11 +98,13 @@ zbx_perf_counter_data_t *add_perf_counter(const char *name, const char *counterp cptr->name = zbx_strdup(NULL, name); cptr->counterpath = zbx_strdup(NULL, counterpath); cptr->interval = interval; + cptr->lang = lang; cptr->value_current = -1; cptr->value_array = (double *)zbx_malloc(cptr->value_array, sizeof(double) * interval); /* add the counter to the query */ - pdh_status = zbx_PdhAddCounter(__func__, cptr, ppsd.pdh_query, counterpath, &cptr->handle); + pdh_status = zbx_PdhAddCounter(__func__, cptr, ppsd.pdh_query, counterpath, + lang, &cptr->handle); cptr->next = ppsd.pPerfCounterList; ppsd.pPerfCounterList = cptr; @@ -116,18 +119,23 @@ zbx_perf_counter_data_t *add_perf_counter(const char *name, const char *counterp break; } - if (NULL != name && 0 == strcmp(cptr->name, name)) - break; - - if (NULL == name && 0 == strcmp(cptr->counterpath, counterpath) && cptr->interval == interval) + if (NULL != name) + { + if (0 == strcmp(cptr->name, name)) + break; + } + else if (0 == strcmp(cptr->counterpath, counterpath) && + cptr->interval == interval && cptr->lang == lang) + { break; + } } if (FAIL == added) { zabbix_log(LOG_LEVEL_DEBUG, "%s() counter '%s' already exists", __func__, counterpath); } - else if (NULL != name) + else if (NULL != name && NULL != cptr) { char *alias_name; @@ -352,7 +360,8 @@ void collect_perfstat(void) if (PERF_COUNTER_NOTSUPPORTED != cptr->status) continue; - zbx_PdhAddCounter(__func__, cptr, ppsd.pdh_query, cptr->counterpath, &cptr->handle); + zbx_PdhAddCounter(__func__, cptr, ppsd.pdh_query, cptr->counterpath, + cptr->lang, &cptr->handle); } ppsd.nextcheck = now + UNSUPPORTED_REFRESH_PERIOD; @@ -462,7 +471,9 @@ out: * * * Parameters: name - [IN] the performance counter name * * value - [OUT] the calculated value * - * error - [OUT] the error message * + * error - [OUT] the error message, it is not always produced * + * when FAIL is returned. It is a caller responsibility * + * to check if the error message is not NULL. * * * * Returns: SUCCEED - the value was retrieved successfully * * FAIL - otherwise * @@ -516,7 +527,11 @@ out: if (NULL != counterpath) { /* request counter value directly from Windows performance counters */ - if (ERROR_SUCCESS == calculate_counter_value(__func__, counterpath, value)) + PDH_STATUS pdh_status = calculate_counter_value(__func__, counterpath, perfs->lang, value); + + if (PDH_NOT_IMPLEMENTED == pdh_status) + *error = zbx_strdup(*error, "Counter is not supported for this Microsoft Windows version"); + else if (ERROR_SUCCESS == pdh_status) ret = SUCCEED; zbx_free(counterpath); @@ -535,6 +550,7 @@ out: * * * Parameters: counterpath - [IN] the performance counter path * * interval - [IN] the data collection interval in seconds * + * lang - [IN] counterpath language (default or English) * * value - [OUT] the calculated value * * error - [OUT] the error message * * * @@ -546,12 +562,14 @@ out: * possible. * * * ******************************************************************************/ -int get_perf_counter_value_by_path(const char *counterpath, int interval, double *value, char **error) +int get_perf_counter_value_by_path(const char *counterpath, int interval, zbx_perf_counter_lang_t lang, + double *value, char **error) { int ret = FAIL; zbx_perf_counter_data_t *perfs = NULL; - zabbix_log(LOG_LEVEL_DEBUG, "In %s() path:%s interval:%d", __func__, counterpath, interval); + zabbix_log(LOG_LEVEL_DEBUG, "In %s() path:%s interval:%d lang:%d", __func__, counterpath, + interval, lang); LOCK_PERFCOUNTERS; @@ -563,7 +581,7 @@ int get_perf_counter_value_by_path(const char *counterpath, int interval, double for (perfs = ppsd.pPerfCounterList; NULL != perfs; perfs = perfs->next) { - if (0 == strcmp(perfs->counterpath, counterpath)) + if (0 == strcmp(perfs->counterpath, counterpath) && perfs->lang == lang) { if (perfs->interval < interval) extend_perf_counter_interval(perfs, interval); @@ -580,14 +598,14 @@ int get_perf_counter_value_by_path(const char *counterpath, int interval, double /* if the requested counter is not already being monitored - start monitoring */ if (NULL == perfs) - perfs = add_perf_counter(NULL, counterpath, interval, error); + perfs = add_perf_counter(NULL, counterpath, interval, lang, error); out: UNLOCK_PERFCOUNTERS; if (SUCCEED != ret && NULL != perfs) { /* request counter value directly from Windows performance counters */ - if (ERROR_SUCCESS == calculate_counter_value(__func__, counterpath, value)) + if (ERROR_SUCCESS == calculate_counter_value(__func__, counterpath, lang, value)) ret = SUCCEED; } diff --git a/src/zabbix_agent/perfstat.h b/src/zabbix_agent/perfstat.h index 8c8a109299b..0984a6a2b62 100644 --- a/src/zabbix_agent/perfstat.h +++ b/src/zabbix_agent/perfstat.h @@ -26,7 +26,8 @@ #include "perfmon.h" -zbx_perf_counter_data_t *add_perf_counter(const char *name, const char *counterpath, int interval, char **error); +zbx_perf_counter_data_t *add_perf_counter(const char *name, const char *counterpath, int interval, + zbx_perf_counter_lang_t lang, char **error); void remove_perf_counter(zbx_perf_counter_data_t *counter); typedef enum @@ -41,7 +42,8 @@ void free_perf_collector(void); void collect_perfstat(void); int get_perf_counter_value_by_name(const char *name, double *value, char **error); -int get_perf_counter_value_by_path(const char *counterpath, int interval, double *value, char **error); +int get_perf_counter_value_by_path(const char *counterpath, int interval, zbx_perf_counter_lang_t lang, + double *value, char **error); int get_perf_counter_value(zbx_perf_counter_data_t *counter, int interval, double *value, char **error); #endif diff --git a/src/zabbix_agent/stats.c b/src/zabbix_agent/stats.c index c5bf6d45f82..9a84bf15b04 100644 --- a/src/zabbix_agent/stats.c +++ b/src/zabbix_agent/stats.c @@ -168,6 +168,9 @@ int init_collector_data(char **error) sz = ZBX_SIZE_T_ALIGN8(sizeof(ZBX_COLLECTOR_DATA)); #ifdef _WINDOWS + + ZBX_UNUSED(error); + sz_cpu = sizeof(zbx_perf_counter_data_t *) * (cpu_count + 1); collector = zbx_malloc(collector, sz + sz_cpu); diff --git a/src/zabbix_agent/zabbix_agentd.c b/src/zabbix_agent/zabbix_agentd.c index 761ff8eab14..8e6e4dad128 100644 --- a/src/zabbix_agent/zabbix_agentd.c +++ b/src/zabbix_agent/zabbix_agentd.c @@ -55,6 +55,7 @@ char **CONFIG_LOAD_MODULE = NULL; char **CONFIG_USER_PARAMETERS = NULL; #if defined(_WINDOWS) char **CONFIG_PERF_COUNTERS = NULL; +char **CONFIG_PERF_COUNTERS_EN = NULL; #endif char *CONFIG_USER = NULL; @@ -421,7 +422,7 @@ static int parse_commandline(int argc, char **argv, ZBX_TASK_EX *t) for (i = 0; NULL != longopts[i].name; i++) { - ch = longopts[i].val; + ch = (char)longopts[i].val; if ('h' == ch || 'V' == ch) continue; @@ -711,7 +712,7 @@ static int add_serveractive_host_cb(const char *host, unsigned short port) ******************************************************************************/ static void zbx_load_config(int requirement, ZBX_TASK_EX *task) { - char *active_hosts = NULL; + static char *active_hosts; struct cfg_line cfg[] = { @@ -786,6 +787,8 @@ static void zbx_load_config(int requirement, ZBX_TASK_EX *task) #ifdef _WINDOWS {"PerfCounter", &CONFIG_PERF_COUNTERS, TYPE_MULTISTRING, PARM_OPT, 0, 0}, + {"PerfCounterEn", &CONFIG_PERF_COUNTERS_EN, TYPE_MULTISTRING, + PARM_OPT, 0, 0}, #endif {"TLSConnect", &CONFIG_TLS_CONNECT, TYPE_STRING, PARM_OPT, 0, 0}, @@ -818,6 +821,7 @@ static void zbx_load_config(int requirement, ZBX_TASK_EX *task) #endif #ifdef _WINDOWS zbx_strarr_init(&CONFIG_PERF_COUNTERS); + zbx_strarr_init(&CONFIG_PERF_COUNTERS_EN); #endif parse_cfg_file(CONFIG_FILE, cfg, requirement, ZBX_CFG_STRICT); @@ -857,6 +861,7 @@ static void zbx_free_config(void) #endif #ifdef _WINDOWS zbx_strarr_free(CONFIG_PERF_COUNTERS); + zbx_strarr_free(CONFIG_PERF_COUNTERS_EN); #endif } @@ -976,7 +981,7 @@ int MAIN_ZABBIX_ENTRY(int flags) exit(EXIT_FAILURE); } - load_perf_counters(CONFIG_PERF_COUNTERS); + load_perf_counters(CONFIG_PERF_COUNTERS, CONFIG_PERF_COUNTERS_EN); #endif zbx_free_config(); @@ -1222,7 +1227,7 @@ int main(int argc, char **argv) exit(EXIT_FAILURE); } - load_perf_counters(CONFIG_PERF_COUNTERS); + load_perf_counters(CONFIG_PERF_COUNTERS, CONFIG_PERF_COUNTERS_EN); #else zbx_set_common_signal_handlers(); #endif diff --git a/src/zabbix_agent/zbxconf.c b/src/zabbix_agent/zbxconf.c index 143f2296a32..d1228128c3e 100644 --- a/src/zabbix_agent/zbxconf.c +++ b/src/zabbix_agent/zbxconf.c @@ -116,7 +116,8 @@ void load_user_parameters(char **lines) * * * Purpose: load performance counters from configuration * * * - * Parameters: lines - array of PerfCounter configuration entries * + * Parameters: def_lines - array of PerfCounter configuration entries * + * eng_lines - array of PerfCounterEn configuration entries * * * * Return value: * * * @@ -125,71 +126,79 @@ void load_user_parameters(char **lines) * Comments: * * * ******************************************************************************/ -void load_perf_counters(const char **lines) +void load_perf_counters(const char **def_lines, const char **eng_lines) { char name[MAX_STRING_LEN], counterpath[PDH_MAX_COUNTER_PATH], interval[8]; - const char **pline; + const char **pline, **lines; char *error = NULL; LPTSTR wcounterPath; int period; - for (pline = lines; NULL != *pline; pline++) + for (lines = def_lines;; lines = eng_lines) { - if (3 < num_param(*pline)) - { - error = zbx_strdup(error, "Required parameter missing."); - goto pc_fail; - } - - if (0 != get_param(*pline, 1, name, sizeof(name))) - { - error = zbx_strdup(error, "Cannot parse key."); - goto pc_fail; - } + zbx_perf_counter_lang_t lang = (lines == def_lines) ? PERF_COUNTER_LANG_DEFAULT : PERF_COUNTER_LANG_EN; - if (0 != get_param(*pline, 2, counterpath, sizeof(counterpath))) + for (pline = lines; NULL != *pline; pline++) { - error = zbx_strdup(error, "Cannot parse counter path."); - goto pc_fail; - } - - if (0 != get_param(*pline, 3, interval, sizeof(interval))) - { - error = zbx_strdup(error, "Cannot parse interval."); - goto pc_fail; - } - - wcounterPath = zbx_acp_to_unicode(counterpath); - zbx_unicode_to_utf8_static(wcounterPath, counterpath, PDH_MAX_COUNTER_PATH); - zbx_free(wcounterPath); + if (3 < num_param(*pline)) + { + error = zbx_strdup(error, "Required parameter missing."); + goto pc_fail; + } + + if (0 != get_param(*pline, 1, name, sizeof(name))) + { + error = zbx_strdup(error, "Cannot parse key."); + goto pc_fail; + } + + if (0 != get_param(*pline, 2, counterpath, sizeof(counterpath))) + { + error = zbx_strdup(error, "Cannot parse counter path."); + goto pc_fail; + } + + if (0 != get_param(*pline, 3, interval, sizeof(interval))) + { + error = zbx_strdup(error, "Cannot parse interval."); + goto pc_fail; + } + + wcounterPath = zbx_acp_to_unicode(counterpath); + zbx_unicode_to_utf8_static(wcounterPath, counterpath, PDH_MAX_COUNTER_PATH); + zbx_free(wcounterPath); + + if (FAIL == check_counter_path(counterpath, lang == PERF_COUNTER_LANG_DEFAULT)) + { + error = zbx_strdup(error, "Invalid counter path."); + goto pc_fail; + } + + period = atoi(interval); + + if (1 > period || MAX_COLLECTOR_PERIOD < period) + { + error = zbx_strdup(NULL, "Interval out of range."); + goto pc_fail; + } + + if (NULL == add_perf_counter(name, counterpath, period, lang, &error)) + { + if (NULL == error) + error = zbx_strdup(error, "Failed to add new performance counter."); + goto pc_fail; + } + + continue; + pc_fail: + zabbix_log(LOG_LEVEL_CRIT, "cannot add performance counter \"%s\": %s", *pline, error); + zbx_free(error); - if (FAIL == check_counter_path(counterpath)) - { - error = zbx_strdup(error, "Invalid counter path."); - goto pc_fail; - } - - period = atoi(interval); - - if (1 > period || MAX_COLLECTOR_PERIOD < period) - { - error = zbx_strdup(NULL, "Interval out of range."); - goto pc_fail; - } - - if (NULL == add_perf_counter(name, counterpath, period, &error)) - { - if (NULL == error) - error = zbx_strdup(error, "Failed to add new performance counter."); - goto pc_fail; + exit(EXIT_FAILURE); } - continue; -pc_fail: - zabbix_log(LOG_LEVEL_CRIT, "cannot add performance counter \"%s\": %s", *pline, error); - zbx_free(error); - - exit(EXIT_FAILURE); + if (lines == eng_lines) + break; } } #endif /* _WINDOWS */ diff --git a/src/zabbix_agent/zbxconf.h b/src/zabbix_agent/zbxconf.h index 60902558a05..3e1a5111f5a 100644 --- a/src/zabbix_agent/zbxconf.h +++ b/src/zabbix_agent/zbxconf.h @@ -38,6 +38,7 @@ extern char *CONFIG_LOAD_MODULE_PATH; extern char **CONFIG_LOAD_MODULE; #ifdef _WINDOWS extern char **CONFIG_PERF_COUNTERS; +extern char **CONFIG_PERF_COUNTERS_EN; #endif extern char *CONFIG_USER; @@ -58,7 +59,7 @@ extern char *CONFIG_TLS_PSK_FILE; void load_aliases(char **lines); void load_user_parameters(char **lines); #ifdef _WINDOWS -void load_perf_counters(const char **lines); +void load_perf_counters(const char **def_lines, const char **eng_lines); #endif #ifdef _AIX diff --git a/tests/zbxmocktest.c b/tests/zbxmocktest.c index 6190c27f876..2c6ccc5a1c1 100644 --- a/tests/zbxmocktest.c +++ b/tests/zbxmocktest.c @@ -175,6 +175,7 @@ char **CONFIG_ALIASES = NULL; char **CONFIG_USER_PARAMETERS = NULL; #if defined(_WINDOWS) char **CONFIG_PERF_COUNTERS = NULL; +char **CONFIG_PERF_COUNTERS_EN = NULL; #endif void zbx_on_exit(int ret) |