Forum Discussion

Eugene_C's avatar
8 years ago

Set threshold for specific instance on all devices

It'd be great to be able to configure threshold for an instance on all devices at once.

Right now i can either configure threshold on a specific device or edit global definitions for a datapoint, and this will apply to all instances.

In my case, I have several instances under DotNet - .Net CLR Memory (RTW.Scheduler is one of them) and i'd like to configure threshold for NumBytesinallHeaps for instance RTW.Scheduler for all devices at once.

Another situation is when we want to set different thresholds for drives C and D for all devices.

  • I found this impossible without an API script.  I initially wrote one to address the non-group-ness of instance groups (like groups of drives), but my script handles device groups, DSes and DS instances, too.   No idea if/when anything like that will be possible in the UI, but at least there is an API approach possible!  The logic is in the code below, though this relies on a module I wrote to encapsulate the API access stuff.  Still, hopefully useful.

    Mark

    verbose 2, "scanning device group $DEVICEGROUP\n";
    if (my $groups  = $lmapi->get_all(path => "/device/groups", filter => "name:$DEVICEGROUP")) {
        if (@$groups == 1) {
            my $devices  = $lmapi->get_all(path => "/device/groups/$groups->[0]->{id}/devices");
            for my $device (@$devices) {
                my $deviceName = $device->{displayName};
                verbose 2, "scanning device $deviceName\n";
                my $devicedatasources  = $lmapi->get_all(path => "/device/devices/$device->{id}/devicedatasources", filter=>"dataSourceName:$DATASOURCENAME");
                for my $devicedatasource (@$devicedatasources) {
                    my @dsfilter;
                    if (defined $INSTANCEGROUP) {
                        @dsfilter = ( filter=>"groupName${INSTANCEGROUPOP}${INSTANCEGROUP}" );
                    }
                    my $instances  = $lmapi->get_all(path => "/device/devices/$device->{id}/devicedatasources/$devicedatasource->{id}/instances", @dsfilter);
                    for my $instance (@$instances) {
                        my $alertsettingspath = "/device/devices/$device->{id}/devicedatasources/$devicedatasource->{id}/instances/$instance->{id}/alertsettings";
                        if (my $alertsettings = $lmapi->get_all(path => $alertsettingspath, filter=>"dataPointName:$DATAPOINTNAME")) {
                            my $myAlertExpr = $alertsettings->[0]->{alertExpr};
                            for my $alertsetting (@$alertsettings) {
                                verbose 2, sprintf(" current alert settings: %s: alertExpr=%s\n", $alertsetting->{dataSourceInstanceAlias}, $myAlertExpr);

                                my $content;
                                if (not defined $ALERTEXPR) {
                                    $content = to_json({ });
                                }
                                elsif ($ALERTEXPR ne $myAlertExpr) {
                                    $content = to_json({ alertExpr => $ALERTEXPR });
                                }
                                if (defined $content) {
                                    verbose 1, "committing change to $device->{displayName}:$alertsetting->{dataSourceInstanceAlias}:${DATASOURCENAME}:${DATAPOINTNAME}\n\t$content\n";
                                    if ($DRYRUN) {
                                        print qq(put(path => "$alertsettingspath/$alertsettings->[0]->{id}", content => $content)), "\n";
                                    }
                                    else {
                                        $lmapi->put(path => "$alertsettingspath/$alertsettings->[0]->{id}", content => $content);
                                    }
                                }
                            }
                        }
                        else {
                            warn "ERROR: failed to get alertsettings: path = $alertsettingspath\n";
                        }
                    }
                }
            }
        }
        else {
            warn "ERROR: found @{[scalar @$groups]} device groups when enumerating device group: $DEVICEGROUP\n";
        }
    }
    else {
        warn "ERROR: unable to enumerate device group: $DEVICEGROUP\n";
    }

  • Mark, thank you for the idea.

    I ended up creating new datasource that is the copy of the datasource i need (.NETCLRMemory in my case) but with filter to discover only one instance that i need (RTW.Scheduler). After that i set appropriate threshold for all devices at once.

    I don't think that it's a good idea (because i actually run the same datasource twice on each device) but i could do it with UI :)/emoticons/smile@2x.png 2x" title=":)" width="20">

  • Understood.  I think that cloning in its current form creates the equivalent of unmaintainable spaghetti code, so I try to avoid it as much as possible even though it is the GOTO (:)) solution for tech support.  Glad you found a way out, though :).

    Regards,
    Mark