LogicMonitor Community logo
     
    • Product Hub
    • Product Forums
      • LM Envision Forum
      • Catchpoint (IPM) Forum
      • Edwin AI Forum
    • Product Updates
      • All Discussions
      • Blogs
      • Feature Requests
      • Product Power Hour
      • End of Life Updates
    • Advocacy
      • MVP Program
      • MSP Connection
    • Learn
      • Welcome to the LM Community
      • Customer Onboarding
      • LM Community News
      • LM Academy
      • Catchpoint Resource Library
      • Release Notes
      • Technical Documentation
    • Events
    • User Groups
    •      
    Discussions
    •                    
    •                    
    •                    
    •                    
    •                    
    •                    
    •                    
    •                    
    •                    
    •                    
    •                    
    •                    
    •                    
    •                    
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   
    Discussions
    LogicMonitor Community logo

    Prevent disruptions, resolve issues faster, and safeguard critical services with the unified observability platform built for predictive, AI-powered IT operations.

    Quick Links
    • Events
    • User Groups
    Social
    #LogicMonitor
    © 2026 LogicMonitor Community  All Rights Reserved.
    Powered byBevy logo
    • Tech ForumsChevronRightIcon
    LM Exchange

    Created Mar 20, 2024

    12 members

    164 discussions

    Unlock the full potential of your LogicMonitor platform with the LM Exchange forum. Discover a wealth of integrations, scripts, and customizations created by the community and LogicMonitor experts. Dive into discussions, share your own contributions, and collaborate with peers to extend the functionality of your monitoring environment. Explore, innovate, and elevate your monitoring experience with the LM Exchange forum today.

    LE
                       
                                       
    • Dave Thurlby

      Dave Thurlby

      Posted 3 months ago • Last reply 3 days ago
      Veeam Backup and Replication
                       

      Looks like the most recent version of Veeam has broken the PS script used to gather datasets. The PS seems to error out when it tries running. Deleted and re-added all modules related, also deleted and re-added the resource. No dice. Discover won't even detect it now, so seems to be officially borked. How can we get LogicMonitor to work on updating the script?

                                             
      13
               
    • Alex‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎‎Boyle

      Alex‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎‎Boyle

      Posted 1 week ago • Last reply 1 week ago
      Verge.io Datasources
                       

      Hello, We had a need to monitor some Verge.io hosts and there seems to be a lack of datasources on the LM Exchange. Is anyone monitoring these using the verge API with a custom datasource? Curious if there's something out there already made before I vibe code something myself.

                                             
      0
               
    • Joel Smith

      Joel Smith

      Posted 1 month ago • Last reply 1 month ago
      Where are the Rubrik Security Cloud Modules?

      After following the official document to configure RSC I cannot configure the webhook properly because the modules do not exist. Can someone show me where to download this module because it is not on the exchange. https://www.logicmonitor.com/support/rubrik-security-cloud-monitoring

                                             
      0
               
    • Dave Lee

      Dave Lee

      Posted 1 month ago • Last reply 1 month ago
      Inherited system.categories via API

      Hello I'm working on some "troubleshooter" scripts to check configuration is correct for certain types of devices. I need to query the system.categories that are applied to some devices. This works fine to systme.categories inside systemProperties but, in some cases, the value I'm looking for has been set as a folder, so I need to also check for inherited properties. I can query the inheritedProperties via the API, but system.categories key/value pair doesn't seem to be in the inherited props that the API response returns. Has anyone done this successfully? Dave

                                             
      0
               
    • Steven Robinson

      Steven Robinson

      Posted 3 months ago • Last reply 3 months ago
      JobMonitor Job Name matters
               

      I'm putting there here for all the literal people like me who follow the directions exactly. In the documentation for using JobMonitor, when it provides examples of how to use the wrapper script, it glosses over the "job name" parameter. Even in the example they just call it "myJob" as though it weren't important. The job name you pass to the wrapper has to MATCH the name of the JobMonitor you created or it won't show up. Here are my instructions: Create a JobMonitor Click Settings->LogicModules Click the + button and add a JobMonitor Name the JobMonitor If you don't like using quote marks later, name it without spaces ex. "WSUSReportTask" Assign an AppliesTo Ex. "isWindows()" if your task is the same on every server system.displayname == "THEBOM-WSUS3" if your task only runs on a server named "THEBOM-WSUS3 Click Save Click Commit Version Download the wrapper from your collector Its located in the lib folder of the collector agent folder. Ex. On collectors hosted on a windows server its C:\Program Files (x86)\LogicMonitor\Agent\lib\lmbatchjobwrapper.js the file expects to be run from cscript, so if you are using node.js, well you are smarter than me Create the scheduled Task on your server The name of the tasks doesn't matter The Program and parameters matter Program: cscript.exe or the full path to the cscript.exe file parameters : <path to wrapper>\lmbatchwrapper.js <collectorIP>:7214 <WinHostResourceName> <JobMonitorModuleName> <cmd+params> ex. here are the params I used to execute my job lmbatchjobwrapper.js thebom-monitor:7214 THEBOM-WSUS3 "WSUSReportTask" "cmd.exe /c c:\scripts\getHostname.bat" Assuming that networking works and you have refreshed your discovery on the resource in Logicmonitor, you should now have the JobMonitor resource and these jobs results will show up.

                                             
      0
               
    • David_Perske

      David_Perske

      Posted 3 years ago • Last reply 3 months ago
      Fortigate Managed Switches

      We were having trouble monitoring Fortigate switches once they had been brought under Fortimanager control as they no longer can be queried directly with SNMP. The switches get onboarded to a 169.x.x.x management network and while it might be possible to make firewall rules etc and use the Fortinet_FortiSwitch datasources it wouldnt be fun or practical in all collector deployments. So we made an addition to fortigate Fortinet_FortiGate_ManagedSwitch Published with identifier MK3TRR Collects; 1. switch status (up/down) with an alert 2. Status of ports 1-52 and collates into a total switch port utilisation complex datapoint with graph. Hope this is helpful

                                             
      7
               
      • LM ExchangeChevronRightIcon
                       
      Adding Data sources to LMExchange
      SteveBamford
      SteveBamford
      Posted 9 months ago • Last reply 4 months ago
      5
               
    • Jared Meidal

      Jared Meidal

      Posted 6 months ago • Last reply 4 months ago
      Seeking feedback on Nutanix monitoring

      We are starting to monitor Nutanix environments in our datacenter, and I've downloaded all the LM modules, so they are ready to use. I'm looking for any success stories and feedback from users, because as of now I can get SNMP for system stats, but nothing from the Nutanix modules themselves. Within Prism we added an SNMP user and the v.3 creds are in the LM resource. It appears the SNMP service needs to be restarted after configuring a user. This is a reference we've used so far: https://portal.nutanix.com/page/documents/kbs/details?targetId=kA0600000008bAECAY#Heading_B

                                             
      7
               
    • SteveBamford

      SteveBamford

      Posted 4 months ago • Last reply 4 months ago
      Dell ECS Network Statistics Version 3.6+ Flux Query

      Dell made some changes to their ECS offering in version 3.6 where system level statistics such as CPU, Memory and Network were removed from the dashboard API and Flux Queries needed to be used to retrieve the data, below are two discovery and collection scripts one for CPU and Memory and one for Network Level statistics that utilize the flux query to retrieve the relevant metrics. Important note: this is for all versions above 3.6 of the Dell EMC ECS Solution all versions before are supported fully by the existing LogicMonitor out of the box packages. The Network statistics will return "0" values from time to time, I am still troubleshooting this, as in the previous script I have found a minimum of 5 minutes works best.   Due to 20000 character limitation on a post the cpu and memory stats can be found here .  Discovery Script: /******************************************************************************* * Dell ECS Network Interface Discovery script. ******************************************************************************/ import groovy.json.JsonSlurper import groovy.json.JsonOutput import groovy.json.JsonBuilder import java.util.concurrent.Executors import java.util.concurrent.TimeUnit import com.santaba.agent.groovyapi.http.*; import com.santaba.agent.util.Settings hostname = hostProps.get("system.hostname") user = hostProps.get("ecs.user") pass = hostProps.get("ecs.pass") collectorplatform = hostProps.get("system.collectorplatform") debug = false def success = false def token = login() if (token) { //Retrieve data for all nodes for CPU and Memory def encoded_instance_props_array = [] def NETresponse = getNetwork(token) // Work through table to retrieve the Node Name and Id to build out the instance level properties. // Internal Note used the methods in "Arista Campus PSU Collection Script" //Process Network Statistics if (debug) println "Net Response: "+ NETresponse def NETJson = new JsonSlurper().parseText(NETresponse) if (debug) println "\n\n Network Values: "+NETJson.Series.Values[0] NETJson.Series.Values[0].each { ifaceEntry -> def nodeId = ifaceEntry[9] def nodeName = ifaceEntry[7] def nodeIfaceName = ifaceEntry[8] wildvalue = "${nodeId}-${nodeIfaceName}" wildalias = "${nodeName}-${nodeIfaceName}" description = "${nodeId}/${nodeIfaceName}" def instance_props = [ "auto.node.id": nodeId, "auto.node.name": nodeName, "auto.node.interface":nodeIfaceName, "auto.node.interface.speed":ifaceEntry[4] ] 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("&")}" } } else if (debug) { println "Bad API response: ${response}"} return 0 def login() { if (debug) println "in login" // Fetch new token using Basic authentication, set in cache file and return if (debug) println "Checking provided ${user} creds at /login.json..." def userCredentials = "${user}:${pass}" def basicAuthStringEnc = new String(Base64.getEncoder().encode(userCredentials.getBytes())) def loginUrl = "https://${hostname}:4443/login.json".toURL() def loginConnection = loginUrl.openConnection() loginConnection.setRequestProperty("Authorization", "Basic " + basicAuthStringEnc) def loginResponseBody = loginConnection.getInputStream()?.text def loginResponseCode = loginConnection.getResponseCode() def loginResponseToken = loginConnection.getHeaderField("X-SDS-AUTH-TOKEN") if (debug) println loginResponseCode if (loginResponseCode == 200 && loginResponseToken) { if (debug) println "Retrieved token: ${loginResponseToken}" return loginResponseToken } else { println "STATUS CODE:\n${loginResponseCode}\n\nRESPONSE:\n${loginResponseBody}" println "Unable to fetch token with ${user} creds at /login.json" } println "Something unknown went wrong when logging in" } def getNetwork(token) { def slurper = new JsonSlurper() def dataUrl = "https://"+hostname+":4443/flux/api/external/v2/query" if (debug) println "Trying to fetch data from ${dataUrl}" def flux = 'from(bucket:\"monitoring_op\") |> range(start: -5m) |> filter(fn: (r) => r._measurement == \"net\" and r._field == \"speed\")' def jsonBody = groovy.json.JsonOutput.toJson(["query":flux]) if (debug) println "Raw JSON Body "+jsonBody if (debug) println "Json Body "+JsonOutput.prettyPrint(jsonBody)+" Type "+jsonBody.getClass() def dataHeader = ["X-SDS-AUTH-TOKEN": token,"Content-Type":"application/json","Accept":"application/json"] if (debug) println("Sent Header: "+dataHeader) // Now we can retrieve the data. def httpClient = Client.open (hostname,4443); httpClient.post(dataUrl,jsonBody,dataHeader); if ( !(httpClient.getStatusCode() =~ /200/)) { println "Failed to retrieve data "+httpClient.getStatusCode() println "Header: "+httpClient.getHeader return(1) } String dataContent = httpClient.getResponseBody() if (debug) println "Status Code "+httpClient.getStatusCode() if (debug) println "Data in response Body "+dataContent return dataContent } Collection Script: /******************************************************************************* * Dell ECS Flux Query Network Statistics ******************************************************************************/ import groovy.json.JsonSlurper import groovy.json.JsonOutput import groovy.json.JsonBuilder import java.util.concurrent.Executors import java.util.concurrent.TimeUnit import com.santaba.agent.groovyapi.http.*; import com.santaba.agent.util.Settings hostname = hostProps.get("system.hostname") user = hostProps.get("ecs.user") pass = hostProps.get("ecs.pass") collectorplatform = hostProps.get("system.collectorplatform") debug = false def success = false def token = login() if (token) { //Retrieve data for all nodes for CPU and Memory def encoded_instance_props_array = [] def NETresponse = getNetwork(token) // Work through table to retrieve the Node Name and Id to build out the instance level properties. // Internal Note used the methods in "Arista Campus PSU Collection Script" //Process Network Statistics if (debug) println "Net Response: "+ NETresponse def NETJson = new JsonSlurper().parseText(NETresponse) if (debug) println "\n\n Net Values: "+NETJson.Series.Values[0] NETJson.Series.Values[0].each { ifaceEntry -> def nodeId = ifaceEntry[9] def nodeName = ifaceEntry[7] def nodeIfaceName = ifaceEntry[8] // Get the _field value so we know which metric we are collecting. def fieldName = ifaceEntry[5] def fieldValue = ifaceEntry[4] wildvalue = "${nodeId}-${nodeIfaceName}" wildalias = "${nodeName}-${nodeIfaceName}" description = "${nodeName}/${nodeIfaceName}" println "${wildvalue}.${fieldName}=${fieldValue}" } } else if (debug) { println "Bad API response: ${response}"} return 0 def login() { if (debug) println "in login" // Fetch new token using Basic authentication, set in cache file and return if (debug) println "Checking provided ${user} creds at /login.json..." def userCredentials = "${user}:${pass}" def basicAuthStringEnc = new String(Base64.getEncoder().encode(userCredentials.getBytes())) def loginUrl = "https://${hostname}:4443/login.json".toURL() def loginConnection = loginUrl.openConnection() loginConnection.setRequestProperty("Authorization", "Basic " + basicAuthStringEnc) def loginResponseBody = loginConnection.getInputStream()?.text def loginResponseCode = loginConnection.getResponseCode() def loginResponseToken = loginConnection.getHeaderField("X-SDS-AUTH-TOKEN") if (debug) println loginResponseCode if (loginResponseCode == 200 && loginResponseToken) { if (debug) println "Retrieved token: ${loginResponseToken}" return loginResponseToken } else { println "STATUS CODE:\n${loginResponseCode}\n\nRESPONSE:\n${loginResponseBody}" println "Unable to fetch token with ${user} creds at /login.json" } println "Something unknown went wrong when logging in" } def getNetwork(token) { def slurper = new JsonSlurper() def dataUrl = "https://"+hostname+":4443/flux/api/external/v2/query" if (debug) println "Trying to fetch data from ${dataUrl}" def flux = 'from(bucket:\"monitoring_op\") |> range(start: -5m) |> filter(fn: (r) => r._measurement == \"net\")' def jsonBody = groovy.json.JsonOutput.toJson(["query":flux]) if (debug) println "Raw JSON Body "+jsonBody if (debug) println "Json Body "+JsonOutput.prettyPrint(jsonBody)+" Type "+jsonBody.getClass() def dataHeader = ["X-SDS-AUTH-TOKEN": token,"Content-Type":"application/json","Accept":"application/json"] if (debug) println("Sent Header: "+dataHeader) // Now we can retrieve the data. def httpClient = Client.open (hostname,4443); httpClient.post(dataUrl,jsonBody,dataHeader); if ( !(httpClient.getStatusCode() =~ /200/)) { println "Failed to retrieve data "+httpClient.getStatusCode() println "Header: "+httpClient.getHeader return(1) } String dataContent = httpClient.getResponseBody() if (debug) println "Status Code "+httpClient.getStatusCode() if (debug) println "Data in response Body "+dataContent return dataContent }   Data Source Configuration: In both cases I have set up the "applies to" setting to "hasCategory("EMC_ECS_Cluster")" The discovery schedule is daily The collection schedule as stated is every 5 minutes.  The collection is configured as batch script in both. Additional comments and notes: One of the biggest challenges I had solving this change from the Dashboard API to the Flux API was that I was receiving a HTTP 401 initially I thought this was the flux query however it turned out to be the saving of the token to the file as per the original data sources, once I removed this and made it the same as my Python script which worked with out issue I resolved this issue. I have an additional request for the Latency statistics, I will share these in a separate post once done. Hope this helps. 

                                             
      0
               
    • SteveBamford

      SteveBamford

      Posted 4 months ago • Last reply 4 months ago
      Dell ECS System Level Statistics Data Sources

      Dell made some changes to their ECS offering in version 3.6 where system level statistics such as CPU, Memory and Network were removed from the dashboard API and Flux Queries needed to be used to retrieve the data, below are two discovery and collection scripts one for CPU and Memory and one for Network Level statistics that utilize the flux query to retrieve the relevant metrics. Important note: this is for all versions above 3.6 of the Dell EMC ECS Solution all versions before are supported fully by the existing LogicMonitor out of the box packages. CPU and Memory Statistics: The following collection and discovery scripts retrieve the CPU and Memory statistics from the flux query API I would recommend keeping the collection frequency at 5 minutes. Discovery Script: /******************************************************************************* * Dell ECS Flux Query CPU and Memory Discovery Script ******************************************************************************/ import groovy.json.JsonSlurper import groovy.json.JsonOutput import groovy.json.JsonBuilder import java.util.concurrent.Executors import java.util.concurrent.TimeUnit import com.santaba.agent.groovyapi.http.*; import com.santaba.agent.util.Settings hostname = hostProps.get("system.hostname") user = hostProps.get("ecs.user") pass = hostProps.get("ecs.pass") collectorplatform = hostProps.get("system.collectorplatform") debug = false def success = false def token = login() // End Templines if (token) { //Retrieve data for all nodes for CPU and Memory def encoded_instance_props_array = [] //Use the flux call for getting the CPU to retrieve the Node information. Future Enhancement find a call for just the Nodes rather than the metrics call. def CPUresponse = getNode(token) if (debug) println "CPU Response: "+ CPUresponse // Work through table to retrieve the Node Name and Id to build out the instance level properties. // Internal Note used the methods in "Arista Campus PSU Collection Script" def CPUJson = new JsonSlurper().parseText(CPUresponse) if (debug) println "\n\n CPU Values: "+CPUJson.Series.Values[0] CPUJson.Series.Values[0].each { nodeEntry -> if (debug) println "In Table" if (debug) println "Node Data "+nodeEntry def nodeId = nodeEntry[9] def nodeName = nodeEntry[8] wildvalue = nodeId wildalias = nodeName description = "${nodeId}/${nodeName}" def instance_props = [ "auto.node.id": nodeId, "auto.node.name": nodeName ] 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("&")}" } } else if (debug) { println "Bad API response: ${response}"} return 0 def login() { if (debug) println "in login" // Fetch new token using Basic authentication, set in cache file and return if (debug) println "Checking provided ${user} creds at /login.json..." def userCredentials = "${user}:${pass}" def basicAuthStringEnc = new String(Base64.getEncoder().encode(userCredentials.getBytes())) def loginUrl = "https://${hostname}:4443/login.json".toURL() def loginConnection = loginUrl.openConnection() loginConnection.setRequestProperty("Authorization", "Basic " + basicAuthStringEnc) def loginResponseBody = loginConnection.getInputStream()?.text def loginResponseCode = loginConnection.getResponseCode() def loginResponseToken = loginConnection.getHeaderField("X-SDS-AUTH-TOKEN") if (debug) println loginResponseCode if (loginResponseCode == 200 && loginResponseToken) { if (debug) println "Retrieved token: ${loginResponseToken}" return loginResponseToken } else { println "STATUS CODE:\n${loginResponseCode}\n\nRESPONSE:\n${loginResponseBody}" println "Unable to fetch token with ${user} creds at /login.json" } println "Something unknown went wrong when logging in" } def getNode(token) { def slurper = new JsonSlurper() def dataUrl = "https://"+hostname+":4443/flux/api/external/v2/query" if (debug) println "Trying to fetch data from ${dataUrl}" //def flux = 'from(bucket:\"monitoring_op\") |> range(start: -5m) |> filter(fn: (r) => r._measurement == \"cpu\" and r.cpu == \"cpu-total\" and r._field == \"usage_idle\" and r.host == \"'+hostname+'\")' def flux = 'from(bucket:\"monitoring_op\") |> range(start: -5m) |> filter(fn: (r) => r._measurement == \"cpu\" and r.cpu == \"cpu-total\" and r._field == \"usage_idle\")' def jsonBody = groovy.json.JsonOutput.toJson(["query":flux]) if (debug) println "Raw JSON Body "+jsonBody if (debug) println "Json Body "+JsonOutput.prettyPrint(jsonBody)+" Type "+jsonBody.getClass() def dataHeader = ["X-SDS-AUTH-TOKEN": token,"Content-Type":"application/json","Accept":"application/json"] if (debug) println("Sent Header: "+dataHeader) // Now we can retrieve the data. def httpClient = Client.open (hostname,4443); httpClient.post(dataUrl,jsonBody,dataHeader); if ( !(httpClient.getStatusCode() =~ /200/)) { println "Failed to retrieve data "+httpClient.getStatusCode() println "Header: "+httpClient.getHeader return(1) } String dataContent = httpClient.getResponseBody() if (debug) println "Status Code "+httpClient.getStatusCode() if (debug) println "Data in response Body "+dataContent //return slurper.parseText(dataContent) return dataContent } Collection Script: /******************************************************************************* * Dell ECS Flux Query CPU and Memory ******************************************************************************/ import groovy.json.JsonSlurper import groovy.json.JsonOutput import groovy.json.JsonBuilder import java.util.concurrent.Executors import java.util.concurrent.TimeUnit import com.santaba.agent.groovyapi.http.*; import com.santaba.agent.util.Settings hostname = hostProps.get("system.hostname") user = hostProps.get("ecs.user") pass = hostProps.get("ecs.pass") collectorplatform = hostProps.get("system.collectorplatform") debug = true def success = false def token = login() // End Templines if (token) { //Retrieve data for all nodes for CPU and Memory def encoded_instance_props_array = [] def CPUresponse = getCPU(token) def MEMresponse = getMemory(token) if (debug) println "CPU Response: "+ CPUresponse if (debug) println "Mem Response: "+ MEMresponse // Work through table to retrieve the Node Name and Id to build out the instance level properties. // Internal Note used the methods in "Arista Campus PSU Collection Script" //Process CPU Metrics def CPUJson = new JsonSlurper().parseText(CPUresponse) if (debug) println "\n\n CPU Values: "+CPUJson.Series.Values[0] CPUJson.Series.Values[0].each { nodeEntry -> if (debug) println "Node Data "+nodeEntry def idleCPU = Float.valueOf(nodeEntry[4]) def usedCPU = 100 - idleCPU def nodeId = nodeEntry[9] def nodeName = nodeEntry[8] wildvalue = nodeId wildalias = nodeName description = "${nodeId}/${nodeName}" println "${wildvalue}.idle_cpu=${idleCPU}" println "${wildvalue}.used_cpu=${usedCPU}" } // Process Memory Metrics def MEMJson = new JsonSlurper().parseText(MEMresponse) if (debug) println "\n\n Mem Values: "+MEMJson.Series.Values[0] MEMJson.Series.Values[0].each { nodeEntry -> def fieldValue = nodeEntry[4] def fieldName = nodeEntry[5] def nodeId = nodeEntry[8] def nodeName = nodeEntry[7] wildvalue = nodeId wildalias = nodeName description = "${nodeId}/${nodeName}" println "${wildvalue}.${fieldName}=${fieldValue}" } } else if (debug) { println "Bad API response: ${response}"} return 0 def login() { if (debug) println "in login" // Fetch new token using Basic authentication, set in cache file and return if (debug) println "Checking provided ${user} creds at /login.json..." def userCredentials = "${user}:${pass}" def basicAuthStringEnc = new String(Base64.getEncoder().encode(userCredentials.getBytes())) def loginUrl = "https://${hostname}:4443/login.json".toURL() def loginConnection = loginUrl.openConnection() loginConnection.setRequestProperty("Authorization", "Basic " + basicAuthStringEnc) def loginResponseBody = loginConnection.getInputStream()?.text def loginResponseCode = loginConnection.getResponseCode() def loginResponseToken = loginConnection.getHeaderField("X-SDS-AUTH-TOKEN") if (debug) println loginResponseCode if (loginResponseCode == 200 && loginResponseToken) { if (debug) println "Retrieved token: ${loginResponseToken}" return loginResponseToken } else { println "STATUS CODE:\n${loginResponseCode}\n\nRESPONSE:\n${loginResponseBody}" println "Unable to fetch token with ${user} creds at /login.json" } println "Something unknown went wrong when logging in" } def getCPU(token) { def slurper = new JsonSlurper() def dataUrl = "https://"+hostname+":4443/flux/api/external/v2/query" if (debug) println "Trying to fetch data from ${dataUrl}" def flux = 'from(bucket:\"monitoring_op\") |> range(start: -5m) |> filter(fn: (r) => r._measurement == \"cpu\" and r.cpu == \"cpu-total\" and r._field == \"usage_idle\")' def jsonBody = groovy.json.JsonOutput.toJson(["query":flux]) if (debug) println "Raw JSON Body "+jsonBody if (debug) println "Json Body "+JsonOutput.prettyPrint(jsonBody)+" Type "+jsonBody.getClass() def dataHeader = ["X-SDS-AUTH-TOKEN": token,"Content-Type":"application/json","Accept":"application/json"] if (debug) println("Sent Header: "+dataHeader) // Now we can retrieve the data. def httpClient = Client.open (hostname,4443); httpClient.post(dataUrl,jsonBody,dataHeader); if ( !(httpClient.getStatusCode() =~ /200/)) { println "Failed to retrieve data "+httpClient.getStatusCode() println "Header: "+httpClient.getHeader return(1) } String dataContent = httpClient.getResponseBody() if (debug) println "Status Code "+httpClient.getStatusCode() if (debug) println "Data in response Body "+dataContent return dataContent } def getMemory(token) { def slurper = new JsonSlurper() def dataUrl = "https://"+hostname+":4443/flux/api/external/v2/query" if (debug) println "Trying to fetch data from ${dataUrl}" //def flux = 'from(bucket:\"monitoring_op\") |> range(start: -5m) |> filter(fn: (r) => r._measurement == \"mem\" and r._field == \"available_percent\")' def flux = 'from(bucket:\"monitoring_op\") |> range(start: -5m) |> filter(fn: (r) => r._measurement == \"mem\")' def jsonBody = groovy.json.JsonOutput.toJson(["query":flux]) if (debug) println "Raw JSON Body "+jsonBody if (debug) println "Json Body "+JsonOutput.prettyPrint(jsonBody)+" Type "+jsonBody.getClass() def dataHeader = ["X-SDS-AUTH-TOKEN": token,"Content-Type":"application/json","Accept":"application/json"] if (debug) println("Sent Header: "+dataHeader) // Now we can retrieve the data. def httpClient = Client.open (hostname,4443); httpClient.post(dataUrl,jsonBody,dataHeader); if ( !(httpClient.getStatusCode() =~ /200/)) { println "Failed to retrieve data "+httpClient.getStatusCode() println "Header: "+httpClient.getHeader return(1) } String dataContent = httpClient.getResponseBody() if (debug) println "Status Code "+httpClient.getStatusCode() if (debug) println "Data in response Body "+dataContent return dataContent } Networking Statistics: See the link  https://community.logicmonitor.com/discussions/lm-exchange/dell-ecs-network-statistics-version-3-6-flux-query/19817 for the network statistics as I ran out of space. Additional comments and notes: One of the biggest challenges I had solving this change from the Dashboard API to the Flux API was that I was receiving a HTTP 401 initially I thought this was the flux query however it turned out to be the saving of the token to the file as per the original data sources, once I removed this and made it the same as my Python script which worked with out issue I resolved this issue. I have an additional request for the Latency statistics, I will share these in a separate post once done. Hope this helps. 

                                             
      0
               
    …