summaryrefslogtreecommitdiffstats
path: root/src/zabbix_agent
diff options
context:
space:
mode:
authorosmiy <osmiy@97f52cf1-0a1b-0410-bd0e-c28be96e8082>2007-06-13 14:41:14 +0000
committerosmiy <osmiy@97f52cf1-0a1b-0410-bd0e-c28be96e8082>2007-06-13 14:41:14 +0000
commitbec21c0f84c702cc67c101ee555cff097464e4b3 (patch)
treef53e2e55b10687b99014b2e2d222aa4959e2adf6 /src/zabbix_agent
parenta26125e9ddda1db970c968fbe68ff223bd1f6b5f (diff)
downloadzabbix-bec21c0f84c702cc67c101ee555cff097464e4b3.tar.gz
zabbix-bec21c0f84c702cc67c101ee555cff097464e4b3.tar.xz
zabbix-bec21c0f84c702cc67c101ee555cff097464e4b3.zip
- added PerfCounter configuration parameter (Eugene)
git-svn-id: svn://svn.zabbix.com/trunk@4279 97f52cf1-0a1b-0410-bd0e-c28be96e8082
Diffstat (limited to 'src/zabbix_agent')
-rw-r--r--src/zabbix_agent/Makefile.am3
-rw-r--r--src/zabbix_agent/cpustat.c6
-rw-r--r--src/zabbix_agent/perfstat.c366
-rw-r--r--src/zabbix_agent/perfstat.h65
-rw-r--r--src/zabbix_agent/stats.c17
-rw-r--r--src/zabbix_agent/stats.h2
-rw-r--r--src/zabbix_agent/zbxconf.c7
7 files changed, 449 insertions, 17 deletions
diff --git a/src/zabbix_agent/Makefile.am b/src/zabbix_agent/Makefile.am
index c0aa43c6..9c8e57c0 100644
--- a/src/zabbix_agent/Makefile.am
+++ b/src/zabbix_agent/Makefile.am
@@ -23,7 +23,8 @@ zabbix_agent_SOURCES = \
cpustat.c cpustat.h \
diskdevices.c diskdevices.h \
interfaces.c interfaces.h \
- zbxconf.c zbxconf.h
+ zbxconf.c zbxconf.h \
+ perfstat.c perfstat.h
zabbix_agent_LDADD = $(agents_ldadd)
diff --git a/src/zabbix_agent/cpustat.c b/src/zabbix_agent/cpustat.c
index c5ebd9b1..be10952f 100644
--- a/src/zabbix_agent/cpustat.c
+++ b/src/zabbix_agent/cpustat.c
@@ -75,7 +75,7 @@ int init_cpu_collector(ZBX_CPUS_STAT_DATA *pcpus)
counter_path, 0,
&pcpus->cpu[0].usage_couter)))
{
- zabbix_log( LOG_LEVEL_ERR, "Unable to add performance counter \"%s\" to query: %s", strerror_from_module(status,"PDH.DLL"));
+ zabbix_log( LOG_LEVEL_ERR, "Unable to add performance counter \"%s\" to query: %s", counter_path, strerror_from_module(status,"PDH.DLL"));
return 2;
}
@@ -88,7 +88,7 @@ int init_cpu_collector(ZBX_CPUS_STAT_DATA *pcpus)
counter_path,0,
&pcpus->cpu[i].usage_couter)))
{
- zabbix_log( LOG_LEVEL_ERR, "Unable to add performance counter \"%s\" to query: %s", strerror_from_module(status,"PDH.DLL"));
+ zabbix_log( LOG_LEVEL_ERR, "Unable to add performance counter \"%s\" to query: %s", counter_path, strerror_from_module(status,"PDH.DLL"));
return 2;
}
}
@@ -110,7 +110,7 @@ int init_cpu_collector(ZBX_CPUS_STAT_DATA *pcpus)
/* Prepare for CPU execution queue usage collection */
if (ERROR_SUCCESS != (status = PdhAddCounter(pcpus->pdh_query, counter_path, 0, &pcpus->queue_counter)))
{
- zabbix_log( LOG_LEVEL_ERR, "Unable to add performance counter \"%s\" to query: %s", strerror_from_module(status,"PDH.DLL"));
+ zabbix_log( LOG_LEVEL_ERR, "Unable to add performance counter \"%s\" to query: %s", counter_path, strerror_from_module(status,"PDH.DLL"));
return 2;
}
diff --git a/src/zabbix_agent/perfstat.c b/src/zabbix_agent/perfstat.c
new file mode 100644
index 00000000..a2b8f59c
--- /dev/null
+++ b/src/zabbix_agent/perfstat.c
@@ -0,0 +1,366 @@
+/*
+** ZABBIX
+** Copyright (C) 2000-2005 SIA Zabbix
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+**/
+
+#include "common.h"
+#include "perfstat.h"
+#include "alias.h"
+
+#include "log.h"
+
+#ifdef _WINDOWS
+ #include "perfmon.h"
+#endif /* _WINDOWS */
+
+/* Static data */
+
+static PERF_COUNTERS *statPerfCounterList=NULL;
+
+/******************************************************************************
+ * *
+ * Function: add_perf_counter *
+ * *
+ * Purpose: Add PerfCounter in to the list of *
+ * *
+ * Parameters: name - name of perfcounter *
+ * counterPath - system perfcounter name *
+ * interval - update interval *
+ * *
+ * Return value: SUCCEED on success or FAIL in other cases *
+ * *
+ * Author: Eugene Grigorjev *
+ * *
+ * Comments: *
+ * *
+ ******************************************************************************/
+static int add_perf_counter(const char *name, const char *counterPath, int interval)
+{
+ PERF_COUNTERS *perfs = NULL;
+ int result = FAIL;
+ char *alias_name = NULL;
+
+ assert(name);
+ assert(counterPath);
+
+ if( interval < 1 || interval > 1800 )
+ {
+ zabbix_log( LOG_LEVEL_WARNING, "PerfCounter FAILED. [%s] (Interval value out of range)", name);
+ return FAIL;
+ }
+
+ for(perfs = statPerfCounterList; ; perfs=perfs->next)
+ {
+ /* Add new parameters */
+ if(perfs == NULL)
+ {
+ perfs = (PERF_COUNTERS *)zbx_malloc(sizeof(PERF_COUNTERS));
+ if (NULL != perfs)
+ {
+ memset(perfs,0,sizeof(PERF_COUNTERS));
+ perfs->name = strdup(name);
+ perfs->counterPath = strdup(counterPath);
+ perfs->interval = interval;
+ perfs->rawValueArray = (PDH_RAW_COUNTER *)zbx_malloc(sizeof(PDH_RAW_COUNTER) * interval);
+ perfs->CurrentCounter = 0;
+ perfs->CurrentNum = 1;
+
+ perfs->next = statPerfCounterList;
+ statPerfCounterList = perfs;
+
+ zabbix_log( LOG_LEVEL_DEBUG, "PerfCounter added. [%s] [%s] [%i]", name, counterPath, interval);
+ result = SUCCEED;
+ }
+ break;
+ }
+
+ /* Replace existing parameters */
+ if (strcmp(perfs->name, name) == 0)
+ {
+ zbx_free(perfs->name);
+ zbx_free(perfs->counterPath);
+ zbx_free(perfs->rawValueArray);
+
+ memset(perfs,0,sizeof(PERF_COUNTERS));
+ perfs->name = strdup(name);
+ perfs->counterPath = strdup(counterPath);
+ perfs->interval = interval;
+ perfs->rawValueArray = (PDH_RAW_COUNTER *)zbx_malloc(sizeof(PDH_RAW_COUNTER) * interval);
+ perfs->CurrentCounter = 0;
+ perfs->CurrentNum = 1;
+
+ perfs->next = statPerfCounterList;
+ statPerfCounterList = perfs;
+
+ zabbix_log( LOG_LEVEL_DEBUG, "PerfCounter replaced. [%s] [%s] [%i]", name, counterPath, interval);
+ result = SUCCEED;
+ }
+ }
+
+ if( SUCCEED == result )
+ {
+ alias_name = zbx_dsprintf(NULL, "__UserPerfCounter[%s]", name);
+
+ result = add_alias(name, alias_name);
+
+ zbx_free(alias_name);
+ }
+ else
+ {
+ zabbix_log( LOG_LEVEL_WARNING, "PerfCounter FAILED. [%s] -> [%s]", name, counterPath);
+ }
+
+ return result;
+}
+
+/******************************************************************************
+ * *
+ * Function: add_perfs_from_config *
+ * *
+ * Purpose: parse config parameter 'PerfCounter' *
+ * *
+ * Parameters: line - line for parsing *
+ * *
+ * Return value: SUCCEED on success or FAIL in other cases *
+ * *
+ * Author: Eugene Grigorjev *
+ * *
+ * Comments: format of input line is - name,"perfcounter name",interval *
+ * *
+ ******************************************************************************/
+int add_perfs_from_config(char *line)
+{
+ char
+ *name = NULL,
+ *counterPath = NULL,
+ *interval = NULL;
+
+ name = line;
+ counterPath = strchr(line,',');
+ if(NULL == counterPath)
+ goto lbl_syntax_error;
+
+ *counterPath = '\0';
+ counterPath++;
+
+ if ( *counterPath != '"' )
+ goto lbl_syntax_error;
+
+ counterPath++;
+
+ interval = strrchr(counterPath,',');
+ if(NULL == interval)
+ goto lbl_syntax_error;
+
+ interval--;
+ if ( *interval != '"' )
+ goto lbl_syntax_error;
+
+ *interval = '\0';
+ interval++;
+
+ *interval = '\0';
+ interval++;
+
+ return add_perf_counter(name, counterPath, atoi(interval));
+
+lbl_syntax_error:
+
+ return FAIL;
+}
+
+/******************************************************************************
+ * *
+ * Function: perfs_list_free *
+ * *
+ * Purpose: free PerfCounter list *
+ * *
+ * Return value: *
+ * *
+ * Author: Eugene Grigorjev *
+ * *
+ * Comments: *
+ * *
+ ******************************************************************************/
+void perfs_list_free(void)
+{
+ PERF_COUNTERS *curr;
+ PERF_COUNTERS *next;
+
+ next = statPerfCounterList;
+ while(next!=NULL)
+ {
+ curr = next;
+ next = curr->next;
+ zbx_free(curr->name);
+ zbx_free(curr->counterPath);
+ zbx_free(curr->rawValueArray);
+ zbx_free(curr);
+ }
+}
+
+
+
+
+/******************************************************************************
+ * *
+ * Function: init_perf_collector *
+ * *
+ * Purpose: Initialize statistic structure and prepare state *
+ * for data calculation *
+ * *
+ * Parameters: pperf - pointer to the structure *
+ * of ZBX_PERF_STAT_DATA type *
+ * *
+ * Return value: If the function succeeds, the return 0, *
+ * great than 0 on an error *
+ * *
+ * Author: Eugene Grigorjev *
+ * *
+ * Comments: *
+ * *
+ ******************************************************************************/
+
+int init_perf_collector(ZBX_PERF_STAT_DATA *pperf)
+{
+#ifdef _WINDOWS
+
+ PERF_COUNTERS *cptr = NULL;
+ PDH_STATUS status;
+
+ memset(pperf, 0, sizeof(ZBX_PERF_STAT_DATA));
+
+ pperf->pPerfCounterList = statPerfCounterList;
+
+ if (PdhOpenQuery(NULL,0,&pperf->pdh_query)!=ERROR_SUCCESS)
+ {
+ zabbix_log( LOG_LEVEL_ERR, "Call to PdhOpenQuery() failed: %s", strerror_from_system(GetLastError()));
+ return 1;
+ }
+
+ /* Add user counters to query */
+ for ( cptr = statPerfCounterList; cptr != NULL; cptr = cptr->next )
+ {
+ if (ERROR_SUCCESS != (status = PdhAddCounter(
+ pperf->pdh_query,
+ cptr->counterPath, 0,
+ &cptr->handle)))
+ {
+ cptr->interval = -1; /* Flag for unsupported counters */
+ cptr->lastValue = NOTSUPPORTED;
+
+ zabbix_log( LOG_LEVEL_ERR, "Unable to add performance counter \"%s\" to query: %s", cptr->counterPath, strerror_from_module(status,"PDH.DLL"));
+ }
+ }
+
+#endif /* _WINDOWS */
+
+ return 0;
+}
+
+/******************************************************************************
+ * *
+ * Function: close_perf_collector *
+ * *
+ * Purpose: Clear state of data calculation *
+ * *
+ * Parameters: pperf - pointer to the structure *
+ * of ZBX_PERF_STAT_DATA type *
+ * *
+ * Return value: *
+ * *
+ * Author: Eugene Grigorjev *
+ * *
+ * Comments: *
+ * *
+ ******************************************************************************/
+
+void close_perf_collector(ZBX_PERF_STAT_DATA *pperf)
+{
+#ifdef _WINDOWS
+ PERF_COUNTERS *cptr = NULL;
+
+ for ( cptr = statPerfCounterList; cptr != NULL; cptr = cptr->next )
+ {
+ if(cptr->handle)
+ {
+ PdhRemoveCounter(cptr->handle);
+ cptr->handle = NULL;
+ }
+ }
+
+ if( pperf->pdh_query )
+ {
+ PdhCloseQuery(pperf->pdh_query);
+ pperf->pdh_query = NULL;
+ }
+
+#endif /* _WINDOWS */
+
+}
+
+void collect_perfstat(ZBX_PERF_STAT_DATA *pperf)
+{
+#ifdef _WINDOWS
+ PERF_COUNTERS *cptr = NULL;
+ PDH_STATISTICS statData;
+ PDH_STATUS status;
+
+ if ( pperf->pdh_query )
+ {
+ if ((status = PdhCollectQueryData(pperf->pdh_query)) != ERROR_SUCCESS)
+ {
+ zabbix_log( LOG_LEVEL_ERR, "Call to PdhCollectQueryData() failed: %s", strerror_from_module(status,"PDH.DLL"));
+ return;
+ }
+
+ /* Process user-defined counters */
+ for ( cptr = statPerfCounterList; cptr != NULL; cptr = cptr->next )
+ {
+ if ( cptr->handle && cptr->interval > 0 ) /* Active counter? */
+ {
+ PdhGetRawCounterValue(
+ cptr->handle,
+ NULL,
+ &cptr->rawValueArray[cptr->CurrentCounter]
+ );
+
+ cptr->CurrentCounter++;
+
+ if ( cptr->CurrentCounter >= cptr->interval )
+ cptr->CurrentCounter = 0;
+
+ PdhComputeCounterStatistics(
+ cptr->handle,
+ PDH_FMT_DOUBLE,
+ (cptr->CurrentNum < cptr->interval) ? 0 : cptr->CurrentCounter,
+ cptr->CurrentNum,
+ cptr->rawValueArray,
+ &statData
+ );
+
+ cptr->lastValue = statData.mean.doubleValue;
+zabbix_log( LOG_LEVEL_DEBUG, "NEW_VALUE: [%s] (%i of %i) [%lf]", cptr->name, cptr->CurrentCounter, cptr->CurrentNum, cptr->lastValue);
+
+ if(cptr->CurrentNum < cptr->interval)
+ cptr->CurrentNum++;
+ }
+ }
+ }
+
+#endif /* _WINDOWS */
+}
diff --git a/src/zabbix_agent/perfstat.h b/src/zabbix_agent/perfstat.h
new file mode 100644
index 00000000..0a935683
--- /dev/null
+++ b/src/zabbix_agent/perfstat.h
@@ -0,0 +1,65 @@
+/*
+** ZABBIX
+** Copyright (C) 2000-2005 SIA Zabbix
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+**/
+
+#ifndef ZABBIX_PERFSTAT_H
+#define ZABBIX_PERFSTAT_H
+
+#if defined (_WINDOWS)
+
+ #include "perfmon.h"
+
+ struct zbx_perfs
+ {
+ struct zbx_perfs *next;
+ char *name;
+ char *counterPath;
+ int interval;
+ PDH_RAW_COUNTER *rawValueArray;
+ HCOUNTER handle;
+ double lastValue;
+ int CurrentCounter;
+ int CurrentNum;
+ };
+
+ typedef struct zbx_perfs PERF_COUNTERS;
+
+ typedef struct s_perfs_stat_data
+ {
+ PERF_COUNTERS *pPerfCounterList;
+ HQUERY pdh_query;
+ } ZBX_PERF_STAT_DATA;
+
+int init_perf_collector(ZBX_PERF_STAT_DATA *pperf);
+void collect_perfstat(ZBX_PERF_STAT_DATA *pcpus);
+void close_perf_collector(ZBX_PERF_STAT_DATA *pcpus);
+
+#else /* not _WINDOWS */
+
+#define PERF_COUNTERS unsigned char
+
+#define init_perf_collector(a)
+#define collect_perfstat(a);
+#define close_perf_collector(a);
+
+#endif /* _WINDOWS */
+
+int add_perfs_from_config(char *line);
+void perfs_list_free(void);
+
+#endif /* ZABBIX_PERFSTAT_H */
diff --git a/src/zabbix_agent/stats.c b/src/zabbix_agent/stats.c
index c158e382..226464fc 100644
--- a/src/zabbix_agent/stats.c
+++ b/src/zabbix_agent/stats.c
@@ -27,6 +27,7 @@
#include "interfaces.h"
#include "diskdevices.h"
#include "cpustat.h"
+#include "perfstat.h"
#include "log.h"
#include "cfg.h"
@@ -69,14 +70,9 @@ void init_collector_data(void)
{
#if defined (_WINDOWS)
- collector = calloc(1, sizeof(ZBX_COLLECTOR_DATA));
+ collector = zbx_malloc(sizeof(ZBX_COLLECTOR_DATA));
- if(NULL == collector)
- {
- zabbix_log(LOG_LEVEL_CRIT, "Can't allocate memory for collector.");
- exit(1);
-
- }
+ memset(collector, 0, sizeof(ZBX_COLLECTOR_DATA));
#else /* not _WINDOWS */
@@ -125,9 +121,7 @@ void free_collector_data(void)
#if defined (_WINDOWS)
- if(NULL == collector) return;
-
- free(collector);
+ zbx_free(collector);
#else /* not _WINDOWS */
@@ -175,10 +169,12 @@ ZBX_THREAD_ENTRY(collector_thread, args)
zabbix_log( LOG_LEVEL_INFORMATION, "zabbix_agentd collector started");
init_cpu_collector(&(collector->cpus));
+ init_perf_collector(&(collector->perfs));
while(ZBX_IS_RUNNING)
{
collect_cpustat(&(collector->cpus));
+ collect_perfstat(&(collector->perfs));
collect_stats_interfaces(&(collector->interfaces));
collect_stats_diskdevices(&(collector->diskdevices));
@@ -186,6 +182,7 @@ ZBX_THREAD_ENTRY(collector_thread, args)
zbx_sleep(1);
}
+ close_perf_collector(&(collector->perfs));
close_cpu_collector(&(collector->cpus));
zabbix_log( LOG_LEVEL_INFORMATION, "zabbix_agentd collector stopped");
diff --git a/src/zabbix_agent/stats.h b/src/zabbix_agent/stats.h
index d750e704..63a12633 100644
--- a/src/zabbix_agent/stats.h
+++ b/src/zabbix_agent/stats.h
@@ -22,6 +22,7 @@
#include "threads.h"
#include "cpustat.h"
+#include "perfstat.h"
#include "interfaces.h"
#include "diskdevices.h"
@@ -30,6 +31,7 @@ typedef struct s_collector_data
ZBX_CPUS_STAT_DATA cpus;
ZBX_INTERFACES_DATA interfaces;
ZBX_DISKDEVICES_DATA diskdevices;
+ ZBX_PERF_STAT_DATA perfs;
} ZBX_COLLECTOR_DATA;
extern ZBX_COLLECTOR_DATA *collector;
diff --git a/src/zabbix_agent/zbxconf.c b/src/zabbix_agent/zbxconf.c
index 1bfc4d7e..5dab12d5 100644
--- a/src/zabbix_agent/zbxconf.c
+++ b/src/zabbix_agent/zbxconf.c
@@ -24,6 +24,7 @@
#include "log.h"
#include "alias.h"
#include "sysinfo.h"
+#include "perfstat.h"
#if defined(ZABBIX_DAEMON)
/* use pid file configureation */
@@ -141,11 +142,11 @@ void load_user_parameters(void)
{
/* PARAMETER, VAR, FUNC, TYPE(0i,1s), MANDATORY,MIN,MAX
*/
- {"Alias", 0, &add_alias_from_config, TYPE_STRING,PARM_OPT,0,0},
- {"UserParameter", 0, &add_parameter, 0, 0, 0, 0},
+ {"Alias", 0, &add_alias_from_config, TYPE_STRING,PARM_OPT,0,0},
+ {"UserParameter", 0, &add_parameter, 0, 0, 0, 0},
#if defined(_WINDOWS)
-/* {"PerfCounter", &CONFIG_PERF_COUNTER, 0, TYPE_STRING,PARM_OPT,0,0}, */
+ {"PerfCounter", 0, &add_perfs_from_config, TYPE_STRING,PARM_OPT,0,0},
#endif /* _WINDOWS */
#if defined(WITH_PLUGINS)