Jason Fant

Certified Expert
  • Posts

    20
  • Joined

  • Last visited

  • Days Won

    1

Reputation

6 Neutral

About Jason Fant

  • Rank
    Observer
    Observer

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. I had a couple people on the forums here help me put this together so I can't take full credit for this! This is what I use to monitor Backup Status on the Publisher only. I want to make it run a little better but I haven't had time to make it better. You are more than welcomed to use it and see if it helps and tweak it to however you see fit...it's all XML, so copy and paste into notepad and save as "CUCM_Backup_Status-.xml" and then you can IMPORT it. Default threshold is for 24hours but can be adjusted per Publisher you monitor. There are 3 properties you need set on the device. for the system.categories property, you need "CUCMPublisher". I use that to help me identify which server is the publisher in the cluster.....I don't want backup status on any subscribers cause a failed backup job could create multiple alarms for 1 job failure. The other two are your ssh.user and .pass creds for CUCM CLI. -EDIT- Oh yea! I forgot to mention that it also checks to make sure a Backup Job is even setup! We've had issues where customers didn't know backup jobs weren't configured, so we monitor for that as well! 🙂 -EDIT- Enjoy!!! 🙂
  2. <?xml version="1.0" encoding="UTF-8" ?> <feed version="1.0" hasPendingRequests="false" > <company></company> <status>200</status> <errmsg>OK</errmsg> <interval>0</interval> <entry type="predatasource"> <version>1605101015</version> <name>CUCM Backup Status-</name> <displayedas>CUCM Backup Status-</displayedas> <description>Monitors the Backup Status for CUCM Clusters via SSH. It will check for SUCCESS as well as compare backup date with current time.</description> <collector>batchscript</collector> <hasMultiInstances>true</hasMultiInstances> <schedule>3600</schedule> <appliesTo>hasCategory(&#34;CUCMPublisher&#34;) &#38;&#38; (ssh.user &#38;&#38; ssh.pass)</appliesTo> <wildcardauto>true</wildcardauto> <wildcardpersist>false</wildcardpersist> <wildcardlinuxscript>ad_script</wildcardlinuxscript> <wildcardlinuxcmdline>type=&#34;embeded&#34; </wildcardlinuxcmdline> <wildcardwinscript>ad_script</wildcardwinscript> <wildcardwincmdline>type=&#34;embeded&#34; </wildcardwincmdline> <wildcardgroovyscript>// import the logicmonitor expect helper class import com.santaba.agent.groovyapi.expect.Expect; // get the hostname and credentials from the device property table hostname = hostProps.get(&#34;system.hostname&#34;); userid = hostProps.get(&#34;ssh.user&#34;); passwd = hostProps.get(&#34;ssh.pass&#34;); // open an ssh connection and wait for the prompt ssh_connection = Expect.open(hostname, userid, passwd); ssh_connection.expect(&#34;admin:&#34;); // enter enable mode ssh_connection.send(&#34;utils disaster_recovery status backup\n&#34;); ssh_connection.expect(&#34;admin:&#34;); // logout from the device ssh_connection.send(&#34;exit\n&#34;); // collect the output, then close the ssh connection output=ssh_connection.before(); ssh_connection.expectClose(); def instances = [] // now lets process the output and check if Backups are even configured output.eachLine{ line -&#62; def splitLine = line.tokenize(&#34; &#34;); // Check to see if Backups are even Configurred // drfCliMsg: No backup status available if (splitLine[0] == &#34;drfCliMsg:&#34;){ instances &#60;&#60; &#34;BackupNotConfigured##Please Configure Backups for CUCM Cluster.&#34; } } // Did we find configured backups? if (instances.size == 0) { instances &#60;&#60; &#34;BackupJob##Backup Job Configured.&#34; } // Did we run into any issues? if (instances.size &#62; 0) { // Yes, print each of them instances.each { instance -&#62; println instance } } // return with a response code that indicates we ran successfully return(0);</wildcardgroovyscript> <wildcardschedule>0</wildcardschedule> <wildcarddisable>false</wildcarddisable> <wildcarddeleteinactive>false</wildcarddeleteinactive> <agdmethod>none</agdmethod> <agdparams></agdparams> <group>CUCM - CallManager</group> <tags></tags> <technology></technology> <adlist><![CDATA[{"agdmethod":"none","method":"ad_script","agdparams":"","id":0,"filters":[],"params":{"type":"embeded","groovyscript":"// import the logicmonitor expect helper class\r\nimport com.santaba.agent.groovyapi.expect.Expect;\r\n\r\n// get the hostname and credentials from the device property table\r\nhostname = hostProps.get(\"system.hostname\");\r\nuserid = hostProps.get(\"ssh.user\");\r\npasswd = hostProps.get(\"ssh.pass\");\r\n\r\n// open an ssh connection and wait for the prompt\r\nssh_connection = Expect.open(hostname, userid, passwd);\r\nssh_connection.expect(\"admin:\");\r\n\r\n// enter enable mode\r\nssh_connection.send(\"utils disaster_recovery status backup\\n\");\r\nssh_connection.expect(\"admin:\");\r\n\r\n// logout from the device\r\nssh_connection.send(\"exit\\n\");\r\n\r\n// collect the output, then close the ssh connection\r\noutput=ssh_connection.before();\r\nssh_connection.expectClose();\r\n\r\ndef instances = []\r\n\r\n// now lets process the output and check if Backups are even configured\r\noutput.eachLine{ line ->\r\n\tdef splitLine = line.tokenize(\" \");\r\n \r\n // Check to see if Backups are even Configurred\r\n // drfCliMsg: No backup status available\r\n if (splitLine[0] == \"drfCliMsg:\"){\r\n instances << \"BackupNotConfigured##Please Configure Backups for CUCM Cluster.\"\r\n }\r\n}\r\n\r\n// Did we find configured backups?\r\nif (instances.size == 0)\r\n{\r\n instances << \"BackupJob##Backup Job Configured.\"\r\n}\r\n\r\n// Did we run into any issues?\r\nif (instances.size > 0)\r\n{\r\n // Yes, print each of them\r\n instances.each\r\n { instance ->\r\n println instance\r\n }\r\n}\r\n\r\n// return with a response code that indicates we ran successfully\r\nreturn(0);"}}]]></adlist> <schemaVersion>2</schemaVersion> <dataSourceType>1</dataSourceType> <attributes> <attribute> <name>scripttype</name> <value>embed</value> <comment></comment> </attribute> <attribute> <name>scriptgroovy</name> <value>// import the logicmonitor expect helper class import com.santaba.agent.groovyapi.expect.Expect; // get the hostname and credentials from the device property table hostname = hostProps.get(&#34;system.hostname&#34;); userid = hostProps.get(&#34;ssh.user&#34;); passwd = hostProps.get(&#34;ssh.pass&#34;); // open an ssh connection and wait for the prompt ssh_connection = Expect.open(hostname, userid, passwd); ssh_connection.expect(&#34;admin:&#34;); // enter enable mode ssh_connection.send(&#34;utils disaster_recovery status backup\n&#34;); ssh_connection.expect(&#34;admin:&#34;); // logout from the device ssh_connection.send(&#34;exit\n&#34;); // collect the output, then close the ssh connection output=ssh_connection.before(); ssh_connection.expectClose(); // now lets process the output output.eachLine{ line -&#62; // let&#39;s turn this: // UCCX VOIP-UCCX-001 UCPREFS SUCCESS Mon Nov 02 02:00:01 EST 2020 activelog/platform/drf/log/2020-11-02-02-00-01_b_voip-uccx-001_uccx_ucprefs.log // into this: // [UCCX, VOIP-UCCX-001, UCPREFS, SUCCESS, Mon, Nov, 02, 02:00:01, EST, 2020, activelog/platform/drf/log/2020-11-02-02-00-01_b_voip-uccx-001_uccx_ucprefs.log] // This lets us address each bit individually. def splitLine = line.tokenize(&#34; &#34;); // Check to see if Backups are even Configurred // drfCliMsg: No backup status available if (splitLine[0] == &#34;drfCliMsg:&#34;){ println(&#34;BackupNotConfigured.status: &#34; + 1); } // in our collection script, we&#39;d add a line to our loop that checks for &#34;Backup Status&#34; like this: // [Status:, SUCCESS, :Backup, Completed...] if (splitLine[0] == &#34;Status:&#34;){ println(&#34;BackupJob.Overall.status: &#34; + ((splitLine[1] == &#34;SUCCESS&#34;)? 0:1)); } if (splitLine[1] == &#34;Filename:&#34;){ // take the tar file name and break it up so we can compare date with Current Time in seconds. // Tar Filename: 2020-11-02-02-00-01.tar -&#62; [2020, 11, 02, 02, 00, 01.tar] def dateSplit = splitLine[2].tokenize(&#34;-&#34;); // convert filename date into format we can convert easily into Seconds since 1970. // yyyy/MM/dd, HH:mm:SS -&#62; seconds def newdate = (dateSplit[0] + &#34;/&#34; + dateSplit[1] + &#34;/&#34; + dateSplit[2] + &#34;, &#34; + dateSplit[3] + &#34;:&#34; + dateSplit[4] + &#34;:00&#34;) def tarFileDateinMSec = new Date(newdate).getTime(); def currentDateinMSec = new Date().getTime(); println(&#34;BackupJob.TimeinMSECSinceLastBackup: &#34; + ((currentDateinMSec - tarFileDateinMSec))); } } // return with a response code that indicates we ran successfully return(0);</value> <comment></comment> </attribute> <attribute> <name>windowsscript</name> <value></value> <comment></comment> </attribute> <attribute> <name>linuxscript</name> <value></value> <comment></comment> </attribute> <attribute> <name>windowscmdline</name> <value></value> <comment></comment> </attribute> <attribute> <name>linuxcmdline</name> <value></value> <comment></comment> </attribute> </attributes> <datapoints> <datapoint> <name>BackupStatus</name> <dataType>7</dataType> <type>2</type> <postprocessormethod>namevalue</postprocessormethod> <postprocessorparam>BackupJob.Overall.status</postprocessorparam> <usevalue>output</usevalue> <alertexpr>= 1 1 1</alertexpr> <alertmissing>1</alertmissing> <alertsubject></alertsubject> <alertbody>LogicMonitor detected that the Backup for ##HOSTNAME## has failed. Please login and investigate.</alertbody> <enableanomalyalertsuppression></enableanomalyalertsuppression> <adadvsettingenabled>false</adadvsettingenabled> <warnadadvsetting></warnadadvsetting> <erroradadvsetting></erroradadvsetting> <criticaladadvsetting></criticaladadvsetting> <description>0 = SUCCESS 1 = FAILURE</description> <maxvalue></maxvalue> <minvalue></minvalue> <userparam1></userparam1> <userparam2></userparam2> <userparam3></userparam3> <iscomposite>false</iscomposite> <rpn></rpn> <alertTransitionIval>1</alertTransitionIval> <alertClearTransitionIval>0</alertClearTransitionIval> </datapoint> <datapoint> <name>TimeSinceLastBackup</name> <dataType>7</dataType> <type>2</type> <postprocessormethod>namevalue</postprocessormethod> <postprocessorparam>##WILDVALUE##.TimeinMSECSinceLastBackup</postprocessorparam> <usevalue>output</usevalue> <alertexpr></alertexpr> <alertmissing>1</alertmissing> <alertsubject></alertsubject> <alertbody>It has been over 24 hours since we detected a SUCCESSFUL backup. Please login and review the backup status.</alertbody> <enableanomalyalertsuppression></enableanomalyalertsuppression> <adadvsettingenabled>false</adadvsettingenabled> <warnadadvsetting></warnadadvsetting> <erroradadvsetting></erroradadvsetting> <criticaladadvsetting></criticaladadvsetting> <description>Time in milliseconds since last successful backup</description> <maxvalue></maxvalue> <minvalue></minvalue> <userparam1></userparam1> <userparam2></userparam2> <userparam3></userparam3> <iscomposite>false</iscomposite> <rpn></rpn> <alertTransitionIval>1</alertTransitionIval> <alertClearTransitionIval>0</alertClearTransitionIval> </datapoint> <datapoint> <name>BackupNotConfiguredStatus</name> <dataType>7</dataType> <type>2</type> <postprocessormethod>namevalue</postprocessormethod> <postprocessorparam>BackupNotConfigured.status</postprocessorparam> <usevalue>output</usevalue> <alertexpr>= 1</alertexpr> <alertmissing>1</alertmissing> <alertsubject></alertsubject> <alertbody>CUCM Disaster Recovery Backups have not been configured. Please configure backups.</alertbody> <enableanomalyalertsuppression></enableanomalyalertsuppression> <adadvsettingenabled>false</adadvsettingenabled> <warnadadvsetting></warnadadvsetting> <erroradadvsetting></erroradadvsetting> <criticaladadvsetting></criticaladadvsetting> <description>Alarms only if we detect a backup job isn&#39;t configured.</description> <maxvalue></maxvalue> <minvalue></minvalue> <userparam1></userparam1> <userparam2></userparam2> <userparam3></userparam3> <iscomposite>false</iscomposite> <rpn></rpn> <alertTransitionIval>0</alertTransitionIval> <alertClearTransitionIval>0</alertClearTransitionIval> </datapoint> <datapoint> <name>TimeSinceLastBackupInHours</name> <dataType>7</dataType> <type>2</type> <postprocessormethod>expression</postprocessormethod> <postprocessorparam>TimeSinceLastBackup / 3600000</postprocessorparam> <usevalue></usevalue> <alertexpr>&#62; 24 24 24</alertexpr> <alertmissing>1</alertmissing> <alertsubject></alertsubject> <alertbody>It has been over ##VALUE## hours since we detected a SUCCESSFUL backup. Please login and review the backup status.</alertbody> <enableanomalyalertsuppression></enableanomalyalertsuppression> <adadvsettingenabled>false</adadvsettingenabled> <warnadadvsetting></warnadadvsetting> <erroradadvsetting></erroradadvsetting> <criticaladadvsetting></criticaladadvsetting> <description></description> <maxvalue></maxvalue> <minvalue></minvalue> <userparam1></userparam1> <userparam2></userparam2> <userparam3></userparam3> <iscomposite>false</iscomposite> <rpn></rpn> <alertTransitionIval>1</alertTransitionIval> <alertClearTransitionIval>0</alertClearTransitionIval> </datapoint> <datapoint> <name>TimeSinceLastBackupInMinutes</name> <dataType>7</dataType> <type>2</type> <postprocessormethod>expression</postprocessormethod> <postprocessorparam>TimeSinceLastBackup / 60000</postprocessorparam> <usevalue></usevalue> <alertexpr></alertexpr> <alertmissing>1</alertmissing> <alertsubject></alertsubject> <alertbody></alertbody> <enableanomalyalertsuppression></enableanomalyalertsuppression> <adadvsettingenabled>false</adadvsettingenabled> <warnadadvsetting></warnadadvsetting> <erroradadvsetting></erroradadvsetting> <criticaladadvsetting></criticaladadvsetting> <description></description> <maxvalue></maxvalue> <minvalue></minvalue> <userparam1></userparam1> <userparam2></userparam2> <userparam3></userparam3> <iscomposite>false</iscomposite> <rpn></rpn> <alertTransitionIval>0</alertTransitionIval> <alertClearTransitionIval>0</alertClearTransitionIval> </datapoint> <datapoint> <name>TimeSinceLastBackupInDays</name> <dataType>7</dataType> <type>2</type> <postprocessormethod>expression</postprocessormethod> <postprocessorparam>TimeSinceLastBackup / (60*60*24*1000)</postprocessorparam> <usevalue></usevalue> <alertexpr></alertexpr> <alertmissing>1</alertmissing> <alertsubject></alertsubject> <alertbody></alertbody> <enableanomalyalertsuppression></enableanomalyalertsuppression> <adadvsettingenabled>false</adadvsettingenabled> <warnadadvsetting></warnadadvsetting> <erroradadvsetting></erroradadvsetting> <criticaladadvsetting></criticaladadvsetting> <description></description> <maxvalue></maxvalue> <minvalue></minvalue> <userparam1></userparam1> <userparam2></userparam2> <userparam3></userparam3> <iscomposite>false</iscomposite> <rpn></rpn> <alertTransitionIval>0</alertTransitionIval> <alertClearTransitionIval>0</alertClearTransitionIval> </datapoint> </datapoints> <graphs> <graph> <name>Backup Status</name> <title>Backup Status</title> <verticallabel>0=SUCCESS, 1=FAILURE</verticallabel> <rigid>false</rigid> <maxvalue>NaN</maxvalue> <minvalue>NaN</minvalue> <displayprio>1</displayprio> <timescale>1day</timescale> <base1024>false</base1024> <graphdatapoints> <graphdatapoint> <name>BackupStatus</name> <datapointname>BackupStatus</datapointname> <cf>1</cf> </graphdatapoint> </graphdatapoints> <graphvirtualdatapoints> </graphvirtualdatapoints> <graphdatas> <graphdata> <type>2</type> <legend>BackupStatus</legend> <color>silver</color> <datapointname>BackupStatus</datapointname> <isvirtualdatapoint>false</isvirtualdatapoint> </graphdata> </graphdatas> </graph> <graph> <name>Time since Last Backup in Days</name> <title>Time since Last Backup in Days</title> <verticallabel>Time in Days</verticallabel> <rigid>false</rigid> <maxvalue>NaN</maxvalue> <minvalue>NaN</minvalue> <displayprio>2</displayprio> <timescale>1day</timescale> <base1024>false</base1024> <graphdatapoints> <graphdatapoint> <name>TimeSinceLastBackup</name> <datapointname>TimeSinceLastBackupInDays</datapointname> <cf>1</cf> </graphdatapoint> </graphdatapoints> <graphvirtualdatapoints> </graphvirtualdatapoints> <graphdatas> <graphdata> <type>2</type> <legend>TimeSinceLastBackupinDays</legend> <color>olive</color> <datapointname>TimeSinceLastBackup</datapointname> <isvirtualdatapoint>false</isvirtualdatapoint> </graphdata> </graphdatas> </graph> <graph> <name>Time since Last Backup in Hours</name> <title>Time since Last Backup in Hours</title> <verticallabel>Time in Hours</verticallabel> <rigid>false</rigid> <maxvalue>NaN</maxvalue> <minvalue>NaN</minvalue> <displayprio>2</displayprio> <timescale>1day</timescale> <base1024>false</base1024> <graphdatapoints> <graphdatapoint> <name>TimeSinceLastBackup</name> <datapointname>TimeSinceLastBackupInHours</datapointname> <cf>1</cf> </graphdatapoint> </graphdatapoints> <graphvirtualdatapoints> </graphvirtualdatapoints> <graphdatas> <graphdata> <type>2</type> <legend>TimeSinceLastBackupinHours</legend> <color>orange2</color> <datapointname>TimeSinceLastBackup</datapointname> <isvirtualdatapoint>false</isvirtualdatapoint> </graphdata> </graphdatas> </graph> <graph> <name>Time since Last Backup in Minutes</name> <title>Time since Last Backup in Minutes</title> <verticallabel>1440 Minutes = 24 hours</verticallabel> <rigid>false</rigid> <maxvalue>NaN</maxvalue> <minvalue>NaN</minvalue> <displayprio>3</displayprio> <timescale>1day</timescale> <base1024>false</base1024> <graphdatapoints> <graphdatapoint> <name>TimeSinceLastBackup</name> <datapointname>TimeSinceLastBackup</datapointname> <cf>1</cf> </graphdatapoint> </graphdatapoints> <graphvirtualdatapoints> <graphvirtualdatapoint> <name>TimeSinceLastBackupinMinutes</name> <rpn>TimeSinceLastBackup / 60000</rpn> </graphvirtualdatapoint> </graphvirtualdatapoints> <graphdatas> <graphdata> <type>2</type> <legend>TimeSinceLastBackupinMinutes</legend> <color>fuchsia</color> <datapointname>TimeSinceLastBackupinMinutes</datapointname> <isvirtualdatapoint>true</isvirtualdatapoint> </graphdata> </graphdatas> </graph> </graphs> <overviewgraphs> </overviewgraphs> <scripts> </scripts> </entry> </feed>
  3. I liked that Resource_Group_Member_Counts datasource that gave you the number of hosts that are in a resource tree. Is that something you can provide for me to import into my instance for testing?
  4. I hope they don't roll out the new UI. I am not a fan of the way it looks and our customers don't seem too fond of that Alerts view.
  5. I too would like that ability. While the traps is somewhat functional, I'd like to be able to take the trap and write some scripting to replace some of the OIDs in the message of the trap to what their names actually are within the MIB. Something like this: Enterprise OID: 1.3.6.1.4.1.231.7.2.1.21.2.3 Message: 1.3.6.1.4.1.231.7.2.1.21.1.3.2: SYS1 1.3.6.1.4.1.231.7.2.1.3.1.1.1: 1 1.3.6.1.4.1.231.7.2.1.3.1.1.10: ADVISORY 1.3.6.1.4.1.231.7.2.1.3.1.1.11: -- 1.3.6.1.4.1.231.7.2.1.3.1.1.12: -- 1.3.6.1.4.1.231.7.2.1.3.1.1.13: -- 1.3.6.1.4.1.231.7.2.1.3.1.1.14: 1615802432 1.3.6.1.4.1.231.7.2.1.3.1.1.2: 0 1.3.6.1.4.1.231.7.2.1.3.1.1.3: 0 1.3.6.1.4.1.231.7.2.1.3.1.1.4: 2147481553 1.3.6.1.4.1.231.7.2.1.3.1.1.5: F4066 1.3.6.1.4.1.231.7.2.1.3.1.1.6: M4 1.3.6.1.4.1.231.7.2.1.3.1.1.7: NO ACT 1.3.6.1.4.1.231.7.2.1.3.1.1.8: BPA 1.3.6.1.4.1.231.7.2.1.3.1.1.9: CP enterpriseOid: 1.3.6.1.4.1.231.7.2.1.21.2.3 To this: Enterprise OID: 1.3.6.1.4.1.231.7.2.1.21.2.3 Message: hicomErrTrpMnemonic: SYS1 hicomErrorPabxId: 1 hicomErrorSubevent: ADVISORY hicomErrorCardRef: -- hicomErrorBoardVersion: -- hicomErrorFwType: -- hicomErrorTimDat: 1615802432 hicomErrorAlGroup: 0 hicomErrorAlSubId: 0 hicomErrorSerialNo: 2147481553 hicomErrorMsgId: F4066 hicomErrorPriority: M4 hicomErrorAction: NO ACT hicomErrorAbsMod: BPA hicomErrorEvent: CP enterpriseOid: 1.3.6.1.4.1.231.7.2.1.21.2.3
  6. Dondy hooked me up with those LogicModules! 🙂
  7. As soon as I deployed it, it found a backup failure! Thank you again!
  8. wait, nevermind! I figured it out! I can use the Date() and getTime() functions to convert the dates into seconds since 1970, and then I can compare times via a common denominator....seconds! def date=new Date().format('yyyyMMddHH') Date filedate = new Date("2020/11/03, 02:02:01"); println "Hello World todates date is: " + date println "file date is: " + filedate println "the FileDate in seconds is: "+ filedate.getTime(); ---GROOVY--- returns null output: Hello World todates date is: 2020110311 file date is: Tue Nov 03 02:02:01 EST 2020 the FileDate in seconds is: 1604386921000
  9. Hey, do you think I can pick your brain some more? Next thing I wanted to stab with this output is parsing the backup date and compare to see if it's older than 24 hours. I tried to take the filename tar file and break it up and compare that against current time with the format of yyyyMMddHH. However.....I'm gonna get a lot of false alarms when this runs and I think my logic might be off....how can I convert these time values into something where I can compare to confirm it's indeed been 24+hrs since last backup. Also attached a screenshot of the script output. Here's my new Collector script: // import the logicmonitor expect helper class import com.santaba.agent.groovyapi.expect.Expect; // get the hostname and credentials from the device property table hostname = hostProps.get("system.hostname"); userid = hostProps.get("ssh.user"); passwd = hostProps.get("ssh.pass"); // open an ssh connection and wait for the prompt ssh_connection = Expect.open(hostname, userid, passwd); ssh_connection.expect("admin:"); // enter enable mode ssh_connection.send("utils disaster_recovery status backup\n"); ssh_connection.expect("admin:"); // logout from the device ssh_connection.send("exit\n"); // collect the output, then close the ssh connection output=ssh_connection.before(); ssh_connection.expectClose(); // now lets process the output output.eachLine{ line -> // let's turn this: // UCCX VOIP-UCCX-001 UCPREFS SUCCESS Mon Nov 02 02:00:01 EST 2020 activelog/platform/drf/log/2020-11-02-02-00-01_b_voip-uccx-001_uccx_ucprefs.log // into this: // [UCCX, VOIP-UCCX-001, UCPREFS, SUCCESS, Mon, Nov, 02, 02:00:01, EST, 2020, activelog/platform/drf/log/2020-11-02-02-00-01_b_voip-uccx-001_uccx_ucprefs.log] // This lets us address each bit individually. def splitLine = line.tokenize(" ") // in our collection script, we'd add a line to our loop that checks for "percentage complete" like this: // [Status:, SUCCESS, :Backup, Completed...] if (splitLine[0] == "Status:"){ println("Overall.status:" + ((splitLine[1] == "SUCCESS")? 0:1)) } if (splitLine[1] == "Filename:"){ // take the tar file name and break it up so we can compare date with Current Time. // [2020, 11, 02, 02, 00, 01.tar] // We can then combine yyyyMMddHHmm and see if that's greater than current time for MMddHHmm // [2020110302 <= 20201103] def tarFileDate = splitLine[2].tokenize("-"); def date=new Date().format('yyyyMMddHH'); if ((tarFileDate[0] + tarFileDate[1] + tarFileDate[2] + tarFileDate[3]) < date){ // TRUE println("currentdate.date: " + date); }else{ // FALSE println("date.date: " + 0); } } if (splitLine[0] == "UCCX"){ // for data collection, we need to output WILDVALUE.status: 1 // splitLine[2] contains our WILDVALUE // [UCCX, VOIP-UCCX-001, UCPREFS, SUCCESS, Mon, Nov, 02, 02:00:01, EST, 2020, activelog/platform/drf/log/2020-11-02-02-00-01_b_voip-uccx-001_uccx_ucprefs.log] // (we defined wildvalue as the first term of the discovery output) println(splitLine[1] + "::" + splitLine[2] + ".status: " + ((splitLine[3] == "SUCCESS")? 0:1)) // the last bit checks that term 3 in our split output contains "SUCCESS". // if it does, let's output 0, if not let's output 1 } } // return with a response code that indicates we ran successfully return(0);
  10. You sir, are the man! That fixed the script! Thank you for helping me!!!
  11. Ya, I understand. However, I was still getting that error for splitLine[2] BEFORE I changed my WILDVALUE to be more unique.
  12. Thanks for the help! I had to make some changes to the Discovery script as some of the lines returned are not unique. So it was having overlapping INSTANCES. To make them unique, I changed the print lines to include the actual name of the UCCX Server. That worked but now it's throwing an error on my collection script. I attached the XML DS if you want to see what I've got. <?xml version="1.0" encoding="UTF-8" ?> <feed version="1.0" hasPendingRequests="false" > <company></company> <status>200</status> <errmsg>OK</errmsg> <interval>0</interval> <entry type="predatasource"> <version>1604336087</version> <name>UCCX Backup StatusFANT-</name> <displayedas>UCCX Backup StatusFANT-</displayedas> <description></description> <collector>batchscript</collector> <hasMultiInstances>true</hasMultiInstances> <schedule>21600</schedule> <appliesTo>hasCategory(&#34;CiscoUCCX&#34;)</appliesTo> <wildcardauto>true</wildcardauto> <wildcardpersist>false</wildcardpersist> <wildcardlinuxscript>ad_script</wildcardlinuxscript> <wildcardlinuxcmdline>type=&#34;embeded&#34; </wildcardlinuxcmdline> <wildcardwinscript>ad_script</wildcardwinscript> <wildcardwincmdline>type=&#34;embeded&#34; </wildcardwincmdline> <wildcardgroovyscript>// import the logicmonitor expect helper class import com.santaba.agent.groovyapi.expect.Expect; // get the hostname and credentials from the device property table hostname = hostProps.get(&#34;system.hostname&#34;); userid = hostProps.get(&#34;ssh.user&#34;); passwd = hostProps.get(&#34;ssh.pass&#34;); // open an ssh connection and wait for the prompt ssh_connection = Expect.open(hostname, userid, passwd); ssh_connection.expect(&#34;admin:&#34;); // enter enable mode ssh_connection.send(&#34;utils disaster_recovery status backup\n&#34;); ssh_connection.expect(&#34;admin:&#34;); // logout from the device ssh_connection.send(&#34;exit\n&#34;); // collect the output, then close the ssh connection output=ssh_connection.before(); ssh_connection.expectClose(); // now lets process the output output.eachLine{ line -&#62; // let&#39;s turn this: // UCCX VOIP-UCCX-001 UCPREFS SUCCESS Mon Nov 02 02:00:01 EST 2020 activelog/platform/drf/log/2020-11-02-02-00-01_b_voip-uccx-001_uccx_ucprefs.log // into this: // [UCCX, VOIP-UCCX-001, UCPREFS, SUCCESS, Mon, Nov, 02, 02:00:01, EST, 2020, activelog/platform/drf/log/2020-11-02-02-00-01_b_voip-uccx-001_uccx_ucprefs.log] // This lets us address each bit individually. def splitLine = line.tokenize(&#34; &#34;) if (splitLine[0] == &#34;UCCX&#34;){ // for instance discovery: println(splitLine[2] + &#34;##&#34; + splitLine[2] + &#34; on &#34; + splitLine[1] + &#34;######&#34; + &#34;uccx_server=&#34; + splitLine[1]) } } // we also need to have an instance to contain the global percent completed: // in our discovery script, we&#39;ll add this: println(&#34;overall##overall&#34;) // return with a response code that indicates we ran successfully return(0);</wildcardgroovyscript> <wildcardschedule>1440</wildcardschedule> <wildcarddisable>false</wildcarddisable> <wildcarddeleteinactive>true</wildcarddeleteinactive> <agdmethod>ilp</agdmethod> <agdparams>auto.uccx_server</agdparams> <group>UCCX - Contact Center eXpress</group> <tags></tags> <technology></technology> <adlist><![CDATA[{"agdmethod":"ilp","method":"ad_script","agdparams":"auto.uccx_server","id":0,"filters":[],"params":{"type":"embeded","groovyscript":"// import the logicmonitor expect helper class\r\nimport com.santaba.agent.groovyapi.expect.Expect;\r\n\r\n// get the hostname and credentials from the device property table\r\nhostname = hostProps.get(\"system.hostname\");\r\nuserid = hostProps.get(\"ssh.user\");\r\npasswd = hostProps.get(\"ssh.pass\");\r\n\r\n// open an ssh connection and wait for the prompt\r\nssh_connection = Expect.open(hostname, userid, passwd);\r\nssh_connection.expect(\"admin:\");\r\n\r\n// enter enable mode\r\nssh_connection.send(\"utils disaster_recovery status backup\\n\");\r\nssh_connection.expect(\"admin:\");\r\n\r\n// logout from the device\r\nssh_connection.send(\"exit\\n\");\r\n\r\n// collect the output, then close the ssh connection\r\noutput=ssh_connection.before();\r\nssh_connection.expectClose();\r\n\r\n// now lets process the output\r\noutput.eachLine{ line ->\r\n\t// let's turn this:\r\n\t// UCCX VOIP-UCCX-001 UCPREFS SUCCESS Mon Nov 02 02:00:01 EST 2020 activelog/platform/drf/log/2020-11-02-02-00-01_b_voip-uccx-001_uccx_ucprefs.log\r\n\t// into this:\r\n\t// [UCCX, VOIP-UCCX-001, UCPREFS, SUCCESS, Mon, Nov, 02, 02:00:01, EST, 2020, activelog/platform/drf/log/2020-11-02-02-00-01_b_voip-uccx-001_uccx_ucprefs.log]\r\n\t// This lets us address each bit individually.\r\n\tdef splitLine = line.tokenize(\" \")\r\n \r\n\tif (splitLine[0] == \"UCCX\"){\r\n\t\t// for instance discovery:\r\n\t\tprintln(splitLine[2] + \"##\" + splitLine[2] + \" on \" + splitLine[1] + \"######\" + \"uccx_server=\" + splitLine[1])\r\n\r\n\t}\r\n}\r\n\r\n// we also need to have an instance to contain the global percent completed:\r\n// in our discovery script, we'll add this:\r\nprintln(\"overall##overall\")\r\n\r\n// return with a response code that indicates we ran successfully\r\nreturn(0);"}}]]></adlist> <schemaVersion>2</schemaVersion> <dataSourceType>1</dataSourceType> <attributes> <attribute> <name>scripttype</name> <value>embed</value> <comment></comment> </attribute> <attribute> <name>scriptgroovy</name> <value>// import the logicmonitor expect helper class import com.santaba.agent.groovyapi.expect.Expect; // get the hostname and credentials from the device property table hostname = hostProps.get(&#34;system.hostname&#34;); userid = hostProps.get(&#34;ssh.user&#34;); passwd = hostProps.get(&#34;ssh.pass&#34;); // open an ssh connection and wait for the prompt ssh_connection = Expect.open(hostname, userid, passwd); ssh_connection.expect(&#34;admin:&#34;); // enter enable mode ssh_connection.send(&#34;utils disaster_recovery status backup\n&#34;); ssh_connection.expect(&#34;admin:&#34;); // logout from the device ssh_connection.send(&#34;exit\n&#34;); // collect the output, then close the ssh connection output=ssh_connection.before(); ssh_connection.expectClose(); // now lets process the output output.eachLine{ line -&#62; // let&#39;s turn this: // UCCX VOIP-UCCX-001 UCPREFS SUCCESS Mon Nov 02 02:00:01 EST 2020 activelog/platform/drf/log/2020-11-02-02-00-01_b_voip-uccx-001_uccx_ucprefs.log // into this: // [UCCX, VOIP-UCCX-001, UCPREFS, SUCCESS, Mon, Nov, 02, 02:00:01, EST, 2020, activelog/platform/drf/log/2020-11-02-02-00-01_b_voip-uccx-001_uccx_ucprefs.log] // This lets us address each bit individually. def splitLine = line.tokenize(&#34; &#34;) // in our collection script, we&#39;d add a line to our loop that checks for &#34;percentage complete&#34; like this: if (splitLine[0] == &#34;Percentage&#34;){ println(&#34;overall.status: &#34; + splitLine[2] } if (splitLine[0] == &#34;UCCX&#34;){ // for data collection, we need to output WILDVALUE.status: 1 // splitLine[2] contains our WILDVALUE // (we defined wildvalue as the first term of the discovery output) println(splitLine[2] + &#34;.status: &#34; + (splitLine[3] == &#34;SUCCESS&#34;)? 100 : 0) // the last bit checks that term 3 in our split output contains &#34;SUCCESS&#34;. // if it does, let&#39;s output 100, if not let&#39;s output 0 } } // return with a response code that indicates we ran successfully return(0);</value> <comment></comment> </attribute> <attribute> <name>windowsscript</name> <value></value> <comment></comment> </attribute> <attribute> <name>linuxscript</name> <value></value> <comment></comment> </attribute> <attribute> <name>windowscmdline</name> <value></value> <comment></comment> </attribute> <attribute> <name>linuxcmdline</name> <value></value> <comment></comment> </attribute> </attributes> <datapoints> <datapoint> <name>OverallStatus</name> <dataType>7</dataType> <type>2</type> <postprocessormethod>namevalue</postprocessormethod> <postprocessorparam>##WILDVALUE##.status</postprocessorparam> <usevalue>output</usevalue> <alertexpr></alertexpr> <alertmissing>1</alertmissing> <alertsubject></alertsubject> <alertbody></alertbody> <enableanomalyalertsuppression></enableanomalyalertsuppression> <adadvsettingenabled>false</adadvsettingenabled> <warnadadvsetting></warnadadvsetting> <erroradadvsetting></erroradadvsetting> <criticaladadvsetting></criticaladadvsetting> <description></description> <maxvalue></maxvalue> <minvalue></minvalue> <userparam1></userparam1> <userparam2></userparam2> <userparam3></userparam3> <iscomposite>false</iscomposite> <rpn></rpn> <alertTransitionIval>0</alertTransitionIval> <alertClearTransitionIval>0</alertClearTransitionIval> </datapoint> </datapoints> <graphs> </graphs> <overviewgraphs> </overviewgraphs> <scripts> </scripts> </entry> </feed>
  13. Hello, I have a UCCX Cluster where I want to monitor the backup status. I've wrote most of the code to SSH into the system and run the command to check the backup status. The issue I'm having is being able to parse it and alarm on it correctly. Can anyone help me on parsing out these three fields.....I assume it'd need to be a Key:Value pair but not sure how to do that. And if I find "SUCCESS", how can I trigger a datapoint threshold? I assume I have to convert the SUCCESS into a 1 or 0 and alarm on that INTEGER. def status = command_output.findAll(~/Status:\s(.*)/) { key, value -> value } def tar_file = command_output.findAll(~/Tar Filename:\s(.*)/) { key, value -> value } def percentage = command_output.findAll(~/Percentage Complete:\s(.*)/) { key, value -> value } Here is my Groovy script: import com.santaba.agent.groovyapi.expect.Expect; import com.santaba.agent.groovyapi.snmp.Snmp; import com.santaba.agent.groovyapi.http.*; import com.santaba.agent.groovyapi.jmx.*; import org.xbill.DNS.*; // import the logicmonitor expect helper class import com.santaba.agent.groovyapi.expect.Expect; // get the hostname and credentials from the device property table hostname = hostProps.get("system.hostname"); userid = hostProps.get("ssh.user"); passwd = hostProps.get("ssh.pass"); // open an ssh connection and wait for the prompt ssh_connection = Expect.open(hostname, userid, passwd); ssh_connection.expect("admin:"); // run command ssh_connection.send("utils disaster_recovery status backup\n"); ssh_connection.expect("admin:"); // logout from the device ssh_connection.send("exit\n"); // collect the output, then close the ssh connection output=ssh_connection.before(); ssh_connection.expectClose(); // Everything here below is just testing/playing with the output...this could be all wrong/bad //=============================================================================================== // strip the info we need value and print the config def status = output.findAll(~/Status:\s(.*)/) def tar_file = output.findAll(~/Tar Filename:\s(.*)/) if ( status =~ "SUCCESS" ) { //Set code to 0 for success" def statuscode = 0 }else{ //Set code to 1 for failure" def statuscode = 1 } println output; // return with a response code that indicates we ran successfully return(0); And here is what the Output looks like: utils disaster_recovery status backup Status: SUCCESS :Backup Completed... Tar Filename: 2020-11-02-02-00-01.tar Storage Location: NETWORK Operation: backup Percentage Complete: 100 UCCX VOIP-UCCX-001 UCPREFS SUCCESS Mon Nov 02 02:00:01 EST 2020 activelog/platform/drf/log/2020-11-02-02-00-01_b_voip-uccx-001_uccx_ucprefs.log UCCX VOIP-UCCX-001 PHX_RPT SUCCESS Mon Nov 02 02:00:07 EST 2020 activelog/platform/drf/log/2020-11-02-02-00-01_b_voip-uccx-001_uccx_phx_rpt.log UCCX VOIP-UCCX-001 UCDB SUCCESS Mon Nov 02 02:00:08 EST 2020 activelog/platform/drf/log/2020-11-02-02-00-01_b_voip-uccx-001_uccx_ucdb.log UCCX VOIP-UCCX-001 PHX_CONFIG SUCCESS Mon Nov 02 02:00:47 EST 2020 activelog/platform/drf/log/2020-11-02-02-00-01_b_voip-uccx-001_uccx_phx_config.log UCCX VOIP-UCCX-001 TCT SUCCESS Mon Nov 02 02:00:47 EST 2020 activelog/platform/drf/log/2020-11-02-02-00-01_b_voip-uccx-001_uccx_tct.log UCCX VOIP-UCCX-001 CDPAGT SUCCESS Mon Nov 02 02:00:48 EST 2020 activelog/platform/drf/log/2020-11-02-02-00-01_b_voip-uccx-001_uccx_cdpagt.log UCCX VOIP-UCCX-001 SYSLOGAGT SUCCESS Mon Nov 02 02:00:48 EST 2020 activelog/platform/drf/log/2020-11-02-02-00-01_b_voip-uccx-001_uccx_syslogagt.log UCCX VOIP-UCCX-001 PLATFORM SUCCESS Mon Nov 02 02:00:49 EST 2020 activelog/platform/drf/log/2020-11-02-02-00-01_b_voip-uccx-001_uccx_platform.log UCCX VOIP-UCCX-001 CLM SUCCESS Mon Nov 02 02:00:51 EST 2020 activelog/platform/drf/log/2020-11-02-02-00-01_b_voip-uccx-001_uccx_clm.log UCCX VOIP-UCCX-001 CCXCOMPONENT SUCCESS Mon Nov 02 02:00:51 EST 2020 activelog/platform/drf/log/2020-11-02-02-00-01_b_voip-uccx-001_uccx_ccxcomponent.log UCCX VOIP-UCCX-001 REPORTER SUCCESS Mon Nov 02 02:01:25 EST 2020 activelog/platform/drf/log/2020-11-02-02-00-01_b_voip-uccx-001_uccx_reporter.log UCCX VOIP-UCCX-001 CUIC_CONFIG SUCCESS Mon Nov 02 02:01:26 EST 2020 activelog/platform/drf/log/2020-11-02-02-00-01_b_voip-uccx-001_uccx_cuic_config.log UCCX VOIP-UCCX-001 IDS_CONFIG SUCCESS Mon Nov 02 02:01:26 EST 2020 activelog/platform/drf/log/2020-11-02-02-00-01_b_voip-uccx-001_uccx_ids_config.log UCCX VOIP-UCCX-002 SYSLOGAGT SUCCESS Mon Nov 02 02:01:27 EST 2020 activelog/platform/drf/log/2020-11-02-02-00-01_b_voip-uccx-002_uccx_syslogagt.log UCCX VOIP-UCCX-002 CDPAGT SUCCESS Mon Nov 02 02:01:28 EST 2020 activelog/platform/drf/log/2020-11-02-02-00-01_b_voip-uccx-002_uccx_cdpagt.log UCCX VOIP-UCCX-002 TCT SUCCESS Mon Nov 02 02:01:28 EST 2020 activelog/platform/drf/log/2020-11-02-02-00-01_b_voip-uccx-002_uccx_tct.log UCCX VOIP-UCCX-002 PHX_CONFIG SUCCESS Mon Nov 02 02:01:29 EST 2020 activelog/platform/drf/log/2020-11-02-02-00-01_b_voip-uccx-002_uccx_phx_config.log UCCX VOIP-UCCX-002 CCXCOMPONENT SUCCESS Mon Nov 02 02:01:29 EST 2020 activelog/platform/drf/log/2020-11-02-02-00-01_b_voip-uccx-002_uccx_ccxcomponent.log UCCX VOIP-UCCX-002 PLATFORM SUCCESS Mon Nov 02 02:01:45 EST 2020 activelog/platform/drf/log/2020-11-02-02-00-01_b_voip-uccx-002_uccx_platform.log UCCX VOIP-UCCX-002 PHX_RPT SUCCESS Mon Nov 02 02:01:46 EST 2020 activelog/platform/drf/log/2020-11-02-02-00-01_b_voip-uccx-002_uccx_phx_rpt.log UCCX VOIP-UCCX-002 CLM SUCCESS Mon Nov 02 02:01:47 EST 2020 activelog/platform/drf/log/2020-11-02-02-00-01_b_voip-uccx-002_uccx_clm.log UCCX VOIP-UCCX-002 REPORTER SUCCESS Mon Nov 02 02:01:47 EST 2020 activelog/platform/drf/log/2020-11-02-02-00-01_b_voip-uccx-002_uccx_reporter.log UCCX VOIP-UCCX-002 CUIC_CONFIG SUCCESS Mon Nov 02 02:01:48 EST 2020 activelog/platform/drf/log/2020-11-02-02-00-01_b_voip-uccx-002_uccx_cuic_config.log UCCX VOIP-UCCX-002 IDS_CONFIG SUCCESS Mon Nov 02 02:01:49 EST 2020 activelog/platform/drf/log/2020-11-02-02-00-01_b_voip-uccx-002_uccx_ids_config.log