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:
authorAndris Zeila <andris.zeila@zabbix.com>2015-06-12 16:19:38 +0300
committerAndris Zeila <andris.zeila@zabbix.com>2015-06-12 16:19:38 +0300
commit96da72dd35890a80580e16f73a683bd3b1c07f94 (patch)
tree73343d7e506fbdbc6fca35500a86e950f2f5d51b
parentd8dadb0df8014ec6fcacd049a03c12c48cac43db (diff)
...G...... [ZBXNEXT-494] added support for proc.cpu.util key on Solaris platform
-rw-r--r--configure.ac8
-rw-r--r--include/sysinfo.h5
-rw-r--r--src/libs/zbxsysinfo/linux/linux.c2
-rw-r--r--src/libs/zbxsysinfo/linux/proc.c28
-rw-r--r--src/libs/zbxsysinfo/linux/proc.h2
-rw-r--r--src/libs/zbxsysinfo/solaris/proc.c303
-rw-r--r--src/libs/zbxsysinfo/solaris/solaris.c1
-rw-r--r--src/zabbix_agent/procstat.c149
-rw-r--r--src/zabbix_agent/procstat.h18
-rw-r--r--src/zabbix_agent/stats.h7
10 files changed, 394 insertions, 129 deletions
diff --git a/configure.ac b/configure.ac
index f0d88754bba..7b7661e74b3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1437,6 +1437,14 @@ if test "x${MKDIR_P}" = "x"; then
fi
AC_MSG_RESULT([ok (${MKDIR_P})])
+dnl Check if process statistics collector should be enabled
+case "x$ARCH" in
+ xlinux|xsolaris)
+ AC_DEFINE(ZBX_PROCSTAT_COLLECTOR, 1 , [Define to 1 on linux and solaris platforms])
+ ;;
+esac
+
+
dnl *****************************************************************
dnl * *
dnl * Output configuration results *
diff --git a/include/sysinfo.h b/include/sysinfo.h
index 461633ac505..0d805422aac 100644
--- a/include/sysinfo.h
+++ b/include/sysinfo.h
@@ -214,6 +214,11 @@ zbx_uint64_t get_kstat_numeric_value(const kstat_named_t *kn);
int GET_SENSOR(AGENT_REQUEST *request, AGENT_RESULT *result);
int KERNEL_MAXFILES(AGENT_REQUEST *request, AGENT_RESULT *result);
int KERNEL_MAXPROC(AGENT_REQUEST *request, AGENT_RESULT *result);
+
+#ifdef ZBX_PROCSTAT_COLLECTOR
+int PROC_CPU_UTIL(AGENT_REQUEST *request, AGENT_RESULT *result);
+#endif
+
int PROC_MEM(AGENT_REQUEST *request, AGENT_RESULT *result);
int PROC_NUM(AGENT_REQUEST *request, AGENT_RESULT *result);
int NET_IF_IN(AGENT_REQUEST *request, AGENT_RESULT *result);
diff --git a/src/libs/zbxsysinfo/linux/linux.c b/src/libs/zbxsysinfo/linux/linux.c
index 48cbcfc5e41..1a75953e127 100644
--- a/src/libs/zbxsysinfo/linux/linux.c
+++ b/src/libs/zbxsysinfo/linux/linux.c
@@ -45,9 +45,9 @@ ZBX_METRIC parameters_specific[] =
{"vm.memory.size", CF_HAVEPARAMS, VM_MEMORY_SIZE, "total"},
+ {"proc.cpu.util", CF_HAVEPARAMS, PROC_CPU_UTIL, "inetd"},
{"proc.num", CF_HAVEPARAMS, PROC_NUM, "inetd"},
{"proc.mem", CF_HAVEPARAMS, PROC_MEM, "inetd"},
- {"proc.cpu.util", CF_HAVEPARAMS, PROC_CPU_UTIL, "inetd"},
{"system.cpu.switches", 0, SYSTEM_CPU_SWITCHES, NULL},
{"system.cpu.intr", 0, SYSTEM_CPU_INTR, NULL},
diff --git a/src/libs/zbxsysinfo/linux/proc.c b/src/libs/zbxsysinfo/linux/proc.c
index 2383c0e3c46..cb4376b066e 100644
--- a/src/libs/zbxsysinfo/linux/proc.c
+++ b/src/libs/zbxsysinfo/linux/proc.c
@@ -935,7 +935,8 @@ void zbx_proc_get_stats(zbx_procstat_util_t *procs, int procs_num)
* -errno - failed to read pids *
* *
******************************************************************************/
-int zbx_proc_get_pids(const char *procname, const char *username, const char *cmdline, zbx_vector_uint64_t *pids)
+int zbx_proc_get_pids(const char *procname, const char *username, const char *cmdline, zbx_uint64_t flags,
+ zbx_vector_uint64_t *pids)
{
const char *__function_name = "zbx_proc_get_pids";
DIR *dir;
@@ -1009,9 +1010,6 @@ out:
return ret;
}
-#define PROCSTAT_CPU_USER 0
-#define PROCSTAT_CPU_SYSTEM 1
-
int PROC_CPU_UTIL(AGENT_REQUEST *request, AGENT_RESULT *result)
{
const char *procname, *username, *cmdline, *tmp;
@@ -1039,13 +1037,17 @@ int PROC_CPU_UTIL(AGENT_REQUEST *request, AGENT_RESULT *result)
cmdline = NULL;
/* utilization type parameter (user|system) */
- if (NULL == (tmp = get_rparam(request, 2)) || '\0' == *tmp || 0 == strcmp(tmp, "user"))
+ if (NULL == (tmp = get_rparam(request, 2)) || '\0' == *tmp || 0 == strcmp(tmp, "total"))
+ {
+ type = ZBX_PROCSTAT_CPU_TOTAL;
+ }
+ else if (0 == strcmp(tmp, "user"))
{
- type = PROCSTAT_CPU_USER;
+ type = ZBX_PROCSTAT_CPU_USER;
}
else if (0 == strcmp(tmp, "system"))
{
- type = PROCSTAT_CPU_SYSTEM;
+ type = ZBX_PROCSTAT_CPU_SYSTEM;
}
else
{
@@ -1078,17 +1080,7 @@ int PROC_CPU_UTIL(AGENT_REQUEST *request, AGENT_RESULT *result)
return SYSINFO_RET_FAIL;
}
- switch (type)
- {
- case PROCSTAT_CPU_USER:
- ret = zbx_procstat_get_utime(procname, username, cmdline, period, &value, &errmsg);
- break;
- case PROCSTAT_CPU_SYSTEM:
- ret = zbx_procstat_get_stime(procname, username, cmdline, period, &value, &errmsg);
- break;
- }
-
- if (SUCCEED != ret)
+ if (SUCCEED != (ret = zbx_procstat_get_util(procname, username, cmdline, 0, period, type, &value, &errmsg)))
{
/* zbx_procstat_get_* functions will return FAIL when either a collection */
/* error was registered or if less than 2 data samples were collected. */
diff --git a/src/libs/zbxsysinfo/linux/proc.h b/src/libs/zbxsysinfo/linux/proc.h
index 7eba6d7248a..d111ab4e214 100644
--- a/src/libs/zbxsysinfo/linux/proc.h
+++ b/src/libs/zbxsysinfo/linux/proc.h
@@ -22,6 +22,4 @@
int byte_value_from_proc_file(FILE *f, const char *label, const char *guard, zbx_uint64_t *bytes);
-int PROC_CPU_UTIL(AGENT_REQUEST *request, AGENT_RESULT *result);
-
#endif
diff --git a/src/libs/zbxsysinfo/solaris/proc.c b/src/libs/zbxsysinfo/solaris/proc.c
index 50320eacd22..c8219bb6a8e 100644
--- a/src/libs/zbxsysinfo/solaris/proc.c
+++ b/src/libs/zbxsysinfo/solaris/proc.c
@@ -22,6 +22,7 @@
#include "sysinfo.h"
#include "zbxregexp.h"
#include "log.h"
+#include "stats.h"
static int check_procstate(psinfo_t *psinfo, int zbx_proc_stat)
{
@@ -318,3 +319,305 @@ out:
return SYSINFO_RET_OK;
}
+
+/******************************************************************************
+ * *
+ * Function: proc_read_cpu_util *
+ * *
+ * Purpose: reads process cpu utilization values from /proc/[pid]/stat file *
+ * *
+ * Parameters: procutil - [IN/OUT] the process cpu utilization data *
+ * *
+ * Return value: SUCCEED - the process cpu utilization data was read *
+ * successfully *
+ * <0 - otherwise, -errno code is returned *
+ * *
+ ******************************************************************************/
+static int proc_read_cpu_util(zbx_procstat_util_t *procutil)
+{
+ int fd, n;
+ char tmp[MAX_STRING_LEN];
+ psinfo_t psinfo;
+ pstatus_t pstatus;
+
+ zbx_snprintf(tmp, sizeof(tmp), "/proc/%d/psinfo", (int)procutil->pid);
+
+ if (-1 == (fd = open(tmp, O_RDONLY)))
+ {
+ zabbix_log(LOG_LEVEL_ERR, "[WDN] cannot open /proc/%d/psinfo", (int)procutil->pid);
+ return -errno;
+ }
+
+ n = read(fd, &psinfo, sizeof(psinfo));
+ close(fd);
+
+ if (-1 == n)
+ return -errno;
+
+ procutil->starttime = psinfo.pr_start.tv_sec;
+
+ zbx_snprintf(tmp, sizeof(tmp), "/proc/%d/status", (int)procutil->pid);
+
+ if (-1 == (fd = open(tmp, O_RDONLY)))
+ {
+ zabbix_log(LOG_LEVEL_ERR, "[WDN] cannot open /proc/%d/status", (int)procutil->pid);
+ return -errno;
+ }
+
+ n = read(fd, &pstatus, sizeof(pstatus));
+ close(fd);
+
+ if (-1 == n)
+ return -errno;
+
+ procutil->utime = ((zbx_uint64_t)pstatus.pr_utime.tv_sec * 1e9 + pstatus.pr_utime.tv_nsec) *
+ sysconf(_SC_CLK_TCK) / 1e9;
+
+ procutil->stime = ((zbx_uint64_t)pstatus.pr_stime.tv_sec * 1e9 + pstatus.pr_stime.tv_nsec) *
+ sysconf(_SC_CLK_TCK) / 1e9;
+
+ zabbix_log(LOG_LEVEL_DEBUG, "[WDN] pid:%d utime: %d %d (%d)", (int)procutil->pid,
+ pstatus.pr_utime.tv_sec, pstatus.pr_utime.tv_nsec,
+ procutil->utime);
+ zabbix_log(LOG_LEVEL_DEBUG, "[WDN] pid:%d stime: %d %d (%d)", (int)procutil->pid,
+ pstatus.pr_stime.tv_sec, pstatus.pr_stime.tv_nsec,
+ procutil->stime);
+
+ return SUCCEED;
+}
+
+/******************************************************************************
+ * *
+ * Function: zbx_proc_get_stats *
+ * *
+ * Purpose: get process cpu utilization data *
+ * *
+ * Parameters: procs - [IN/OUT] an array of process utilization data *
+ * procs_num - [IN] the number of items in procs array *
+ * *
+ ******************************************************************************/
+void zbx_proc_get_stats(zbx_procstat_util_t *procs, int procs_num)
+{
+ const char *__function_name = "zbx_proc_get_stats";
+ int i;
+
+ zabbix_log(LOG_LEVEL_TRACE, "In %s() procs_num:%d", __function_name, procs_num);
+
+ for (i = 0; i < procs_num; i++)
+ procs[i].error = proc_read_cpu_util(&procs[i]);
+
+ zabbix_log(LOG_LEVEL_TRACE, "End of %s()", __function_name);
+}
+
+/******************************************************************************
+ * *
+ * Function: zbx_proc_get_pids *
+ * *
+ * Purpose: get pids matching the specified process name, user name and *
+ * command line *
+ * *
+ * Parameters: procname - [IN] the process name, NULL - all *
+ * username - [IN] the user name, NULL - all *
+ * cmdline - [IN] the command line, NULL - all *
+ * pids - [OUT] the vector of matching pids *
+ * *
+ * Return value: SUCCEED - the pids were read successfully *
+ * -errno - failed to read pids *
+ * *
+ ******************************************************************************/
+int zbx_proc_get_pids(const char *procname, const char *username, const char *cmdline, zbx_uint64_t flags,
+ zbx_vector_uint64_t *pids)
+{
+ const char *__function_name = "zbx_proc_get_pids";
+ DIR *dir;
+ struct dirent *entries;
+ struct passwd *usrinfo;
+ char tmp[MAX_STRING_LEN];
+ int pid, ret = FAIL, fd = -1;
+ psinfo_t psinfo; /* In the correct procfs.h, the structure name is psinfo_t */
+#ifdef HAVE_ZONE_H
+ zoneid_t zoneid;
+#endif
+
+ zabbix_log(LOG_LEVEL_TRACE, "In %s() procname:%s username:%s cmdline:%s zone:%d", __function_name,
+ ZBX_NULL2EMPTY_STR(procname), ZBX_NULL2EMPTY_STR(username), ZBX_NULL2EMPTY_STR(cmdline), flags);
+
+ if (NULL != username)
+ {
+ /* in the case of invalid user there are no matching processes, set empty result */
+ if (NULL == (usrinfo = getpwnam(username)))
+ {
+ ret = SUCCEED;
+ goto out;
+ }
+ }
+ else
+ usrinfo = NULL;
+
+ if (NULL == (dir = opendir("/proc")))
+ {
+ ret = -errno;
+ goto out;
+ }
+
+#ifdef HAVE_ZONE_H
+ zoneid = getzoneid();
+#endif
+
+ while (NULL != (entries = readdir(dir)))
+ {
+ /* skip entries not containing pids */
+ if (FAIL == is_uint32(entries->d_name, &pid))
+ continue;
+
+ if (-1 != fd)
+ {
+ close(fd);
+ fd = -1;
+ }
+
+ zbx_snprintf(tmp, sizeof(tmp), "/proc/%s/psinfo", entries->d_name);
+
+ if (-1 == (fd = open(tmp, O_RDONLY)))
+ continue;
+
+ if (-1 == read(fd, &psinfo, sizeof(psinfo)))
+ continue;
+
+ if (NULL != procname && '\0' != *procname && 0 != strcmp(procname, psinfo.pr_fname))
+ continue;
+
+ if (NULL != usrinfo && usrinfo->pw_uid != psinfo.pr_uid)
+ continue;
+
+ if (NULL != cmdline && '\0' != *cmdline && NULL == zbx_regexp_match(psinfo.pr_psargs, cmdline, NULL))
+ continue;
+
+#ifdef HAVE_ZONE_H
+ if (0 == (ZBX_PROCSTAT_FLAGS_ZONE_ALL & flags) && psinfo.pr_zoneid != zoneid)
+ continue;
+#endif
+
+ zbx_vector_uint64_append(pids, pid);
+ }
+
+ closedir(dir);
+ if (-1 != fd)
+ close(fd);
+
+ ret = SUCCEED;
+out:
+ zabbix_log(LOG_LEVEL_TRACE, "End of %s(): %s", __function_name, zbx_result_string(ret));
+
+ return ret;
+}
+
+int PROC_CPU_UTIL(AGENT_REQUEST *request, AGENT_RESULT *result)
+{
+ const char *procname, *username, *cmdline, *tmp, *flags;
+ char *errmsg = NULL;
+ int period, type, ret;
+ double value;
+ zbx_uint64_t zoneflag;
+
+ /* proc.cpu.util[<procname>,<username>,(user|system),<cmdline>,(avg1|avg5|avg15)] */
+ if (6 < request->nparam)
+ {
+ SET_MSG_RESULT(result, zbx_strdup(NULL, "Too many parameters."));
+ return SYSINFO_RET_FAIL;
+ }
+
+#ifndef HAVE_ZONE_H
+ if (5 == request->nparam && GLOBAL_ZONEID != getzoneid())
+ {
+ SET_MSG_RESULT(result, zbx_strdup(NULL, "Unsupported 6th parameter."));
+ return SYSINFO_RET_FAIL;
+ }
+#endif
+
+ /* zbx_procstat_get_* functions expect NULL for default values - */
+ /* convert empty procname, username and cmdline strings to NULL values */
+ if (NULL != (procname = get_rparam(request, 0)) && '\0' == *procname)
+ procname = NULL;
+
+ if (NULL != (username = get_rparam(request, 1)) && '\0' == *username)
+ username = NULL;
+
+ if (NULL != (cmdline = get_rparam(request, 3)) && '\0' == *cmdline)
+ cmdline = NULL;
+
+ /* utilization type parameter (user|system) */
+ if (NULL == (tmp = get_rparam(request, 2)) || '\0' == *tmp || 0 == strcmp(tmp, "total"))
+ {
+ type = ZBX_PROCSTAT_CPU_TOTAL;
+ }
+ else if (0 == strcmp(tmp, "user"))
+ {
+ type = ZBX_PROCSTAT_CPU_USER;
+ }
+ else if (0 == strcmp(tmp, "system"))
+ {
+ type = ZBX_PROCSTAT_CPU_SYSTEM;
+ }
+ else
+ {
+ SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter."));
+ return SYSINFO_RET_FAIL;
+ }
+
+ /* mode parameter (avg1|avg5|avg15) */
+ if (NULL == (tmp = get_rparam(request, 4)) || '\0' == *tmp || 0 == strcmp(tmp, "avg1"))
+ {
+ period = SEC_PER_MIN;
+ }
+ else if ( 0 == strcmp(tmp, "avg5"))
+ {
+ period = SEC_PER_MIN * 5;
+ }
+ else if ( 0 == strcmp(tmp, "avg15"))
+ {
+ period = SEC_PER_MIN * 15;
+ }
+ else
+ {
+ SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid fifth parameter."));
+ return SYSINFO_RET_FAIL;
+ }
+
+ if (NULL == (flags = get_rparam(request, 5)) || '\0' == *flags)
+ {
+ zoneflag = ZBX_PROCSTAT_FLAGS_ZONE_CURRENT;
+ }
+ else if(0 == strcmp(flags, "all"))
+ {
+ zoneflag = ZBX_PROCSTAT_FLAGS_ZONE_ALL;
+ }
+ else
+ {
+ SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid sixth parameter."));
+ return SYSINFO_RET_FAIL;
+ }
+
+ if (SUCCEED != zbx_procstat_enabled())
+ {
+ SET_MSG_RESULT(result, zbx_strdup(NULL, "Collector is not started."));
+ return SYSINFO_RET_FAIL;
+ }
+
+ if (SUCCEED != (ret = zbx_procstat_get_util(procname, username, cmdline, zoneflag, period, type, &value,
+ &errmsg)))
+ {
+ /* zbx_procstat_get_* functions will return FAIL when either a collection */
+ /* error was registered or if less than 2 data samples were collected. */
+ /* In the first case the errmsg will contain error message. */
+ if (NULL != errmsg)
+ {
+ SET_MSG_RESULT(result, errmsg);
+ return SYSINFO_RET_FAIL;
+ }
+ }
+ else
+ SET_DBL_RESULT(result, value);
+
+ return SYSINFO_RET_OK;
+}
diff --git a/src/libs/zbxsysinfo/solaris/solaris.c b/src/libs/zbxsysinfo/solaris/solaris.c
index 19f1f7f241d..dee24d9ac1f 100644
--- a/src/libs/zbxsysinfo/solaris/solaris.c
+++ b/src/libs/zbxsysinfo/solaris/solaris.c
@@ -43,6 +43,7 @@ ZBX_METRIC parameters_specific[] =
{"vm.memory.size", CF_HAVEPARAMS, VM_MEMORY_SIZE, "free"},
+ {"proc.cpu.util", CF_HAVEPARAMS, PROC_CPU_UTIL, "inetd"},
{"proc.num", CF_HAVEPARAMS, PROC_NUM, "inetd"},
{"proc.mem", CF_HAVEPARAMS, PROC_MEM, "inetd"},
diff --git a/src/zabbix_agent/procstat.c b/src/zabbix_agent/procstat.c
index 18bdcb6b8e8..4201a57217c 100644
--- a/src/zabbix_agent/procstat.c
+++ b/src/zabbix_agent/procstat.c
@@ -22,7 +22,6 @@
#include "mutexs.h"
#include "stats.h"
#include "ipc.h"
-#include "db.h"
#include "procstat.h"
#ifdef ZBX_PROCSTAT_COLLECTOR
@@ -117,6 +116,7 @@ typedef struct
size_t procname;
size_t username;
size_t cmdline;
+ zbx_uint64_t flags;
/* the index of first (oldest) entry in the history data */
int h_first;
@@ -149,6 +149,7 @@ typedef struct
const char *procname;
const char *username;
const char *cmdline;
+ zbx_uint64_t flags;
/* error code */
int error;
@@ -392,6 +393,7 @@ static int procstat_running()
* procname - [IN] the process name *
* username - [IN] the user name *
* cmdline - [IN] the command line *
+ * flags - [IN] platform specific flags *
* *
* Return value: The process statistics query for the specified parameters or *
* NULL if the statistics are not being gathered for the *
@@ -399,7 +401,7 @@ static int procstat_running()
* *
******************************************************************************/
static zbx_procstat_query_t *procstat_get_query(void *base, const char *procname, const char *username,
- const char *cmdline)
+ const char *cmdline, zbx_uint64_t flags)
{
zbx_procstat_query_t *query;
@@ -410,7 +412,8 @@ static zbx_procstat_query_t *procstat_get_query(void *base, const char *procname
{
if (0 == zbx_strcmp_null(procname, PROCSTAT_PTR_NULL(base, query->procname)) &&
0 == zbx_strcmp_null(username, PROCSTAT_PTR_NULL(base, query->username)) &&
- 0 == zbx_strcmp_null(cmdline, PROCSTAT_PTR_NULL(base, query->cmdline)))
+ 0 == zbx_strcmp_null(cmdline, PROCSTAT_PTR_NULL(base, query->cmdline)) &&
+ flags == query->flags)
{
return query;
}
@@ -426,15 +429,16 @@ static zbx_procstat_query_t *procstat_get_query(void *base, const char *procname
* *
* Purpose: adds a new query to process statistics collector *
* *
- * Parameters: procname - [IN] the process name *
- * username - [IN] the user name *
- * cmdline - [IN] the command line *
+ * Parameters: procname - [IN] the process name *
+ * username - [IN] the user name *
+ * cmdline - [IN] the command line *
+ * flags - [IN] platform specific flags *
* *
* Return value: *
* This function calls exit() on shared memory errors. *
* *
******************************************************************************/
-static void procstat_add(const char *procname, const char *username, const char *cmdline)
+static void procstat_add(const char *procname, const char *username, const char *cmdline, zbx_uint64_t flags)
{
const char *__function_name = "procstat_add";
char *errmsg = NULL;
@@ -503,6 +507,7 @@ static void procstat_add(const char *procname, const char *username, const char
query->procname = procstat_strdup(procstat_ref.addr, procname);
query->username = procstat_strdup(procstat_ref.addr, username);
query->cmdline = procstat_strdup(procstat_ref.addr, cmdline);
+ query->flags = flags;
query->last_accessed = time(NULL);
query->next = header->active_queries;
header->active_queries = query_offset;
@@ -573,9 +578,9 @@ void zbx_procstat_init()
/******************************************************************************
* *
- * Function: zbx_procstat_get_utime *
+ * Function: zbx_procstat_get_util *
* *
- * Purpose: gets process user time utilization *
+ * Purpose: gets process cpu utilization *
* *
* Parameters: procname - [IN] the process name, NULL - all *
* username - [IN] the user name, NULL - all *
@@ -583,7 +588,9 @@ void zbx_procstat_init()
* collector_func - [IN] the callback function to use for process *
* statistics gathering *
* period - [IN] the time period *
- * utime - [OUT] the user time *
+ * type - [IN] the cpu utilization type, see *
+ * ZBX_PROCSTAT_CPU_* defines *
+ * value - [OUT] the utilization in % *
* errmsg - [OUT] the error message *
* *
* Return value: *
@@ -595,126 +602,71 @@ void zbx_procstat_init()
* This function calls exit() on shared memory errors. *
* *
******************************************************************************/
-int zbx_procstat_get_utime(const char *procname, const char *username, const char *cmdline, int period,
- double *utime, char **errmsg)
+int zbx_procstat_get_util(const char *procname, const char *username, const char *cmdline, zbx_uint64_t flags,
+ int period, int type, double *value, char **errmsg)
{
int ret = FAIL, current, start;
- zbx_procstat_query_t *pstat;
- zbx_uint64_t ticks_diff, time_diff;
+ zbx_procstat_query_t *query;
+ zbx_uint64_t ticks_diff = 0, time_diff;
zbx_dshm_lock(&collector->procstat);
procstat_reattach();
- if (NULL == (pstat = procstat_get_query(procstat_ref.addr, procname, username, cmdline)))
+ if (NULL == (query = procstat_get_query(procstat_ref.addr, procname, username, cmdline, flags)))
{
- procstat_add(procname, username, cmdline);
+ procstat_add(procname, username, cmdline, flags);
goto out;
}
- pstat->last_accessed = time(NULL);
+ query->last_accessed = time(NULL);
- if (0 != pstat->error)
+ if (0 != query->error)
{
- *errmsg = zbx_dsprintf(*errmsg, "Cannot read cpu utilization data: %s", zbx_strerror(-pstat->error));
+ *errmsg = zbx_dsprintf(*errmsg, "Cannot read cpu utilization data: %s", zbx_strerror(-query->error));
goto out;
}
- if (1 >= pstat->h_count)
+ if (1 >= query->h_count)
goto out;
- if (period >= pstat->h_count)
- period = pstat->h_count - 1;
+ if (period >= query->h_count)
+ period = query->h_count - 1;
- if (MAX_COLLECTOR_HISTORY <= (current = pstat->h_first + pstat->h_count - 1))
+ if (MAX_COLLECTOR_HISTORY <= (current = query->h_first + query->h_count - 1))
current -= MAX_COLLECTOR_HISTORY;
if (0 > (start = current - period))
start += MAX_COLLECTOR_HISTORY;
- ticks_diff = pstat->h_data[current].utime - pstat->h_data[start].utime;
- time_diff = (zbx_uint64_t)(pstat->h_data[current].timestamp.sec - pstat->h_data[start].timestamp.sec) *
- 1000000000 + pstat->h_data[current].timestamp.ns - pstat->h_data[start].timestamp.ns;
-
- /* 1e9 (nanoseconds) * 1e2 (percent) * 1e1 (one digit decimal place) */
- ticks_diff *= 1000000000000;
- ticks_diff /= time_diff * sysconf(_SC_CLK_TCK);
- *utime = (double)ticks_diff / 10;
-
- ret = SUCCEED;
-out:
- zbx_dshm_unlock(&collector->procstat);
+ if (0 != (type & ZBX_PROCSTAT_CPU_USER))
+ ticks_diff += query->h_data[current].utime - query->h_data[start].utime;
- return ret;
-}
-
-/******************************************************************************
- * *
- * Function: zbx_procstat_get_stime *
- * *
- * Purpose: gets process system time utilization *
- * *
- * Parameters: procname - [IN] the process name, NULL - all *
- * username - [IN] the user name, NULL - all *
- * cmdline - [IN] the command line, NULL - all *
- * period - [IN] the time period *
- * stime - [OUT] the system time *
- * errmsg - [OUT] the error message *
- * *
- * Return value: *
- * SUCCEED - the stime value was retrieved successfully *
- * FAIL - either collector does not have at least two data samples *
- * required to calculate the statistics, or an error occurred *
- * during the collection process. In the second case the errmsg *
- * will contain an error message. *
- * This function calls exit() on shared memory errors. *
- * *
- ******************************************************************************/
-int zbx_procstat_get_stime(const char *procname, const char *username, const char *cmdline, int period,
- double *stime, char **errmsg)
-{
- int ret = FAIL, current, start;
- zbx_procstat_query_t *pstat;
- zbx_uint64_t ticks_diff, time_diff;
+ if (0 != (type & ZBX_PROCSTAT_CPU_SYSTEM))
+ ticks_diff += query->h_data[current].stime - query->h_data[start].stime;
- zbx_dshm_lock(&collector->procstat);
+ time_diff = (zbx_uint64_t)(query->h_data[current].timestamp.sec - query->h_data[start].timestamp.sec) *
+ 1000000000 + query->h_data[current].timestamp.ns - query->h_data[start].timestamp.ns;
- procstat_reattach();
- if (NULL == (pstat = procstat_get_query(procstat_ref.addr, procname, username, cmdline)))
+ zabbix_log(LOG_LEVEL_DEBUG, "[WDN] ticks:" ZBX_FS_UI64 " time:" ZBX_FS_UI64, ticks_diff, time_diff);
{
- procstat_add(procname, username, cmdline);
- goto out;
- }
+ int i;
- pstat->last_accessed = time(NULL);
+ zabbix_log(LOG_LEVEL_DEBUG, "[WDN] first:%d, count:%d", query->h_first, query->h_count);
+ zabbix_log(LOG_LEVEL_DEBUG, "[WDN] start:%d, current:%d", start, current);
- if (0 != pstat->error)
- {
- *errmsg = zbx_dsprintf(*errmsg, "Cannot read cpu utilization data: %s", zbx_strerror(-pstat->error));
- goto out;
+ for (i = 0; i < query->h_count; i++)
+ {
+ zabbix_log(LOG_LEVEL_DEBUG, "[WDN] [%03d] utime:" ZBX_FS_UI64 ", stime:" ZBX_FS_UI64,
+ i, query->h_data[i].utime, i, query->h_data[i].stime);
+ }
}
- if (1 >= pstat->h_count)
- goto out;
-
- if (period >= pstat->h_count)
- period = pstat->h_count - 1;
-
- if (MAX_COLLECTOR_HISTORY <= (current = pstat->h_first + pstat->h_count - 1))
- current -= MAX_COLLECTOR_HISTORY;
-
- if (0 > (start = current - period))
- start += MAX_COLLECTOR_HISTORY;
-
- ticks_diff = pstat->h_data[current].stime - pstat->h_data[start].stime;
- time_diff = (zbx_uint64_t)(pstat->h_data[current].timestamp.sec - pstat->h_data[start].timestamp.sec) *
- 1000000000 + pstat->h_data[current].timestamp.ns - pstat->h_data[start].timestamp.ns;
-
/* 1e9 (nanoseconds) * 1e2 (percent) * 1e1 (one digit decimal place) */
ticks_diff *= 1000000000000;
ticks_diff /= time_diff * sysconf(_SC_CLK_TCK);
- *stime = (double)ticks_diff / 10;
+ *value = (double)ticks_diff / 10;
ret = SUCCEED;
out:
@@ -724,7 +676,8 @@ out:
}
/* external functions used by procstat collector */
-int zbx_proc_get_pids(const char *procname, const char *username, const char *cmdline, zbx_vector_uint64_t *pids);
+int zbx_proc_get_pids(const char *procname, const char *username, const char *cmdline, zbx_uint64_t flags,
+ zbx_vector_uint64_t *pids);
void zbx_proc_get_stats(zbx_procstat_util_t *procs, int procs_num);
/******************************************************************************
@@ -787,6 +740,7 @@ void zbx_procstat_collect()
qdata->procname = PROCSTAT_PTR_NULL(procstat_ref.addr, query->procname);
qdata->username = PROCSTAT_PTR_NULL(procstat_ref.addr, query->username);
qdata->cmdline = PROCSTAT_PTR_NULL(procstat_ref.addr, query->cmdline);
+ qdata->flags = query->flags;
qdata->utime = 0;
qdata->stime = 0;
@@ -810,7 +764,8 @@ void zbx_procstat_collect()
{
qdata = (zbx_procstat_query_data_t *)queries.values[i];
- qdata->error = zbx_proc_get_pids(qdata->procname, qdata->username, qdata->cmdline, &qdata->pids);
+ qdata->error = zbx_proc_get_pids(qdata->procname, qdata->username, qdata->cmdline, qdata->flags,
+ &qdata->pids);
if (SUCCEED == qdata->error)
pids_num += qdata->pids.values_num;
@@ -956,8 +911,8 @@ void zbx_procstat_collect()
zbx_timespec(&query->h_data[index].timestamp);
}
- memcpy(PROCSTAT_SNAPSHOT(procstat_ref.addr), stats, sizeof(zbx_procstat_util_t) * pids.values_num);
header->pids_num = pids.values_num;
+ memcpy(PROCSTAT_SNAPSHOT(procstat_ref.addr), stats, sizeof(zbx_procstat_util_t) * pids.values_num);
zbx_free(stats);
zbx_vector_uint64_destroy(&pids);
diff --git a/src/zabbix_agent/procstat.h b/src/zabbix_agent/procstat.h
index a69951b75b7..06fb0efe0a6 100644
--- a/src/zabbix_agent/procstat.h
+++ b/src/zabbix_agent/procstat.h
@@ -20,6 +20,16 @@
#ifndef ZABBIX_PROCSTAT_H
#define ZABBIX_PROCSTAT_H
+#ifdef ZBX_PROCSTAT_COLLECTOR
+
+#define ZBX_PROCSTAT_CPU_USER 1
+#define ZBX_PROCSTAT_CPU_SYSTEM 2
+#define ZBX_PROCSTAT_CPU_TOTAL 3
+
+#define ZBX_PROCSTAT_FLAGS_ZONE_CURRENT 0
+#define ZBX_PROCSTAT_FLAGS_ZONE_ALL 1
+
+
/* process cpu utilization data */
typedef struct
{
@@ -43,11 +53,11 @@ int zbx_procstat_collector_enabled();
int zbx_procstat_enabled();
-int zbx_procstat_get_utime(const char *procname, const char *username, const char *cmdline,
- int period, double *utime, char **errmsg);
-int zbx_procstat_get_stime(const char *procname, const char *username, const char *cmdline,
- int period, double *stime, char **errmsg);
+int zbx_procstat_get_util(const char *procname, const char *username, const char *cmdline, zbx_uint64_t flags,
+ int period, int type, double *value, char **errmsg);
void zbx_procstat_collect();
#endif
+
+#endif
diff --git a/src/zabbix_agent/stats.h b/src/zabbix_agent/stats.h
index 969ee43c42e..20ef63374c2 100644
--- a/src/zabbix_agent/stats.h
+++ b/src/zabbix_agent/stats.h
@@ -31,13 +31,6 @@
# include "vmstats.h"
#endif
-#if defined(__sun) && defined(__SVR4)
-# define ZBX_PROCSTAT_COLLECTOR
-#endif
-#if defined(__linux)
-# define ZBX_PROCSTAT_COLLECTOR
-#endif
-
#ifdef ZBX_PROCSTAT_COLLECTOR
# include "procstat.h"
#endif