Forum Discussion

Kelemvor's avatar
Kelemvor
Icon for Expert rankExpert
2 years ago

Can I pull a specific system property in an API call?

Hi,

I’m writing an API call that pulls only specific fields.  I can get all the normal fields, but I want to get system.groups.  System.groups is inside the systemProperties array of variables and I haven’t been able to figure out if I can pull it.

I’m using: &fields=name,displayName,collectorDescription,hostStatus and want to add systemProperties[system.groups] but can’t find any syntax that will work.  I’ve found examples on how to Filter on a property, but not how to just display it.

Anyone know how I can do this?

Thanks.

  • Anonymous's avatar
    Anonymous

    Following to see if LM has an answer. I haven’t been able to figure it out.

  • You cannot pull properties from the device endpoint, but you can filter -- the method is limited (supports only one property match). You can use a filter like so (if you wish to restrict to specific values of that property).

    filter=systemProperties.name:system.groups,systemProperties.value:VALUE

    We’ve generally ended up with a full dump of /device/devices/$device->{id}/properties into a hash and then we reference that data as needed with a simple wrapper function to lookup property values from the hash.  It requires more API calls, but actually is useful and it works. I checked all our code and we pretty much never use that first method.

  • Here is the core chunk of a script that dumps all properties for each device. It was just a throaway POC I kept around, might be helpful. In Perl because I still Perl :). Get off my lawn!

    my $lmapi = WM::LMAPI->new(company => $COMPANY) or die;

    my %filter = (filter => $FILTER) if (defined $FILTER and length $FILTER);
    my $devices = $lmapi->get_all(path => "/device/devices", fields => "id,name,displayName", %filter);
    verbose 1, "@{[scalar @$devices]} devices found\n";
    DEVICE:
    for my $device (@$devices) {
    # extract and display device properties
    if (my $properties = $lmapi->get_all(path => "/device/devices/$device->{id}/properties")) {
    my $output;
    for my $prop (sort { $a->{name} cmp $b->{name} } @{$properties}) {
    if (my ($filtername,$filtervalue) = ($HACKFILTER =~ /^([^:]+):(.*)/)) {
    next DEVICE if (lc $prop->{name} eq lc $filtername and $prop->{value} ne $filtervalue);
    }
    $output .= $prop->{name} . ": " . $prop->{value} . "\n";
    }
    print $device->{displayName}, "\n";
    print $output, "\n";
    }
    }
  • Anonymous's avatar
    Anonymous

    We’ve generally ended up with a full dump of /device/devices/$device->{id}/properties into a hash and then we reference that data as needed with a simple wrapper function to lookup property values from the hash.

    This is what I do too. Instead of filtering in the call, I just fetch everything and filter afterwards.

  • Yeah, filtering doesn’t help me.  I’m actually filtering on the hoststatus field to pull all the “Dead” devices.  I just wanted to have the Group show up in the results so I can tell easier what something is.

    Not a huge deal if I can’t but would be nice if I could.

    I’m actually on a chat with LM support right now and am assuming he’s about to give me the same answer.  :)

  • Sorry, one more point -- I was checking our backup script and we don’t actually use /properties there except for grouping results (/properties gives you all properties in a list, so it is appropriate if you don’t know where to look for an input property name). Within device results, there are keys to arrays for systemProperties, customProperties, autoProperties inheritedProperties. So you just have to get the device (possibly filtered by one property/value pair) and then extract what you need from those lists, like so:

    sub getprop {
    my $properties = shift;
    my $name = shift;

    my $pval = (map { $_->{value} } grep { $_->{name} eq $name } @{$properties})[0];

    return $pval;
    }

    So for system.groups, that would be getprop($device->{systemProperties}, ‘system.groups’).

  • Anonymous's avatar
    Anonymous

    Yeah, filtering doesn’t help me.  I’m actually filtering on the hoststatus field to pull all the “Dead” devices.  I just wanted to have the Group show up in the results so I can tell easier what something is.

    Not a huge deal if I can’t but would be nice if I could.

    I’m actually on a chat with LM support right now and am assuming he’s about to give me the same answer.  :)

    Why not make a group based on that property then query /device/groups/{id}/devices?

  • @Kelemvor ~ the script here will pull the system.groups value for you: https://github.com/krshearman/LMAPI_v3/blob/main/GetDeviceProperties_SystemGroups.py

    #!/bin/env python

    import requests
    import json
    import hashlib
    import base64
    import time
    import hmac



    # - Account Info - replace with your own values
    Company = ""
    AccessKey = ""
    AccessId = ""

    # Request Info
    httpVerb ='GET'
    # This gets the properties for a device with id of 804
    deviceId = 804
    resourcePath = f'/device/devices/{deviceId}/properties'
    data = ''

    # Construct URL
    url = 'https://'+ Company +'.logicmonitor.com/santaba/rest' + resourcePath

    # Get current time in milliseconds
    epoch = str(int(time.time() * 1000))

    # Concatenate Request details
    requestVars = httpVerb + epoch + data + resourcePath

    # Construct signature
    hmac1 = hmac.new(AccessKey.encode(), msg=requestVars.encode(), digestmod=hashlib.sha256).hexdigest()
    signature = base64.b64encode(hmac1.encode())

    # Construct headers
    auth = 'LMv1 ' + AccessId + ':' + signature.decode() + ':' + epoch
    headers = {'Content-Type': 'application/json', 'Authorization': auth, 'X-Version': '3'}

    # Make request
    response = requests.get(url, data=data, headers=headers)
    strdata = response.content
    parsed = json.loads(strdata)
    #print(parsed)

    # Print status and body of response
    print('Response Status:', response.status_code)
    # print('Response Body:', response.content)

    for x in range(len(parsed['items'])):
    if parsed['items']['name'] == "system.groups":
    print(parsed['items']['value'])

    Hope it helps!

  • Anonymous's avatar
    Anonymous

    OP wanted to call /device/devices and filter based on the value of system.groups to only return devices where the system.groups value matches. 

  • OP wanted to call /device/devices and filter based on the value of system.groups to only return devices where the system.groups value matches. 

    I thought it might be helpful to be able to get to that property and then go from there.