PageRenderTime 68ms CodeModel.GetById 30ms RepoModel.GetById 0ms app.codeStats 0ms

/modules/core/native-system/src/main/java/org/rhq/core/system/NativeSystemInfo.java

https://github.com/ccrouch/rhq
Java | 355 lines | 239 code | 58 blank | 58 comment | 31 complexity | 093da262220e5c062bf9d4862f5571fd MD5 | raw file
  1. /*
  2. * RHQ Management Platform
  3. * Copyright (C) 2005-2008 Red Hat, Inc.
  4. * All rights reserved.
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License, version 2, as
  8. * published by the Free Software Foundation, and/or the GNU Lesser
  9. * General Public License, version 2.1, also as published by the Free
  10. * Software Foundation.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License and the GNU Lesser General Public License
  16. * for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * and the GNU Lesser General Public License along with this program;
  20. * if not, write to the Free Software Foundation, Inc.,
  21. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  22. */
  23. package org.rhq.core.system;
  24. import java.io.BufferedReader;
  25. import java.io.IOException;
  26. import java.io.InputStreamReader;
  27. import java.net.InetAddress;
  28. import java.net.UnknownHostException;
  29. import java.util.ArrayList;
  30. import java.util.List;
  31. import org.apache.commons.logging.Log;
  32. import org.apache.commons.logging.LogFactory;
  33. import org.hyperic.sigar.FileSystem;
  34. import org.hyperic.sigar.FileSystemMap;
  35. import org.hyperic.sigar.Mem;
  36. import org.hyperic.sigar.NetConnection;
  37. import org.hyperic.sigar.NetFlags;
  38. import org.hyperic.sigar.NetInterfaceStat;
  39. import org.hyperic.sigar.OperatingSystem;
  40. import org.hyperic.sigar.Sigar;
  41. import org.hyperic.sigar.SigarException;
  42. import org.hyperic.sigar.SigarProxy;
  43. import org.hyperic.sigar.Swap;
  44. import org.rhq.core.system.pquery.ProcessInfoQuery;
  45. /**
  46. * The superclass for all the native {@link SystemInfo} implementations. You are free to subclass this implementation if
  47. * there are additional platform-specific methods that need to be exposed. Most functionality, however, can be exposed
  48. * via this native superclass implementation.
  49. *
  50. * <p>This implementation uses SIGAR. To enable debug logging in SIGAR, set the system property "sigar.nativeLogging" or
  51. * call {@link Sigar#enableLogging(boolean)}.</p>
  52. *
  53. * @author John Mazzitelli
  54. */
  55. public class NativeSystemInfo implements SystemInfo {
  56. private final Log log = LogFactory.getLog(NativeSystemInfo.class);
  57. private SigarProxy sigar;
  58. /**
  59. * Always returns <code>true</code> to indicate that the native library is available.
  60. *
  61. * @see SystemInfo#isNative()
  62. */
  63. public boolean isNative() {
  64. return true;
  65. }
  66. public OperatingSystemType getOperatingSystemType() {
  67. OperatingSystem os = OperatingSystem.getInstance();
  68. if (OperatingSystem.NAME_LINUX.equals(os.getName())) {
  69. return OperatingSystemType.LINUX;
  70. }
  71. if (OperatingSystem.NAME_SOLARIS.equals(os.getName())) {
  72. return OperatingSystemType.SOLARIS;
  73. }
  74. if (OperatingSystem.NAME_WIN32.equals(os.getName())) {
  75. return OperatingSystemType.WINDOWS;
  76. }
  77. if (OperatingSystem.NAME_HPUX.equals(os.getName())) {
  78. return OperatingSystemType.HPUX;
  79. }
  80. if (OperatingSystem.NAME_AIX.equals(os.getName())) {
  81. return OperatingSystemType.AIX;
  82. }
  83. if (OperatingSystem.NAME_MACOSX.equals(os.getName())) {
  84. return OperatingSystemType.OSX;
  85. }
  86. if (OperatingSystem.NAME_FREEBSD.equals(os.getName())) {
  87. return OperatingSystemType.BSD;
  88. }
  89. return OperatingSystemType.JAVA;
  90. }
  91. public String getOperatingSystemName() {
  92. return OperatingSystem.getInstance().getName();
  93. }
  94. public String getOperatingSystemVersion() {
  95. return OperatingSystem.getInstance().getVersion();
  96. }
  97. public String getHostname() throws SystemInfoException {
  98. try {
  99. return sigar.getNetInfo().getHostName();
  100. } catch (Exception e) {
  101. // For some reason, the native layer failed to get the hostname
  102. // Let's fallback and ask Java for help. But if that fails, too,
  103. // let's wrap the native layer's exception since we'll want to
  104. // see its cause since it'll probably have a more descriptive error message
  105. try {
  106. return InetAddress.getLocalHost().getCanonicalHostName();
  107. } catch (UnknownHostException uhe) {
  108. throw new SystemInfoException(e);
  109. }
  110. }
  111. }
  112. public List<NetworkAdapterInfo> getAllNetworkAdapters() throws SystemInfoException {
  113. ArrayList<NetworkAdapterInfo> adapters = new ArrayList<NetworkAdapterInfo>();
  114. try {
  115. String[] interfaceNames = sigar.getNetInterfaceList();
  116. if (interfaceNames != null) {
  117. for (String interfaceName : interfaceNames) {
  118. if (interfaceName.indexOf(':') != -1) {
  119. continue; //filter out virtual IPs
  120. }
  121. adapters.add(new NetworkAdapterInfo(sigar.getNetInterfaceConfig(interfaceName)));
  122. }
  123. }
  124. } catch (Exception e) {
  125. throw new SystemInfoException(e);
  126. }
  127. return adapters;
  128. }
  129. public NetworkAdapterStats getNetworkAdapterStats(String interfaceName) {
  130. try {
  131. NetInterfaceStat interfaceStat = sigar.getNetInterfaceStat(interfaceName);
  132. return new NetworkAdapterStats(interfaceStat);
  133. } catch (SigarException e) {
  134. throw new SystemInfoException(e);
  135. }
  136. }
  137. public NetworkStats getNetworkStats(String addressName, int port) {
  138. List<NetConnection> matches = getNetworkConnections(addressName, port);
  139. NetworkStats stats = new NetworkStats(matches.toArray(new NetConnection[matches.size()]));
  140. return stats;
  141. }
  142. public List<NetConnection> getNetworkConnections(String addressName, int port) {
  143. try {
  144. int flags = NetFlags.CONN_SERVER | NetFlags.CONN_CLIENT | NetFlags.CONN_TCP;
  145. NetConnection[] conns = sigar.getNetConnectionList(flags);
  146. InetAddress matchAddress = (addressName != null) ? InetAddress.getByName(addressName) : null;
  147. List<NetConnection> list = new ArrayList<NetConnection>();
  148. for (NetConnection conn : conns) {
  149. if (port > 0 && (conn.getLocalPort() != port)) {
  150. continue; // does not match the port we are looking for
  151. }
  152. if (matchAddress != null && !matchAddress.equals(InetAddress.getByName(conn.getLocalAddress()))) {
  153. continue; // does not match the address we are looking for
  154. }
  155. list.add(conn); // matches our criteria, add it to the list to be returned to the caller
  156. }
  157. return list;
  158. } catch (SigarException e) {
  159. throw new SystemInfoException(e);
  160. } catch (UnknownHostException e) {
  161. throw new SystemInfoException(e);
  162. }
  163. }
  164. private List<InetAddress> getInetAddressInList(String address) throws UnknownHostException {
  165. List<InetAddress> inetAddresses = new ArrayList<InetAddress>();
  166. if (address != null) {
  167. inetAddresses.add(InetAddress.getByName(address));
  168. }
  169. return inetAddresses;
  170. }
  171. public List<ServiceInfo> getAllServices() throws SystemInfoException {
  172. throw new UnsupportedOperationException("Cannot get services for this plaform");
  173. }
  174. public List<ProcessInfo> getAllProcesses() {
  175. ArrayList<ProcessInfo> processes = new ArrayList<ProcessInfo>();
  176. long[] pids = null;
  177. final int timeout = 2 * 60 * 1000; // 2 minutes
  178. log.debug("Retrieving PIDs of all running processes...");
  179. long startTime = System.currentTimeMillis();
  180. try {
  181. pids = sigar.getProcList();
  182. long elapsedTime = System.currentTimeMillis() - startTime;
  183. log.debug("Retrieval of " + pids.length + " PIDs took " + elapsedTime + " ms.");
  184. // NOTE: Do not close sigarImpl on success, as the ProcessInfos created below will reuse it.
  185. } catch (Exception e) {
  186. log.warn("Failed to retrieve PIDs of all running processes.", e);
  187. }
  188. if (pids != null) {
  189. for (long pid : pids) {
  190. if (log.isTraceEnabled()) {
  191. log.trace("Loading process info for pid " + pid + "...");
  192. }
  193. ProcessInfo info = new ProcessInfo(pid, sigar);
  194. processes.add(info);
  195. }
  196. }
  197. return processes;
  198. }
  199. public List<ProcessInfo> getProcesses(String piq) {
  200. ProcessInfoQuery piql = new ProcessInfoQuery(getAllProcesses());
  201. return piql.query(piq);
  202. }
  203. public ProcessInfo getThisProcess() {
  204. long self;
  205. self = sigar.getPid();
  206. ProcessInfo info = new ProcessInfo(self);
  207. return info;
  208. }
  209. public ProcessExecutionResults executeProcess(ProcessExecution processExecution) {
  210. // TODO: doesn't look like SIGAR has an API to fork/execute processes? fallback to using the Java way
  211. return SystemInfoFactory.createJavaSystemInfo().executeProcess(processExecution);
  212. }
  213. public int getNumberOfCpus() {
  214. try {
  215. // NOTE: This will return the number of cores, not the number of sockets.
  216. return sigar.getCpuPercList().length;
  217. } catch (Exception e) {
  218. throw new UnsupportedOperationException("Cannot get number of CPUs from native layer", e);
  219. }
  220. }
  221. public Mem getMemoryInfo() {
  222. try {
  223. return sigar.getMem();
  224. } catch (Exception e) {
  225. throw new UnsupportedOperationException("Cannot get memory info from native layer", e);
  226. }
  227. }
  228. public Swap getSwapInfo() {
  229. try {
  230. // Removed this check since http://jira.hyperic.com/browse/SIGAR-112 is fixed.
  231. /*
  232. int enabledCpuCount = sigar.getCpuPercList().length;
  233. int totalCpuCount = sigar.getCpuInfoList().length;
  234. if (enabledCpuCount < totalCpuCount) {
  235. log.info("Aborting swap info collection because one or more CPUs is disabled - " + enabledCpuCount
  236. + " out of " + totalCpuCount + " CPUs are enabled.");
  237. return null;
  238. }
  239. */
  240. return sigar.getSwap();
  241. } catch (Exception e) {
  242. throw new UnsupportedOperationException("Cannot get swap info from native layer", e);
  243. }
  244. }
  245. public String readLineFromConsole(boolean noEcho) throws IOException {
  246. String input;
  247. if (noEcho) {
  248. input = Sigar.getPassword("");
  249. } else {
  250. input = new BufferedReader(new InputStreamReader(System.in)).readLine();
  251. }
  252. return input;
  253. }
  254. public void writeLineToConsole(String line) throws IOException {
  255. System.out.print(line); // note: don't use println - let the caller append newline char to 'line' if needed
  256. }
  257. public CpuInformation getCpu(int cpuIndex) {
  258. return new CpuInformation(cpuIndex, sigar);
  259. }
  260. public List<FileSystemInfo> getFileSystems() {
  261. List<String> mountPoints = new ArrayList<String>();
  262. try {
  263. FileSystemMap map = sigar.getFileSystemMap();
  264. mountPoints.addAll(map.keySet());
  265. } catch (Exception e) {
  266. log.warn("Cannot obtain native file system information", e); // ignore native error otherwise
  267. }
  268. List<FileSystemInfo> infos = new ArrayList<FileSystemInfo>();
  269. for (String mountPoint : mountPoints) {
  270. infos.add(new FileSystemInfo(mountPoint));
  271. }
  272. return infos;
  273. }
  274. public FileSystemInfo getFileSystem(String path) {
  275. String mountPoint = null;
  276. try {
  277. FileSystem mountPointForPath = sigar.getFileSystemMap().getMountPoint(path);
  278. if (mountPointForPath != null)
  279. mountPoint = mountPointForPath.getDirName();
  280. } catch (Throwable e) {
  281. log.warn("Cannot obtain native file system information for [" + path + "]", e); // ignore native error otherwise
  282. }
  283. FileSystemInfo fileSystem = new FileSystemInfo(mountPoint);
  284. return fileSystem;
  285. }
  286. public String getSystemArchitecture() {
  287. OperatingSystem op = OperatingSystem.getInstance();
  288. return op.getArch();
  289. }
  290. /**
  291. * Constructor for {@link NativeSystemInfo} with package scope so only the {@link SystemInfoFactory} can instantiate
  292. * this object.
  293. */
  294. public NativeSystemInfo() {
  295. this.sigar = SigarAccess.getSigar();
  296. }
  297. }