diff options
Diffstat (limited to 'src/zabbix_agent/perfstat.c')
-rw-r--r-- | src/zabbix_agent/perfstat.c | 354 |
1 files changed, 151 insertions, 203 deletions
diff --git a/src/zabbix_agent/perfstat.c b/src/zabbix_agent/perfstat.c index d27da20d..30eeaa38 100644 --- a/src/zabbix_agent/perfstat.c +++ b/src/zabbix_agent/perfstat.c @@ -25,11 +25,9 @@ #ifdef _WINDOWS #include "perfmon.h" -#endif /* _WINDOWS */ /* Static data */ - -static PERF_COUNTERS *statPerfCounterList=NULL; +static ZBX_PERF_STAT_DATA *ppsd = NULL; /****************************************************************************** * * @@ -48,84 +46,80 @@ static PERF_COUNTERS *statPerfCounterList=NULL; * Comments: * * * ******************************************************************************/ -static int add_perf_counter(const char *name, const char *counterPath, int interval) +int add_perf_counter(const char *name, const char *counterPath, int interval) { - PERF_COUNTERS *perfs = NULL; - int result = FAIL; - char *alias_name = NULL; + PERF_COUNTERS *cptr; + PDH_STATUS status; + char *alias_name; + int result = FAIL; assert(name); assert(counterPath); - if( interval < 1 || interval > 1800 ) - { - zabbix_log( LOG_LEVEL_WARNING, "PerfCounter FAILED. [%s] (Interval value out of range)", name); + zabbix_log(LOG_LEVEL_DEBUG, "In add_perf_counter() [name:%s] [counter:%s] [interval:%d]", + name, counterPath, interval); + + if (NULL == ppsd->pdh_query) { + zabbix_log(LOG_LEVEL_WARNING, "PerfCounter %s: \"%s\" FAILED: Collector is not started!", + name, counterPath); return FAIL; } - for(perfs = statPerfCounterList; ; perfs=perfs->next) - { - /* Add new parameters */ - if(perfs == NULL) - { - perfs = (PERF_COUNTERS *)zbx_malloc(perfs, 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(perfs->rawValueArray, - 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; - } + if (interval < 1 || interval > 900) { + zabbix_log(LOG_LEVEL_WARNING, "PerfCounter %s: \"%s\" FAILED: Interval value out of range", + name, counterPath); + return FAIL; + } - /* 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(perfs->rawValueArray, + for (cptr = ppsd->pPerfCounterList; ; cptr = cptr->next) { + /* Add new parameters */ + if (NULL == cptr) { + cptr = (PERF_COUNTERS *)zbx_malloc(cptr, sizeof(PERF_COUNTERS)); + + memset(cptr, 0, sizeof(PERF_COUNTERS)); + cptr->next = ppsd->pPerfCounterList; + cptr->name = strdup(name); + cptr->counterPath = strdup(counterPath); + cptr->interval = interval; + cptr->rawValueArray = (PDH_RAW_COUNTER *)zbx_malloc(cptr->rawValueArray, sizeof(PDH_RAW_COUNTER) * interval); - perfs->CurrentCounter = 0; - perfs->CurrentNum = 1; + cptr->CurrentNum = 1; - perfs->next = statPerfCounterList; - statPerfCounterList = perfs; + /* Add user counters to query */ + if (ERROR_SUCCESS != (status = PdhAddCounter(ppsd->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")); + } else + zabbix_log(LOG_LEVEL_DEBUG, "PerfCounter %s: \"%s\" successfully added. Interval %d seconds", + name, cptr->counterPath, interval); + + ppsd->pPerfCounterList = cptr; - zabbix_log( LOG_LEVEL_DEBUG, "PerfCounter replaced. [%s] [%s] [%i]", name, counterPath, interval); result = SUCCEED; + break; + } + + if (*name != '\0' && 0 == strcmp(cptr->name, name)) { + zabbix_log(LOG_LEVEL_WARNING, "PerfCounter %s: \"%s\" FAILED: Counter already exists", + name, counterPath); + break; } } - if( SUCCEED == result ) - { + if (SUCCEED == result && *name != '\0') { 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); - } - + }/* else + zabbix_log(LOG_LEVEL_WARNING, "PerfCounter %s: \"%s\" FAILED", + name, counterPath); +*/ return result; } @@ -144,43 +138,33 @@ static int add_perf_counter(const char *name, const char *counterPath, int inter * Comments: format of input line is - name,"perfcounter name",interval * * * ******************************************************************************/ -int add_perfs_from_config(char *line) +int add_perfs_from_config(const char *line) { - char - *name = NULL, - *counterPath = NULL, - *interval = NULL; - - name = line; - counterPath = strchr(line,','); - if(NULL == counterPath) - goto lbl_syntax_error; + char name[MAX_STRING_LEN], + counterPath[PDH_MAX_COUNTER_PATH], + interval[MAX_STRING_LEN]; - *counterPath = '\0'; - counterPath++; + assert(line); - if ( *counterPath != '"' ) + if (num_param(line) != 3) goto lbl_syntax_error; - counterPath++; - - interval = strrchr(counterPath,','); - if(NULL == interval) + if (0 != get_param(line, 1, name, sizeof(name))) goto lbl_syntax_error; - interval--; - if ( *interval != '"' ) + if (0 != get_param(line, 2, counterPath, sizeof(counterPath))) goto lbl_syntax_error; - *interval = '\0'; - interval++; + if (0 != get_param(line, 3, interval, sizeof(interval))) + goto lbl_syntax_error; - *interval = '\0'; - interval++; + if (FAIL == check_counter_path(counterPath)) + goto lbl_syntax_error; return add_perf_counter(name, counterPath, atoi(interval)); - lbl_syntax_error: + zabbix_log(LOG_LEVEL_WARNING, "PerfCounter \"%s\" FAILED: Invalid format.", + line); return FAIL; } @@ -200,24 +184,18 @@ lbl_syntax_error: ******************************************************************************/ 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); - } - statPerfCounterList = NULL; -} - + PERF_COUNTERS *cptr; + while (NULL != ppsd->pPerfCounterList) { + cptr = ppsd->pPerfCounterList; + ppsd->pPerfCounterList = cptr->next; + zbx_free(cptr->name); + zbx_free(cptr->counterPath); + zbx_free(cptr->rawValueArray); + zbx_free(cptr); + } +} /****************************************************************************** * * @@ -229,60 +207,25 @@ void perfs_list_free(void) * 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 * + * Return value: * * * * Author: Eugene Grigorjev * * * * Comments: * * * ******************************************************************************/ - int init_perf_collector(ZBX_PERF_STAT_DATA *pperf) { -#ifdef _WINDOWS - - PERF_COUNTERS *cptr = NULL; - PDH_STATUS status; - int is_empty = 1; - - memset(pperf, 0, sizeof(ZBX_PERF_STAT_DATA)); + zabbix_log(LOG_LEVEL_DEBUG, "In init_perf_collector()"); - 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")); - } - else - { - is_empty = 0; - } - } + ppsd = pperf; - if ( is_empty ) - { - close_perf_collector(pperf); + if (ERROR_SUCCESS != PdhOpenQuery(NULL, 0, &ppsd->pdh_query)) { + zabbix_log(LOG_LEVEL_ERR, "Call to PdhOpenQuery() failed: %s", strerror_from_system(GetLastError())); + return FAIL; } -#endif /* _WINDOWS */ - - return 0; + return SUCCEED; } /****************************************************************************** @@ -291,8 +234,7 @@ int init_perf_collector(ZBX_PERF_STAT_DATA *pperf) * * * Purpose: Clear state of data calculation * * * - * Parameters: pperf - pointer to the structure * - * of ZBX_PERF_STAT_DATA type * + * Parameters: * * * * Return value: * * * @@ -301,78 +243,84 @@ int init_perf_collector(ZBX_PERF_STAT_DATA *pperf) * Comments: * * * ******************************************************************************/ - -void close_perf_collector(ZBX_PERF_STAT_DATA *pperf) +void close_perf_collector() { -#ifdef _WINDOWS - PERF_COUNTERS *cptr = NULL; + PERF_COUNTERS *cptr; - for ( cptr = statPerfCounterList; cptr != NULL; cptr = cptr->next ) - { - if(cptr->handle) - { + if (NULL == ppsd->pdh_query) + return; + + for (cptr = ppsd->pPerfCounterList; cptr != NULL; cptr = cptr->next) + if (NULL != cptr->handle) { PdhRemoveCounter(cptr->handle); cptr->handle = NULL; } - } - if( pperf->pdh_query ) - { - PdhCloseQuery(pperf->pdh_query); - pperf->pdh_query = NULL; - } - -#endif /* _WINDOWS */ + PdhCloseQuery(ppsd->pdh_query); + ppsd->pdh_query = NULL; + perfs_list_free(); } -void collect_perfstat(ZBX_PERF_STAT_DATA *pperf) +/****************************************************************************** + * * + * Function: collect_perfstat * + * * + * Purpose: * + * * + * Parameters: * + * * + * Return value: * + * * + * Author: Eugene Grigorjev * + * * + * Comments: * + * * + ******************************************************************************/ +void collect_perfstat() { -#ifdef _WINDOWS - PERF_COUNTERS *cptr = NULL; + PERF_COUNTERS *cptr; 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; - - if(cptr->CurrentNum < cptr->interval) - cptr->CurrentNum++; - } - } + if (NULL == ppsd->pdh_query) + return; + + if (ERROR_SUCCESS != (status = PdhCollectQueryData(ppsd->pdh_query))) { + zabbix_log( LOG_LEVEL_ERR, "Call to PdhCollectQueryData() failed: %s", strerror_from_module(status,"PDH.DLL")); + return; } + + /* Process user-defined counters */ + for ( cptr = ppsd->pPerfCounterList; cptr != NULL; cptr = cptr->next ) + { + if (cptr->interval == -1) /* Inactive counter? */ + continue; -#endif /* _WINDOWS */ + 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; + + if(cptr->CurrentNum < cptr->interval) + cptr->CurrentNum++; + } } +#endif /* _WINDOWS */ |