CPU usage parameters on Windows moved to winnt.nsm from winperf.nsm and no longer...
authorVictor Kirhenshtein <victor@netxms.org>
Mon, 3 Oct 2016 10:17:46 +0000 (13:17 +0300)
committerVictor Kirhenshtein <victor@netxms.org>
Mon, 3 Oct 2016 10:17:46 +0000 (13:17 +0300)
ChangeLog
include/nms_agent.h
src/agent/subagents/winnt/Makefile.am
src/agent/subagents/winnt/cpu.cpp [new file with mode: 0644]
src/agent/subagents/winnt/main.cpp
src/agent/subagents/winnt/winnt.vcproj
src/agent/subagents/winperf/winperf.cpp

index 37e29b2..be5f04e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -27,6 +27,7 @@
 - New object tool type "server script"
 - Number of polls can be set for "diff" type thresholds 
 - Instance discovery scripts can return instances as map instance/instance name
+- CPU usage parameters on Windows moved to winnt.nsm from winperf.nsm and no longer depends on PDH
 - New agent metrics for self-monitoring:
        Agent.SyslogProxy.IsEnabled, Agent.SyslogProxy.ReceivedMessages, Agent.SyslogProxy.QueueSize
 - Management console
index e050fcc..8e71424 100644 (file)
 #define DCIDESC_SYSTEM_CPU_LOADAVG5               _T("Average CPU load for last 5 minutes")
 #define DCIDESC_SYSTEM_CPU_LOADAVG15              _T("Average CPU load for last 15 minutes")
 
-
 #define DCIDESC_SYSTEM_CPU_USAGE_EX               _T("Average CPU {instance} utilization for last minute")
 #define DCIDESC_SYSTEM_CPU_USAGE5_EX              _T("Average CPU {instance} utilization for last 5 minutes")
 #define DCIDESC_SYSTEM_CPU_USAGE15_EX             _T("Average CPU {instance} utilization for last 15 minutes")
-#define DCIDESC_SYSTEM_CPU_USAGECURR_EX           _T("Current CPU {instance} utilization")
 #define DCIDESC_SYSTEM_CPU_USAGE                  _T("Average CPU utilization for last minute")
 #define DCIDESC_SYSTEM_CPU_USAGE5                 _T("Average CPU utilization for last 5 minutes")
 #define DCIDESC_SYSTEM_CPU_USAGE15                _T("Average CPU utilization for last 15 minutes")
 #define DCIDESC_SYSTEM_CPU_USAGECURR              _T("Current CPU utilization")
+#define DCIDESC_SYSTEM_CPU_USAGECURR_EX           _T("Current CPU {instance} utilization")
 
 #define DCIDESC_SYSTEM_CPU_USAGE_USER_EX          _T("Average CPU {instance} utilization (user) for last minute")
 #define DCIDESC_SYSTEM_CPU_USAGE5_USER_EX         _T("Average CPU {instance} utilization (user) for last 5 minutes")
 #define DCIDESC_SYSTEM_CPU_USAGE_USER             _T("Average CPU utilization (user) for last minute")
 #define DCIDESC_SYSTEM_CPU_USAGE5_USER            _T("Average CPU utilization (user) for last 5 minutes")
 #define DCIDESC_SYSTEM_CPU_USAGE15_USER           _T("Average CPU utilization (user) for last 15 minutes")
+#define DCIDESC_SYSTEM_CPU_USAGECURR_USER         _T("Current CPU utilization (user)")
+#define DCIDESC_SYSTEM_CPU_USAGECURR_USER_EX      _T("Current CPU {instance} utilization (user)")
 
 #define DCIDESC_SYSTEM_CPU_USAGE_NICE_EX          _T("Average CPU {instance} utilization (nice) for last minute")
 #define DCIDESC_SYSTEM_CPU_USAGE5_NICE_EX         _T("Average CPU {instance} utilization (nice) for last 5 minutes")
 #define DCIDESC_SYSTEM_CPU_USAGE_NICE             _T("Average CPU utilization (nice) for last minute")
 #define DCIDESC_SYSTEM_CPU_USAGE5_NICE            _T("Average CPU utilization (nice) for last 5 minutes")
 #define DCIDESC_SYSTEM_CPU_USAGE15_NICE           _T("Average CPU utilization (nice) for last 15 minutes")
+#define DCIDESC_SYSTEM_CPU_USAGECURR_NICE         _T("Current CPU utilization (nice)")
+#define DCIDESC_SYSTEM_CPU_USAGECURR_NICE_EX      _T("Current CPU {instance} utilization (nice)")
 
 #define DCIDESC_SYSTEM_CPU_USAGE_SYSTEM_EX        _T("Average CPU {instance} utilization (system) for last minute")
 #define DCIDESC_SYSTEM_CPU_USAGE5_SYSTEM_EX       _T("Average CPU {instance} utilization (system) for last 5 minutes")
 #define DCIDESC_SYSTEM_CPU_USAGE_SYSTEM           _T("Average CPU utilization (system) for last minute")
 #define DCIDESC_SYSTEM_CPU_USAGE5_SYSTEM          _T("Average CPU utilization (system) for last 5 minutes")
 #define DCIDESC_SYSTEM_CPU_USAGE15_SYSTEM         _T("Average CPU utilization (system) for last 15 minutes")
