Create a watcher to check that the IP address of device is same or changing

I have a data set in which I want to check if each device's IP is the same or changed if it is the same then good if it is changing then notify alert or Jira ticket.

How do I make the watcher for that I am a novice in elastic so that's why I want your little help..

Are you familiar with Watcher? What you want to do is possible but it will need to be customized to your environment.

In a general sense, I think the easiest way to do this is to run the watch at a regular interval (for example, once per day) and then for each device, count the number of distinct IP addresses. And if that device has more than 1 IP, then clearly it's changed.

So for example, here's the query part of the Watch:

          "body": {
            "size": 0,
            "query": {
              "bool": {
                "filter": [
                  {
                    "range": {
                      "@timestamp": {
                        "gte": "now-1d/d",
                        "lte": "now"
                      }
                    }
                  }
                ]
              }
            },
            "aggs": {
              "devices": {
                "terms": {
                  "field": "devicename",
                  "size": 10000
                },
                "aggs": {
                  "distinct_ips": {
                    "cardinality": {
                      "field": "ip"
                    }
                  },
                  "ips": {
                    "terms": {
                      "field": "ip",
                      "size": 10000
                    }
                  }
                }
              }
            }
          }

And in the condition part, you could do something like:

    "condition": {
      "script": """
        return ctx.payload.aggregations.devices.buckets.stream().anyMatch(b -> b.distinct_ips.value > 1);
          """
    },

As for the actions section, you will need a transform section to filter and flatten the results. Something like:

        "transform": {
          "script": """
         return ctx.payload.aggregations.devices.buckets.stream().filter(b -> b.distinct_ips.value > 1).flatMap(b -> b.ips.buckets.stream().map(innerB -> ['ip':innerB.key,'device':b.key])).collect(Collectors.toList());
          """
        },

And when you actually alert you can iterate thought the output with something similar to:

         {{#ctx.payload._value}}
          device:{{device}} has {{ip}}
        {{/ctx.payload._value}}

to produce an output that looks like:

          device:foo has 168.72.100.1
          device:foo has 168.72.100.17

Full example here

The size specifies a maximum number of devices/IPs to aggregate on.

how can I check all devices with changing Ip in one day or in a single run?

This example, as constructed, will do that. It's just that the example data I used only had one instance of a device with a changing IP.

Thanks boss, that solution perfectly worked

1 Like

In this logic how we can trigger action in case of distinct is greater than 1 and the IPs in that object have any un-matched element in first 3 number of IP
e.g:
192.10.0.1
182.10.1.0

so in above case trigger action,

That should be the logic :slight_smile:

List<String> strings = Arrays.asList("193.168.10.0", "192.168.10.1", "192.168.10.2");
        System.out.println(strings.stream().allMatch(string ->
                strings.get(0).substring(0, 10).equals(string.substring(0, 10))));

In-case if IP has 255.192.100.1 the above logic won't work, means hard-coded value won't work.
so updated logic is like.

 String substringToBeMatched = strings.get(0).substring(0, strings.get(0).lastIndexOf(".")) ;
        System.out.println(strings.stream().allMatch(string ->
                substringToBeMatched
                        .equals(string.substring(0, string.lastIndexOf(".")))));

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.