Nutanix Prism Central Monitoring
Last updated - 16 January, 2026
LogicMonitor offers out-of-the-box monitoring for the Nutanix Prism Central. This monitoring suite leverages the Nutanix Prism Central v4 REST APIs to monitor Nutanix clusters, hypervisor hosts, and virtual machines.
For more information about Nutanix APIs, see Nutanix v4 APIs from Nutanix.
LogicMonitor’s Nutanix Prism Central monitoring package is compatible with the following versions:
- Nutanix PC (Prism Central) 7.3 and later
- Nutanix AOS (Acropolis Operating System) 7.3 and later
- Nutanix AHV (Acropolis Hypervisor) 10.3 and later
Requirements for Nutanix Prism Central Monitoring
To enable Nutanix Prism Central Monitoring, you need the following:
LogicMonitor_Collector_SnippetsDataSource- Access to Nutanix Prism Central API (port 9440 by default)
- Local Nutanix Prism Central user credentials with read-only permissions
Recommendation: Use a local account with “Prism Viewer” permissions. For more information, see Built-in Roles List from Nutanix.
Adding Resources into Monitoring
Nutanix Prism Central resources can be added into monitoring using the following methods:
- Automatically using an Advanced NetScan (recommended)
- Manually, by adding resources and assigning required properties
Using NetScan is strongly recommended for larger or dynamic Nutanix environments, as it automates discovery and maintains hierarchical resource organization.
Warning: To avoid overages, verify that you have sufficient LogicMonitor licenses before running the NetScan. Test NetScan filters carefully to avoid unintentionally adding unwanted Nutanix resources.
Using Advanced NetScan to add Nutanix Prism Central Resources (Recommended)
For more information about using Advanced NetScan, see Enhanced Script Netscan.
- In LogicMonitor, navigate to Modules > Exchange.
- Locate and install the Nutanix Prism Central LogicModules.
For a list of modules, see Monitoring Modules. - Navigate to Resources > Add > Several resources > Advanced NetScan.
- On the Add Advanced NetScan page, enter a descriptive name you want to associate with this NetScan (for example, Nutanix Prism Central Resources).
- Select the Collector to execute the NetScan.
For more information, see Collector Assignment in Enhanced Script Netscan. - Select “Enhanced Script NetScan” from the Method drop-down list.
- From the Enhanced Script section, select Resource Credentials > Use custom credentials for this scan.
- Add the following properties that provide the NetScan with the required Nutanix Prism Central credentials and change how and where the NetScan creates and organizes resources:
| Property | Value | Required |
|---|---|---|
nutanix.prism.central.user | Prism Central username with Viewer role (for example, logicmonitor_viewer) | Yes |
nutanix.prism.central.pass | Prism Central password | Yes |
nutanix.prism.central.host | Hostname or IP of Prism Central (for example, 10.10.10.100 or prism.company.com) | Yes |
nutanix.prism.central.port | API port (default is 9440) | 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. | 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. | Yes |
hostname.source | Enables the selection of the source of the hostname that is used by the NetScan. Note: This is useful in preventing duplicate resource creation when conflicts are found for existing resources. For more information, see NetScan Troubleshooting. | No |
skip.device.dedupe | Enables you to skip device deduplication checks, making LogicMonitor API credentials not required. | No |
rootFolder | The name of the LogicMonitor Resource Group that this NetScan creates or uses if already existing. The value can be a nested child folder. For example, Nutanix/Production or DataCenter/Nutanix. Default is “Nutanix Prism Central Resources”. | No |
lmapi.timelimit.sec | Set to configure the amount of time dedicated to making LM API queries. Default 60, allowable range 30-120. | No |
Recommendation: To verify desired functionality, start with a specific filter of some Resources you want to monitor, then 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 Nutanix Cluster at a time until you are confident that your Properties and Filters are properly defined to achieve your desired outcome.
Warning: If filters are not configured, the NetScan attempts to add all discovered Nutanix hosts and VMs as individual LogicMonitor resources.
- Select Embed a Groovy script and embed the following the NetScan script:
/*******************************************************************************
* © 2007-2025 - LogicMonitor, Inc. All rights reserved.
******************************************************************************/
import com.santaba.agent.groovy.utils.GroovyScriptHelper as GSH
import com.logicmonitor.mod.Snippets
import groovy.json.JsonSlurper
Boolean debug = false
Boolean log = false
// Set props object based on whether or not we are running inside a netscan or debug console
def props
def prismCentralHost
try {
hostProps.get("system.hostname")
props = hostProps
prismCentralHost = props.get("nutanix.prism.central.host", props.get("system.hostname", ""))
debug = true // set debug to true so that we can ensure we do not print sensitive properties
}
catch (MissingPropertyException) {
props = netscanProps
prismCentralHost = props.get("nutanix.prism.central.host", "")
}
def modLoader = GSH.getInstance(GroovySystem.version).getScript("Snippets", Snippets.getLoader()).withBinding(getBinding())
def lmDebugSnip = modLoader.load("lm.debug", "1")
def lmDebug = lmDebugSnip.debugSnippetFactory(out, debug, log, "Nutanix_PrismCentral_Netscan")
def emit = modLoader.load("lm.emit", "1")
def httpSnip = modLoader.load("proto.http", "0")
def http = httpSnip.httpSnippetFactory(props)
def nutanixPrismCentralSnip = modLoader.load("nutanix.prism.central", "0")
def nutanixPrismCentral = nutanixPrismCentralSnip.nutanixPrismCentralSnippetFactory(props, lmDebug, http)
// Configuration options
def rootFolder = props.get("rootFolder") ?: "Nutanix Prism Central Resources"
Boolean skipDeviceDedupe = props.get("skip.device.dedupe", "false").toBoolean()
String hostnameSource = props.get("hostname.source", "")?.toLowerCase()?.trim()
// Initialize LM API for device deduplication if not skipped
def lmApi
if (!skipDeviceDedupe) {
def lmApiSnippet = modLoader.load("lm.api", "0")
lmApi = lmApiSnippet.lmApiSnippetFactory(props, http, lmDebug)
}
// Get information about devices that already exist in LM portal
List fields = ["name", "currentCollectorId", "displayName", "id", "customProperties"]
Map args = ["size": 1000, "fields": fields.join(",")]
def lmDevices
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
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": []
]
// Get all hosts data with pagination
def hostsData = nutanixPrismCentral.httpGet("clustermgmt/v4.0/config/hosts?\$limit=100")
def allHosts = []
def hostsCurrentPage = 0
def hostsPageSize = 100
if (hostsData && hostsData.data) {
allHosts.addAll(hostsData.data)
lmDebug.LMDebugPrint("Hosts first page: Found ${hostsData.data.size()} hosts")
// Check if there are more pages to process
def hostsHasMore = hostsData.metadata?.links?.find { it.rel == "next" } != null
if (hostsHasMore) {
lmDebug.LMDebugPrint("Hosts pagination detected. Total available: ${hostsData.totalAvailableResults ?: 'unknown'}")
// Continue fetching remaining pages
while (hostsHasMore) {
hostsCurrentPage++
lmDebug.LMDebugPrint("Fetching hosts page ${hostsCurrentPage + 1}...")
def hostsPageData = nutanixPrismCentral.httpGet("clustermgmt/v4.0/config/hosts?\$limit=${hostsPageSize}&\$page=${hostsCurrentPage}")
if (hostsPageData && hostsPageData.data && hostsPageData.data.size() > 0) {
allHosts.addAll(hostsPageData.data)
lmDebug.LMDebugPrint("Hosts page ${hostsCurrentPage + 1}: Found ${hostsPageData.data.size()} hosts")
// Check if there's a next page
hostsHasMore = hostsPageData.metadata?.links?.find { it.rel == "next" } != null
} else {
lmDebug.LMDebugPrint("No more hosts data found, stopping pagination")
hostsHasMore = false
}
// Safety check to prevent infinite loops
if (hostsCurrentPage > 50) {
lmDebug.LMDebugPrint("Reached maximum hosts page limit (50), stopping pagination")
break
}
}
}
}
lmDebug.LMDebugPrint("Total hosts discovered: ${allHosts.size()}")
// Process each host
allHosts.each { host ->
def hostExtId = host.extId
def hostName = host.hostName
def serial = host.blockSerial
lmDebug.LMDebug("Processing host: ${hostName} (extId: ${hostExtId})")
if (!hostExtId || !hostName) {
lmDebug.LMDebug("ERROR: Host missing required fields (extId: ${hostExtId}, name: ${hostName}), skipping")
return
}
String displayName = hostName
def hostname = hostName
def ip = hostName
// Try to get IP from hypervisor external address
if (host.hypervisor?.externalAddress?.ipv4?.value) {
ip = host.hypervisor.externalAddress.ipv4.value
hostname = ip
// Try reverse DNS lookup
try {
def reverseDnsName = InetAddress.getByName(ip)?.getHostName()
if (reverseDnsName && reverseDnsName != ip) {
hostname = reverseDnsName
}
} catch (Exception e) {
lmDebug.LMDebug("DEBUG: Failed to resolve reverse DNS for ${ip}: ${e.message}")
}
}
// Check for existing device in LM portal
def deviceMatch = false
if (!skipDeviceDedupe) {
if (pathFlag == "ind") {
deviceMatch = lmApi.findPortalDevice(displayName, args)
} else if (pathFlag == "all") {
deviceMatch = lmApi.checkExistingDevices(displayName, lmDevices)
}
}
if (deviceMatch) {
if (hostname != deviceMatch?.name) {
// 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" : hostname,
"displayName": displayName
],
"LM" : [
"hostname" : deviceMatch?.name,
"collectorId": deviceMatch?.currentCollectorId,
"displayName": deviceMatch?.displayName
],
"Resolved": false
]
]
// Resolve hostname collision based on user preference
if (hostnameSource == "lm" || hostnameSource == "logicmonitor") {
hostname = deviceMatch?.name
displayName = deviceMatch?.displayName
deviceMatch = false
if (collisionInfo && collisionInfo[displayName]) {
collisionInfo[displayName]["Resolved"] = true
}
} else if (hostnameSource == "netscan") {
if (collisionInfo && collisionInfo[displayName]) {
collisionInfo[displayName]["Resolved"] = true
}
displayName = "${displayName} - ${ip}"
deviceMatch = false
}
if (collisionInfo) {
duplicateResources["resources"].add(collisionInfo)
}
}
// Don't worry about matches where the hostname values are the same
// These will update via normal NetScan processing and should be ignored
else {
deviceMatch = false
}
}
// Determine device group based on cluster
def deviceGroups = []
deviceGroups << "${rootFolder}"
// Resource host properties
Map hostProps = [
"system.categories" : "Nutanix_Hypervisor",
"nutanix.prism.central.host": prismCentralHost,
"nutanix.prism.central.user": props.get("nutanix.prism.central.user"),
"nutanix.prism.central.pass": props.get("nutanix.prism.central.pass"),
"nutanix.hypervisor.serial" : serial
]
def resource = [
"hostname" : hostname,
"displayname": displayName,
"hostProps" : hostProps,
"groupName" : deviceGroups
]
lmDebug.LMDebugPrint("Adding host: ${displayName} (${hostname})")
if (!deviceMatch) resources.add(resource)
}
// Get Prism Central resource information
lmDebug.LMDebugPrint("Fetching Prism Central resource...")
def domainManagerData = nutanixPrismCentral.httpGet("prism/v4.0/config/domain-managers")
if (domainManagerData && domainManagerData.data && domainManagerData.data.size() > 0) {
def domainManager = domainManagerData.data[0]
lmDebug.LMDebugPrint("Processing Prism Central resource")
// Perform nslookup on nutanix.prism.central.host
String prismHostForLookup = prismCentralHost
String prismHostIP = null
String prismHostDNS = prismCentralHost
try {
def inetAddress = InetAddress.getByName(prismHostForLookup)
prismHostIP = inetAddress.getHostAddress()
prismHostDNS = inetAddress.getHostName()
lmDebug.LMDebug("DEBUG: DNS lookup for ${prismHostForLookup}: IP=${prismHostIP}, DNS=${prismHostDNS}")
} catch (Exception e) {
lmDebug.LMDebug("ERROR: Failed to resolve ${prismHostForLookup}: ${e.message}")
// If lookup fails, use the original value
prismHostIP = prismCentralHost
prismHostDNS = prismCentralHost
}
// Determine hostname based on nslookup result
String pcHostname = prismHostIP
// Determine displayname from config.name
String pcConfigName = domainManager.config?.name ?: "Unnamed"
String pcDisplayName = pcConfigName
// If config.name is "Unnamed", use DNS name
if (pcConfigName == "Unnamed") {
pcDisplayName = prismHostDNS
lmDebug.LMDebug("DEBUG: Config name is 'Unnamed', using DNS name: ${pcDisplayName}")
}
// Check for existing device in LM portal
def pcDeviceMatch = false
if (!skipDeviceDedupe) {
if (pathFlag == "ind") {
pcDeviceMatch = lmApi.findPortalDevice(pcDisplayName, args)
} else if (pathFlag == "all") {
pcDeviceMatch = lmApi.checkExistingDevices(pcDisplayName, lmDevices)
}
}
if (pcDeviceMatch) {
if (pcHostname != pcDeviceMatch?.name) {
// 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 pcCollisionInfo = [
(pcDisplayName): [
"Netscan" : [
"hostname" : pcHostname,
"displayName": pcDisplayName
],
"LM" : [
"hostname" : pcDeviceMatch?.name,
"collectorId": pcDeviceMatch?.currentCollectorId,
"displayName": pcDeviceMatch?.displayName
],
"Resolved": false
]
]
// Resolve hostname collision based on user preference
if (hostnameSource == "lm" || hostnameSource == "logicmonitor") {
pcHostname = pcDeviceMatch?.name
pcDisplayName = pcDeviceMatch?.displayName
pcDeviceMatch = false
if (pcCollisionInfo && pcCollisionInfo[pcDisplayName]) {
pcCollisionInfo[pcDisplayName]["Resolved"] = true
}
} else if (hostnameSource == "netscan") {
pcDisplayName = "${pcDisplayName} - ${pcHostname}"
pcDeviceMatch = false
if (pcCollisionInfo && pcCollisionInfo[pcDisplayName]) {
pcCollisionInfo[pcDisplayName]["Resolved"] = true
}
}
if (pcCollisionInfo) {
duplicateResources["resources"].add(pcCollisionInfo)
}
}
// Don't worry about matches where the hostname values are the same
// These will update via normal netscan processing and should be ignored
else {
pcDeviceMatch = false
}
}
if (!pcDeviceMatch) {
// Prism Central resource properties
Map pcHostProps = [
"system.categories" : "Nutanix_PrismCentral",
"nutanix.prism.central.user": props.get("nutanix.prism.central.user"),
"nutanix.prism.central.pass": props.get("nutanix.prism.central.pass")
]
def pcDeviceGroups = []
pcDeviceGroups << "${rootFolder}"
def pcResource = [
"hostname" : pcHostname,
"displayname": pcDisplayName,
"hostProps" : pcHostProps,
"groupName" : pcDeviceGroups
]
lmDebug.LMDebugPrint("Adding Prism Central resource: ${pcDisplayName} (${pcHostname})")
resources.add(pcResource)
} else {
lmDebug.LMDebug("DEBUG: Skipping Prism Central resource - already exists in portal")
}
} else {
lmDebug.LMDebug("WARNING: No Prism Central domain manager data found")
}
lmDebug.LMDebugPrint("Duplicate Resources:")
if (duplicateResources && duplicateResources.resources) {
duplicateResources.resources.each { collisionInfo ->
if (collisionInfo) {
collisionInfo.each { key, value ->
lmDebug.LMDebugPrint("\t${key}: ${value}")
}
}
}
}
lmDebug.LMDebugPrint("Summary: Found ${resources.size()} resource(s) to add (including Prism Central)")
if ((resources.size()) == 0) {
lmDebug.LMDebugPrint("No resources to add. Exiting netscan.")
} else {
emit.resource(resources, debug)
}
return 0- 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 Nutanix Prism Central. 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.
Note: NetScans can add or move resources and resource groups, but cannot delete existing resources. For more information, see Dynamic Resource Groups.
Manually Adding Resources into Monitoring
- In LogicMonitor, navigate to Resources > Add.
- Enter the hostname or IP address of the Prism Central instance.
- Assign the resource to an appropriate Resource Group.
- Add the required properties listed below.
- Ensure the assigned Collector can reach Prism Central on port 9440 (or configured port).
To monitor AHV hypervisor hosts manually, add each host as an individual resource and assign the appropriate Prism Central credentials.
Prism Central Required Host Properties
Set the following properties on the Prism Central resource or a parent Resource Group:
| Property | Description | Required |
nutanix.prism.central.user | Prism Central API username | Yes |
nutanix.prism.central.pass | Prism Central API password | Yes |
nutanix.prism.central.port | Prism Central API port (default: 9440) | No |
AVH Hypervisor Required Host Properties
Set the following properties on AHV hypervisor resources or their parent Resource Group:
| Property | Description | Required |
nutanix.prism.central.user | Prism Central API username | Yes |
nutanix.prism.central.pass | Prism Central API password | Yes |
nutanix.prism.central.host | Prism Central hostname or IP | Yes |
nutanix.prism.central.port | Prism Central API port (default: 9440) | No |
NetScan Troubleshooting
The NetScan for this suite can update existing resources in the portal to add relevant information retrieved from Nutanix’s API. It is also possible for the NetScan to create duplicate resources in the portal when a conflict exists where the display name is the same, but the value for system.hostname differs. To ensure resources are updated properly and duplicate resources are not created, this NetScan uses LogicMonitor’s API to query existing resources and report name conflicts discovered. This file can be accessed in the collector logs. For more information on retrieving collector logs, see Collector logging – Sending logs to LogicMonitor.
The resources 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” resources 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” resources 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 resources with the same display name.
Note: NetScans are not able to update the value of system.hostname, however they may update display name, custom properties, and group assignments.
Import LogicModules
Install all Nutanix Prism Central LogicModules from the Exchange. If the modules are already installed, verify that you are running the most recent versions.
LogicModules in Package
The Nutanix Prism Central monitoring suite includes the following LogicModules:
| Module Name | Type | Description |
|---|---|---|
Nutanix_Hypervisor_CPU | DataSource | Monitors Prism Central Hypervisor CPU Usage. |
Nutanix_Hypervisor_ControllerPerformance | DataSource | Monitors Prism Central Hypervisor Controller Performance. |
Nutanix_Hypervisor_Info | PropertySource | Sets appropriate device properties for Nutanix Prism Central Hypervisors. |
Nutanix_Hypervisor_Memory | DataSource | Monitors Prism Central Hypervisor Memory Usage. |
Nutanix_Hypervisor_NetworkInterfaces | DataSource | Monitors Prism Central Hypervisor Network Interface Status. |
Nutanix_Hypervisor_NodeHealth | DataSource | Monitors Prism Central Hypervisor Status and Health Check Score. |
Nutanix_Hypervisor_Storage | DataSource | Monitors Prism Central Hypervisor Storage Usage. |
Nutanix_PrismCentral_Clusters | DataSource | Monitors Prism Central Cluster Performance, Utilization, Total Hosts and Total VMs. |
Nutanix_PrismCentral_Hosts | DataSource | Monitors Prism Central Host Status and Health Check Score. |
Nutanix_PrismCentral_Licensing | DataSource | Monitors Prism Central Licensing information and days until expiry. |
Nutanix_PrismCentral_VMs | DataSource | Monitors Prism Central Virtual Machine Performance and Utilization metrics. |
addCategory_Nutanix_Hypervisor | PropertySource | Sets appropriate category for Nutanix Prism Central Hypervisors. |
addCategory_Nutanix_PrismCentral | PropertySource | Sets appropriate category for Nutanix Prism Central |
When setting static datapoint thresholds on the various metrics tracked by this package’s DataSources, LogicMonitor follows the technology owner’s best practice KPI recommendations.
Recommendation: If necessary, LogicMonitor encourages you to adjust these predefined thresholds to meet the unique needs of your environment. For more information on tuning datapoint thresholds, see Static Thresholds for Datapoints.