VMware vSphere Monitoring
Last updated on 04 December, 2024LogicMonitor offers out-of-the-box monitoring for the VMware vSphere. This monitoring suite leverages the vSphere Web Services and Automation APIs to monitor VMware vCenter Server Appliances (VCSA), VMware ESXi hosts, and Virtual Machines:
- vSphere Web Services/VMware vSphere API. For more information, see vSphere Web Services API.
- vSphere Automation API. For more information, see vSphere Automation API Reference.
Technology Type
Server & Operations Hardware
Compatibility
As of July 2023, LogicMonitor’s VMware vSphere package is known to be compatible with:
- VMware vCenter Server Appliance 6.7 through vCenter Server 8.0.x
- VMware ESXi 6.5 GA through ESXi 8.0.x
Setup Requirements
- VMware vSphere LogicModules
- LogicMonitor_Collector_Snippets DataSource
- Collector 32.400 or later
- vCenter and ESXi Read-Only User credentials
- VMWare Tools
You can download VMware Tools from VMWare Customer Connect.
Note: vSphere performance counters must be enabled and configured with the default settings (counter level and interval). Using a non-default configuration can potentially cause some datapoints to not properly report data.
VMware vSphere modules are organized into the following categories:
- monitoring of ESXi hosts
- monitoring the runtime of the vCenter appliance
- monitoring the various vSphere objects (datastores, virtual machines, clusters, and so on).
The different categories require different user permissions.
The following table lists the categories that VMware vSphere modules monitor and the user permissions required for each category:
Category | User Permissions Required |
ESXi hosts | Local read-only user Note: Note: vSphere does not currently support domain users for ESXi hosts. For more information, see the following version applicable documentation from VMware:ESXi 7.x: Add an ESXi User in the VMware Host Client |
The runtime of vCenter appliance | N/A |
The various vSphere objects (For example, (datastores, virtual machines, and clusters) | A user can be placed in the following:
localaccounts.user.add CLI command in the appliance API |
VMware vCenter Appliance
For monitoring the vCenter Appliance’s runtime, the following can be used:
- Domain users—The user needs to be assigned to the default SSO group
SystemConfiguration.Administrators
.
Note: Administrator privileges are required due to these modules monitoring runtime statistics of the vCenter Appliance as a whole (for example, CPU/Mem/Filesystem usage, and running services).
- Local users—The user needs to be assigned to the Superadministrator role.
Note: If the SSO group SystemConfiguration.Administrators was previously deleted, it can be restored by creating a new group and naming it SystemConfiguration.Administrators. In addition, the SSO group can also be restored by running the following command: /usr/lib/vmware-vmafd/bin/dir-cli ssogroup create –name SystemConfiguration.Administrators
Assigning a user to the SystemConfiguration.administrator
group provides a different set of permissions than assigning a user to the Administrator group. By default, the SystemConfiguration.A dministrator
group only allows a user to access the VAMI (https://:5480), and not the vCenter environment.
Using the same user for VMware vCenter Appliance and vSphere Monitoring
A single user can be used for monitoring both the vSphere and for the vCenter Appliance.
The following permissions are required:
User Type | Permissions Required |
Domain User |
|
Local User |
|
Creating a user for an ESXi Host
The exact process varies by ESXi version. For more information, see Add an ESXi User in the VMware Host Client from VMware.
Creating a user for vSphere
For more information, see Add vCenter Single Sign-On Users from VMware.
Creating a user for vCenter Appliance Monitoring
For more information, see Create a Local User Account in the vCenter Server Appliance from VMware.
Note:Regardless of the domain, at least read-only global permissions are required for monitoring. After creating a user, you must be assigned Global Permissions to the read-only user group. To ensure modules can collect data, the Propagate to Children must be enabled.
Add Resources into Monitoring
You can add VMware vSphere resources using the following methods:
- (Recommended) Advanced NetScan
For more information, see What is a NetScan. - Manually
Using Advanced Netscan to add VMware Resources (Recommended)
For a given VMware vCenter, the Enhanced Script Netscan creates a Resource Group with nested Resource Groups and Resources to match your vCenter organizational structure of Datacenters, Clusters, Resource Pools, user-defined vCenter Folders, ESXi Hosts, and Virtual Machines. The NetScan properties and filters allows you to control what Resource Groups are created and what ESXi Hosts and Virtual Machines are added to LogicMonitor as Resources. For more information about using Advanced Netscan, see Enhanced Script Netscan.
Warning: If you do not configure the LogicMonitor recommended filters (listed), the NetScan attempts to add all ESXi Hosts and Virtual Machines defined in the target vCenter environment as discrete LogicMonitor resources.
- In your LogicMonitor Portal > Modules > Exchange, install the VMware vSphere LogicModules.
- Navigate to Resources > Add > Several Devices > Advanced NetScan.
The Add Advanced NetScan page is displayed - Enter a name that you want to associate with this NetScan. For example, “VMware vCenter” or “VMware vSphere”.
- Select the Collector to execute the NetScan.
By default, the NetScan assigns new resources to the collector executing the NetScan - Select Enhanced Script NetScan from the Method drop-down list.
- From the Enhanced Script section, select Device Credentials > Use custom credentials for this scan.
- Add the following properties that provide the NetScan with the required VMware API credentials and change how and where the NetScan creates and organizes resources.
Property | Value | Example | Required |
vcenter.user | vCenter read-only user | [email protected] | Yes |
vcenter.pass | vCenter read-only password | ************ | Yes |
vcenter.hostname | Hostname for the vCenter If a vcenter.url is not set, this value will be used to attempt to connect to the vCenter. | IP Address or FQDN | Yes |
vcenter.url | URL to access the VCSA | https://<vcenter.hostname>/sdk | No |
esx.user | Credential to use for connecting to the ESXi host The same credential is used for every ESXi host. If the property is not set, then the credentials specified for the vCenter are used. If you are unable to connect to the host with the provided credentials, the device is still discovered, and the credentials must be manually set on the ESXi Host Resources or parent Resource Groups. | readonly_user | No |
esx.pass | Credential to use for connecting to the ESXi host. | ************ | No |
lmaccess.id OR logicmonitor.access.id | A LogicMonitor API access id to search for duplicate resources in the NetScan prior to adding them to the portal. For more information on portal monitoring, see LogicMonitor Portal Monitoring. | Yes | |
lmaccess.key OR logicmonitor.access.key | A LogicMonitor API key to search for duplicate resources in the NetScan prior to adding them to the portal. For more information on portal monitoring, see LogicMonitor Portal Monitoring. | Yes | |
hostname.source | Allows for selection of the source of the hostname that is used by the NetScan. This is useful in preventing duplicate device creation when conflicts are found for existing resources. For more information, see NetScan Troubleshooting. | No |
The additional optional properties can be set to modify how exactly the devices are added to LogicMonitor, and how the folder structure is created.
Property | Value | Examples | Default Value |
rootFolder | Root folder where all discovered devices are placed in LogicMonitor. Value can be nested. If the Resource Group does not exist, the NetScan creates it. | Customer01/VMware | N/A |
discover.esxi | When true, LogicMonitor adds esxi Hosts. Note: This property has no impact on virtual machine discovery, these properties can be individually toggled. | true, false | true |
discover.vm | When true, LogicMonitor discovers the VMs. Note: This property has no impact on ESXi discovery, these properties can be individually toggled. | true, false | true |
view.vmsAndTemplates | Toggle to create the VM and templates inventory view: Datacenter > Cluster > Folder > VM LogicMonitor recreates this folder structure. Note: Regardless of the option, VM templates are not discovered. | true, false | true |
view.hostAndCluster | Toggle to create the host and cluster inventory view: Datacenter > Cluster > Host > Resource pool > VM When true, LogicMonitor recreates this folder structure. | true, false | true |
view.standaloneVm | Toggle when the host and cluster view is used, and when VMs that are not in a resource pool are placed into a default folder called Standalone VMs. LogicMonitor recreates this folder structure. | true, false | true |
- In the Filters section, use the following filter properties to omit specific Resources (Virtual Machines, ESXi Hosts) from discovery.
These filters behave the same way as Active Discovery filters. The following device level properties are automatically discovered and can be filtered on. Available filter operations include: Equal, NotEqual, GreaterThan, GreaterEqual, LessThan, LessEqual, Contain, NotContain, Exist, NotExist, RegexMatch, RegexNotMatch.
The following list provides examples on how to use these filters.
Recommendation: With large vCenter environments, you can incrementally change the filter operations or values to onboard monitored resources in stages. For example, you can configure the filters to only discover or import one datacenter at a time, or a few clusters at a time, so an Autobalanced Collector Group has time to distribute the monitoring workload.
Warning: If you do not configure the listed filter properties, NetScan attempts to add all ESXi Hosts and Virtual Machines defined in the target vCenter environment.
Property | Description | Example |
vcenter.datacenter | Used to filter out all VMs in a specific datacenter. | Datacenter01 |
vcenter.cluster | vSphere Clusters whose resources you wish to discover or exclude. | Cluster01 |
vcenter.resourcepool | Resource pools, whose resources you wish to discover/exclude. | ResourcePool01 |
vcenter.folder | vCenter Folders, whose resources you wish to discover/exclude. | vCLS |
vcenter.hostname | ESXi Hosts or Virtual Machines you want to discover or exclude. | *[Tt]est.* |
Filtering by VMware.vcenter.tag
- Each tag is organized by a category and the category is appended to the resource property. If the tag category is “Organization” then the resource property name in Logicmonitor will be vmware.vcenter.tag.organization.
- Since tags may not exist on all resources there must be an “exists” filter for a tag needed for filtering.
- If the VMware category “Organization” contains the values “Sales, Marketing and Research” and you want to only process virtual machines from the Sales department you would create the filter vmware.vcenter.tag.oraganization Contains Sales.
- Select Embed a Groovy script and embed the following script:
Warning: Do not edit the script. Edited Enhanced Script NetScans are not supported. If the LogicMonitor-provided script is edited, LogicMonitor Support may (at their discretion) require you to overwrite your edits with the supported script if problems arise. The Enhanced Script NetScan limits LM Envision Resource creation to <= 600 per hour. To create more than 600 Resources, schedule the NetScan to recur each hour until all resources are added.
/*******************************************************************************
* © 2007-2024 - LogicMonitor, Inc. All rights reserved.
******************************************************************************/
import com.santaba.agent.groovy.utils.GroovyScriptHelper
import com.logicmonitor.mod.Snippets
import com.santaba.agent.AgentVersion
import java.text.DecimalFormat
// To run in debug mode, set to true
Boolean debug = false
// To enable logging, set to true
Boolean log = false
// Set props object based on whether or not we are running inside a netscan or debug console
def props
try {
hostProps.get("system.hostname")
props = hostProps
debug = true // set debug to true so that we can ensure we do not print sensitive properties
}
catch (MissingPropertyException) {
props = netscanProps
}
def host = props.get("vcenter.hostname", props.get("system.hostname"))
def user = props.get("vcenter.user") ?: props.get("vcsa.user") ?: props.get("esx.user")
def pass = props.get("vcenter.pass") ?: props.get("vcsa.pass") ?: props.get("esx.pass")
def addr = props.get("vcenter.url") ?: props.get("vcsa.url") ?: props.get("esx.url") ?: "https://${host}/sdk"
if (!host || !user || !pass || !addr) {
throw new Exception("Required parameters are missing.")
}
def logCacheContext = "${host}::vmware-vsphere"
Boolean skipDeviceDedupe = props.get("skip.device.dedupe", "false").toBoolean()
String hostnameSource = props.get("hostname.source", "")?.toLowerCase()?.trim()
Integer collectorVersion = AgentVersion.AGENT_VERSION.toInteger()
// Bail out early if we don't have the correct minimum collector version to ensure netscan runs properly
if (collectorVersion < 32400) {
def formattedVer = new DecimalFormat("00.000").format(collectorVersion / 1000)
throw new Exception("Upgrade collector running netscan to 32.400 or higher to run full featured enhanced netscan. Currently running version ${formattedVer}.")
}
props["proxy.enable"] = false
def modLoader = GroovyScriptHelper.getInstance(GroovySystem.version).getScript("Snippets", Snippets.getLoader()).withBinding(getBinding())
def emit = modLoader.load("lm.emit", "1.1")
def lmDebugSnip = modLoader.load("lm.debug", "1")
def lmDebug = lmDebugSnip.debugSnippetFactory(out, debug, log, logCacheContext)
def httpSnip = modLoader.load("proto.http", "0")
def http = httpSnip.httpSnippetFactory(props)
def cacheSnip = modLoader.load("lm.cache", "0")
def cache = cacheSnip.cacheSnippetFactory(lmDebug, logCacheContext)
def vSphereAPISnip = modLoader.load("vmware.vsphere.api")
def vSphereAPI = vSphereAPISnip.vSphereAutomationAPIFactory(props, lmDebug, cache, http)
def vSphereSDKSnip = modLoader.load("vmware.vsphere.sdk")
def vSphereSDK = vSphereSDKSnip.vSphereAutomationSDKFactory(props, lmDebug, cache)
// Only initialize lmApi snippet class if customer has not opted out
def lmApi
if (!skipDeviceDedupe) {
def lmApiSnippet = modLoader.load("lm.api", "0")
lmApi = lmApiSnippet.lmApiSnippetFactory(props, http, lmDebug)
}
def esxUser = props.get("esx.user", user)
def esxPass = props.get("esx.pass", pass)
def rootFolder = props.get("rootFolder") ?: "vCenterResources"
def includeESXiHosts = (props.get("discover.esxi") ?: true).toBoolean()
def includeVMs = (props.get("discover.vm") ?: true).toBoolean()
def includeHostsAndClustersView = (props.get("view.hostandcluster") ?: true).toBoolean()
def includeVMsAndTemplatesView = (props.get("view.vmsandtemplates") ?: true).toBoolean()
def includeStandaloneVM = (props.get("view.standaloneVm") ?: true).toBoolean()
def maxESXiLoginFailure = (props.get("esx.maxloginfailures", "10").trim()).toInteger()
int eTimeout = 3
int ttlESXiLoginFailure = 0
// Get information about devices that already exist in LM portal
List fields = ["name", "currentCollectorId", "displayName"]
Map args = ["size": 1000, "fields": fields.join(",")]
def lmDevices
// But first determine if the portal size is within a range that allows us to get all devices at once
def pathFlag, portalInfo, timeLimitSec, timeLimitMs
if (!skipDeviceDedupe) {
portalInfo = lmApi.apiCallInfo("Devices", args)
timeLimitSec = props.get("lmapi.timelimit.sec", "60").toInteger()
timeLimitMs = (timeLimitSec) ? Math.min(Math.max(timeLimitSec, 30), 120) * 1000 : 60000 // Allow range 30-120 sec if configured; default to 60 sec
if (portalInfo.timeEstimateMs > timeLimitMs) {
lmDebug.LMDebugPrint("Estimate indicates LM API calls would take longer than time limit configured. Proceeding with individual queries by display name for each device to add.")
lmDebug.LMDebugPrint("\t${portalInfo}\n\tNOTE: Time limit is set to ${timeLimitSec} seconds. Adjust this limit by setting the property lmapi.timelimit.sec. Max 120 seconds, min 30 seconds.")
pathFlag = "ind"
}
else {
lmDebug.LMDebugPrint("Response time indicates LM API calls will complete in a reasonable time range. Proceeding to collect info on all devices to cross reference and prevent duplicate device creation.\n\t${portalInfo}")
pathFlag = "all"
lmDevices = lmApi.getPortalDevices(args)
}
}
List<Map> resources = []
def now = new Date()
def dateFormat = "yyyy-MM-dd'T'HH:mm:ss.s z"
TimeZone tz = TimeZone.getDefault()
Map duplicateResources = [
"date" : now.format(dateFormat, tz),
"message" : "Duplicate device names and display names, keyed by display name that would be assigned by the netscan, found within LogicMonitor portal. Refer to documentation for how to resolve name collisions using 'hostname.source' netscan property.",
"total" : 0,
"resources" : []
]
def ilpCredentials = [:]
def tags = [:]
// Determine the vSphere host that we are making API queries to
def productType = ["vpx": 0, "embeddedEsx": 1]
def productId = productType[vSphereSDK.si.serviceContent.about.getProperties().productLineId]
if (productId == 0) { // vCenter
ilpCredentials["vcenter.user"] = user
ilpCredentials["vcenter.pass"] = pass
ilpCredentials["vcenter.addr"] = addr
tags = vSphereAPI.getTags()
lmDebug.LMDebugPrint("INFO: vCenter tags found: ${tags}")
} else if (productId == 1) { // ESXi
ilpCredentials["esx.user"] = esxUser ?: user
ilpCredentials["esx.pass"] = esxPass ?: pass
ilpCredentials["esx.addr"] = addr
}
def tagPropPrefix = "vmware.vcenter.tag"
Closure tagFormatter = { (it) ? it.collectEntries { cat, tag -> ["${tagPropPrefix}.${cat}", tag.join(",")] } : [:] }
def foundHost = false
def relationships = [:]
def vms = vSphereSDK.getMOs("VirtualMachine").each { updateEntityLineage(it, relationships) }
def hosts = vSphereSDK.getMOs("HostSystem").each { updateEntityLineage(it, relationships) }
vms.each { vm ->
def resource = [:]
def MOR = vm.MOR
if (!MOR) {
lmDebug.LMDebug("ERROR: MOR not found for ${vm}, skipping")
return
}
if (vm.resourcePool == null) {
lmDebug.LMDebug("ERROR: ${vm} is a template, skipping")
return
}
String displayName = vm.name
def hostname = displayName
def ip = displayName
def vmMo = vSphereSDK.createMO(MOR)
def guestIpAddress = vmMo?.guest?.ipAddress
if (guestIpAddress) {
ip = guestIpAddress
hostname = ip
def reverseDnsName = InetAddress.getByName(guestIpAddress)?.getHostName()
if (reverseDnsName) {
hostname = reverseDnsName
}
}
// Check for existing device in LM portal with this displayName; set to false initially and update to true when dupe found
def deviceMatch = false
// If customer has opted out of device deduplication checks, we skip the lookups where we determine if a match exists and proceed as false
if (!skipDeviceDedupe) {
if (pathFlag == "ind") {
deviceMatch = lmApi.findPortalDevice(displayName, args)
if (!deviceMatch) deviceMatch = lmApi.findPortalDeviceByName(ip, args)
}
else if (pathFlag == "all") {
deviceMatch = lmApi.checkExistingDevices(displayName, lmDevices)
if (!deviceMatch) deviceMatch = lmApi.checkExistingDevicesByName(ip, lmDevices)
}
}
if (deviceMatch) {
// Log duplicates that would cause additional devices to be created; unless these entries are resolved, they will not be added to resources for netscan output
def collisionInfo = [
(displayName) : [
"Netscan" : [
"hostname" : ip,
"displayName" : displayName
],
"LM" : [
"hostname" : deviceMatch.name,
"collectorId" : deviceMatch.currentCollectorId,
"displayName" : deviceMatch.displayName
],
"Resolved" : false
]
]
// If user specified to use LM hostname on display name match, update hostname variable accordingly
// and flag it as no longer a match since we have resolved the collision with user"s input
if (hostnameSource == "lm" || hostnameSource == "logicmonitor") {
ip = deviceMatch.name
deviceMatch = false
collisionInfo[displayName]["Resolved"] = true
}
// If user specified to use netscan data for hostname, update the display name to make it unique
// and flag it as no longer a match since we have resolved the collision with user"s input
else if (hostnameSource == "netscan") {
// Update the resolved status before we change the displayName
collisionInfo[displayName]["Resolved"] = true
displayName = "${displayName} - ${ip}"
deviceMatch = false
}
duplicateResources["resources"].add(collisionInfo)
}
foundHost = vSphereSDK.isVmTheHost(vmMo)
if (!includeVMs && foundHost != vmMo) return
def deviceGroups = []
def compLine = getLineage("RESOURCEPOOL", MOR.val, relationships)
def vmLine = getLineage("FOLDER", MOR.val, relationships)
def compFolder = includeHostsAndClustersView ? folderFormatter(compLine, rootFolder, includeStandaloneVM) : null
def vmFolder = includeVMsAndTemplatesView ? folderFormatter(vmLine, rootFolder, includeStandaloneVM) : null
if (foundHost == vmMo) {
// Rely on the vmFolder here. If not including standalone VMs, but the vCenter is a standalone VM, discover it anyway
def baseFolder = (vmFolder ?: folderFormatter(vmLine, rootFolder, includeStandaloneVM))?.split("/")[0]
deviceGroups << baseFolder
}
if (includeVMs) deviceGroups << compFolder << vmFolder
deviceGroups = deviceGroups.minus(null)
if (!deviceGroups) {
lmDebug.LMDebug("DEBUG: VM ${vm.name} skipped due to no containing folder determined. This could be due to different filters being set.")
return
}
if (foundHost == vmMo) { // This is the vCenter VM
resource = [
"hostname" : hostname,
"displayname": displayName,
"hostProps" : ["system.categories": "VMware_vCenter,VMwareVM",
"vcenter.vm.name" : vm.name,
"vcenter.hostname" : host,
"esx.user" : esxUser,
"esx.pass" : esxPass],
"groupName" : deviceGroups << "VMware vCenters"
]
resource.hostProps += tagFormatter(tags[vSphereSDK.rootFolder.MOR.value])
resource.hostProps += ilpCredentials
} else {
resource = [
"hostname" : hostname,
"displayname": displayName,
"hostProps" : ["system.categories": "VMwareVM",
"vcenter.vm.name" : vm.name],
"groupName" : deviceGroups
]
}
// Power state for filtering
def powerState = vm.runtime?.powerState?.value?.toString()
if (powerState) resource.hostProps += ["netscan.powerstate": powerState]
// If the netscan is running on a vCenter device
if (productId == 0) {
// Add vCenter tags
resource.hostProps += tagFormatter(tags[MOR.value as String])
// Add all parent entities as device properties
def lineage = lineageParser(compLine + vmLine)
lineage.each { k, v -> resource.hostProps?."vcenter.${k.toLowerCase()}" = v.join(",") }
}
resources.add(resource)
}
if (includeESXiHosts) {
hosts.each { esxi ->
def resource = [:]
def MOR = esxi.MOR
if (!MOR) {
lmDebug.LMDebug("ERROR: MOR not found for ${esxi}, skipping")
return
}
String displayName = esxi.name
def hostname = displayName
def ip = displayName
def esxiMo = vSphereSDK.createMO(MOR)
def hostIpAddress = esxiMo?.config?.vmotion?.ipConfig?.ipAddress
if (hostIpAddress) {
ip = hostIpAddress
hostname = ip
def reverseDnsName = InetAddress.getByName(hostIpAddress)?.getHostName()
if (reverseDnsName) {
hostname = reverseDnsName
}
}
// Check for existing device in LM portal with this displayName; set to false initially and update to true when dupe found
def deviceMatch = false
// If customer has opted out of device deduplication checks, we skip the lookups where we determine if a match exists and proceed as false
if (!skipDeviceDedupe) {
if (pathFlag == "ind") {
deviceMatch = lmApi.findPortalDevice(displayName, args)
if (!deviceMatch) deviceMatch = lmApi.findPortalDeviceByName(ip, args)
}
else if (pathFlag == "all") {
deviceMatch = lmApi.checkExistingDevices(displayName, lmDevices)
if (!deviceMatch) deviceMatch = lmApi.checkExistingDevicesByName(ip, lmDevices)
}
}
if (deviceMatch) {
// Log duplicates that would cause additional devices to be created; unless these entries are resolved, they will not be added to resources for netscan output
def collisionInfo = [
(displayName) : [
"Netscan" : [
"hostname" : ip,
"displayName" : displayName
],
"LM" : [
"hostname" : deviceMatch.name,
"collectorId" : deviceMatch.currentCollectorId,
"displayName" : deviceMatch.displayName
],
"Resolved" : false
]
]
// If user specified to use LM hostname on display name match, update hostname variable accordingly
// and flag it as no longer a match since we have resolved the collision with user"s input
if (hostnameSource == "lm" || hostnameSource == "logicmonitor") {
ip = deviceMatch.name
deviceMatch = false
collisionInfo[displayName]["Resolved"] = true
}
// If user specified to use netscan data for hostname, update the display name to make it unique
// and flag it as no longer a match since we have resolved the collision with user"s input
else if (hostnameSource == "netscan") {
// Update the resolved status before we change the displayName
collisionInfo[displayName]["Resolved"] = true
displayName = "${displayName} - ${ip}"
deviceMatch = false
}
duplicateResources["resources"].add(collisionInfo)
}
def deviceGroups = []
def compLine = getLineage("RESOURCEPOOL", MOR.val, relationships)
def compFolder = folderFormatter(compLine, rootFolder, includeStandaloneVM)
deviceGroups << "${compFolder}/ESXi hosts"
deviceGroups = deviceGroups.minus(null)
def vSphere = null
def esxiAddr = "https://${esxi.name}/sdk"
lmDebug.LMDebug("INFO: Attempting to login to the ESX host ${esxi} (${esxi.name}) with user ${esxUser}")
try {
if (ttlESXiLoginFailure < maxESXiLoginFailure) {
vSphere = vSphereSDKSnip.vSphereAutomationSDKFactory(props, lmDebug, cache, hostname)
} else {
vSphere = null
}
} catch (Exception e) {
lmDebug.LMDebug("\tDEBUG: Unable to login to ESXi host ${esxi} at ${esxiAddr}, skipping...")
lmDebug.LMDebug("\t\tERROR: $e")
ttlESXiLoginFailure++
}
if (!vSphere) {
lmDebug.LMDebug("DEBUG: Unable to connect to ESXi host ${esxi.name} with the provided credentials")
// We were unable to connect to the ESXi host directly, just add it as a standard device
resource = [
"hostname" : hostname,
"displayname": displayName,
"hostProps" : ["esx.netscan.status": "Netscan did not connect to ESX host."], // Do not set the system category "VMware_ESXi" since we can't actually use this as an ESXi device
"groupName" : deviceGroups
]
} else {
lmDebug.LMDebug("INFO: Successful connection to ESXi host ${esxi.name}")
def esxMo = vSphereSDK.getMOs("HostSystem")[0]
resource = [
"hostname" : hostname,
"displayname": displayName,
"hostProps" : [
"esx.user" : esxUser,
"esx.pass" : esxPass,
"esx.addr" : esxiAddr,
"system.categories": "VMware_ESXi"],
"groupName" : deviceGroups
]
}
resource.hostProps."vcenter.hostname" = host
resource.hostProps += ilpCredentials
// If the netscan is running on a vCenter device
if (productId == 0) {
// Add vCenter tags
resource.hostProps += tagFormatter(tags[MOR?.value as String])
// Add all parent entities as device properties
def lineage = lineageParser(compLine)
lineage.each { k, v -> resource.hostProps?."vcenter.${k.toLowerCase()}" = v.join(",") }
}
resources.add(resource)
}
}
lmDebug.LMDebugPrint("Duplicate Resources:")
duplicateResources.resources.each {
lmDebug.LMDebugPrint("\t${it}")
}
emit.resource(resources, debug)
return 0
def folderFormatter(lineage, rootFolder = "", includeStandaloneVM) {
if (lineage.size() > 1) {
def folder = lineage.collect { Map folderMap ->
def type = folderMap.type.toUpperCase()
if (type == "FOLDER") {
if (folderMap.parent[0] == null) { // This is the parent folder
return rootFolder ?: "VMware - ${folderMap.name}"
} else if (folderMap.name == "vm") {
return "VMs" // VMs and templates folder
} else {
return folderMap.name
}
} else if (type == "DATACENTER") {
return "Datacenter - ${folderMap.name}"
} else if (type == "CLUSTERCOMPUTERESOURCE") {
return "Cluster - ${folderMap.name}"
} else if (type == "RESOURCEPOOL") {
return "Resource Pool - ${folderMap.name}"
} else if (type == "COMPUTERESOURCE") {
return "Standalone ESXi hosts"
} else {
return folderMap.name
}
// Don't put the device in a folder named after it
}[0..-2]
if (lineage.size() >= 2) {
// Check for standalone VMs that are not in a resourcePool, and put them in their own standalone folder
if (lineage[-1].type == "VIRTUALMACHINE" && (lineage[-2].type != "RESOURCEPOOL" && lineage[-2].type != "FOLDER")) {
if (includeStandaloneVM) {
folder << "Standalone VMs"
} else {
// This is a standalone, and if we don't want to include it, return nothing
return null
}
}
}
return folder.join("/")
}
return null
}
Map lineageParser(lineage) {
def out = [:].withDefault { [] }
lineage.each { out[it?.type] << it?.name }
out.collectEntries { k, v ->
v.unique()
if (k.toUpperCase() == "CLUSTERCOMPUTERESOURCE") {
k = "CLUSTER"
} else if (k.toUpperCase() == "FOLDER") {
v.remove("vm") // Autogenerated folders
v.remove("Datacenters")
}
_out = [k, v]
}
}
/**
* Sets the relationships map for the supplied Managed Object and all of it"s parents.
* For most Managed Object types it only looks at the parent property, for virtual machines, the containing resourcePool is also mapped.
* example for virtual machines this may map something like virtual machine -> resource pool -> host cluster -> folder -> datacenter
* and virtual machine -> containing folders -> datacenter
*/
def updateEntityLineage(MO, Map relationships) {
if (!MO) return
int entityUpdateMax = 86400 // Time in seconds until cached data is forced to update, default 1 day
int epoch = System.currentTimeSeconds()
def mor = MO.MOR
def entityID = mor?.val
def type = mor?.type?.toUpperCase()
def parent = MO.parent
def parentID = parent?.MOR?.val
def parentIDs = [parentID]
if (parent && entityID) {
int time = epoch - ((relationships.get(entityID)?.lastUpdate) ?: 0)
if (time >= entityUpdateMax || !relationships.get(entityID)?.parent?.contains(parentID)) {
// Now check parent
updateEntityLineage(parent, relationships)
if (type == "VIRTUALMACHINE") {
// For VMs we want to both trace through the compute resources (resource pool) as well as the actual parent (folder)
def rp = MO.resourcePool
def rpID = rp?.MOR?.val
parentIDs << rpID
updateEntityLineage(rp, relationships)
}
}
}
def relationship = [
"name" : MO.name,
"type" : type,
"class" : MO.class?.getName(),
"lastUpdate": epoch,
"parent" : parentIDs?.minus(null),
"MO" : MO
]
relationships.put(entityID, relationship)
}
/**
* Returns the supplied inventory item"s computational lineage as based on the relationships map.
* This is based on the Hosts and Clusters Inventory Lists view in the vCenter UI. This view contains the virtual machine, resource pools, esx hosts, clusters, datacenters and more.
*/
def getLineage(relationshipType, entityID, Map relationships, lineage = []) {
if( !entityID || !relationships ) return lineage
def entry = relationships.get(entityID)
if (entry) {
// If the vm host is running vcsa 6.7 and is not in a resourcepool, then we can't currently trace its compute lineage
def parent = entry.type == "VIRTUALMACHINE" ? entry.parent.find{ relationships.get(it)?.type == relationshipType } : entry.parent[0]
if (entry.name != "host" && entry.name != "Resources") {
lineage.add(0, entry)
}
getLineage(relationshipType, parent, relationships, lineage)
}
return lineage
}
- In the Schedule section, select Run this NetScan on a schedule. For dynamic environments, you can schedule the NetScan to run as frequently as hourly.
Note: Subsequent NetScan runs will add or move resources or resource groups based on changes in VMware vCenter. However, the NetScan does not have the ability to delete resources.
- Select Save or Save & Run.
After running the NetScan, review the history for the number of resources added, or for error messages if the NetScan does not create any resources. As needed, create Dynamic Resource Groups to organize Resources by business need and to apply workload-specific monitoring credentials.
Manually Assigning Properties to Resources
If you add hosts through an Advanced Netscan, then the relevant properties and credentials are discovered and assigned to the hosts automatically. If the hosts are added manually into LogicMonitor, use the following properties. For more information , see Adding Devices.
ESXi Host
Property | Value | Example values | Required |
esx.user | ESXi read-only user | root | Yes |
esx.pass | ESXi read-only password | ***** | Yes |
esx.url | Optional URL to access the ESXi Default value is https://<host>/sdk | https://esx01/sdk | No |
esx.maxloginfailures | Maximum number of times the ESXi credentials will be attempted before giving up. Once the max is hit the ESXi host will be setup as devices without credentials and a esx.netscan.status saying it can’t connect. \n Default=10 | No |
vCenter Server Appliance Host Properties
There are multiple options for configuring the vcenter user. For more information, see Using the same user for VMware vCenter Appliance and vSphere Monitoring.
Property | Value | Example values | Required |
vcenter.user | vCenter user | [email protected] | Yes |
vcenter.pass | vCenter password | ******** | Yes |
vcenter.url | Optional URL to access the VCSA Default value is https://<host>/sdk | https://vcenter01/sdk | No |
vcsa.user | Optional vCenter SystemConfiguration.Administrator SSO group user or SuperAdmin local user | [email protected] | No |
vcsa.pass | Optional vCenter SystemConfiguration.Administrator SSO group password or SuperAdmin local password | ******** | No |
Note: In vSphere, there are no API only users. By default every user should be able to access both the host’s web interface and perform API calls. If a user is unable to, then this could point to some configuration issues for the user/role. In the case of vCenter Server Appliance monitoring, the VAMI interface (default access on port 5480) must also be accessible.
Considerations
Collector Proxies
If you are using a proxy for your Collector access, then you must exclude the appliance hosts from being proxied by your Collector or the Collector cannot access the VMware API. This is done by adding a value to the proxy.exclude setting in your Collector’s agent.conf file that reflect these hosts, proxy.exclude=hostname1|hostname2|hostname3|…, where the various hostnames represent the IPs/hostnames for the various ESXi or vCenter hosts that have been added into LogicMonitor and are being monitored by the Collector.
If the Collector is not able to access the VMware API and your ESXi/vCenter device has been added through its hostname, edit the device to use its IP instead and repeat these configuration edits if needed.
Modifying the API Port or URL
If your vCenter or ESXi hosts are configured to expose their API on nonstandard ports, you can set the properties vcenter.url or esx.url with an appropriate URL (For example, https://192.168.1.100:8443/sdk).
Import LogicModules
From the LogicMonitor Exchange, import all VMware vSphere Monitoring LogicModules from the package. For more information, see LogicModules in Package. If these LogicModules are already installed, ensure you have the latest versions.
After the LogicModules are imported, data collection automatically begins.
Troubleshooting
- If not able to receive most data on the VMware_vCenterAppliance_* modules, ensure the user permissions are configured correctly. The user must be able to access the VAMI, default at https://HOST:5480. Due to the vCenterAppliance modules monitoring the runtime of the vCenter environment, you need specific administrator level access. The following details what settings should be assigned for user type:
User | Permissions |
Domain users | SystemConfiguration.Adminstrator SSO group |
Local users | SuperAdmin role |
Note:This is different than assigning the user the Administrator role. The VAMI operates outside of the vCenter environment, and so access to SystemConfiguration.Adminstrator
only allows access to the VAMI and not the vCenter client.
- If only some of the VMware_vSphere_* or VMware_Esxi_* modules are able to report data, ensure the user permissions are configured correctly. When assigning the read-only role to a user, the option to ‘Propagate to Children’ must be enabled. You can verify that the correct permissions are set by accessing the vCenter Client with the configured user. You must be able to view all of the various vSphere objects (hosts, datastores, switches, VMs) that you want to monitor. VMware will only display objects that the user has access to, and accessing a parent object, for example, ESXi host does not inherently give access to the children, like VMs.
- If your vCenter 5-minute Statistics Collection Level is set to “Level 1”, some datapoints may not return data. To access all of the necessary counters monitored, you must set your vCenter Statistics Collection Level to “Level 2.” This can be done within your vSphere Web Client (you must use the ‘flex’or ‘flash’ interface (not HTML5)) by doing the following:
- Select your vCenter instance in tree.
- Open the Configure tab.
- Select General > Statistics > Edit.
- From the dropdown in the Statistics Level column, select “Level 2” for the first item listed in the table.
- Large queries to clusters may place an excessive load on internal databases, resulting in data collection issues. For more information, see Performance charts are empty and displays the error from VMware.
- You must ensure your vCenter server is sized appropriately for the numbers of hosts and VMs it is managing. For size requirements, see System Requirements for the New vCenter Server Appliance from VMWare.
Note: the vCenter database requirements must be added to the vCenter server requirements if they are on the same machine.
If vCenter does not have enough resources, vCenter may refuse some connections to the API (HTTPS) port (seen in the HTTPS- DataSource in LogicMonitor), or it may report a value of “-1” to some performance queries. Both of these situations cause gaps in graphs.
Netscan Troubleshooting
The NetScan for this suite can update existing devices in the portal to add relevant information retrieved from the VMware vSphere API. It is also possible for the NetScan to create duplicate devices in the portal when a conflict exists where the display name is the same, but the value for system.hostname is different.
To ensure devices are updated properly and duplicate devices are not created, this NetScan uses LogicMonitor’s API to query existing devices and report name conflicts discovered. This file can be accessed in the collector logs. For more information, see Collector logging.
The devices in this report are not reported to LogicMonitor as part of the NetScan output unless the NetScan has been configured with the property hostname.source. This property allows a user to resolve the name conflicts discovered by selecting the source of the hostname that is used in the NetScan output. Two possible hostname sources are determined by the following values:
- “lm” or “logicmonitor” Devices with name conflicts use the existing
system.hostname
in LogicMonitor to ensure a device in the portal is updated using the NetScan. This setting does not create a new device. - “netscan” Devices with name conflicts maintain system.hostname determined in the NetScan script and update the display name reported to append –
<system.hostname>
to ensure it is unique and can be added to the portal. This option is beneficial if you do not have strict naming conventions and have multiple devices with the same display name.
Note:NetScans are not able to update the value of system.hostname. NetScans can update display name, custom properties, and group assignments.
VMware vSphere LogicModules in Package
VMware vSphere modules are organized into three distinct categories based on the components that are being monitored.
VMware ESXi modules provide availability, performance, and hardware sensor monitoring for VMware ESXi hosts and Virtual Machine monitoring for Standalone ESXi hosts not managed by vCenter.
Display Name | Type | Description | Replaces |
VMware_ESXi_CPU | DataSource | Tracks the utilization of host’s CPUs. | VMware_ESXi_Resources VMware_ESXi_HostPerformance |
VMware_ESXi_DatastoreThroughput | DataSource | Monitors vSphere / vCenter host performance metrics. | VMware_ESXi_DatastorePerformance |
VMware_ESXi_DatastoreUsage | DataSource | Monitors storage capacity of ESXi datastores. Data is only valid if datastore is accessible. | VMware_ESXi_DatastoreCapacity |
VMware_ESXi_Disks | DataSource | Monitors disk usage of the ESXi host. | VMware_ESXi_HostPerformance |
VMware_ESXi_HardwareHealthSensor | DataSource | Monitors hardware health sensors as reported by ESXi. Sensors monitored are the hardware health sensors located in the Storage / Memory / Processor monitoring tabs and are separate from the system sensors which are reported on by VMware_ESXi_SystemHealthSensor. Sensors with an unknown or grey status are filtered from active discovery. | VMware_ESXi_HardwareHealthSensors VMware_ESXi_HardwareSensorFans VMware_ESXi_HardwareSensorPower VMware_ESXi_HardwareSensors |
VMware_ESXi_LogicalProcessors | DataSource | Tracks the utilization of the ESXi host CPUs’ logical processors. | VMware_ESXi_HostCPUCores |
VMware_ESXi_Memory | DataSource | Monitors the memory available to the ESXi host. | VMware_ESXi_HostPerformance |
VMware_ESXi_NetworkInterfaces | DataSource | Monitors the bandwidth of the ESXi host network interfaces. | VMware_ESXi_HostInterfaces |
VMware_ESXi_NetworkState | DataSource | Monitors the statuses of ESX host’s networks and distributed port groups. | VMware_ESXi_NetworkStatus |
VMware_ESXi_Power | DataSource | Monitors the power usage of the ESXi host. | N/A |
VMware_ESXi_SystemHealthSensor | DataSource | Monitors the hardware health system sensors on an ESXi host as reported by VMware. The system sensors being monitored are separate from the additional storage, memory, and CPU sensors hardware sensors. | N/A |
VMware_ESXi_VirtualMachineDiskCapacity | DataSource | Monitors virtual disk storage capacity metrics on individual virtual machines. | VMware_vSphere_vDiskCapacity |
VMware_ESXi_VirtualMachinePerformance | DataSource | Monitors the CPU, disk, and memory, & network performance metrics for ESXi virtual machines. | VMware_vSphere_VMperformance |
VMware_ESXi_VirtualMachineSnapshots | DataSource | Monitors ages of snapshots on individual virtual machines. | VMware_vSphere_VMsnapshots |
VMware_ESXi_VirtualMachineStatus | DataSource | Tracks power, heartbeat, fault tolerance, guest tools states, as well as time since last power-on on individual virtual machines. | VMware_vSphere_VMstatus |
VMware_vSphere_Network_Topology | TopologySource | Generate VMware network topologies based on data from vCenter. | VMware_vCenter_Network_Topology |
VMware_vSphere_VirtualMachine_Topology | TopologySource | Generate VMware virtual machine topologies based on data from vCenter. | VMware_vCenter_VM_Topology |
addERI_ESXi | PropertySource | Sets device External Resource IDs (ERIs) for VMware ESXi hosts for topology mapping, including host UUID, MAC addresses, IQN, and WWN. Sets ERI Type (ERT) to “HyperVisor”. | N/A |
VMware_vSphere_Info | PropertySource | Provides additional info for the vSphere host. | VMware_ESXi_ObjectCount VMware_vCenter_ObjectCount |
VMware_LM_Troubleshooter | DataSource | Checks various settings to make sure that ESXi/vCenter collection will work properly. Will direct the user on how to fix any discovered issues. | N/A |
VMware vCenterAppliance modules provide data on availability and performance Monitoring of VMware vCenter Server Appliances.
Display Name | Type | Description | Replaces |
VMware_vCenterAppliance_Backup | DataSource | Collects recovery backup information from the most recent backup occurrence. | VMware_VCSA_Backups |
VMware_vCenterAppliance_CPU | DataSource | Monitors the vCenter host’s CPU information. | VMware_VCSA_CPU |
VMware_vCenterAppliance_DiskPerformance | DataSource | Monitors the vCenter host’s disk performance. | VMware_VCSA_DiskPerformance |
VMware_vCenterAppliance_FileSystemPartitions | DataSource | Monitors the utilization of vCenter host’s filesystem partitions. | VMware_VCSA_FilesystemCapacity |
VMware_vCenterAppliance_FileSystemSwap | DataSource | Monitors the utilization of vCenter host’s disk swap. | VMware_VCSA_Swap |
VMware_vCenterAppliance_HealthStatus | DataSource | Monitors the vCenter host’s health status of various system services such as applmgmt, database-storage, load, memory, software-packages, storage, swap, and system. | VMware_VCSA_HealthStatus |
VMware_vCenterAppliance_HighAvailability | DataSource | Monitors the status of vCenter HA (VCHA). | VMware_vCenter_AdmissionControl VMware_vCenter_HANodeHealth VMware_vCenter_HAStatus |
VMware_vCenterAppliance_Memory | DataSource | Monitors the vCenter host’s memory information. | VMware_VCSA_Memory |
VMware_vCenterAppliance_NetworkInterfaces | DataSource | Monitors the vCenter host’s network connection. | VMware_VCSA_Network |
VMware_vCenterAppliance_Power | DataSource | Monitors the total power usage of the vCenter environment. | N/A |
VMware_vCenterAppliance_Services | DataSource | Monitors the vCenter host’s services’ runtime state. | VMware_VCSA_Services |
addCategory_vCenter | PropertySource | Sets categories for optional additional vCenter monitoring services, if they are in use, including vCenter clusters with HA (VCHA) and VCSA backups. | addCategory_vCenterHA |
VMware_vSphere_Info | PropertySource | Provides additional info for the vSphere host. | VMware_ESXi_ObjectCount VMware_vCenter_ObjectCount |
VMware_LM_Troubleshooter | DataSource | Checks various settings to make sure that ESXi/vCenter collection will work properly. Will direct the user on how to fix any discovered issues. | N/A |
VMware vSphere modules provide availability and performance monitoring for the vSphere environment (virtual machines, clusters, resource pools, datastores, etc.).
Display Name | Type | Description | Replaces |
VMware_vSphere_Clusters | DataSource | Monitors ESX host clusters’ CPU and Memory metrics on vCenter devices. | VMware_vCenter_ClusterPerformance |
VMware_vSphere_DatastoreClusters | DataSource | Monitors storage usage of vCenter datastore clusters. | VMware_vCenter_DatastoreClusters |
VMware_vSphere_DatastoreStatus | DataSource | Monitors operating status of vSphere datastore. | VMware_vCenter_DatastoreStatus |
VMware_vSphere_DatastoreThroughput | DataSource | Monitors vSphere / vCenter host performance metrics. | VMware_vCenter_DatastorePerformance |
VMware_vSphere_DatastoreUsage | DataSource | Monitors storage usage of vCenter datastores. Data is only valid if datastore is accessible. | VMware_vCenter_DatastoreCapacity |
VMware_vSphere_HighAvailability | DataSource | Monitors vSphere High Availability (vSphere HA) and admission control, including resources available for HA and if any vSphere HA agent (FDM) is experiencing issues. | VMware_vCenter_AdmissionControl |
VMware_vSphere_HostStatus | DataSource | Monitors the state of the vCenter ESXi hosts. | VMware_vCenter_HostStatus |
VMware_vSphere_NetworkState | DataSource | Monitors the status of vCenter networks and distributed virtual port groups. | VMware_vCenter_NetworkStatus |
VMware_vSphere_ResourcePools | DataSource | Monitors resource pools’ CPU and Memory metrics on vCenter devices. | VMware_vCenter_ResourcePools |
VMware_vSphere_VirtualMachineDiskCapacity | DataSource | Monitors virtual disk storage capacity metrics on individual virtual machines. | VMware_vCenter_VMDiskCapacity |
VMware_vSphere_VirtualMachineNetworkInterface | DataSource | Monitors virtual machine interface data throughput and packet transmission. | VMware_vCenter_VMInterface |
VMware_vSphere_VirtualMachinePerformance | DataSource | Monitors the CPU, disk, memory and network performance metrics on individual virtual machines. | VMware_vCenter_VMPerformance |
VMware_vSphere_VirtualMachineSnapshots | DataSource | Monitors ages of snapshots on individual virtual machines. | VMware_vCenter_VMSnapshots |
VMware_vSphere_VirtualMachineStatus | DataSource | Tracks power, heartbeat, fault tolerance, guest tools states, as well as time since last power-on on individual virtual machines. | VMware_vCenter_VMStatus |
VMware_vCenter_Cluster_Topology | TopologySource | Generate VMware cluster topologies based on data from vCenter. | VMware_ESXi_Topology |
VMware_vCenter_Datastore_Topology | TopologySource | Generate VMware datastore topologies based on data from vCenter. | VMware_ESXi_Topology |
VMware_vSphere_Network_Topology | TopologySource | Generate VMware network topologies based on data from vCenter. | VMware_vCenter_Network_Topology |
VMware_vSphere_VirtualMachine_Topology | TopologySource | Generate VMware virtual machine topologies based on data from vCenter. | VMware_vCenter_VM_Topology |
addERI_vCenter | PropertySource | Sets device External Resource IDs (ERIs) for VMware ESX vCenters for topology mapping, including UUID. Sets ERI Type (ERT) to “PhysicalServer”. | N/A |
addCategory_vCenter | PropertySource | Sets categories for optional additional vCenter monitoring services, if they are in use, including vCenter clusters with HA (VCHA) and VCSA backups. | addCategory_vCenterHA |
VMware_vSphere_Info | PropertySource | Provides additional info for the vSphere host. | VMware_ESXi_ObjectCount VMware_vCenter_ObjectCount |
VMware_LM_Troubleshooter | DataSource | Checks various settings to make sure that ESXi/vCenter collection will work properly. Will direct the user on how to fix any discovered issues. | N/A |
When setting static datapoint thresholds on the various metrics tracked by this package’s modules, LogicMonitor follows the technology owner’s best practice KPI recommendations.
Recommendation:If necessary, we encourage you to adjust these predefined thresholds to meet the unique needs of your environment. For more information, see Tuning Static Thresholds for Datapoints.
Migration from Legacy Modules
If you are currently monitoring VMware devices using any of these legacy modules, you will not experience data loss upon importing the new modules. This is because module names have been changed to eliminate module overwriting. For more information, see Deprecated LogicModules.
However, you will collect duplicate data and receive duplicate alerts for as long as both sets of modules are active. For this reason and to avoid adding unnecessary additional load to vCenter Servers, you should disable the above-listed modules after importing the new set of modules and confirm they are working as intended in your environment.
Recommendation:When a DataSource is disabled, it stops querying the host and generating alerts, but maintains all historical data. You may want to delete the legacy modules altogether, but consider this move carefully as all historical data will be lost at deletion. For more information, see Disabling Monitoring for a DataSource or Instance.