diff options
author | Andris Zeila <andris.zeila@zabbix.com> | 2015-06-12 16:19:38 +0300 |
---|---|---|
committer | Andris Zeila <andris.zeila@zabbix.com> | 2015-06-12 16:19:38 +0300 |
commit | 96da72dd35890a80580e16f73a683bd3b1c07f94 (patch) | |
tree | 73343d7e506fbdbc6fca35500a86e950f2f5d51b | |
parent | d8dadb0df8014ec6fcacd049a03c12c48cac43db (diff) |
...G...... [ZBXNEXT-494] added support for proc.cpu.util key on Solaris platform
-rw-r--r-- | configure.ac | 8 | ||||
-rw-r--r-- | include/sysinfo.h | 5 | ||||
-rw-r--r-- | src/libs/zbxsysinfo/linux/linux.c | 2 | ||||
-rw-r--r-- | src/libs/zbxsysinfo/linux/proc.c | 28 | ||||
-rw-r--r-- | src/libs/zbxsysinfo/linux/proc.h | 2 | ||||
-rw-r--r-- | src/libs/zbxsysinfo/solaris/proc.c | 303 | ||||
-rw-r--r-- | src/libs/zbxsysinfo/solaris/solaris.c | 1 | ||||
-rw-r--r-- | src/zabbix_agent/procstat.c | 149 | ||||
-rw-r--r-- | src/zabbix_agent/procstat.h | 18 | ||||
-rw-r--r-- | src/zabbix_agent/stats.h | 7 |
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 |