Follow Mike's blog
Archives for the month of: December, 2016

DESCRIPTION:

LogicMonitor Datasources are designed for grabbing NUMBERS not text. This is good for performance info but there’s a lot of useful info that is NOT NUMBERS. Like model name/numbers, serial numbers (with letters, dashes etc), contact name, and location (street address etc). PropertySources can retrieve info using a groovy script and set properties automatically. For official help article, click here.  Note: The web interface warns you that you MUST have collector version 22.180 or newer (I think the help doc mentions 22.227 or newer because that’s required for the “test” button). In any case, the current “early access” version is 22.253, so I suggest you install this or newer.

Here’s what properties look like. Notice auto. prefix

INSTRUCTIONS:

Click Settings > PropertySources > Add  (note the name is being changed from Property Rules to PropertySources.  Copy & paste the info below to fill in the fields. Be sure to use the TEST button before you save.

 

My next goal is to write some to detect more stuff. This would be a nifty automatic way for Dynamic groups and for Inventory reports and searches.

  • What version of MS-SQL is running

Description: Sets ‘location=whatever’, ‘contact=whatever’, etc that it gets from SNMP values under the common branch 1.3.6.1.2.1.1

Name: SNMP basic info

Applies to:  hasCategory(“SNMP”)

Groovy Script:

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

/* ==== EXAMPLE OUTPUT ========
location= 11 Main Street, Goleta, CA 93111
contact=Mike Suding
model=RouterOS RB750Gr2
uptime= 242 days, 12:32:43.00
system_name= PE-E48D8C982B35
*/


Description: Set ‘serial_number=whatever’ and ‘BIOS_version=whatever’ using WMI (useful if you run Windows on bare-metal (not a hypervisor)

Name:  Serial Number and BIOS from Windows

Applies to: system.model !~ “Virtual” && system.model !~ “domU” && isWindows()    
(note: for efficiency, narrow to only Windows on bare-metal –not virtual)

Groovy Script:

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. example Oracle uses port 1521, Postgres=5432 etc)

Name:  Is Postgres database running

Applies to: Servers() 
(note: for efficiency, narrow to only servers –not switches etc)

Groovy Script:

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

Name:  HyperV

Applies to: system.model !~ “Virtual” && system.model !~ “domU” && isWindows()    
(note: for efficiency, narrow to only Windows on bare-metal)

Groovy Script:

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 text next to “SERVER:” (example:  Microsoft-IIS/8.5)

Name:  Web_server

Applies to:  isWindows()   (note: for efficiency, narrow to only Windows)

Groovy Script:

import com.santaba.agent.groovyapi.http.*; // needed for http.get 
def hostname=hostProps.get("system.hostname"); 
def my_url="http://" + 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’ (Active Directory Domain Services) is running

Name:  Active Directory

Applies to:   isWindows()  (note: for efficiency, narrow to only Windows)

Groovy Script:

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’ (Microsoft Exchange Active Directory Topology) is running

Name:  Exchange
Applies to: isWindows()     (note: for efficiency, narrow to only Windows)

Groovy Script:

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

Name:  MS_SQL

Applies to: isWindows()     (note: for efficiency, narrow to only Windows)

Groovy Script:

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=’ showing version. Uses SQL query. Uses Windows auth but can be changed to use SQL auth

Name:  MS_SQL version

Applies to: system.db.mssql     (narrow to only MS-SQL computers)

Groovy Script:

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; 

DESCRIPTION:

Since many IT people use a ticketing system, they often want to track and handle the alerts and the associated “work” in a ticketing system like Zendesk.

Here’s what this integration does:

  1. When an alert triggers, LogicMonitor sends a notification (a webhook call) and this creates an incident “ticket” in Zendesk with a status of “new”
  2. When someone acknowledges the alert, LogicMonitor sends another notification (a webhook call) and this adds a comment to the Zendesk ticket and changes the status from “new” to “pending” to inform people.
  3. When the problem is fixed or goes away, LogicMonitor sends a ‘clear’ notification (via a webhook call) and this adds a comment to the Zendesk ticket and changes the status to “solved”

SUMMARY OF STEPS:

  • I made a LogicMonitor user called “Zendesk user”. It wasn’t required but it just makes things easier to understand when looking at settings. The role/permissions are not important.
  • I created an “Integration” called “Zendesk” (this makes an extra ‘contact method’ show up when you build an escalation chain). See below for details on 3 items (new, ack, and close) in this ‘integration’.
  • I created an Escalation chain called “Zendesk escalation chain” and I specified the Stage to go to user “Zendesk” and picked the contact method called “Zendesk test”
  • I created a rule called “Zendesk rule”. For testing I only made it send notifications for one device for only for my one special datasource called “Mike ping” which makes it less disruptive to other people.

 

DETAILS:

Below is the info I typed in the “Alert Data” field. I chose JSON format. Notice for this customer, I needed to put in 1 custom field because they set they were set as ‘required fields’ in Zendesk. They are Phone number. If I didn’t specify these fields, then Zendesk would not allow me to change the ticket status to “solved”.

Type of webhook:  Active alert (aka new alert)

HTTP method: POST

URL:  https://     acme.zendesk.com/api/v2/tickets.json

Use Custom Headers: NO

Data type: RAW (not key/value)

Format: JSON

{"ticket": {"requester": {"name": "Mike Suding", "email": "mike.suding@logicmonitor.com"}, "subject": "LM alert ##ALERTID## ##LEVEL## on host named ##HOST##" starting ##START##, "comment": { "body": "This is an alert from LogicMonitor via webhook \n ##MESSAGE##"}, "priority": "normal", "custom_fields": [{"id": 23842396, "value": "805 phone"}] }}

Type of webhook: Acknowledge

HTTP method: PUT

URL: https://    acme.zendesk.com/api/v2/tickets/##EXTERNALTICKETID##.json

Use Custom headers: NO

Data type: RAW    and format: JSON

{"ticket": { "comment": { "body": "Since the LogicMonitor alert was acked, this comment is added to ticket and status changed to pending ##ALERTID## ##ADMIN.EMAIL##" }, "status": "pending" }}

Type of webhook: Cleared (ie close the ticket)

HTTP method: PUT

URL:  https://    acme.zendesk.com/api/v2/tickets/##EXTERNALTICKETID##.json

Use custom headers: NO

Data type: RAW     and format: JSON

{"ticket": { "status": "solved", "comment": { "body": "The alert is cleared ##ALERTID## so we will set ticket status to SOLVED", "author_id": 21950241428 }}}

note: you need to specify YOUR author_id ( a Zendesk ID number for the agent/user). You can see this in a response when you create a ticket. I used CURL.exe command line. It also shows in response as ‘submitter_id’.

REQUIREMENTS: You need to use Firefox or Safari (if mac). Chrome doesn’t support java browser applets anymore. Also, on the target Windows computer, you need to disable NLA (Network Level Authentication) a setting for RDP shown in the video.

 

 

DESCRIPTION:

Some disk drives and SSD (Solid State Drives) have a feature called “S.M.A.R.T.” which means “Self-Monitoring, Analysis & Reporting Technology”. On Windows computers, this information is stored in WMI. I wrote a PowerShell script-based datasource to collect this info. Since not all drives have this SMART feature, I put in a datapoint that also shows if it has this feature/capability (1=yes, 0=no).

 

smart-status

INSTRUCTIONS:

  1. Download this datasource file and add it to your account:  Settings > Datasources > Add > From file
  2. Wait a few minutes for it to start collecting….Test it by looking in the “Raw Data” tab.
  3. I set it to alert threshold to ‘warning’ if the value is anything other than “OK” but you can change it.

NOTES:

As with most of my datasources, you cannot get official technical support from LogicMonitor.