Come join our live training webinar every other Wednesday at 11am PST and hear LogicMonitor experts explain best practices and answer common questions. We understand these are uncertain times, and we are here to help!
PropertySources auto-assign properties at the resource level based on the output of a Groovy or PowerShell script. Automating property assignments has a wide range of benefits for improved inventory tracking and reporting; troubleshooting; and dynamically grouping devices based on their shared properties.
At a high level, PropertySources work as follows:
Once established, PropertySources will run:
Note: In order for PropertySources to work properly for cloud resources, you’ll need to first enable monitoring via a local Collector.
To create a new PropertySource, select Settings | PropertySources | Add | PropertySource. From the Create New PropertySource dialog, there are several configurations that must be established.
As a best practice, give your PropertySource a descriptive name. Specify the platform or application and, if necessary, a specific component of the platform.
As a best practice, if the PropertySource name does not sufficiently describe what the PropertySource is collecting, the Description field should provide enough additional detail so that someone viewing the name and description will easily recognize the PropertySource’s purpose.
In the Group field, specify the PropertySource group to which the PropertySource will be added. If this field is left empty, the PropertySource will be added into the default “@ungrouped” group. If you enter text that does not match an existing PropertySource group, a new group will be created on the fly.
The Applies To field accepts LogicMonitor’s AppliesTo scripting as input to determine which resources will be associated with this PropertySource. For detailed information on using this field (including its wizard and test functionality), along with an overview of the AppliesTo scripting syntax, see AppliesTo Scripting Overview.
From the Data type field’s dropdown menu, select “ERISource” if the PropertySource is being created for the purpose of assigning external resource IDs (ERIs) to resources for topology mapping. Otherwise, leave the default of “PropertySource” in place. For more information on PropertySources that assign ERIs, see Topology Mapping Overview.
If “ERISource” is selected for the Data type field, the Collect every field displays. From its dropdown menu, select the interval at which this PropertySource should poll data. This interval overrides the default once-a-day polling schedule of non-ERISource PropertySources.
PropertySource scripts may be written in a Groovy or PowerShell.
Let’s take a look at how we would create a PropertySource that collects information from PureStorage arrays. This PropertySource will identify the array name, ID, revision, and version number and store this information as properties on the device.
To do this, we would employ the following Groovy script format:
import java.net.*; import java.io.*; import java.util.*; import java.text.*; import groovy.json.JsonSlurper;
hostName = hostProps.get("system.hostname"); apitoken = hostProps.get("purestorage.apitoken.pass");
base_url = "https://" + hostName; arrayInfo_commmand = "/api/1.4/array"; api_url = new URL(base_url + arrayInfo_commmand);
cookie = getSession();
connection = api_url.openConnection(); connection.setRequestMethod("GET"); connection.setDoOutput(true); connection.setRequestProperty("Content-Type", "application/json"); connection.setRequestProperty("Cookie", cookie);
if (connection.getResponseCode() != 200) { // no -- return an error code that indicates failure return(2); }
jsonslurper = new JsonSlurper(); arrayInfo_map = jsonslurper.parseText(connection.content.text);
arrayInfo_map.each { key, value -> // print out each key and value println "$key=$value"; }
Based on the format of the above script, we would expect an output resembling the following.
array_name=MY-PURE-001 id=93f00dad-b1aa-1234-5678-ec55f5ba55d6 revision=201609291808+e9e9b09 version=4.7.6
These four key-value pairs will be automatically stored as properties on your device. In the event that a value changes, the property will be updated during the next Active Discovery iteration.
To test your script’s ability to properly assign the designated properties to a device, click the Test Script button and select a device to test the script against. Only devices that match the Applies To expression can be selected.
For your convenience, we’ve provided several working, real-world PropertySource scripts to give you a starting point for common scenarios:
Description: Returns a list of OIDs related to all NetApp devices. Applies productVersion, productModel, productFirmwareVersion, productSerialNumber, ProductPartnerSerialNumber, and productMachineType as properties in key-value pair format on their respective devices.
Applies to: isNetApp()
Groovy script:
import com.santaba.agent.groovyapi.snmp.Snmp; // get the snmp host from the device properties def host = hostProps.get('system.hostname'); // define a list of product oids def netapp_product_mib = [ productVersion : '.1.3.6.1.4.1.789.1.1.3.0', productModel : '.1.3.6.1.4.1.789.1.1.7.0', productFirmwareVersion : '.1.3.6.1.4.1.789.1.1.11.0', productSerialNum : '.1.3.6.1.4.1.789.1.1.14.0', productPartnerSerialNum : '.1.3.6.1.4.1.789.1.1.15.0', productMachineType : '.1.3.6.1.4.1.789.1.1.16.0', ]; // iterate over each oid entry netapp_product_mib.each { key, oid -> // retrieve the oid and print the value value = Snmp.get(host, oid); println "auto." + key + "=" + value; } return(0);
Description: Sets ‘location=something’, ‘contact=something’, and so on that it gets from SNMP values under the common branch 1.3.6.1.2.1.1.
Applies to: hasCategory(“SNMP”)
def hostname = hostProps.get("system.hostname") import com.santaba.agent.groovyapi.snmp.Snmp; //for SNMP get def OID_model = "1.3.6.1.2.1.1.1.0" // the OID we want def model = Snmp.get(hostname, OID_model); println "model=" + model //show on screen def OID_uptime = "1.3.6.1.2.1.1.3.0" // the OID we want def uptime = Snmp.get(hostname, OID_uptime); println "uptime=" + uptime def OID_contact = "1.3.6.1.2.1.1.4.0" // the OID we want def contact = Snmp.get(hostname, OID_contact); println "contact=" + contact def OID_system_name = "1.3.6.1.2.1.1.5.0" // the OID we want def system_name = Snmp.get(hostname, OID_system_name); println "system_name=" + system_name def OID_location = "1.3.6.1.2.1.1.6.0" // the OID we want def location = Snmp.get(hostname, OID_location); println "location=" + location return 0
Description: Set ‘serial_number=something’ and ‘BIOS_version=something’ using WMI (useful if you run Windows on bare-metal (not a hypervisor).
Applies to: system.model !~ “Virtual” && system.model !~ “domU” && isWindows() (For efficiency, narrow to only Windows on bare metal–not virtual)
hostname=hostProps.get("system.hostname"); my_query="Select * from Win32_BIOS" namespace="CIMv2" import com.santaba.agent.groovyapi.win32.WMI; import com.santaba.agent.groovyapi.win32.WMISession; def session = WMI.open(hostname); def obj = session.queryFirst(namespace, my_query, 10); println "serial_number=" + obj.SERIALNUMBER println "bios_version=" + obj.SMBIOSBIOSVERSION return 0
Description: Set ‘postgres=yes’ by checking to see if a specific TCP port is open (useful for detecting lots of applications, e.g. Oracle uses port 1521, Postgres=5432, etc.)
Applies to: Servers() (For efficiency, narrow to only servers–not switches)
def hostname = hostProps.get("system.hostname") def port_number = 5432 try { new Socket(hostname, port_number).close(); // Socket try to open a REMOTE port println "postgres=yes" // remote port can be opened } catch(Exception e) { println "connection on port " + port_number + " failed" } return 0
Description: Set ‘hyper-v=yes’, detects Microsoft Hyper-V by detecting if the service named VMMS (Hyper-V Virtual Machine Management) is running.
Applies to: system.model !~ “Virtual” && system.model !~ “domU” && isWindows() (For efficiency, narrow to only Windows on bare metal)
hostname=hostProps.get("system.hostname") my_query="Select name,state from Win32_Service Where Name ='vmms'" import com.santaba.agent.groovyapi.win32.WMI; import com.santaba.agent.groovyapi.win32.WMISession; def session = WMI.open(hostname); def obj = session.queryFirst("CIMv2", my_query, 10); if (obj.STATE == "Running") { println "hyper-v=yes" } else { println "hyper-v=no" } return 0
Description: Set ‘Web_server=something’ property by retrieving the web page and grabbing the text next to “SERVER:” (e.g. Microsoft-IIS/8.5).
Applies to: isWindows() (For efficiency, narrow to only Windows)
import com.santaba.agent.groovyapi.http.*; // needed for http.get def hostname=hostProps.get("system.hostname"); def my_url="https://" + hostname my_input_string = HTTP.get(my_url) def my_regex = /(?i)server: (.*)/ def my_matcher = (my_input_string =~ my_regex) my_stuff = my_matcher[0][1] println "web_server=" + my_stuff return 0;
Description: Set ‘domain_controller=yes’ property if the service ‘NTDS’ (i.e. Active Directory Domain Services) is running.
hostname=hostProps.get("system.hostname"); my_query="Select name,state from Win32_Service Where Name ='NTDS'" import com.santaba.agent.groovyapi.win32.WMI; import com.santaba.agent.groovyapi.win32.WMISession; def session = WMI.open(hostname); def result = session.queryFirst("CIMv2", my_query, 10); if (result.STATE == "Running") { println "active_directory=yes" } else { println "active_directory=no" } return 0;
Description: Set ‘exchange=yes’ property if the service ‘MSExchangeADTopology’ (i.e. Microsoft Exchange Active Directory Topology) is running.
hostname=hostProps.get("system.hostname"); my_query="Select name,state from Win32_Service Where Name ='MSExchangeADTopology'" import com.santaba.agent.groovyapi.win32.WMI; import com.santaba.agent.groovyapi.win32.WMISession; def session = WMI.open(hostname); def result = session.queryFirst("CIMv2", my_query, 10); if (result.STATE == "Running") { println "exchange=yes" } else { println "exchange=no" } return 0
Description: Set ‘MS_SQL=yes’ if the service named MSSQLSERVER is running.
hostname=hostProps.get("system.hostname"); my_query="Select name,state from Win32_Service Where Name ='MSSQLSERVER'" import com.santaba.agent.groovyapi.win32.WMI; import com.santaba.agent.groovyapi.win32.WMISession; def session = WMI.open(hostname); def obj = session.queryFirst("CIMv2", my_query, 10); if (obj.STATE == "Running") { println "MS_SQL=yes" } else { println "MS_SQL=no" } return 0
Description: Set ‘MS_SQL_version=something’. Uses SQL query. Uses Windows auth but can be changed to use SQL auth.
Applies to: system.db.mssql
(For efficiency,(narrow to only MS SQL computers)
def hostname = hostProps.get("system.hostname"); import groovy.sql.Sql // needed for SQL connection and query def url = "jdbc:sqlserver://" + hostname + ";databaseName=master;integratedSecurity=true"; def driver = "com.microsoft.sqlserver.jdbc.SQLServerDriver"; sql = Sql.newInstance(url, driver) // connects to SQL server def query_result = sql.firstRow("SELECT @@version as info") full_version_info = query_result.info sql.close() // Close connection input_string_1 = full_version_info def regex_1 = /(?<=SQL Server)(.*)(?=-)/; //capture between 'SQL Server' until '-' def matcher_1 = (input_string_1 =~ regex_1) version = matcher_1[0][1].trim() input_string_2 = full_version_info def regex_2 = /(?<=\n)(.*)(?=Edition)/; //capture between line break until 'Edition' def matcher_2 = (input_string_2 =~ regex_2) edition = matcher_2[0][1].trim() println "ms_sql_version=" + version +" "+ edition return 0;
Once you have created a PropertySource, you are able to view and edit it from Settings | LogicModules | PropertySources. Additionally, from the header of the PropertySource settings page (shown next), you can click the More button to perform one of the following actions:
In This Article