summaryrefslogtreecommitdiffstats
path: root/src/zabbix_agent_win32
diff options
context:
space:
mode:
authorsauros <sauros@97f52cf1-0a1b-0410-bd0e-c28be96e8082>2002-12-09 12:57:22 +0000
committersauros <sauros@97f52cf1-0a1b-0410-bd0e-c28be96e8082>2002-12-09 12:57:22 +0000
commitf1608bb129124cee3115b0401e39019cabac6778 (patch)
tree09295db3a9720e7475d84a34729f0643bc929431 /src/zabbix_agent_win32
parent574723158db387d229e65265fba2fef267b5b761 (diff)
downloadzabbix-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-xsrc/zabbix_agent_win32/Debug/ZabbixW32.exebin0 -> 404 bytes
-rwxr-xr-xsrc/zabbix_agent_win32/Release/ZabbixW32.exebin0 -> 6846 bytes
-rw-r--r--src/zabbix_agent_win32/ZabbixW32.dsp4
-rw-r--r--src/zabbix_agent_win32/alias.cpp76
-rw-r--r--src/zabbix_agent_win32/collect.cpp34
-rw-r--r--src/zabbix_agent_win32/comm.cpp61
-rw-r--r--src/zabbix_agent_win32/config.cpp107
-rw-r--r--src/zabbix_agent_win32/main.cpp1
-rw-r--r--src/zabbix_agent_win32/sysinfo.cpp30
-rw-r--r--src/zabbix_agent_win32/zabbixw32.h51
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
new file mode 100755
index 00000000..0f32b9cd
--- /dev/null
+++ b/src/zabbix_agent_win32/Debug/ZabbixW32.exe
Binary files differ
diff --git a/src/zabbix_agent_win32/Release/ZabbixW32.exe b/src/zabbix_agent_win32/Release/ZabbixW32.exe
new file mode 100755
index 00000000..e98ace8f
--- /dev/null
+++ b/src/zabbix_agent_win32/Release/ZabbixW32.exe
Binary files differ
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[];