Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/zabbix/zabbix.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog.d/feature/ZBXNEXT-12871
-rw-r--r--include/perfmon.h14
-rw-r--r--include/sysinfo.h1
-rw-r--r--src/libs/zbxsysinfo/win32/pdhmon.c21
-rw-r--r--src/libs/zbxsysinfo/win32/win32.c1
-rw-r--r--src/libs/zbxwin32/perfmon.c79
-rw-r--r--src/zabbix_agent/cpustat.c9
-rw-r--r--src/zabbix_agent/perfstat.c48
-rw-r--r--src/zabbix_agent/perfstat.h6
-rw-r--r--src/zabbix_agent/stats.c3
-rw-r--r--src/zabbix_agent/zabbix_agentd.c13
-rw-r--r--src/zabbix_agent/zbxconf.c117
-rw-r--r--src/zabbix_agent/zbxconf.h3
-rw-r--r--tests/zbxmocktest.c1
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)