-
-#define DCIDESC_SYSTEM_CPU_USAGE_IDLE_EX               _T("Average CPU {instance} utilization (idle) for last minute")
-#define DCIDESC_SYSTEM_CPU_USAGE5_IDLE_EX              _T("Average CPU {instance} utilization (idle) for last 5 minutes")
-#define DCIDESC_SYSTEM_CPU_USAGE15_IDLE_EX             _T("Average CPU {instance} utilization (idle) for last 15 minutes")
-#define DCIDESC_SYSTEM_CPU_USAGE_IDLE          _T("Average CPU utilization (idle) for last minute")
-#define DCIDESC_SYSTEM_CPU_USAGE5_IDLE         _T("Average CPU utilization (idle) for last 5 minutes")
-#define DCIDESC_SYSTEM_CPU_USAGE15_IDLE                _T("Average CPU utilization (idle) for last 15 minutes")
-
-#define DCIDESC_SYSTEM_CPU_USAGE_IOWAIT_EX             _T("Average CPU {instance} utilization (iowait) for last minute")
-#define DCIDESC_SYSTEM_CPU_USAGE5_IOWAIT_EX            _T("Average CPU {instance} utilization (iowait) for last 5 minutes")
-#define DCIDESC_SYSTEM_CPU_USAGE15_IOWAIT_EX           _T("Average CPU {instance} utilization (iowait) for last 15 minutes")
-#define DCIDESC_SYSTEM_CPU_USAGE_IOWAIT                _T("Average CPU utilization (iowait) for last minute")
-#define DCIDESC_SYSTEM_CPU_USAGE5_IOWAIT               _T("Average CPU utilization (iowait) for last 5 minutes")
-#define DCIDESC_SYSTEM_CPU_USAGE15_IOWAIT              _T("Average CPU utilization (iowait) for last 15 minutes")
-
-#define DCIDESC_SYSTEM_CPU_USAGE_IRQ_EX                _T("Average CPU {instance} utilization (irq) for last minute")
-#define DCIDESC_SYSTEM_CPU_USAGE5_IRQ_EX               _T("Average CPU {instance} utilization (irq) for last 5 minutes")
-#define DCIDESC_SYSTEM_CPU_USAGE15_IRQ_EX              _T("Average CPU {instance} utilization (irq) for last 15 minutes")
-#define DCIDESC_SYSTEM_CPU_USAGE_IRQ           _T("Average CPU utilization (irq) for last minute")
-#define DCIDESC_SYSTEM_CPU_USAGE5_IRQ          _T("Average CPU utilization (irq) for last 5 minutes")
-#define DCIDESC_SYSTEM_CPU_USAGE15_IRQ         _T("Average CPU utilization (irq) for last 15 minutes")
-
-#define DCIDESC_SYSTEM_CPU_USAGE_SOFTIRQ_EX            _T("Average CPU {instance} utilization (softirq) for last minute")
-#define DCIDESC_SYSTEM_CPU_USAGE5_SOFTIRQ_EX           _T("Average CPU {instance} utilization (softirq) for last 5 minutes")
-#define DCIDESC_SYSTEM_CPU_USAGE15_SOFTIRQ_EX          _T("Average CPU {instance} utilization (softirq) for last 15 minutes")
-#define DCIDESC_SYSTEM_CPU_USAGE_SOFTIRQ               _T("Average CPU utilization (softirq) for last minute")
-#define DCIDESC_SYSTEM_CPU_USAGE5_SOFTIRQ              _T("Average CPU utilization (softirq) for last 5 minutes")
-#define DCIDESC_SYSTEM_CPU_USAGE15_SOFTIRQ             _T("Average CPU utilization (softirq) for last 15 minutes")
+#define DCIDESC_SYSTEM_CPU_USAGECURR_SYSTEM       _T("Current CPU utilization (system)")
+#define DCIDESC_SYSTEM_CPU_USAGECURR_SYSTEM_EX    _T("Current CPU {instance} utilization (system)")
+
+#define DCIDESC_SYSTEM_CPU_USAGE_IDLE_EX          _T("Average CPU {instance} utilization (idle) for last minute")
+#define DCIDESC_SYSTEM_CPU_USAGE5_IDLE_EX         _T("Average CPU {instance} utilization (idle) for last 5 minutes")
+#define DCIDESC_SYSTEM_CPU_USAGE15_IDLE_EX        _T("Average CPU {instance} utilization (idle) for last 15 minutes")
+#define DCIDESC_SYSTEM_CPU_USAGE_IDLE             _T("Average CPU utilization (idle) for last minute")
+#define DCIDESC_SYSTEM_CPU_USAGE5_IDLE            _T("Average CPU utilization (idle) for last 5 minutes")
+#define DCIDESC_SYSTEM_CPU_USAGE15_IDLE           _T("Average CPU utilization (idle) for last 15 minutes")
+#define DCIDESC_SYSTEM_CPU_USAGECURR_IDLE         _T("Current CPU utilization (idle)")
+#define DCIDESC_SYSTEM_CPU_USAGECURR_IDLE_EX      _T("Current CPU {instance} utilization (idle)")
+
+#define DCIDESC_SYSTEM_CPU_USAGE_IOWAIT_EX        _T("Average CPU {instance} utilization (iowait) for last minute")
+#define DCIDESC_SYSTEM_CPU_USAGE5_IOWAIT_EX       _T("Average CPU {instance} utilization (iowait) for last 5 minutes")
+#define DCIDESC_SYSTEM_CPU_USAGE15_IOWAIT_EX      _T("Average CPU {instance} utilization (iowait) for last 15 minutes")
+#define DCIDESC_SYSTEM_CPU_USAGE_IOWAIT           _T("Average CPU utilization (iowait) for last minute")
+#define DCIDESC_SYSTEM_CPU_USAGE5_IOWAIT          _T("Average CPU utilization (iowait) for last 5 minutes")
+#define DCIDESC_SYSTEM_CPU_USAGE15_IOWAIT         _T("Average CPU utilization (iowait) for last 15 minutes")
+#define DCIDESC_SYSTEM_CPU_USAGECURR_IOWAIT       _T("Current CPU utilization (iowait)")
+#define DCIDESC_SYSTEM_CPU_USAGECURR_IOWAIT_EX    _T("Current CPU {instance} utilization (iowait)")
+
+#define DCIDESC_SYSTEM_CPU_USAGE_IRQ_EX           _T("Average CPU {instance} utilization (irq) for last minute")
+#define DCIDESC_SYSTEM_CPU_USAGE5_IRQ_EX          _T("Average CPU {instance} utilization (irq) for last 5 minutes")
+#define DCIDESC_SYSTEM_CPU_USAGE15_IRQ_EX         _T("Average CPU {instance} utilization (irq) for last 15 minutes")
+#define DCIDESC_SYSTEM_CPU_USAGE_IRQ              _T("Average CPU utilization (irq) for last minute")
+#define DCIDESC_SYSTEM_CPU_USAGE5_IRQ             _T("Average CPU utilization (irq) for last 5 minutes")
+#define DCIDESC_SYSTEM_CPU_USAGE15_IRQ            _T("Average CPU utilization (irq) for last 15 minutes")
+#define DCIDESC_SYSTEM_CPU_USAGECURR_IRQ          _T("Current CPU utilization (irq)")
+#define DCIDESC_SYSTEM_CPU_USAGECURR_IRQ_EX       _T("Current CPU {instance} utilization (irq)")
+
+#define DCIDESC_SYSTEM_CPU_USAGE_SOFTIRQ_EX       _T("Average CPU {instance} utilization (softirq) for last minute")
+#define DCIDESC_SYSTEM_CPU_USAGE5_SOFTIRQ_EX      _T("Average CPU {instance} utilization (softirq) for last 5 minutes")
+#define DCIDESC_SYSTEM_CPU_USAGE15_SOFTIRQ_EX     _T("Average CPU {instance} utilization (softirq) for last 15 minutes")
+#define DCIDESC_SYSTEM_CPU_USAGE_SOFTIRQ          _T("Average CPU utilization (softirq) for last minute")
+#define DCIDESC_SYSTEM_CPU_USAGE5_SOFTIRQ         _T("Average CPU utilization (softirq) for last 5 minutes")
+#define DCIDESC_SYSTEM_CPU_USAGE15_SOFTIRQ        _T("Average CPU utilization (softirq) for last 15 minutes")
+#define DCIDESC_SYSTEM_CPU_USAGECURR_SOFTIRQ      _T("Current CPU utilization (softirq)")
+#define DCIDESC_SYSTEM_CPU_USAGECURR_SOFTIRQ_EX   _T("Current CPU {instance} utilization (softirq)")
 
 #define DCIDESC_SYSTEM_CPU_USAGE_STEAL_EX         _T("Average CPU {instance} utilization (steal) for last minute")
 #define DCIDESC_SYSTEM_CPU_USAGE5_STEAL_EX        _T("Average CPU {instance} utilization (steal) for last 5 minutes")
 #define DCIDESC_SYSTEM_CPU_USAGE_STEAL            _T("Average CPU utilization (steal) for last minute")
 #define DCIDESC_SYSTEM_CPU_USAGE5_STEAL           _T("Average CPU utilization (steal) for last 5 minutes")
 #define DCIDESC_SYSTEM_CPU_USAGE15_STEAL          _T("Average CPU utilization (steal) for last 15 minutes")
