Advertisement
Guest User

Untitled

a guest
Aug 21st, 2017
101
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 15.13 KB | None | 0 0
  1. #!/usr/bin/env python
  2.  
  3. """
  4. Python program that generates various statistics for one or more virtual machines
  5.  
  6. A list of virtual machines can be provided as a comma separated list.
  7. """
  8.  
  9. from __future__ import print_function
  10. from pyVim.connect import SmartConnect, Disconnect
  11. from pyVmomi import vmodl, vim
  12. from datetime import timedelta, datetime
  13.  
  14. import argparse
  15. import atexit
  16. import getpass
  17.  
  18. import ssl
  19.  
  20. def GetArgs():
  21. """
  22. Supports the command-line arguments listed below.
  23. """
  24. parser = argparse.ArgumentParser(description='Process args for retrieving all the Virtual Machines')
  25. parser.add_argument('-s', '--host', required=True, action='store', help='Remote host to connect to')
  26. parser.add_argument('-o', '--port', type=int, default=443, action='store', help='Port to connect on')
  27. parser.add_argument('-u', '--user', required=True, action='store', help='User name to use when connecting to host')
  28. parser.add_argument('-p', '--password', required=False, action='store',
  29. help='Password to use when connecting to host')
  30. parser.add_argument('-m', '--vm', required=True, action='store', help='On eor more Virtual Machines to report on')
  31. parser.add_argument('-c', '--cert_check_skip', required=False, action='store_true', help='skip ssl certificate check')
  32. parser.add_argument('-i', '--interval', type=int, default=15, action='store',
  33. help='Interval to average the vSphere stats over')
  34. args = parser.parse_args()
  35. return args
  36.  
  37.  
  38. def BuildQuery(content, vchtime, counterId, instance, vm, interval):
  39. perfManager = content.perfManager
  40. metricId = vim.PerformanceManager.MetricId(counterId=counterId, instance=instance)
  41. startTime = vchtime - timedelta(minutes=(interval + 1))
  42. endTime = vchtime - timedelta(minutes=1)
  43. query = vim.PerformanceManager.QuerySpec(intervalId=20, entity=vm, metricId=[metricId], startTime=startTime,
  44. endTime=endTime)
  45. perfResults = perfManager.QueryPerf(querySpec=[query])
  46. if perfResults:
  47. return perfResults
  48. else:
  49. print('ERROR: Performance results empty. TIP: Check time drift on source and vCenter server')
  50. print('Troubleshooting info:')
  51. print('vCenter/host date and time: {}'.format(vchtime))
  52. print('Start perf counter time : {}'.format(startTime))
  53. print('End perf counter time : {}'.format(endTime))
  54. print(query)
  55. exit()
  56.  
  57.  
  58.  
  59. def PrintVmInfo(vm, content, vchtime, interval, perf_dict, ):
  60. statInt = interval * 3 # There are 3 20s samples in each minute
  61. summary = vm.summary
  62. disk_list = []
  63. network_list = []
  64.  
  65. # Convert limit and reservation values from -1 to None
  66. if vm.resourceConfig.cpuAllocation.limit == -1:
  67. vmcpulimit = "None"
  68. else:
  69. vmcpulimit = "{} Mhz".format(vm.resourceConfig.cpuAllocation.limit)
  70. if vm.resourceConfig.memoryAllocation.limit == -1:
  71. vmmemlimit = "None"
  72. else:
  73. vmmemlimit = "{} MB".format(vm.resourceConfig.cpuAllocation.limit)
  74.  
  75. if vm.resourceConfig.cpuAllocation.reservation == 0:
  76. vmcpures = "None"
  77. else:
  78. vmcpures = "{} Mhz".format(vm.resourceConfig.cpuAllocation.reservation)
  79. if vm.resourceConfig.memoryAllocation.reservation == 0:
  80. vmmemres = "None"
  81. else:
  82. vmmemres = "{} MB".format(vm.resourceConfig.memoryAllocation.reservation)
  83.  
  84. vm_hardware = vm.config.hardware
  85. for each_vm_hardware in vm_hardware.device:
  86. if (each_vm_hardware.key >= 2000) and (each_vm_hardware.key < 3000):
  87. disk_list.append('{} | {:.1f}GB | Thin: {} | {}'.format(each_vm_hardware.deviceInfo.label,
  88. each_vm_hardware.capacityInKB/1024/1024,
  89. each_vm_hardware.backing.thinProvisioned,
  90. each_vm_hardware.backing.fileName))
  91. elif (each_vm_hardware.key >= 4000) and (each_vm_hardware.key < 5000):
  92. network_list.append('{} | {} | {}'.format(each_vm_hardware.deviceInfo.label,
  93. each_vm_hardware.deviceInfo.summary,
  94. each_vm_hardware.macAddress))
  95.  
  96. #CPU Ready Average
  97. statCpuReady = BuildQuery(content, vchtime, (StatCheck(perf_dict, 'cpu.ready.summation')), "", vm, interval)
  98. cpuReady = (float(sum(statCpuReady[0].value[0].value)) / statInt)
  99. #CPU Usage Average % - NOTE: values are type LONG so needs divided by 100 for percentage
  100. statCpuUsage = BuildQuery(content, vchtime, (StatCheck(perf_dict, 'cpu.usage.average')), "", vm, interval)
  101. cpuUsage = ((float(sum(statCpuUsage[0].value[0].value)) / statInt) / 100)
  102. #Memory Active Average MB
  103. statMemoryActive = BuildQuery(content, vchtime, (StatCheck(perf_dict, 'mem.active.average')), "", vm, interval)
  104. memoryActive = (float(sum(statMemoryActive[0].value[0].value) / 1024) / statInt)
  105. #Memory Shared
  106. statMemoryShared = BuildQuery(content, vchtime, (StatCheck(perf_dict, 'mem.shared.average')), "", vm, interval)
  107. memoryShared = (float(sum(statMemoryShared[0].value[0].value) / 1024) / statInt)
  108. #Memory Balloon
  109. statMemoryBalloon = BuildQuery(content, vchtime, (StatCheck(perf_dict, 'mem.vmmemctl.average')), "", vm, interval)
  110. memoryBalloon = (float(sum(statMemoryBalloon[0].value[0].value) / 1024) / statInt)
  111. #Memory Swapped
  112. statMemorySwapped = BuildQuery(content, vchtime, (StatCheck(perf_dict, 'mem.swapped.average')), "", vm, interval)
  113. memorySwapped = (float(sum(statMemorySwapped[0].value[0].value) / 1024) / statInt)
  114. #Datastore Average IO
  115. statDatastoreIoRead = BuildQuery(content, vchtime, (StatCheck(perf_dict, 'datastore.numberReadAveraged.average')),
  116. "*", vm, interval)
  117. DatastoreIoRead = (float(sum(statDatastoreIoRead[0].value[0].value)) / statInt)
  118. statDatastoreIoWrite = BuildQuery(content, vchtime, (StatCheck(perf_dict, 'datastore.numberWriteAveraged.average')),
  119. "*", vm, interval)
  120. DatastoreIoWrite = (float(sum(statDatastoreIoWrite[0].value[0].value)) / statInt)
  121. #Datastore Average Latency
  122. statDatastoreLatRead = BuildQuery(content, vchtime, (StatCheck(perf_dict, 'datastore.totalReadLatency.average')),
  123. "*", vm, interval)
  124. DatastoreLatRead = (float(sum(statDatastoreLatRead[0].value[0].value)) / statInt)
  125. statDatastoreLatWrite = BuildQuery(content, vchtime, (StatCheck(perf_dict, 'datastore.totalWriteLatency.average')),
  126. "*", vm, interval)
  127. DatastoreLatWrite = (float(sum(statDatastoreLatWrite[0].value[0].value)) / statInt)
  128.  
  129. #Network usage (Tx/Rx)
  130. statNetworkTx = BuildQuery(content, vchtime, (StatCheck(perf_dict, 'net.transmitted.average')), "", vm, interval)
  131. networkTx = (float(sum(statNetworkTx[0].value[0].value) * 8 / 1024) / statInt)
  132. statNetworkRx = BuildQuery(content, vchtime, (StatCheck(perf_dict, 'net.received.average')), "", vm, interval)
  133. networkRx = (float(sum(statNetworkRx[0].value[0].value) * 8 / 1024) / statInt)
  134.  
  135. print('\nNOTE: Any VM statistics are averages of the last {} minutes\n'.format(statInt / 3))
  136. print('Server Name :', summary.config.name)
  137. print('Description :', summary.config.annotation)
  138. print('Guest :', summary.config.guestFullName)
  139. if vm.rootSnapshot:
  140. print('Snapshot Status : Snapshots present')
  141. else:
  142. print('Snapshot Status : No Snapshots')
  143. print('VM .vmx Path :', summary.config.vmPathName)
  144. try:
  145. print('Virtual Disks :', disk_list[0])
  146. if len(disk_list) > 1:
  147. disk_list.pop(0)
  148. for each_disk in disk_list:
  149. print(' ', each_disk)
  150. except IndexError:
  151. pass
  152. print('Virtual NIC(s) :', network_list[0])
  153. if len(network_list) > 1:
  154. network_list.pop(0)
  155. for each_vnic in network_list:
  156. print(' ', each_vnic)
  157. print('[VM] Limits : CPU: {}, Memory: {}'.format(vmcpulimit, vmmemlimit))
  158. print('[VM] Reservations : CPU: {}, Memory: {}'.format(vmcpures, vmmemres))
  159. print('[VM] Number of vCPUs :', summary.config.numCpu)
  160. print('[VM] CPU Ready : Average {:.1f} %, Maximum {:.1f} %'.format((cpuReady / 20000 * 100),
  161. ((float(max(
  162. statCpuReady[0].value[
  163. 0].value)) / 20000 * 100))))
  164. print('[VM] CPU (%) : {:.0f} %'.format(cpuUsage))
  165. print('[VM] Memory : {} MB ({:.1f} GB)'.format(summary.config.memorySizeMB, (float(summary.config.memorySizeMB) / 1024)))
  166. print('[VM] Memory Shared : {:.0f} %, {:.0f} MB'.format(
  167. ((memoryShared / summary.config.memorySizeMB) * 100), memoryShared))
  168. print('[VM] Memory Balloon : {:.0f} %, {:.0f} MB'.format(
  169. ((memoryBalloon / summary.config.memorySizeMB) * 100), memoryBalloon))
  170. print('[VM] Memory Swapped : {:.0f} %, {:.0f} MB'.format(
  171. ((memorySwapped / summary.config.memorySizeMB) * 100), memorySwapped))
  172. print('[VM] Memory Active : {:.0f} %, {:.0f} MB'.format(
  173. ((memoryActive / summary.config.memorySizeMB) * 100), memoryActive))
  174. print('[VM] Datastore Average IO : Read: {:.0f} IOPS, Write: {:.0f} IOPS'.format(DatastoreIoRead,
  175. DatastoreIoWrite))
  176. print('[VM] Datastore Average Latency : Read: {:.0f} ms, Write: {:.0f} ms'.format(DatastoreLatRead,
  177. DatastoreLatWrite))
  178. print('[VM] Overall Network Usage : Transmitted {:.3f} Mbps, Received {:.3f} Mbps'.format(networkTx, networkRx))
  179. print('[Host] Name : {}'.format(summary.runtime.host.name))
  180. print('[Host] CPU Detail : Processor Sockets: {}, Cores per Socket {}'.format(
  181. summary.runtime.host.summary.hardware.numCpuPkgs,
  182. (summary.runtime.host.summary.hardware.numCpuCores / summary.runtime.host.summary.hardware.numCpuPkgs)))
  183. print('[Host] CPU Type : {}'.format(summary.runtime.host.summary.hardware.cpuModel))
  184. print('[Host] CPU Usage : Used: {} Mhz, Total: {} Mhz'.format(
  185. summary.runtime.host.summary.quickStats.overallCpuUsage,
  186. (summary.runtime.host.summary.hardware.cpuMhz * summary.runtime.host.summary.hardware.numCpuCores)))
  187. print('[Host] Memory Usage : Used: {:.0f} GB, Total: {:.0f} GB\n'.format(
  188. (float(summary.runtime.host.summary.quickStats.overallMemoryUsage) / 1024),
  189. (float(summary.runtime.host.summary.hardware.memorySize) / 1024 / 1024 / 1024)))
  190.  
  191.  
  192. def StatCheck(perf_dict, counter_name):
  193. counter_key = perf_dict[counter_name]
  194. return counter_key
  195.  
  196.  
  197. def GetProperties(content, viewType, props, specType):
  198. # Build a view and get basic properties for all Virtual Machines
  199. objView = content.viewManager.CreateContainerView(content.rootFolder, viewType, True)
  200. tSpec = vim.PropertyCollector.TraversalSpec(name='tSpecName', path='view', skip=False, type=vim.view.ContainerView)
  201. pSpec = vim.PropertyCollector.PropertySpec(all=False, pathSet=props, type=specType)
  202. oSpec = vim.PropertyCollector.ObjectSpec(obj=objView, selectSet=[tSpec], skip=False)
  203. pfSpec = vim.PropertyCollector.FilterSpec(objectSet=[oSpec], propSet=[pSpec], reportMissingObjectsInResults=False)
  204. retOptions = vim.PropertyCollector.RetrieveOptions()
  205. totalProps = []
  206. retProps = content.propertyCollector.RetrievePropertiesEx(specSet=[pfSpec], options=retOptions)
  207. totalProps += retProps.objects
  208. while retProps.token:
  209. retProps = content.propertyCollector.ContinueRetrievePropertiesEx(token=retProps.token)
  210. totalProps += retProps.objects
  211. objView.Destroy()
  212. # Turn the output in retProps into a usable dictionary of values
  213. gpOutput = []
  214. for eachProp in totalProps:
  215. propDic = {}
  216. for prop in eachProp.propSet:
  217. propDic[prop.name] = prop.val
  218. propDic['moref'] = eachProp.obj
  219. gpOutput.append(propDic)
  220. return gpOutput
  221.  
  222.  
  223. def main():
  224. args = GetArgs()
  225. try:
  226. vmnames = args.vm
  227. si = None
  228. if args.password:
  229. password = args.password
  230. else:
  231. password = getpass.getpass(prompt="Enter password for host {} and user {}: ".format(args.host, args.user))
  232. try:
  233. if args.cert_check_skip:
  234. context = ssl._create_unverified_context()
  235. si = SmartConnect(host=args.host,
  236. user=args.user,
  237. pwd=password,
  238. port=int(args.port),
  239. sslContext=context)
  240. else:
  241. si = SmartConnect(host=args.host,
  242. user=args.user,
  243. pwd=password,
  244. port=int(args.port))
  245. except IOError as e:
  246. pass
  247. if not si:
  248. print('Could not connect to the specified host using specified username and password')
  249. return -1
  250.  
  251. atexit.register(Disconnect, si)
  252. content = si.RetrieveContent()
  253. # Get vCenter date and time for use as baseline when querying for counters
  254. vchtime = si.CurrentTime()
  255.  
  256. # Get all the performance counters
  257. perf_dict = {}
  258. perfList = content.perfManager.perfCounter
  259. for counter in perfList:
  260. counter_full = "{}.{}.{}".format(counter.groupInfo.key, counter.nameInfo.key, counter.rollupType)
  261. perf_dict[counter_full] = counter.key
  262.  
  263. retProps = GetProperties(content, [vim.VirtualMachine], ['name', 'runtime.powerState'], vim.VirtualMachine)
  264.  
  265. #Find VM supplied as arg and use Managed Object Reference (moref) for the PrintVmInfo
  266. for vm in retProps:
  267. if (vm['name'] in vmnames) and (vm['runtime.powerState'] == "poweredOn"):
  268. PrintVmInfo(vm['moref'], content, vchtime, args.interval, perf_dict)
  269. elif vm['name'] in vmnames:
  270. print('ERROR: Problem connecting to Virtual Machine. {} is likely powered off or suspended'.format(vm['name']))
  271.  
  272. except vmodl.MethodFault as e:
  273. print('Caught vmodl fault : ' + e.msg)
  274. return -1
  275. except Exception as e:
  276. print('Caught exception : ' + str(e))
  277. return -1
  278.  
  279. return 0
  280.  
  281. # Start program
  282. if __name__ == "__main__":
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement