diff options
author | sauros <sauros@97f52cf1-0a1b-0410-bd0e-c28be96e8082> | 2002-12-09 12:57:22 +0000 |
---|---|---|
committer | sauros <sauros@97f52cf1-0a1b-0410-bd0e-c28be96e8082> | 2002-12-09 12:57:22 +0000 |
commit | f1608bb129124cee3115b0401e39019cabac6778 (patch) | |
tree | 09295db3a9720e7475d84a34729f0643bc929431 /src/zabbix_agent_win32 | |
parent | 574723158db387d229e65265fba2fef267b5b761 (diff) | |
download | zabbix-f1608bb129124cee3115b0401e39019cabac6778.tar.gz zabbix-f1608bb129124cee3115b0401e39019cabac6778.tar.xz zabbix-f1608bb129124cee3115b0401e39019cabac6778.zip |
Version 1.0.0-alpha3
Changes:
* Added parameter aliases
* Added request processing timeout (controlled by "Timeout" parameter
in configuration file)
* Added support for user-specified performance counters
Executables (both debug and release builds) also added to the repository.
git-svn-id: svn://svn.zabbix.com/trunk@589 97f52cf1-0a1b-0410-bd0e-c28be96e8082
Diffstat (limited to 'src/zabbix_agent_win32')
-rwxr-xr-x | src/zabbix_agent_win32/Debug/ZabbixW32.exe | bin | 0 -> 404 bytes | |||
-rwxr-xr-x | src/zabbix_agent_win32/Release/ZabbixW32.exe | bin | 0 -> 6846 bytes | |||
-rw-r--r-- | src/zabbix_agent_win32/ZabbixW32.dsp | 4 | ||||
-rw-r--r-- | src/zabbix_agent_win32/alias.cpp | 76 | ||||
-rw-r--r-- | src/zabbix_agent_win32/collect.cpp | 34 | ||||
-rw-r--r-- | src/zabbix_agent_win32/comm.cpp | 61 | ||||
-rw-r--r-- | src/zabbix_agent_win32/config.cpp | 107 | ||||
-rw-r--r-- | src/zabbix_agent_win32/main.cpp | 1 | ||||
-rw-r--r-- | src/zabbix_agent_win32/sysinfo.cpp | 30 | ||||
-rw-r--r-- | src/zabbix_agent_win32/zabbixw32.h | 51 |
10 files changed, 349 insertions, 15 deletions
diff --git a/src/zabbix_agent_win32/Debug/ZabbixW32.exe b/src/zabbix_agent_win32/Debug/ZabbixW32.exe Binary files differnew file mode 100755 index 00000000..0f32b9cd --- /dev/null +++ b/src/zabbix_agent_win32/Debug/ZabbixW32.exe diff --git a/src/zabbix_agent_win32/Release/ZabbixW32.exe b/src/zabbix_agent_win32/Release/ZabbixW32.exe Binary files differnew file mode 100755 index 00000000..e98ace8f --- /dev/null +++ b/src/zabbix_agent_win32/Release/ZabbixW32.exe diff --git a/src/zabbix_agent_win32/ZabbixW32.dsp b/src/zabbix_agent_win32/ZabbixW32.dsp index c6fd381c..a8daec55 100644 --- a/src/zabbix_agent_win32/ZabbixW32.dsp +++ b/src/zabbix_agent_win32/ZabbixW32.dsp @@ -87,6 +87,10 @@ LINK32=link.exe # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File +SOURCE=.\alias.cpp +# End Source File +# Begin Source File + SOURCE=.\collect.cpp # End Source File # Begin Source File diff --git a/src/zabbix_agent_win32/alias.cpp b/src/zabbix_agent_win32/alias.cpp new file mode 100644 index 00000000..ef4d29b5 --- /dev/null +++ b/src/zabbix_agent_win32/alias.cpp @@ -0,0 +1,76 @@ +/* +** ZabbixW32 - Win32 agent for Zabbix +** Copyright (C) 2002 Victor Kirhenshtein +** +** 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. +** +** $module: alias.cpp +** +**/ + +#include "zabbixw32.h" + + +// +// Static data +// + +static ALIAS *aliasList=NULL; + + +// +// Add alias to the list +// Returns TRUE on success or FALSE if alias with that name already exist +// + +BOOL AddAlias(char *name,char *value) +{ + ALIAS *alias; + + // Find alias in the list + for(alias=aliasList;alias!=NULL;alias=alias->next) + if (!strcmp(alias->name,name)) + return FALSE; + + // Create new structure and add it to the list + alias=(ALIAS *)malloc(sizeof(ALIAS)); + memset(alias,0,sizeof(ALIAS)); + strncpy(alias->name,name,MAX_ALIAS_NAME-1); + alias->value=(char *)malloc(strlen(value)+1); + strcpy(alias->value,value); + alias->next=aliasList; + aliasList=alias; + + return TRUE; +} + + +// +// Checks parameter and expands it if aliased +// + +void ExpandAlias(char *orig,char *expanded) +{ + ALIAS *alias; + + for(alias=aliasList;alias!=NULL;alias=alias->next) + if (!strcmp(alias->name,orig)) + { + strcpy(expanded,alias->value); + return; + } + + strcpy(expanded,orig); +} diff --git a/src/zabbix_agent_win32/collect.cpp b/src/zabbix_agent_win32/collect.cpp index a8a7153a..1d557406 100644 --- a/src/zabbix_agent_win32/collect.cpp +++ b/src/zabbix_agent_win32/collect.cpp @@ -21,13 +21,13 @@ **/ #include "zabbixw32.h" -#include <pdh.h> // // Global variables // +USER_COUNTER *userCounterList=NULL; float statProcUtilization[MAX_CPU+1]; float statProcUtilization5[MAX_CPU+1]; float statProcUtilization15[MAX_CPU+1]; @@ -58,6 +58,8 @@ void CollectorThread(void *) PDH_STATUS status; SYSTEM_INFO sysInfo; DWORD i,cpuHistoryIdx,cpuQueueHistoryIdx; + USER_COUNTER *cptr; + PDH_STATISTICS statData; TlsSetValue(dwTlsLogPrefix,"Collector: "); // Set log prefix for collector thread GetSystemInfo(&sysInfo); @@ -115,13 +117,27 @@ void CollectorThread(void *) memset(cpuQueueHistory,0,sizeof(LONG)*900); cpuQueueHistoryIdx=0; + // Add user counters to query + for(cptr=userCounterList;cptr!=NULL;cptr=cptr->next) + { + if (PdhAddCounter(query,cptr->counterPath,0,&cptr->handle)!=ERROR_SUCCESS) + { + cptr->interval=-1; // Flag for unsupported counters + cptr->lastValue=NOTSUPPORTED; + WriteLog("Unable to add user-defined counter %s=\"%s\" to query\r\n", + cptr->name,cptr->counterPath); + } + } + // Data collection loop WriteLog("Initialization complete\r\n"); do { LONG sum; int j,n; + DWORD dwTicksStart,dwTicksElapsed; + dwTicksStart=GetTickCount(); if ((status=PdhCollectQueryData(query))!=ERROR_SUCCESS) WriteLog("PdhCollectQueryData failed (status=%08X)\r\n",status); @@ -193,6 +209,22 @@ void CollectorThread(void *) cpuQueueHistoryIdx++; if (cpuQueueHistoryIdx==900) cpuQueueHistoryIdx=0; + + // Process user-defined counters + for(cptr=userCounterList;cptr!=NULL;cptr=cptr->next) + if (cptr->interval>0) // Active counter? + { + PdhGetRawCounterValue(cptr->handle,NULL,&cptr->rawValueArray[cptr->currPos++]); + if (cptr->currPos==cptr->interval) + cptr->currPos=0; + PdhComputeCounterStatistics(cptr->handle,PDH_FMT_DOUBLE,cptr->currPos, + cptr->interval,cptr->rawValueArray,&statData); + cptr->lastValue=(float)statData.mean.doubleValue; + } + + dwTicksElapsed=GetTickCount()-dwTicksStart; + if (dwTicksElapsed>100) + WriteLog("Processing took more then 100 milliseconds (%d milliseconds)\r\n",dwTicksElapsed); } while(WaitForSingleObject(eventShutdown,1000)==WAIT_TIMEOUT); diff --git a/src/zabbix_agent_win32/comm.cpp b/src/zabbix_agent_win32/comm.cpp index b69558e9..a1975ebb 100644 --- a/src/zabbix_agent_win32/comm.cpp +++ b/src/zabbix_agent_win32/comm.cpp @@ -24,6 +24,29 @@ // +// Request structure +// + +struct REQUEST +{ + char cmd[MAX_ZABBIX_CMD_LEN]; + char result[MAX_STRING_LEN]; +}; + + +// +// Request processing thread +// + +static unsigned int __stdcall ProcessingThread(void *arg) +{ + TlsSetValue(dwTlsLogPrefix,"ProcessingThread: "); + ProcessCommand(((REQUEST *)arg)->cmd,((REQUEST *)arg)->result); + return 0; +} + + +// // Client communication thread // @@ -31,26 +54,54 @@ static void CommThread(void *param) { SOCKET sock; int rc; - char cmd[MAX_ZABBIX_CMD_LEN],result[MAX_STRING_LEN]; + REQUEST rq; + struct timeval timeout; + FD_SET rdfs; + HANDLE hThread=NULL; + unsigned int tid; TlsSetValue(dwTlsLogPrefix,"CommThread: "); // Set log prefix for communication thread sock=(SOCKET)param; - rc=recv(sock,cmd,MAX_ZABBIX_CMD_LEN,0); + // Wait for command from server + FD_ZERO(&rdfs); + FD_SET(sock,&rdfs); + timeout.tv_sec=COMMAND_TIMEOUT; + timeout.tv_usec=0; + if (select(sock+1,&rdfs,NULL,NULL,&timeout)==0) + { + WriteLog("Timed out waiting for server command\r\n"); + goto end_session; + } + + rc=recv(sock,rq.cmd,MAX_ZABBIX_CMD_LEN,0); if (rc<=0) { WriteLog("recv() failed [%s]\r\n",strerror(errno)); goto end_session; } - cmd[rc-1]=0; - ProcessCommand(cmd,result); - send(sock,result,strlen(result),0); + rq.cmd[rc-1]=0; + + hThread=(HANDLE)_beginthreadex(NULL,0,ProcessingThread,(void *)&rq,0,&tid); + if (WaitForSingleObject(hThread,confTimeout)==WAIT_TIMEOUT) + { + sprintf(rq.result,"%f",(float)TIMEOUT_ERROR); + WriteLog("Timed out while processing request (%s)\r\n",rq.cmd); + } + send(sock,rq.result,strlen(rq.result),0); // Terminate session end_session: shutdown(sock,2); closesocket(sock); + + // Now wait for processing thread completion if we start one + if (hThread!=NULL) + { + WaitForSingleObject(hThread,INFINITE); + CloseHandle(hThread); + } } diff --git a/src/zabbix_agent_win32/config.cpp b/src/zabbix_agent_win32/config.cpp index 8027fdcd..47d191d9 100644 --- a/src/zabbix_agent_win32/config.cpp +++ b/src/zabbix_agent_win32/config.cpp @@ -24,6 +24,66 @@ // +// Parse PerfCounter=... parameter and add new performance counter +// Argument is a config file parameter value which should have the following syntax: +// <key>,"<counter path>",<time interval> +// Returns TRUE on success and FALSE otherwise +// + +static BOOL AddPerformanceCounter(char *args) +{ + char *ptr1,*ptr2,*eptr,buffer[MAX_ALIAS_NAME]; + USER_COUNTER *counter; + int i; + + ptr1=strchr(args,','); + if (ptr1==NULL) + return FALSE; // Invalid syntax + + *ptr1=0; + ptr1++; + StrStrip(args); + StrStrip(ptr1); + if (*ptr1!='"') + return FALSE; // Invalid syntax + ptr1++; + ptr2=strchr(ptr1,'"'); + if (ptr2==NULL) + return FALSE; // Invalid syntax + *ptr2=0; + ptr2++; + StrStrip(ptr2); + if (*ptr2!=',') + return FALSE; // Invalid syntax + ptr2++; + StrStrip(ptr2); + + i=strtol(ptr2,&eptr,10); + if ((*eptr!=0)|| // Not a decimal number + (i<1)||(i>1800)) // Interval value out of range + return FALSE; // Invalid syntax + + // Add internal alias + sprintf(buffer,"__usercnt{%s}",args); + if (!AddAlias(args,buffer)) + return FALSE; + + counter=(USER_COUNTER *)malloc(sizeof(USER_COUNTER)); + memset(counter,0,sizeof(USER_COUNTER)); + + strncpy(counter->name,args,MAX_COUNTER_NAME-1); + strncpy(counter->counterPath,ptr1,MAX_PATH-1); + counter->interval=i; + counter->rawValueArray=(PDH_RAW_COUNTER *)malloc(sizeof(PDH_RAW_COUNTER)*counter->interval); + + // Add to the list + counter->next=userCounterList; + userCounterList=counter; + return TRUE; +} + + +// // Read configuration // @@ -105,6 +165,53 @@ BOOL ReadConfig(void) confListenPort=(WORD)n; } } + else if (!stricmp(buffer,"Alias")) + { + char *sep; + + sep=strchr(ptr,':'); + if (sep==NULL) + { + errors++; + if (optStandalone) + printf("Error in configuration file, line %d: invalid alias syntax\n",sourceLine); + } + else + { + *sep=0; + sep++; + StrStrip(ptr); + StrStrip(sep); + AddAlias(ptr,sep); + } + } + else if (!stricmp(buffer,"Timeout")) + { + int tm; + + tm=atoi(ptr); + if ((tm>0)&&(tm<=30)) + { + confTimeout=tm*1000; // Convert to milliseconds + } + else + { + errors++; + if (optStandalone) + printf("Error in configuration file, line %d: invalid timeout value (%d seconds)\n", + sourceLine,tm); + } + } + else if (!stricmp(buffer,"PerfCounter")) + { + if (!AddPerformanceCounter(ptr)) + { + errors++; + if (optStandalone) + printf("Error in configuration file, line %d: invalid performance counter specification\n", + sourceLine); + } + } else if ((!stricmp(buffer,"PidFile"))||(!stricmp(buffer,"NoTimeWait"))|| (!stricmp(buffer,"StartAgents"))||(!stricmp(buffer,"DebugLevel"))) { diff --git a/src/zabbix_agent_win32/main.cpp b/src/zabbix_agent_win32/main.cpp index f25b5297..d555addc 100644 --- a/src/zabbix_agent_win32/main.cpp +++ b/src/zabbix_agent_win32/main.cpp @@ -36,6 +36,7 @@ char confFile[MAX_PATH]="C:\\zabbix_agentd.conf"; char logFile[MAX_PATH]="C:\\zabbix_agentd.log"; WORD confListenPort=10000; DWORD confServerAddr=0; +DWORD confTimeout=3000; // 3 seconds default timeout // diff --git a/src/zabbix_agent_win32/sysinfo.cpp b/src/zabbix_agent_win32/sysinfo.cpp index ace65d84..28993e9a 100644 --- a/src/zabbix_agent_win32/sysinfo.cpp +++ b/src/zabbix_agent_win32/sysinfo.cpp @@ -22,7 +22,6 @@ #include "zabbixw32.h" #include <psapi.h> -#include <pdh.h> // @@ -332,11 +331,33 @@ static float H_PerfCounter(char *cmd,char *arg) // +// Handler for user counters +// + +static float H_UserCounter(char *cmd,char *arg) +{ + USER_COUNTER *counter; + char *ptr1,*ptr2; + + ptr1=strchr(cmd,'{'); + ptr2=strchr(cmd,'}'); + ptr1++; + *ptr2=0; + for(counter=userCounterList;counter!=NULL;counter=counter->next) + if (!strcmp(counter->name,ptr1)) + return counter->lastValue; + + return NOTSUPPORTED; +} + + +// // Parameters and handlers // static AGENT_COMMAND commands[]= { + { "__usercnt{*}",H_UserCounter,NULL,NULL }, { "cpu_util",H_ProcUtil,NULL,(char *)0x00 }, { "cpu_util5",H_ProcUtil,NULL,(char *)0x01 }, { "cpu_util15",H_ProcUtil,NULL,(char *)0x02 }, @@ -365,12 +386,15 @@ static AGENT_COMMAND commands[]= // Command processing function // -void ProcessCommand(char *cmd,char *result) +void ProcessCommand(char *received_cmd,char *result) { int i; float fResult=NOTSUPPORTED; - char *strResult=NULL; + char *strResult=NULL,cmd[MAX_ZABBIX_CMD_LEN]; + + ExpandAlias(received_cmd,cmd); + // Find match for command for(i=0;;i++) { if (commands[i].name[0]==0) diff --git a/src/zabbix_agent_win32/zabbixw32.h b/src/zabbix_agent_win32/zabbixw32.h index 8595e34f..238c919d 100644 --- a/src/zabbix_agent_win32/zabbixw32.h +++ b/src/zabbix_agent_win32/zabbixw32.h @@ -26,6 +26,7 @@ #include <windows.h> #include <process.h> #include <stdio.h> +#include <pdh.h> #include "common.h" @@ -33,30 +34,62 @@ // Common constants // -#define AGENT_VERSION "1.0.0-alpha2" +#define AGENT_VERSION "1.0.0-alpha3" #define ZABBIX_SERVICE_NAME "ZabbixAgentdW32" -#define MAX_ZABBIX_CMD_LEN MAX_STRING_LEN +#define COMMAND_TIMEOUT 5 +#define MAX_ZABBIX_CMD_LEN MAX_STRING_LEN #define MAX_CPU 16 #define MAX_PARAMETERS 256 #define MAX_PARAM_NAME 64 #define MAX_PROCESSES 4096 #define MAX_MODULES 512 +#define MAX_ALIAS_NAME 120 +#define MAX_COUNTER_NAME (MAX_ALIAS_NAME-12) // // Parameter definition structure // -typedef struct +struct AGENT_COMMAND { char name[MAX_PARAM_NAME]; // Command's name - float (* handler_float)(char *,char *); // Handler if return value is numeric - char * (* handler_string)(char *,char *); // Handler if return value is string + float (* handler_float)(char *,char *); // Handler if return value is numeric + char *(* handler_string)(char *,char *); // Handler if return value is string char *arg; // Optional command argument -} AGENT_COMMAND; +}; + + +// +// Alias information structure +// + +struct ALIAS +{ + ALIAS *next; + char name[MAX_ALIAS_NAME]; + char *value; +}; + + +// +// User-defined performance counter structure +// + +struct USER_COUNTER +{ + USER_COUNTER *next; // Pointer to next counter in chain + char name[MAX_PARAM_NAME]; + char counterPath[MAX_PATH]; + LONG interval; // Time interval used in calculations + LONG currPos; // Current position in buffer + HCOUNTER handle; // Counter handle (set by collector thread) + PDH_RAW_COUNTER *rawValueArray; + float lastValue; // Last computed average value +}; // @@ -89,6 +122,9 @@ void ProcessCommand(char *cmd,char *result); BOOL ReadConfig(void); +BOOL AddAlias(char *name,char *value); +void ExpandAlias(char *orig,char *expanded); + // // Global variables @@ -102,6 +138,9 @@ extern char confFile[]; extern char logFile[]; extern DWORD confServerAddr; extern WORD confListenPort; +extern DWORD confTimeout; + +extern USER_COUNTER *userCounterList; extern float statProcUtilization[]; extern float statProcUtilization5[]; |