+#define DCIDESC_SYSTEM_CPU_USAGECURR_STEAL        _T("Current CPU utilization (steal)")
+#define DCIDESC_SYSTEM_CPU_USAGECURR_STEAL_EX     _T("Current CPU {instance} utilization (steal)")
 
 #define DCIDESC_SYSTEM_CPU_USAGE_GUEST_EX         _T("Average CPU {instance} utilization (guest) for last minute")
 #define DCIDESC_SYSTEM_CPU_USAGE5_GUEST_EX        _T("Average CPU {instance} utilization (guest) for last 5 minutes")
 #define DCIDESC_SYSTEM_CPU_USAGE_GUEST            _T("Average CPU utilization (guest) for last minute")
 #define DCIDESC_SYSTEM_CPU_USAGE5_GUEST           _T("Average CPU utilization (guest) for last 5 minutes")
 #define DCIDESC_SYSTEM_CPU_USAGE15_GUEST          _T("Average CPU utilization (guest) for last 15 minutes")
+#define DCIDESC_SYSTEM_CPU_USAGECURR_GUEST        _T("Current CPU utilization (guest)")
+#define DCIDESC_SYSTEM_CPU_USAGECURR_GUEST_EX     _T("Current CPU {instance} utilization (guest)")
 
 #define DCIDESC_SYSTEM_IO_DISKQUEUE               _T("Average disk queue length for last minute")
 #define DCIDESC_SYSTEM_IO_DISKQUEUE_MIN           _T("Minimum disk queue length for last minute")
