Elastalert: New Term ruletype can't recognize old term after restart alert process

Created on 18 Jul 2017  ·  3Comments  ·  Source: Yelp/elastalert

I'm using metricbeat to collect system information of 57 machines.
If there is any new server start to send message through metricbeat, elastalert should send notification to administrators.

As far as I know, it should query documents in 7 days (terms_window_size setting), if there is any new term appear but not include in the past 7 days, it should send alert message.

My rule config is working without any error messages, but it send 57 alert message when I restart the alert process or change the rule config everytime.
Is that normal? Or how could I modify the rule config to avoid the false alert when restart the alert process?
Any help or guidance would be greatly appreciated!

My rule config:

name: Alert New Server
index: metricbeat-*
type: new_term

fields:
  - "beat.hostname"

query_key: beat.hostname
terms_window_size:
  days: 7

realert:
  minutes: 0

filter:
- term:
    metricset.name: "cpu"
- term:
    type: "metricsets"

alert:
- "email"

email:
- "[email protected]"
help wanted

Most helpful comment

Fixed the issue by changing one line in ruletypes.py.

I saw this message in the log file. The field name is correct but it can't find any values of the field.

INFO:elastalert:Found no values for beat.hostname

And I also print the query string and query result, the bucket is empty. I guess that's the reason why it can't find any values.
Query String:

{
    ......
    "aggs": {
        "values": {
        "terms": {
             "field": "beat.hostname.keyword",
             "size": 2147483647
    ......
}

Query Result:

......
  "aggregations": {
    "filtered": {
      "doc_count": 2073026,
      "values": {
        "doc_count_error_upper_bound": 0,
        "sum_other_doc_count": 0,
        "buckets": []
      }
    }
  }

Then, I found this line in ruletypes.py changed the field name.

field_name['field'] = add_raw_postfix(field, self.is_five())

It will check elasticsearch version, if it's 5.0, then add .keyword after the field name.

def add_raw_postfix(field, is_five):
    if is_five:
        end = '.keyword'
    else:
        end = '.raw'
    if not field.endswith(end):
        field += end
    return field

I'm not sure why elasticsearch can't recognize beat.hostname.keyword, beat.hostname is keyword type in the index.

"beat": {
            "properties": {
              "hostname": {
                "type": "keyword",
                "ignore_above": 1024
              }

Anyway, I changed the line into this, and it's working. Weird.

field_name['field'] = field

All 3 comments

Fixed the issue by changing one line in ruletypes.py.

I saw this message in the log file. The field name is correct but it can't find any values of the field.

INFO:elastalert:Found no values for beat.hostname

And I also print the query string and query result, the bucket is empty. I guess that's the reason why it can't find any values.
Query String:

{
    ......
    "aggs": {
        "values": {
        "terms": {
             "field": "beat.hostname.keyword",
             "size": 2147483647
    ......
}

Query Result:

......
  "aggregations": {
    "filtered": {
      "doc_count": 2073026,
      "values": {
        "doc_count_error_upper_bound": 0,
        "sum_other_doc_count": 0,
        "buckets": []
      }
    }
  }

Then, I found this line in ruletypes.py changed the field name.

field_name['field'] = add_raw_postfix(field, self.is_five())

It will check elasticsearch version, if it's 5.0, then add .keyword after the field name.

def add_raw_postfix(field, is_five):
    if is_five:
        end = '.keyword'
    else:
        end = '.raw'
    if not field.endswith(end):
        field += end
    return field

I'm not sure why elasticsearch can't recognize beat.hostname.keyword, beat.hostname is keyword type in the index.

"beat": {
            "properties": {
              "hostname": {
                "type": "keyword",
                "ignore_above": 1024
              }

Anyway, I changed the line into this, and it's working. Weird.

field_name['field'] = field

For Elasticsearch 1 and 2, the ".raw" prefix for non-analyzed fields was a logstash specific thing. If you used logstash and prefixed indexes with "logstash-", it would automatically create this field.

I'm not sure if that still applies for Elasticsearch 5 and ".keyword". We should definitely add an option to disable this if you currently can't.

I am using elasticsearch 6 and also have this issue. Made the same change and it worked.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

aromualdo picture aromualdo  ·  4Comments

tkumark picture tkumark  ·  3Comments

junaid1460 picture junaid1460  ·  3Comments

Eyad87 picture Eyad87  ·  4Comments

wjk1982 picture wjk1982  ·  3Comments