Recent Discussions
Connectwise Integration Documentation Missing Step
There is a need to add a step to the Integration Docs (We're doing Connectwise, but I'm sure others need it as well)... https://www.logicmonitor.com/support/connectwise-integration It doesn't state that the escalation time in the alert rules that push to it should be set to "0" where possible to prevent over aggressive updates across the API from occurring. It is stated in the Alert Rule Documentation but isn't stated where the activity it ultimately effects is performed. Support recommended I use the Feedback option in the support sidebar... but that's blackhole with no feedback channel, so I'm posting it here instead.Cole_McDonald9 hours agoProfessor24Views1like1CommentWebsite Data in Table Widget
I have a number of websites that are being monitored. I would like to create a dashboard with a table of response times from the Washington LogicMonitor site. However the Table widget does not have an option to include Website data - only resources which seem to exclude data from Website monitoring. I can add graphs and alerts of website data but cant seem to find a way to access the raw website polling data in the Table widget. Is this a known limitation?bleclair13 hours agoNeophyte70Views1like6CommentsHow to Add Arista Wireless Access Points in Logic Monitor?
Hello Team, Can someone guide me how to add the Arista Wireless APs in Logic Monitor. One of our client uses Arista APs in their remote sites which we manage through Arista Cloud Vision Portal. We would like to know if this can be done in LM or not? Thanks & regards, Gautam Vennagautamvenna19 hours agoNeophyte431Views3likes3CommentsAdding Arista AP's to LogicMonitor
There was a previous request about this, and I have been working on this my self, so I thought I would share what I have delivered. Required Custom Parameters. The Discovery and collection scripts are expecting the following custom properties to be present for each device I have added these at the folder (in our case "Networks") so they cascade down. AristaWIFI.api.endpoint - This is the endpoint within CV-Cue under advanced setting for configuration and management API integrations. AristaWIFI.api.key - The API Key for CV-CUE AristaWIFI.api.token - The API Token for CV-CUE If these are not provided then the collector and discovery scripts will fail. NetScan: I had issues getting the netscan to work in Groovy so wrote a pyhton script to do this which links to Arista CloudVision and LogicMonitor, I have something in my backlog now to migrate this to groovy, the biggest challenge I have is that the HTTP DELETE call in Groovy is expecting data which is not needed for the delete call to close the session. This also uses the Python Core Library we use for all of our LogicMonitor integrations, so sharing is a tad difficult as I would have share the script and our Core Library. If people think this is worth While I would add it in the future. I set a system category of "AristaWifi" to easily identify Arista AP's for the collection and discovery scripts. Finally I also include the AP's ID on discovery as this is used to pull the specific AP from CV-CUE as the custom Property "CVcueId". What Metrics can be collected. Currently I am collecting CPU and Memory which I have created a Arista WIFI General Metrics Data source, and Arista WIFI SSID Metrics which is collecting the Associated Clients and the SSID State which is whether it is Enabled (1) or Disabled (0), I also have unknown (3) if the information can not be retrieved from the JSON. Arista Wifi General Metrics: This data source is configured to use Script as the collection source, below is the script. Note: The logout is commented out until I can result the http delete issue mentioned above. /******************************************************************************* * Arista WIFI Integration with CUE for discovery of the AP's ******************************************************************************/ import com.santaba.agent.groovyapi.http.* import com.santaba.agent.groovy.utils.GroovyScriptHelper as GSH import com.logicmonitor.mod.Snippets import com.santaba.agent.AgentVersion import java.text.DecimalFormat import com.santaba.agent.util.Settings import groovy.json.JsonOutput import groovy.json.JsonSlurper import groovy.json.JsonBuilder import java.util.concurrent.Executors import java.util.concurrent.TimeUnit // 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 } String key = props.get("AristaWIFI.api.key") String token = props.get("AristaWIFI.api.token") String AristaEndPoint = props.get("AristaWIFI.api.endpoint") //Get the Arista CV WIFI Node Node Id as discovered in the scanning script and submitted to the device.. String nodeId = props.get("CVcueId") String clientId = "logicmonitor" String wifiUrl = "https://"+AristaEndPoint+"/wifi/api/" if (!key) { throw new Exception("Must provide AristaWIFI.api.key to run this script. Verify necessary credentials have been provided in Netscan properties.") } if (!token) { throw new Exception("Must provide AristaWIFI.api.token credentials to run this script. Verify necessary credentials have been provided in Netscan properties.") } if (!clientId) { throw new Exception("Must provide AristaWIFI.api.clientId credentials to run this script. Verify necessary credentials have been provided in Netscan properties.") } //def logCacheContext = "${org}::arista-wifi-cloud" //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}.") } httpClient = HTTP.open(AristaEndPoint,443); httpClient.setHTTPProxy('[YOUR Proxy]',8080); // Log in to arista loginurl = "https://"+AristaEndPoint+"/wifi/api/session" payloadstring = '{"type":"apiKeycredentials","keyId":"'+key+'","keyValue":"'+token+'","timeout":129,"clientIdentifier": "'+clientId+'"}'; def payload = payloadstring; //println payload; def loginResponse = httpClient.post(loginurl,payload,["Content-Type":"application/json"]); if ( !(httpClient.getStatusCode() =~ /20/) ) { // Error has occured println "Authentication Failure"; println httpClient.getStatusCode(); println loginResponse; return(1); } String RawCookie = httpClient.getHeader("Set-Cookie") //Have Kept but as yet not needed will remove if not needed.. String httpResponseBody = httpClient.getResponseBody() //Retrieve the Cookie to use from the header. AristaCookie = RawCookie.split(';')[0] //Retrieve AP data. deviceURL = 'manageddevices/aps?startindex=0&pagesize=1000&locationid=0&nodeid=0&boxid='+nodeId SendUrl = wifiUrl+deviceURL def header = ["Content-Type":"application/json","Cookie":AristaCookie] String deviceResponse = httpClient.get(SendUrl,header) if ( !(httpClient.getStatusCode() =~ /200/)) { println "Failed to retrieve data "+httpClient.getStatusCode return 1 } String deviceBody = httpClient.getResponseBody() def deviceJson = new JsonSlurper().parseText(deviceBody) def healthStats = deviceJson.managedDevices.healthStats def wildvalue = "" Integer rawminCPU = healthStats[0].minCpuUtilization Integer minCpu = rawminCPU/100 Integer rawavgCPU = healthStats[0].avgCpuUtilization Integer avgCpu = rawavgCPU/100 Integer rawmaxCPU = healthStats[0].maxCpuUtilization Integer maxCpu = rawmaxCPU/100 Integer rawminMem = healthStats[0].minMemoryUtilization Integer minMem = rawminCPU/100 Integer rawAvgMem = healthStats[0].avgMemoryUtilization Integer avgMem = rawAvgMem/100 Integer rawmaxMem = healthStats[0].maxMemoryUtilization Integer maxMem = rawmaxCPU/100 println "${wildvalue}.mincpu=${minCpu}" println "${wildvalue}.avgcpu=${avgCpu}" println "${wildvalue}.maxcpu=${maxCpu}" println "${wildvalue}.minMem=${minMem}" println "${wildvalue}.avgMem=${avgMem}" println "${wildvalue}.maxMem=${maxMem}" // Commented out log out process for now as will need to revisit currently reducing Timeout to 5 minutes for the session. /* String cookieString = '"'+AristaCookie+'"' def logoutheaders = ["Content-Type":"application/json","Cookie":AristaCookie] println logoutheaders def logoutResponse = httpClient.delete(loginurl,"{}",logoutheaders) logoutResult = httpClient.getStatusCode() if ( !(httpClient.getStatusCode() =~ /20/) ) { //Error has occured println "Logout Failure"; println httpClient.getStatusCode(); println loginResponse; return(1); } println logoutResponse;*/ def LMDebugPrint(message) { if (debug) { println(message.toString()) } } return 0 Arista WIFI SSID Metrics: This will collect the number of associated clients by Band (IE 2.4ghz) and SSID I have the created graphs to aggregate the data together for total number of associated clients. Discovery Script: /******************************************************************************* * Arista WIFI Integration with CUE for discovery of the AP's ******************************************************************************/ import com.santaba.agent.groovyapi.http.* import com.santaba.agent.groovy.utils.GroovyScriptHelper as GSH import com.logicmonitor.mod.Snippets import com.santaba.agent.AgentVersion import java.text.DecimalFormat import com.santaba.agent.util.Settings import groovy.json.JsonOutput import groovy.json.JsonSlurper import groovy.json.JsonBuilder import java.util.concurrent.Executors import java.util.concurrent.TimeUnit // 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 } String key = props.get("AristaWIFI.api.key") String token = props.get("AristaWIFI.api.token") String AristaEndPoint = props.get("AristaWIFI.api.endpoint") //Get the Arista CV WIFI Node Node Id as discovered in the scanning script and submitted to the device.. String nodeId = props.get("CVcueId") String clientId = "logicmonitor" String wifiUrl = "https://"+AristaEndPoint+"/wifi/api/" if (!key) { throw new Exception("Must provide AristaWIFI.api.key to run this script. Verify necessary credentials have been provided in Netscan properties.") } if (!token) { throw new Exception("Must provide AristaWIFI.api.token credentials to run this script. Verify necessary credentials have been provided in Netscan properties.") } if (!clientId) { throw new Exception("Must provide AristaWIFI.api.clientId credentials to run this script. Verify necessary credentials have been provided in Netscan properties.") } //def logCacheContext = "${org}::arista-wifi-cloud" //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}.") } httpClient = HTTP.open(AristaEndPoint,443); httpClient.setHTTPProxy('[Your Proxy]',8080); // Log in to arista loginurl = "https://"+AristaEndPoint+"/wifi/api/session" payloadstring = '{"type":"apiKeycredentials","keyId":"'+key+'","keyValue":"'+token+'","timeout":129,"clientIdentifier": "'+clientId+'"}'; def payload = payloadstring; //println payload; def loginResponse = httpClient.post(loginurl,payload,["Content-Type":"application/json"]); if ( !(httpClient.getStatusCode() =~ /20/) ) { // Error has occured println "Authentication Failure"; println httpClient.getStatusCode(); println loginResponse; return(1); } String RawCookie = httpClient.getHeader("Set-Cookie") //Have Kept but as yet not needed will remove if not needed.. String httpResponseBody = httpClient.getResponseBody() //Retrieve the Cookie to use from the header. AristaCookie = RawCookie.split(';')[0] //Retrieve AP data. deviceURL = 'manageddevices/aps?startindex=0&pagesize=1000&locationid=0&nodeid=0&boxid='+nodeId SendUrl = wifiUrl+deviceURL def header = ["Content-Type":"application/json","Cookie":AristaCookie] String deviceResponse = httpClient.get(SendUrl,header) if ( !(httpClient.getStatusCode() =~ /200/)) { println "Failed to retrieve data "+httpClient.getStatusCode return 1 } String deviceBody = httpClient.getResponseBody() def encoded_instance_props_array = [] def deviceJson = new JsonSlurper().parseText(deviceBody) def wildvalue = "" def wildalias = "" def description = "" def getOperatingBand = "" def getSSID = "" def radios = deviceJson.managedDevices.radios radios[0].each { RadioEntry -> // Build out wireless entries. getOperatingBand = RadioEntry.operatingBand RadioEntry.wirelessInterfaces.each { ssidEntry -> getssid = ssidEntry.ssid description = ssidEntry.bssid wildvalue = getOperatingBand+"_"+getssid wildalias = wildvalue def instance_props = [ "auto.opertating.band": RadioEntry.operatingBand, "auto.ssid": ssidEntry.ssid, "auto.bssid":ssidEntry.bssid, "auto.ssid.profileId":ssidEntry.ssidProfileId ] encoded_instance_props_array = instance_props.collect() { property, value -> URLEncoder.encode(property.toString()) + "=" + URLEncoder.encode(value.toString()) } println "${wildvalue}##${wildalias}##${description}####${encoded_instance_props_array.join("&")}" } } // Commented out log out process for now as will need to revisit currently reducing Timeout to 5 minutes for the session. /* String cookieString = '"'+AristaCookie+'"' def logoutheaders = ["Content-Type":"application/json","Cookie":AristaCookie] println logoutheaders def logoutResponse = httpClient.delete(loginurl,"{}",logoutheaders) logoutResult = httpClient.getStatusCode() if ( !(httpClient.getStatusCode() =~ /20/) ) { //Error has occured println "Logout Failure"; println httpClient.getStatusCode(); println loginResponse; return(1); } println logoutResponse;*/ def LMDebugPrint(message) { if (debug) { println(message.toString()) } } return 0 Collection Script: /******************************************************************************* * Arista WIFI Integration with CUE for discovery of the AP's ******************************************************************************/ import com.santaba.agent.groovyapi.http.* import com.santaba.agent.groovy.utils.GroovyScriptHelper as GSH import com.logicmonitor.mod.Snippets import com.santaba.agent.AgentVersion import java.text.DecimalFormat import com.santaba.agent.util.Settings import groovy.json.JsonOutput import groovy.json.JsonSlurper import groovy.json.JsonBuilder import java.util.concurrent.Executors import java.util.concurrent.TimeUnit // 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 } String key = props.get("AristaWIFI.api.key") String token = props.get("AristaWIFI.api.token") String AristaEndPont = props.get("AristaWIFI.api.endpoint") //Get the Arista CV WIFI Node Node Id as discovered in the scanning script and submitted to the device.. String nodeId = props.get("CVcueId") String clientId = "logicmonitor" String wifiUrl = "https://"+AristaEndPont+"/wifi/api/" if (!key) { throw new Exception("Must provide AristaWIFI.api.key to run this script. Verify necessary credentials have been provided in Netscan properties.") } if (!token) { throw new Exception("Must provide AristaWIFI.api.token credentials to run this script. Verify necessary credentials have been provided in Netscan properties.") } if (!clientId) { throw new Exception("Must provide AristaWIFI.api.clientId credentials to run this script. Verify necessary credentials have been provided in Netscan properties.") } if (!AristaEndPont) { throw new Exception("Must provide AristaWIFI.api.endpoint to run this script. Verify necessary variable is within your LogicMonitor instance before continuing.") } //def logCacheContext = "${org}::arista-wifi-cloud" //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}.") } httpClient = HTTP.open(AristaEndPont,443); httpClient.setHTTPProxy('[Your Proxy]',8080); // Log in to arista loginurl = "https://"+AristaEndPont+"/wifi/api/session" payloadstring = '{"type":"apiKeycredentials","keyId":"'+key+'","keyValue":"'+token+'","timeout":129,"clientIdentifier": "'+clientId+'"}'; def payload = payloadstring; //println payload; def loginResponse = httpClient.post(loginurl,payload,["Content-Type":"application/json"]); if ( !(httpClient.getStatusCode() =~ /20/) ) { // Error has occured println "Authentication Failure"; println httpClient.getStatusCode(); println loginResponse; return(1); } String RawCookie = httpClient.getHeader("Set-Cookie") //Have Kept but as yet not needed will remove if not needed.. String httpResponseBody = httpClient.getResponseBody() //Retrieve the Cookie to use from the header. AristaCookie = RawCookie.split(';')[0] //Retrieve AP data. deviceURL = 'manageddevices/aps?startindex=0&pagesize=1000&locationid=0&nodeid=0&boxid='+nodeId SendUrl = wifiUrl+deviceURL def header = ["Content-Type":"application/json","Cookie":AristaCookie] String deviceResponse = httpClient.get(SendUrl,header) if ( !(httpClient.getStatusCode() =~ /200/)) { println "Failed to retrieve data "+httpClient.getStatusCode return 1 } String deviceBody = httpClient.getResponseBody() def encoded_instance_props_array = [] def deviceJson = new JsonSlurper().parseText(deviceBody) def wildvalue = "" def wildalias = "" def description = "" def getOperatingBand = "" def getSSID = "" def radios = deviceJson.managedDevices.radios def ssidActive = 3 radios[0].each { RadioEntry -> // Build out wireless entries. getOperatingBand = RadioEntry.operatingBand RadioEntry.wirelessInterfaces.each { ssidEntry -> getssid = ssidEntry.ssid description = ssidEntry.bssid wildvalue = getOperatingBand+"_"+getssid wildalias = wildvalue if (ssidEntry.active == true) { ssidActive = 1 } else { ssidActive = 0 } println "${wildvalue}.numAssocClients=${ssidEntry.numAssocClients}" println "${wildvalue}.active=${ssidActive}" } } // Commented out log out process for now as will need to revisit currently reducing Timeout to 5 minutes for the session. /* String cookieString = '"'+AristaCookie+'"' def logoutheaders = ["Content-Type":"application/json","Cookie":AristaCookie] println logoutheaders def logoutResponse = httpClient.delete(loginurl,"{}",logoutheaders) logoutResult = httpClient.getStatusCode() if ( !(httpClient.getStatusCode() =~ /20/) ) { //Error has occured println "Logout Failure"; println httpClient.getStatusCode(); println loginResponse; return(1); } println logoutResponse;*/ def LMDebugPrint(message) { if (debug) { println(message.toString()) } } return 024Views0likes1CommentOAuth 2.0 Web Check Monitoring
Hello, I have an API healthcheck URI that I need to monitor. At first I thought I could use the external website web check, but it appears as if that only offers 2 authentication methods: basic and NTLM. The resource I need to monitor requires OAuth 2.0 authentication. For this I need to have: OAuth credentials (client ID and secret) x-api-key Scopes Bearer token I am able to create this in Postman, but not sure how best to approach this on the LogicMonitor platform. Any ideas on the best method to monitor a website that requires OAuth 2.0?autarch2 days agoNeophyte20Views0likes1CommentAd integrated Zone transfer monitoring
Hi We are Monitoring Domain controllers in LogicMonitor and the environment has AD integrated zones transfers for LDAP is there any way we can monitor these as the existing DNS- datasource doesnot meet our requirements as it has only non-AD integrated zone transfersvenkat2 days agoNeophyte49Views0likes0CommentsLM / ServiceNow Integration
I'm working on some API commands for ServiceNow from LogicMonitor and am trying to see if there's a way to see further information from the return payload from ServiceNow when a ticket is generated via the integration. In particular, I'm trying to capture the sys_id field from ServiceNow so that I can use this to access the ticket in an escalation step using a custom HTTPS API command. I can see the payload includes sys_id in the integration logs, and indeed LogicMonitor uses it to generate the link to the ticket on the alert screens. Does anyone know if there's a token or such that can be used to access this info, or if there would be a way of storing it for access?Jason_Clemons2 days agoNeophyte70Views0likes2CommentsRename a collector?
I swore that in the old UIv3 you could rename a collector hostname. I dont mean the resource representation of the collector, when it monitors itself, I mean the actual name it has in the collector context. When I try to manage the collector on the collectors page, there is no option to change it. But we have a situation where we have to. Does this mean we need to rebuild and redeploy the collector to change it? The 2 collectors have similar collector names (collector hostnames), and while their respective resource names (for self-monitoring) have different displaynames etc, on the machines themselves, they have the same system.sysname. So this is causing some weird bug where alerts on either collector cause the alert to show on both. Kind of amusing. COLLECTOR "DEVICE NAME" /// RESOURCE DISPLAYNAME /// SYSTEM.SYSNAME ------------------------------------------------------------------- CORP\FF-FF01 /// FF-FF01.CompanyA.Com /// FF-FF01 WAN\FF-FF01 /// FF-FF01.CompanyB.Com /// FF-FF01 Because the sysnames are also the same (they sit in completely different networks) I think its confusing LogicMonitor, so I suspect the team that deploys there is going to have to honestly redo one of the collectors completely. But when fishing around in the UIv4 collectors page, I saw no way to change the "CORP\FF-FF01" or "WAN\FF-FF01" part. I think the sysname is going to force a complete redeploy on one, but its just weird I cant change the name.Lewis_Beard2 days agoProfessor63Views0likes0CommentsBMC Remedy Integration
Hi all I'm looking to do an ITSM integration with BMC Helix/Remedy, which isn't natively supported. It looks as though we can create a new incident by making a POST request to their API. But, if we want to do an update, it seems their API requires that you first query the API for an internal ID for the Incident, then make a second call with the update referring to that internal ID. Apparently this behaviour in the API cannot be altered. I don't see any way to achieve this in LogicMonitor. Has anyone successfully integrated LM and BMC Helix/Remedy? I think we will likely need to build something to sit between and receive the updates from LM and then call the Helix API. Interested in hearing what others may have done to achieve this. DaveDave_Lee3 days agoAdvisor278Views0likes2Comments