Use a Property Source to find dead devices
This is a PropertySource which runs with active discovery and adds the property auto.lmstatus to the device properties with the current Hoststatus value. It does this using the REST API and It works great with Dynamic grouping, for example if you wanted to know which device in your portal were currently in a dead status you could create a dynamic group with the applies to of “auto.lmstatus=="dead". One advantage to using a property source is if the device comes back on-line, Active Discovery will immediately run and change the property to "normal" removing the device from the group. A copy of the PropertySource is at the bottom of the post.
Let’s walk through the groovy script.
Define the account information
This is polling the device properties. I recommend setting this at the group level so they are inherited to the devices.
an example of the properties would be
api.user = 5kCPqLgY4DGYP27uw2hc
api.pass = ye[$3y7)_4g6L6uH2TC72k{V6HBUf]Ys+9!vB)[9 *note, any property with .pass in the name will not have visible data.
api.account = lmjeffwoeber
Define the Query. We just need the HostSatatus for the device the script is running on.
Next we build the URL for the API.
This next part builds the security and runs the API. It can pretty much be copy\pasted into any groovy scripts that use the REST API.
<span class="pln">//get current time
epoch = System.currentTimeMillis();
//calculate signature
requestVars = "GET" + epoch + resourcePath;
hmac = Mac.getInstance("HmacSHA256");
secret = new SecretKeySpec(accessKey.getBytes(), "HmacSHA256");
hmac.init(secret);
hmac_signed = Hex.encodeHexString(hmac.doFinal(requestVars.getBytes()));
signature = hmac_signed.bytes.encodeBase64();
// HTTP Get
CloseableHttpClient httpclient = HttpClients.createDefault();
httpGet = new HttpGet(url);
httpGet.addHeader("Authorization" , "LMv1 " + accessId + ":" + signature + ":" + epoch);
response = httpclient.execute(httpGet);
responseBody = EntityUtils.toString(response.getEntity());
code = response.getStatusLine().getStatusCode();</span>
The API will return a JSON payload. We use the Groovy Slurper to transfer the payload to respose_obj were we can use the data.
They JSON will look like
We can use the value with response_obj.data.items[0].hostStatus.value
Now we print the Key=Value for the property source
This will add the property source "auto.lmstatus" to the device
finally we return 0 do indicate a success.
This is how the PropertySource will appear on the device

Lastly, we can create Dynamic Groups based off the Hostatus. For example use an applies to auto.lmstatus=="dead" to group all of the dead devices into one group, or auto.lmstatus=~"dead" to also include Dead-Collector

LMStatus PropertySource
<span class="pln">import org.apache.http.HttpEntity
import org.apache.http.client.methods.CloseableHttpResponse
import org.apache.http.client.methods.HttpGet
import org.apache.http.impl.client.CloseableHttpClient
import org.apache.http.impl.client.HttpClients
import org.apache.http.util.EntityUtils
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Hex;import com.santaba.agent.groovyapi.http.*;
import groovy.json.JsonSlurper;
def hostName = hostProps.get("system.displayname");
//Account Info
def accessId = hostProps.get("api.user");
def accessKey = hostProps.get("api.pass");
def account = hostProps.get("api.account");
data = ''
def queryParams = '?fields=hostStatus&filter=displayName:'+hostName;
def resourcePath = "/device/devices"
def url = "https://" + account + ".logicmonitor.com" + "/santaba/rest" + resourcePath + queryParams;
//get current time
epoch = System.currentTimeMillis();
//calculate signature
requestVars = "GET" + epoch + resourcePath;
hmac = Mac.getInstance("HmacSHA256");
secret = new SecretKeySpec(accessKey.getBytes(), "HmacSHA256");
hmac.init(secret);
hmac_signed = Hex.encodeHexString(hmac.doFinal(requestVars.getBytes()));
signature = hmac_signed.bytes.encodeBase64();
// HTTP Get
CloseableHttpClient httpclient = HttpClients.createDefault();
httpGet = new HttpGet(url);
httpGet.addHeader("Authorization" , "LMv1 " + accessId + ":" + signature + ":" + epoch);
response = httpclient.execute(httpGet);
responseBody = EntityUtils.toString(response.getEntity());
code = response.getStatusLine().getStatusCode();
// user groovy slurper
json_slurper = new JsonSlurper();
response_obj = json_slurper.parseText(responseBody);
//print output
println "LMStatus=" +response_obj.data.items[0].hostStatus.value;
httpclient.close();
return (0);</span>
Stefan Wuensch
·5 years agoI believe this PS is made partially obsolete by the new system.hoststatus Device Property which was introduced in v149.
https://www.logicmonitor.com/support/v-149-release-notes
However, in v153 that Property system.hoststatus was made restricted, preventing it from being used in any LogicModules.
https://www.logicmonitor.com/support/v-153-release-notes
(If you had already added it to the AppliesTo on a LogicModule before v153 it continues to work. You just can't make any additional edits to that module without removing that Property.)
The system.hoststatus is still available and working on Dynamic Groups though.
Jeff_Woeber
OP6 years agoHi All
One of the latest portal updates appears to have broken this propertysource. The fix is to change this line
println "LMStatus=" +response_obj.data.items[0].hostStatus.value
LM User
·6 years agoMarked as private, cant download.
Jason_Miller
·8 years agoThanks, got this to work. I love it. I added it to the Exchange: 6FXRA4
Tom_Lasswell
·8 years ago@Beau Breeden are you getting any property source applied? on a non-dead device you should still see a property source get attached. If it's working at all, you should see a property source added to each device "LMStatus=" saying alive or dead. If it's not working likely it's your API.user and API.pass keys that are incorrect and make sure you set the API.account as well to your subdomain.
Beau_Breeden
·8 years agoAnthony,
I just applied added this as a PropertySource, specified a group of servers, and ran the script test. It succeeded, but applied the properties to 0 devices, even though there are roughly 500 devices, several of which are dead. Any suggestions to where I could be going wrong?
Tom_Lasswell
·9 years agoMakes since.
Antony Hawkins
·9 years ago@Tom Lasswell no, active discovery does not run when a device's alert status changes (this could potentially be every few seconds, as various metrics went into and out of alert conditions).
Tom_Lasswell
·9 years agoThis is great, just implemented.
Using for another feature as well in a dynamic group. We have at several times where we'll take major site outages that have 100+ devices, the collectors go a little bonkers with the failed task rates, so we can disable all the datasources and any existing alerts when the device goes dead. Added feature :)/emoticons/smile@2x.png 2x" title=":)" width="20">
I noticed you're using the hostStatus, maybe we could also use the alertStatus as well, break it up, and say what the highest state of alert the device is as well? Does active discovery run when a device changes alert state as well? Or just when it goes from dead to normal?
Antony Hawkins
·9 years ago@Jeff.Woeber that's very cool!
One minor tweak, the 'def hostName' line:
...should be:
...to cope with spaces and other non-URL-friendly characters that are permitted in device display names.
:)/emoticons/smile@2x.png 2x" title=":)" width="20">