Forum Discussion

Lewis_Beard's avatar
3 years ago

Logicmonitor_sdk filters are driving me insane. Please help?

So I've been trying to use the logicmonitor_sdk and it seems pretty good, but I keep getting stumped by the (in my opinion) completely barren documentation, at least thats how I view it.

In particular I'm struggling with filters. On the SDK page, if I look at GetDeviceDatasourceList ( https://www.logicmonitor.com/support-files/rest-api-developers-guide/sdks/docs/#api-LM-getDeviceDatasourceList ) the example filter says this:

        filter = filter_example # String | (optional)

I have no idea what to even do here. I have tried this but whether I leave the filter empty or use this one, I still get back ALL the datasources on my device, not just the one based on my custom one (31690755):

    datasource_filter = 'data_source_id:31690755'
    datasource_response = api_instance.get_device_datasource_list(device_id, fields="", size=1000, offset=0, filter=datasource_filter)
    datasource_dict = datasource_response.to_dict()
    datasource_list = datasource_dict["items"]
    print (datasource_list)
 

I am aware of the page discussing filters in general, but the SDK doesnt seem to exactly like it does when I'm doing the non-sdk approach. I DID manage to find an example on the communities page that let me filter on a property for other things (example: 'inheritedProperties.name:"SupportTeam",inheritedProperties.value:"WSAE"') so I was able to get my device list I wanted.

But ultimately I intend to call api_instance.get_device_datasource_instance_list, so I need the (local) id of the datasource, not the global one, data_source_id. So to get it I have to call get_device_datasource_list, but my filter isnt working. I'm still getting all of them.

I can obviously loop through them all and do an if for my custom name, but I should be able to filter it.

I guess the details dont matter, but I'm wondering:

tldr: how in the world in the sdk do you just filter for a single property and value? I've tried:

        'data_source_id:31690755'
        'data_source_id:"31690755"'
        'datasourceId:31690755'
        'datasourceId:"31690755"'
 

I am completely stumped. I hate to ask for help but I cannot for the life of me figure out how to make the filter do anything, and I cant find an sdk-specific version of the filter rules.

 

Thanks!

 

  • Anonymous's avatar
    Anonymous
    3 years ago

    How about this?

    from lm import lm # details on how to use this here: https://communities.logicmonitor.com/topic/7713-lm-wrapper-for-the-python-sdk/
    
    #replace with the global datasource id from which you want instances listed
    ds_global_id = 53
    
    # get the device list
    devices = {device.name:device.to_dict() for device in lm.get_device_list(size=1000).items}
    
    # loop through each device
    for k,device in devices.items():
        # get the list of datasources for the current device (this has to be done for every device, ug...)
        datasources = lm.get_device_datasource_list(device['id'],size=1000).items
        #create a new entry under each device to contain the datasources for that device
        device['datasources'] = [
            # let that entry only contain the information we need, global ds id, local ds id, ds name, and isntance count
            {"global_ds_id": ds.data_source_id,"name": ds.data_source_name,"local_ds_id": ds.id,"instance_number": ds.instance_number}
            for ds in datasources
            # only include datasources that actually have instances
            if ds.instance_number > 0 and ds.data_source_id == ds_global_id
        ]
        # loop through each datasource on the device that has instances
        for ds in device['datasources']:
            # call for the list of instances and store as a new entry on this datasource
            ds['instances'] = lm.get_device_datasource_instance_list(device_id=device['id'], hds_id=ds['local_ds_id']).items
    
    for device,v in devices.items(): #for each device
        for ds in v['datasources']: # for each datasource that has non-zero count of instances on the device
            for instance in ds['instances']: # for each instance in the non-zero count datasource
                print(f"{device},{ds['name']},{instance.name}")

     

  • Anonymous's avatar
    Anonymous
    4 minutes ago, Lewis Beard said:

    completely barren documentation

    Not just your opinion. Derives from the fact that LM uses Swagger to create their API, including the SDK, including the documentation. The documentation is written by a computer.

    Are you just trying to get one datasource? .get_datasource_by_id(id) maybe?

    Also, I constantly have problems with filters using the SDK. Even though it's built by a computer, the implementation of the parameters that are available in the API isn't always implemented the same on every SDK method. What I do is fetch all every time and use list /dict comprehension to get just the ones i want.

  • Ultimately I'm looping through a subset of my devices (that filter works) and for each one, I just want to get all the instances of my custom Network Interfaces, so that I can use a csv module in python to put them out to a csv WITH their ids, because I'm going to provide this to someone, and they are going to fill in some values, and then I'll read some thresholds in and set them in bulk by instance id. I know there is a report that generates these but I want to provide one that has the programming details (instance ids, device ids, etc) that will make setting them easier.

    So yeah, I know the global id of my custom source but the versions on my devices are unique to each device so I have to snag the local ones to use the command that gets interfaces by id.

  • Anonymous's avatar
    Anonymous

    How about this?

    from lm import lm # details on how to use this here: https://communities.logicmonitor.com/topic/7713-lm-wrapper-for-the-python-sdk/
    
    #replace with the global datasource id from which you want instances listed
    ds_global_id = 53
    
    # get the device list
    devices = {device.name:device.to_dict() for device in lm.get_device_list(size=1000).items}
    
    # loop through each device
    for k,device in devices.items():
        # get the list of datasources for the current device (this has to be done for every device, ug...)
        datasources = lm.get_device_datasource_list(device['id'],size=1000).items
        #create a new entry under each device to contain the datasources for that device
        device['datasources'] = [
            # let that entry only contain the information we need, global ds id, local ds id, ds name, and isntance count
            {"global_ds_id": ds.data_source_id,"name": ds.data_source_name,"local_ds_id": ds.id,"instance_number": ds.instance_number}
            for ds in datasources
            # only include datasources that actually have instances
            if ds.instance_number > 0 and ds.data_source_id == ds_global_id
        ]
        # loop through each datasource on the device that has instances
        for ds in device['datasources']:
            # call for the list of instances and store as a new entry on this datasource
            ds['instances'] = lm.get_device_datasource_instance_list(device_id=device['id'], hds_id=ds['local_ds_id']).items
    
    for device,v in devices.items(): #for each device
        for ds in v['datasources']: # for each datasource that has non-zero count of instances on the device
            for instance in ds['instances']: # for each instance in the non-zero count datasource
                print(f"{device},{ds['name']},{instance.name}")

     

  • I found a better way... Using Python3 and logicmonitor-sdk==3.0.213

    First, the key "data_source_id" key received in device object answer doesn't work as a filter, you have to remove the underscore and uppercase the next character like "dataSourceId" instead.

    Example :

        datasource_filter = "dataSourceId:1130"

    If there is a String as value, encapsulate with \"

        datasource_filter = "device_display_name:\"DEVICENAME\"" 

    For different Operators, look here:

    Operators : https://www.logicmonitor.com/support/rest-api-basic-filters

  • Thanks, I appreciate it. I managed to do something vaguely similar by the time you posted it, but I appreciate it.

    I just wish the filter was less of a mystery. :)/emoticons/smile@2x.png 2x" title=":)" width="20" />

    Cheers!