index 92d9bbb..2d0584e 100644 (file)
@@ -9,6 +9,7 @@
 # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
 EXTRA_DIST = \
+       cpu.cpp \
        main.cpp \
        net.cpp \
        procinfo.cpp \
diff --git a/src/agent/subagents/winnt/cpu.cpp b/src/agent/subagents/winnt/cpu.cpp
new file mode 100644 (file)
index 0000000..110c1ca
--- /dev/null
@@ -0,0 +1,238 @@
+/*
+** NetXMS platform subagent for Windows
+** Copyright (C) 2003-2016 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.
+**
+** File: cpu.cpp
+**
+**/
+
+#include "winnt_subagent.h"
+#include <winternl.h>
+
+static int s_cpuCount = 0;
+static SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION *s_cpuTimes = NULL;
+static UINT32 *s_usage = NULL;
+static UINT32 *s_idle = NULL;
+static UINT32 *s_kernel = NULL;
+static UINT32 *s_user = NULL;
+static int s_bpos = 0;
+static CRITICAL_SECTION s_lock;
+
+/**
+ * CPU collector thread
+ */
+static THREAD_RESULT THREAD_CALL CPUStatCollector(void *arg)
+{
+   nxlog_debug(3, _T("CPU stat collector started (%d CPUs)"), s_cpuCount);
+
+   SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION *prev = s_cpuTimes;
+   SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION *curr = &s_cpuTimes[s_cpuCount];
+
+   ULONG cpuTimesLen = sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) * s_cpuCount;
+   ULONG size;
+   NtQuerySystemInformation(SystemProcessorPerformanceInformation, s_cpuTimes, cpuTimesLen, &size);
+
+   while(!AgentSleepAndCheckForShutdown(1000))
+   {
+      if (NtQuerySystemInformation(SystemProcessorPerformanceInformation, curr, cpuTimesLen, &size) != 0)
+      {
+         memcpy(curr, prev, cpuTimesLen);
+      }
+
+      UINT64 sysIdle = 0;
+      UINT64 sysKernel = 0;
+      UINT64 sysUser = 0;
+
+      EnterCriticalSection(&s_lock);
+
+      int idx = s_bpos;
+      for(int i = 0; i < s_cpuCount; i++, idx++)
+      {
+         UINT64 idle = curr[i].IdleTime.QuadPart - prev[i].IdleTime.QuadPart;
+         UINT64 kernel = curr[i].KernelTime.QuadPart - prev[i].KernelTime.QuadPart;
+         UINT64 user = curr[i].UserTime.QuadPart - prev[i].UserTime.QuadPart;
+         UINT64 total = kernel + user;  // kernel time includes idle time
+
+         sysIdle += idle;
+         sysKernel += kernel;
+         sysUser += user;
+
+         if (total > 0)
+         {
+            s_usage[idx] = (UINT32)((total - idle) * 10000 / total);
+            s_idle[idx] = (UINT32)(idle * 10000 / total);
+            s_kernel[idx] = (UINT32)((kernel - idle) * 10000 / total);
+            s_user[idx] = (UINT32)(user * 10000 / total);
+         }
+         else
+         {
+            s_usage[idx] = 0;
+            s_idle[idx] = 0;
+            s_kernel[idx] = 0;
+            s_user[idx] = 0;
+         }
+      }
+
+      UINT64 sysTotal = sysKernel + sysUser;
+      if (sysTotal > 0)
+      {
+         s_usage[idx] = (UINT32)((sysTotal - sysIdle) * 10000 / sysTotal);
+         s_idle[idx] = (UINT32)(sysIdle * 10000 / sysTotal);
+         s_kernel[idx] = (UINT32)((sysKernel - sysIdle) * 10000 / sysTotal);
+         s_user[idx] = (UINT32)(sysUser * 10000 / sysTotal);
+      }
+      else
+      {
+         s_usage[idx] = 0;
+         s_idle[idx] = 0;
+         s_kernel[idx] = 0;
+         s_user[idx] = 0;
+      }
+
+      s_bpos += s_cpuCount + 1;
+      if (s_bpos >= (s_cpuCount + 1) * 900)
+         s_bpos = 0;
+
+      LeaveCriticalSection(&s_lock);
+      
+      // swap buffers
+      if (curr == s_cpuTimes)
+      {
+         curr = prev;
+         prev = s_cpuTimes;
+      }
+      else
+      {
+         prev = curr;
+         curr = s_cpuTimes;
+      }
+   }
+   nxlog_debug(3, _T("CPU stat collector stopped"));
+   return THREAD_OK;
+}
+
+/**
+ * Collector thread handle
+ */
+static THREAD s_collectorThread = INVALID_THREAD_HANDLE;
+
+/**
+ * Start collector
+ */
+void StartCPUStatCollector()
+{
+   SYSTEM_INFO si;
+   GetSystemInfo(&si);
+   s_cpuCount = (int)si.dwNumberOfProcessors;
+   s_cpuTimes = (SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION *)malloc(sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) * s_cpuCount * 2);
+   s_usage = (UINT32 *)calloc(900, sizeof(UINT32) * (s_cpuCount + 1));
+   s_idle = (UINT32 *)calloc(900, sizeof(UINT32) * (s_cpuCount + 1));
+   s_kernel = (UINT32 *)calloc(900, sizeof(UINT32) * (s_cpuCount + 1));
+   s_user = (UINT32 *)calloc(900, sizeof(UINT32) * (s_cpuCount + 1));
+   InitializeCriticalSectionAndSpinCount(&s_lock, 1000);
+   s_collectorThread = ThreadCreateEx(CPUStatCollector, 0, NULL);
+}
+
+/**
+ * Stop collector
+ */
+void StopCPUStatCollector()
+{
+   ThreadJoin(s_collectorThread);
+   free(s_cpuTimes);
+   free(s_usage);
+   free(s_idle);
+   free(s_kernel);
+   free(s_user);
+   DeleteCriticalSection(&s_lock);
+}
+
+/**
+ * Handler for System.CPU.Usage parameters
+ */
+LONG H_CPUUsage(const TCHAR *param, const TCHAR *arg, TCHAR *value, AbstractCommSession *session)
+{
+   int cpuIndex;
+   if (arg[0] == 'T')   // Total
+   {
+      cpuIndex = s_cpuCount;
+   }
+   else
+   {
+      TCHAR buffer[64];
+      if (!AgentGetParameterArg(param, 1, buffer, 64))
+         return SYSINFO_RC_UNSUPPORTED;
+      cpuIndex = _tcstol(buffer, NULL, 10);
+      if ((cpuIndex < 0) || (cpuIndex >= s_cpuCount))
+         return SYSINFO_RC_UNSUPPORTED;
+   }
+
+   UINT32 usage = 0;
+   int step = s_cpuCount + 1;
+   int count;
+   switch(arg[1])
+   {
+      case '0':
+         count = 1;
+         break;
+      case '1':
+         count = 60;
+         break;
+      case '2':
+         count = 300;
+         break;
+      case '3':
+         count = 900;
+         break;
+      default:
+         return SYSINFO_RC_UNSUPPORTED;
+         break;
+   }
+
+   UINT32 *data;
+   switch(arg[2])
+   {
+      case 'U':
+         data = s_usage;
+         break;
+      case 'I':
+         data = s_idle;
+         break;
+      case 's':
+         data = s_kernel;
+         break;
+      case 'u':
+         data = s_user;
+         break;
+      default:
+         return SYSINFO_RC_UNSUPPORTED;
+         break;
+   }
+
+   EnterCriticalSection(&s_lock);
+   for(int p = s_bpos - step, i = 0; i < count; i++, p -= step)
+   {
+      if (p < 0)
+         p = s_cpuCount * 900 - step;
+      usage += data[p + cpuIndex];
+   }
+   LeaveCriticalSection(&s_lock);
+
+   usage /= count;
+   _sntprintf(value, MAX_RESULT_LENGTH, _T("%d.%02d"), usage / 100, usage % 100);
+   return SYSINFO_RC_SUCCESS;
+}
index 77f2bbc..1788264 100644 (file)
@@ -31,6 +31,7 @@ LONG H_AgentDesktop(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCo
 LONG H_AppAddressSpace(const TCHAR *pszCmd, const TCHAR *pArg, TCHAR *pValue, AbstractCommSession *session);
 LONG H_ArpCache(const TCHAR *cmd, const TCHAR *arg, StringList *value, AbstractCommSession *session);
 LONG H_ConnectedUsers(const TCHAR *pszCmd, const TCHAR *pArg, TCHAR *pValue, AbstractCommSession *session);
+LONG H_CPUUsage(const TCHAR *param, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
 LONG H_Desktops(const TCHAR *cmd, const TCHAR *arg, StringList *value, AbstractCommSession *session);
 LONG H_HandleCount(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
 LONG H_InstalledProducts(const TCHAR *cmd, const TCHAR *arg, Table *value, AbstractCommSession *);
@@ -53,6 +54,9 @@ LONG H_SysUpdateTime(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractC
 LONG H_ThreadCount(const TCHAR *cmd, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
 LONG H_WindowStations(const TCHAR *cmd, const TCHAR *arg, StringList *value, AbstractCommSession *session);
 
+void StartCPUStatCollector();
+void StopCPUStatCollector();
+
 /**
  * Optional imports
  */
@@ -153,6 +157,23 @@ static LONG H_ChangeUserPassword(const TCHAR *action, StringList *args, const TC
    return (status == NERR_Success) ? ERR_SUCCESS : ERR_INTERNAL_ERROR; 
 }
 
+/**
+ * Subagent initialization
+ */
+static BOOL SubAgentInit(Config *config)
+{
+   StartCPUStatCollector();
+   return true;
+}
+
+/**
+ * Called by master agent at unload
+ */
+static void SubAgentShutdown()
+{
+   StopCPUStatCollector();
+}
+
 /**
  * Supported parameters
  */
@@ -198,7 +219,48 @@ static NETXMS_SUBAGENT_PARAM m_parameters[] =
        { _T("Process.WkSet(*)"), H_ProcInfo, (TCHAR *)PROCINFO_WKSET, DCI_DT_UINT64, DCIDESC_PROCESS_WKSET },
        { _T("System.AppAddressSpace"), H_AppAddressSpace, NULL, DCI_DT_UINT, DCIDESC_SYSTEM_APPADDRESSSPACE },
        { _T("System.ConnectedUsers"), H_ConnectedUsers, NULL, DCI_DT_INT, DCIDESC_SYSTEM_CONNECTEDUSERS },
-       { _T("System.HandleCount"), H_HandleCount, NULL, DCI_DT_UINT, DCIDESC_SYSTEM_HANDLECOUNT },
+   
+   { _T("System.CPU.CurrentUsage"), H_CPUUsage, _T("T0U"), DCI_DT_FLOAT, DCIDESC_SYSTEM_CPU_USAGECURR },
+   { _T("System.CPU.CurrentUsage.Idle"), H_CPUUsage, _T("T0I"), DCI_DT_FLOAT, DCIDESC_SYSTEM_CPU_USAGECURR_IDLE },
+   { _T("System.CPU.CurrentUsage.System"), H_CPUUsage, _T("T0s"), DCI_DT_FLOAT, DCIDESC_SYSTEM_CPU_USAGECURR_SYSTEM },
+   { _T("System.CPU.CurrentUsage.User"), H_CPUUsage, _T("T0u"), DCI_DT_FLOAT, DCIDESC_SYSTEM_CPU_USAGECURR_USER },
+
+   { _T("System.CPU.CurrentUsage(*)"), H_CPUUsage, _T("C0U"), DCI_DT_FLOAT, DCIDESC_SYSTEM_CPU_USAGECURR_EX },
+   { _T("System.CPU.CurrentUsage.Idle(*)"), H_CPUUsage, _T("C0I"), DCI_DT_FLOAT, DCIDESC_SYSTEM_CPU_USAGECURR_IDLE_EX },
+   { _T("System.CPU.CurrentUsage.System(*)"), H_CPUUsage, _T("C0s"), DCI_DT_FLOAT, DCIDESC_SYSTEM_CPU_USAGECURR_SYSTEM_EX },
+   { _T("System.CPU.CurrentUsage.User(*)"), H_CPUUsage, _T("C0u"), DCI_DT_FLOAT, DCIDESC_SYSTEM_CPU_USAGECURR_USER_EX },
+
+   { _T("System.CPU.Usage"), H_CPUUsage, _T("T1U"), DCI_DT_FLOAT, DCIDESC_SYSTEM_CPU_USAGE },
+   { _T("System.CPU.Usage.Idle"), H_CPUUsage, _T("T1I"), DCI_DT_FLOAT, DCIDESC_SYSTEM_CPU_USAGE_IDLE },
+   { _T("System.CPU.Usage.System"), H_CPUUsage, _T("T1s"), DCI_DT_FLOAT, DCIDESC_SYSTEM_CPU_USAGE_SYSTEM },
+   { _T("System.CPU.Usage.User"), H_CPUUsage, _T("T1u"), DCI_DT_FLOAT, DCIDESC_SYSTEM_CPU_USAGE_USER },
+       
+   { _T("System.CPU.Usage(*)"), H_CPUUsage, _T("C1U"), DCI_DT_FLOAT, DCIDESC_SYSTEM_CPU_USAGE_EX },
+   { _T("System.CPU.Usage.Idle(*)"), H_CPUUsage, _T("C1I"), DCI_DT_FLOAT, DCIDESC_SYSTEM_CPU_USAGE_IDLE_EX },
+   { _T("System.CPU.Usage.System(*)"), H_CPUUsage, _T("C1s"), DCI_DT_FLOAT, DCIDESC_SYSTEM_CPU_USAGE_SYSTEM_EX },
+   { _T("System.CPU.Usage.User(*)"), H_CPUUsage, _T("C1u"), DCI_DT_FLOAT, DCIDESC_SYSTEM_CPU_USAGE_USER_EX },
+   
+   { _T("System.CPU.Usage5"), H_CPUUsage, _T("T2U"), DCI_DT_FLOAT, DCIDESC_SYSTEM_CPU_USAGE5 },
+   { _T("System.CPU.Usage5.Idle"), H_CPUUsage, _T("T2I"), DCI_DT_FLOAT, DCIDESC_SYSTEM_CPU_USAGE5_IDLE },
+   { _T("System.CPU.Usage5.System"), H_CPUUsage, _T("T2s"), DCI_DT_FLOAT, DCIDESC_SYSTEM_CPU_USAGE5_SYSTEM },
+   { _T("System.CPU.Usage5.User"), H_CPUUsage, _T("T2u"), DCI_DT_FLOAT, DCIDESC_SYSTEM_CPU_USAGE5_USER },
+   
+   { _T("System.CPU.Usage5(*)"), H_CPUUsage, _T("C2U"), DCI_DT_FLOAT, DCIDESC_SYSTEM_CPU_USAGE5_EX },
+   { _T("System.CPU.Usage.Idle(*)"), H_CPUUsage, _T("C2I"), DCI_DT_FLOAT, DCIDESC_SYSTEM_CPU_USAGE5_IDLE_EX },
+   { _T("System.CPU.Usage.System(*)"), H_CPUUsage, _T("C2s"), DCI_DT_FLOAT, DCIDESC_SYSTEM_CPU_USAGE5_SYSTEM_EX },
+   { _T("System.CPU.Usage.User(*)"), H_CPUUsage, _T("C2u"), DCI_DT_FLOAT, DCIDESC_SYSTEM_CPU_USAGE5_USER_EX },
+   
+   { _T("System.CPU.Usage15"), H_CPUUsage, _T("T3U"), DCI_DT_FLOAT, DCIDESC_SYSTEM_CPU_USAGE15 },
+   { _T("System.CPU.Usage5.Idle"), H_CPUUsage, _T("T3I"), DCI_DT_FLOAT, DCIDESC_SYSTEM_CPU_USAGE15_IDLE },
+   { _T("System.CPU.Usage5.System"), H_CPUUsage, _T("T3s"), DCI_DT_FLOAT, DCIDESC_SYSTEM_CPU_USAGE15_SYSTEM },
+   { _T("System.CPU.Usage5.User"), H_CPUUsage, _T("T3u"), DCI_DT_FLOAT, DCIDESC_SYSTEM_CPU_USAGE15_USER },
+   
+   { _T("System.CPU.Usage15(*)"), H_CPUUsage, _T("C3U"), DCI_DT_FLOAT, DCIDESC_SYSTEM_CPU_USAGE15_EX },
+   { _T("System.CPU.Usage15.Idle(*)"), H_CPUUsage, _T("C3I"), DCI_DT_FLOAT, DCIDESC_SYSTEM_CPU_USAGE15_IDLE_EX },
+   { _T("System.CPU.Usage15.System(*)"), H_CPUUsage, _T("C3s"), DCI_DT_FLOAT, DCIDESC_SYSTEM_CPU_USAGE15_SYSTEM_EX },
+   { _T("System.CPU.Usage15.User(*)"), H_CPUUsage, _T("C3u"), DCI_DT_FLOAT, DCIDESC_SYSTEM_CPU_USAGE15_USER_EX },
+       
+   { _T("System.HandleCount"), H_HandleCount, NULL, DCI_DT_UINT, DCIDESC_SYSTEM_HANDLECOUNT },
        { _T("System.ProcessCount"), H_ProcCount, NULL, DCI_DT_UINT, DCIDESC_SYSTEM_PROCESSCOUNT },
        { _T("System.ServiceState(*)"), H_ServiceState, NULL, DCI_DT_INT, DCIDESC_SYSTEM_SERVICESTATE },
        { _T("System.ThreadCount"), H_ThreadCount, NULL, DCI_DT_UINT, DCIDESC_SYSTEM_THREADCOUNT },
@@ -250,7 +312,7 @@ static NETXMS_SUBAGENT_INFO m_info =
 {
        NETXMS_SUBAGENT_INFO_MAGIC,
        _T("WinNT"), NETXMS_VERSION_STRING,
-       NULL, NULL, NULL,
+       SubAgentInit, SubAgentShutdown, NULL,
        sizeof(m_parameters) / sizeof(NETXMS_SUBAGENT_PARAM),
        m_parameters,
        sizeof(m_lists) / sizeof(NETXMS_SUBAGENT_LIST),
index 42f69ad..1011fbd 100644 (file)
                        Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
                        UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
                        >
+                       <File
+                               RelativePath=".\cpu.cpp"
+                               >
+                       </File>
                        <File
                                RelativePath=".\main.cpp"
                                >
index 88366dc..33d7c50 100644 (file)
 /**
  * Constants
  */
-#define MAX_CPU_COUNT                  256
-
 #define WPF_ENABLE_DEFAULT_COUNTERS    0x0001
 
 /**
  * Static variables
  */
 static DWORD m_dwFlags = WPF_ENABLE_DEFAULT_COUNTERS;
-static DWORD m_dwNumCPU = 1;
-static WINPERF_COUNTER *s_processorCounters0[MAX_CPU_COUNT];
-static WINPERF_COUNTER *s_processorCounters1[MAX_CPU_COUNT];
-static WINPERF_COUNTER *s_processorCounters5[MAX_CPU_COUNT];
-static WINPERF_COUNTER *s_processorCounters15[MAX_CPU_COUNT];
 static MUTEX s_autoCountersLock = MutexCreate();
 static StringObjectMap<WINPERF_COUNTER> *s_autoCounters = new StringObjectMap<WINPERF_COUNTER>(false);
 
@@ -58,10 +51,6 @@ static struct
    { _T("System.CPU.LoadAvg"), _T("\\System\\Processor Queue Length"), 0, 60, COUNTER_TYPE_FLOAT, _T("Average CPU load for last minute"), DCI_DT_FLOAT },
    { _T("System.CPU.LoadAvg5"), _T("\\System\\Processor Queue Length"), 0, 300, COUNTER_TYPE_FLOAT, _T("Average CPU load for last 5 minutes"), DCI_DT_FLOAT },
    { _T("System.CPU.LoadAvg15"), _T("\\System\\Processor Queue Length"), 0, 900, COUNTER_TYPE_FLOAT, _T("Average CPU load for last 15 minutes"), DCI_DT_FLOAT },
-   { _T("System.CPU.CurrentUsage"), _T("\\Processor(_Total)\\% Processor Time"), 0, 2, COUNTER_TYPE_INT32, DCIDESC_SYSTEM_CPU_USAGECURR, DCI_DT_INT },
-   { _T("System.CPU.Usage"), _T("\\Processor(_Total)\\% Processor Time"), 0, 60, COUNTER_TYPE_INT32, DCIDESC_SYSTEM_CPU_USAGE, DCI_DT_INT },
-   { _T("System.CPU.Usage5"), _T("\\Processor(_Total)\\% Processor Time"), 0, 300, COUNTER_TYPE_INT32, DCIDESC_SYSTEM_CPU_USAGE5, DCI_DT_INT },
-   { _T("System.CPU.Usage15"), _T("\\Processor(_Total)\\% Processor Time"), 0, 900, COUNTER_TYPE_INT32, DCIDESC_SYSTEM_CPU_USAGE15, DCI_DT_INT },
    { _T("System.IO.DiskQueue"), _T("\\PhysicalDisk(_Total)\\Avg. Disk Queue Length"), 0, 60, COUNTER_TYPE_FLOAT, DCIDESC_SYSTEM_IO_DISKQUEUE, DCI_DT_FLOAT },
    { _T("System.IO.DiskTime"), _T("\\PhysicalDisk(_Total)\\% Disk Time"), 0, 60, COUNTER_TYPE_FLOAT, _T("Average disk busy time for last minute"), DCI_DT_FLOAT },
    { NULL, NULL, 0, 0, 0, NULL, 0 }
@@ -89,55 +78,6 @@ static LONG H_WinPerfFeatures(const TCHAR *pszParam, const TCHAR *pArg, TCHAR *p
    return SYSINFO_RC_SUCCESS;
 }
 
-/**
- * Value of CPU utilization counter
- */
-static LONG H_CPUUsage(const TCHAR *pszParam, const TCHAR *pArg, TCHAR *pValue, AbstractCommSession *session)
-{
-   LONG nProcessor, nRet = SYSINFO_RC_SUCCESS;
-   TCHAR *pEnd, szBuffer[16];
-
-   if (!AgentGetParameterArg(pszParam, 1, szBuffer, 16))
-      return SYSINFO_RC_UNSUPPORTED;
-
-   nProcessor = _tcstol(szBuffer, &pEnd, 0);
-   if ((*pEnd != 0) || (nProcessor < 0) || (nProcessor >= (LONG)m_dwNumCPU))
-      return SYSINFO_RC_UNSUPPORTED;
-
-   switch(pArg[0])
-   {
-      case _T('0'):  // System.CPU.Usage(*)
-         if (s_processorCounters0[nProcessor] != NULL)
-            ret_int(pValue, s_processorCounters0[nProcessor]->value.iLong);
-         else
-            nRet = SYSINFO_RC_ERROR;
-         break;
-      case _T('1'):  // System.CPU.Usage(*)
-         if (s_processorCounters1[nProcessor] != NULL)
-            ret_int(pValue, s_processorCounters1[nProcessor]->value.iLong);
-         else
-            nRet = SYSINFO_RC_ERROR;
-         break;
-      case _T('2'):  // System.CPU.Usage5(*)
-         if (s_processorCounters5[nProcessor] != NULL)
-            ret_int(pValue, s_processorCounters5[nProcessor]->value.iLong);
-         else
-            nRet = SYSINFO_RC_ERROR;
-         break;
-      case _T('3'):  // System.CPU.Usage15(*)
-         if (s_processorCounters15[nProcessor] != NULL)
-            ret_int(pValue, s_processorCounters15[nProcessor]->value.iLong);
-         else
-            nRet = SYSINFO_RC_ERROR;
-         break;
-      default:
-         nRet = SYSINFO_RC_UNSUPPORTED;
-         break;
-   }
-
-   return nRet;
-}
-
 /**
  * Value of given counter collected by one of the collector threads
  */
@@ -415,10 +355,6 @@ static NETXMS_SUBAGENT_PARAM m_parameters[] =
 {
    { _T("PDH.CounterValue(*)"), H_PdhCounterValue, NULL, DCI_DT_INT, _T("") },
    { _T("PDH.Version"), H_PdhVersion, NULL, DCI_DT_UINT, _T("Version of PDH.DLL") },
-       { _T("System.CPU.CurrentUsage(*)"), H_CPUUsage, _T("0"), DCI_DT_INT, DCIDESC_SYSTEM_CPU_USAGECURR_EX },
-       { _T("System.CPU.Usage(*)"), H_CPUUsage, _T("1"), DCI_DT_INT, DCIDESC_SYSTEM_CPU_USAGE_EX },
-   { _T("System.CPU.Usage5(*)"), H_CPUUsage, _T("2"), DCI_DT_INT, DCIDESC_SYSTEM_CPU_USAGE5_EX },
-   { _T("System.CPU.Usage15(*)"), H_CPUUsage, _T("3"), DCI_DT_INT, DCIDESC_SYSTEM_CPU_USAGE15_EX },
        { _T("System.ThreadCount"), H_CounterAlias, _T("\\System\\Threads"), DCI_DT_UINT, DCIDESC_SYSTEM_THREADCOUNT },
        { _T("System.Uptime"), H_CounterAlias, _T("\\System\\System Up Time"), DCI_DT_UINT, DCIDESC_SYSTEM_UPTIME },
    { _T("WinPerf.Features"), H_WinPerfFeatures, NULL, DCI_DT_UINT, _T("Features supported by this WinPerf version") },
@@ -498,18 +434,6 @@ static void AddPredefinedCounters()
                       (TCHAR *)pCnt, m_counterList[i].iDCIDataType,
                       m_counterList[i].pszDescription);
    }
-
-   // Add CPU utilization counters
-   GetSystemInfo(&sysInfo);
-   m_dwNumCPU = sysInfo.dwNumberOfProcessors;
-   for(i = 0; i < m_dwNumCPU; i++)
-   {
-      _sntprintf(szBuffer, MAX_PATH, _T("\\Processor(%d)\\%% Processor Time"), i);
-      s_processorCounters0[i] = AddCounter(szBuffer, 0, 2, COUNTER_TYPE_INT32);
-      s_processorCounters1[i] = AddCounter(szBuffer, 0, 60, COUNTER_TYPE_INT32);
-      s_processorCounters5[i] = AddCounter(szBuffer, 0, 300, COUNTER_TYPE_INT32);
-      s_processorCounters15[i] = AddCounter(szBuffer, 0, 900, COUNTER_TYPE_INT32);
-   }
 }
 
 /**