XEN subagent: added table XEN.Net.DomainInterfaces
[public/netxms.git] / src / agent / subagents / xen / xen.cpp
1 /*
2 ** NetXMS XEN hypervisor subagent
3 ** Copyright (C) 2017 Raden Solutions
4 **
5 ** This program is free software; you can redistribute it and/or modify
6 ** it under the terms of the GNU General Public License as published by
7 ** the Free Software Foundation; either version 2 of the License, or
8 ** (at your option) any later version.
9 **
10 ** This program is distributed in the hope that it will be useful,
11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ** GNU General Public License for more details.
14 **
15 ** You should have received a copy of the GNU General Public License
16 ** along with this program; if not, write to the Free Software
17 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 **
19 ** File: xen.cpp
20 **
21 **/
22
23 #include "xen.h"
24
25 /**
26 * Handlers
27 */
28 LONG H_XenDomainCPUUsage(const TCHAR *param, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
29 LONG H_XenDomainList(const TCHAR *param, const TCHAR *arg, StringList *value, AbstractCommSession *session);
30 LONG H_XenDomainNetIfTable(const TCHAR *param, const TCHAR *arg, Table *value, AbstractCommSession *session);
31 LONG H_XenDomainNetStats(const TCHAR *param, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
32 LONG H_XenDomainTable(const TCHAR *param, const TCHAR *arg, Table *value, AbstractCommSession *session);
33 LONG H_XenHostCPUUsage(const TCHAR *param, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
34 LONG H_XenHostOnlineCPUs(const TCHAR *param, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
35 LONG H_XenHostPhyInfo(const TCHAR *param, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
36 LONG H_XenHostVersion(const TCHAR *param, const TCHAR *arg, TCHAR *value, AbstractCommSession *session);
37
38 /**
39 * Convert XEN log level into NetXMS debug level
40 */
41 inline int ConvertLogLevel(xentoollog_level level)
42 {
43 if (level >= XTL_ERROR)
44 return 1;
45 if (level >= XTL_WARN)
46 return 3;
47 if (level >= XTL_NOTICE)
48 return 4;
49 return 5;
50 }
51
52 /**
53 * Write log message
54 */
55 static void LogMessage(struct xentoollog_logger *logger,
56 xentoollog_level level,
57 int errnoval /* or -1 */,
58 const char *context /* eg "xc", "xl", may be 0 */,
59 const char *format /* without level, context, \n */,
60 va_list al)
61 {
62 char msg[4096];
63 vsnprintf(msg, 4096, format, al);
64 nxlog_debug(ConvertLogLevel(level), _T("XEN: [%hs] (%hs): %hs"), xtl_level_to_string(level), context, msg);
65 }
66
67 /**
68 * Write progress message
69 */
70 static void LogProgress(struct xentoollog_logger *logger,
71 const char *context /* see above */,
72 const char *doing_what /* no \r,\n */,
73 int percent, unsigned long done, unsigned long total)
74 {
75 }
76
77 /**
78 * Destroy logger
79 */
80 static void LogDestroy(struct xentoollog_logger *logger)
81 {
82 }
83
84 /**
85 * Logger definition
86 */
87 xentoollog_logger g_xenLogger = { LogMessage, LogProgress, LogDestroy };
88
89 /**
90 * Called by master agent at unload
91 */
92 static void SubagentShutdown()
93 {
94 XenStopCPUCollector();
95 }
96
97 /**
98 * Subagent initialization
99 */
100 static BOOL SubagentInit(Config *config)
101 {
102 XenStartCPUCollector();
103 return TRUE;
104 }
105
106 /**
107 * Parameters
108 */
109 static NETXMS_SUBAGENT_PARAM s_parameters[] =
110 {
111 { _T("XEN.Domain.CPU.CurrentUsage(*)"), H_XenDomainCPUUsage, _T("0"), DCI_DT_FLOAT, _T("XEN domain {instance}: current CPU utilization") },
112 { _T("XEN.Domain.CPU.Usage(*)"), H_XenDomainCPUUsage, _T("1"), DCI_DT_FLOAT, _T("XEN domain {instance}: average CPU utilization for last minute") },
113 { _T("XEN.Domain.CPU.Usage15(*)"), H_XenDomainCPUUsage, _T("F"), DCI_DT_FLOAT, _T("XEN domain {instance}: average CPU utilization for last 15 minutes") },
114 { _T("XEN.Domain.CPU.Usage5(*)"), H_XenDomainCPUUsage, _T("5"), DCI_DT_FLOAT, _T("XEN domain {instance}: average CPU utilization for last 5 minutes") },
115 { _T("XEN.Domain.Net.RxBytes(*)"), H_XenDomainNetStats, _T("RB"), DCI_DT_UINT64, _T("XEN domain {instance}: network usage (bytes received)") },
116 { _T("XEN.Domain.Net.RxPackets(*)"), H_XenDomainNetStats, _T("RP"), DCI_DT_UINT64, _T("XEN domain {instance}: network usage (packets received)") },
117 { _T("XEN.Domain.Net.TxBytes(*)"), H_XenDomainNetStats, _T("TB"), DCI_DT_UINT64, _T("XEN domain {instance}: network usage (bytes transmitted)") },
118 { _T("XEN.Domain.Net.TxPackets(*)"), H_XenDomainNetStats, _T("TP"), DCI_DT_UINT64, _T("XEN domain {instance}: network usage (packets transmitted)") },
119 { _T("XEN.Host.CPU.Cores"), H_XenHostPhyInfo, _T("c"), DCI_DT_INT, _T("XEN host: number of CPU cores") },
120 { _T("XEN.Host.CPU.CurrentUsage"), H_XenHostCPUUsage, _T("0"), DCI_DT_FLOAT, _T("XEN host: current CPU utilization") },
121 { _T("XEN.Host.CPU.Frequency"), H_XenHostPhyInfo, _T("F"), DCI_DT_INT, _T("XEN host: number of CPU cores") },
122 { _T("XEN.Host.CPU.LogicalCount"), H_XenHostPhyInfo, _T("C"), DCI_DT_INT, _T("XEN host: number of logical CPUs") },
123 { _T("XEN.Host.CPU.Online"), H_XenHostOnlineCPUs, NULL, DCI_DT_INT, _T("XEN host: number of online CPUs") },
124 { _T("XEN.Host.CPU.PhysicalCount"), H_XenHostPhyInfo, _T("P"), DCI_DT_INT, _T("XEN host: number of physical CPUs") },
125 { _T("XEN.Host.CPU.Usage"), H_XenHostCPUUsage, _T("1"), DCI_DT_FLOAT, _T("XEN host: average CPU utilization for last minute") },
126 { _T("XEN.Host.CPU.Usage15"), H_XenHostCPUUsage, _T("F"), DCI_DT_FLOAT, _T("XEN host: average CPU utilization for last 15 minutes") },
127 { _T("XEN.Host.CPU.Usage5"), H_XenHostCPUUsage, _T("5"), DCI_DT_FLOAT, _T("XEN host: average CPU utilization for last 5 minutes") },
128 { _T("XEN.Host.Memory.Free"), H_XenHostPhyInfo, _T("M"), DCI_DT_UINT64, _T("XEN host: free memory") },
129 { _T("XEN.Host.Memory.FreePerc"), H_XenHostPhyInfo, _T("m"), DCI_DT_FLOAT, _T("XEN host: free memory (%)") },
130 { _T("XEN.Host.Memory.Outstanding"), H_XenHostPhyInfo, _T("O"), DCI_DT_UINT64, _T("XEN host: outstanding memory") },
131 { _T("XEN.Host.Memory.OutstandingPerc"), H_XenHostPhyInfo, _T("o"), DCI_DT_FLOAT, _T("XEN host: outstanding memory (%)") },
132 { _T("XEN.Host.Memory.Scrub"), H_XenHostPhyInfo, _T("S"), DCI_DT_UINT64, _T("XEN host: scrub memory") },
133 { _T("XEN.Host.Memory.ScrubPerc"), H_XenHostPhyInfo, _T("s"), DCI_DT_FLOAT, _T("XEN host: scrub memory (%)") },
134 { _T("XEN.Host.Memory.Total"), H_XenHostPhyInfo, _T("T"), DCI_DT_UINT64, _T("XEN host: total memory") },
135 { _T("XEN.Host.Memory.Used"), H_XenHostPhyInfo, _T("U"), DCI_DT_UINT64, _T("XEN host: used memory") },
136 { _T("XEN.Host.Memory.UsedPerc"), H_XenHostPhyInfo, _T("u"), DCI_DT_FLOAT, _T("XEN host: used memory (%)") },
137 { _T("XEN.Host.Version"), H_XenHostVersion, NULL, DCI_DT_STRING, _T("XEN host: version") }
138 };
139
140 /**
141 * Lists
142 */
143 static NETXMS_SUBAGENT_LIST s_lists[] =
144 {
145 { _T("XEN.Domains"), H_XenDomainList, NULL }
146 };
147
148 /**
149 * Tables
150 */
151 static NETXMS_SUBAGENT_TABLE s_tables[] =
152 {
153 { _T("XEN.Domains"), H_XenDomainTable, NULL, _T("ID"), _T("XEN: domains (virtual machines)") },
154 { _T("XEN.Net.DomainInterfaces"), H_XenDomainNetIfTable, NULL, _T("NAME"), _T("XEN: domain network interfaces") }
155 };
156
157 /**
158 * Subagent information
159 */
160 static NETXMS_SUBAGENT_INFO m_info =
161 {
162 NETXMS_SUBAGENT_INFO_MAGIC,
163 _T("XEN"), NETXMS_VERSION_STRING,
164 SubagentInit, SubagentShutdown, NULL,
165 sizeof(s_parameters) / sizeof(NETXMS_SUBAGENT_PARAM),
166 s_parameters,
167 sizeof(s_lists) / sizeof(NETXMS_SUBAGENT_LIST),
168 s_lists,
169 sizeof(s_tables) / sizeof(NETXMS_SUBAGENT_TABLE),
170 s_tables, // tables
171 0, NULL, // actions
172 0, NULL // push parameters
173 };
174
175 /**
176 * Entry point for NetXMS agent
177 */
178 DECLARE_SUBAGENT_ENTRY_POINT(XEN)
179 {
180 *ppInfo = &m_info;
181 return TRUE;
182 }
183
184 #ifdef _WIN32
185
186 /**
187 * DLL entry point
188 */
189 BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
190 {
191 if (dwReason == DLL_PROCESS_ATTACH)
192 DisableThreadLibraryCalls(hInstance);
193 return TRUE;
194 }
195
196 #endif