3
votes

I have a project where I am to analyze and visualize access log data. I use Logstash to send data to Elasticsearch and then visualize some stuff with Kibana.
Everything has worked fine until I discovered that I needed the Path Hierarchy Analyzer to show what I want to. I now have a custom template (JSON) and changed the out section of my Logstash configuration. But when I index data, my template is not being applied.

(Version 5.2 of Elasticseach and Logstash, can't update since that is the version in use at the place where I work).

My JSON file is valid. As far as the input and filters go, my Logstash configuration is fine, too. I guess I made a mistake in the output.

I already tried setting manage_template to false. I also tried template_overwrite => "false" just for the sake of it.

I tried creating the index first (Kibana Dev Tools) and populating it after. I created the index template and then the index. That way my template was applied and when I created the index pattern, everything seemed correct. Then I indexed one of my log files. I ended up with a Courier Fetch Error. http://localhost:9200/_all/_mapping?pretty=1 showed my that while indexing my data a default template was being used instead of my custom one. Nothing was different from before adding a custom template.

I searched the web and read everything I could find on stackoverflow and in the elastic forum about custom templates not being applied. I tried out all the solutions provided there, that is why I ended up opting for a custom template saved locally and providing the path in my logstash output. But I am all out of ideas now.

This is the output of my logstash configuration:

output {

        elasticsearch { 

                hosts => ["localhost:9200"] 
                template => "/etc/logstash/conf.d/template.json" 
                index => "beam-%{+YYYY.MM.dd}"   
                manage_template => "true" 
                template_overwrite => "true" 
                document_type => "beamlogs"
        } 

        stdout {  
                codec => rubydebug 
        } 

}

And this is my custom template:

{
"template": "beam_custom",
"index_patterns": "beam-*",
"order" : 5,
"settings": {
    "number_of_shards": 1,
    "analysis": {
      "analyzer": {
        "custom_path_tree": {
          "tokenizer": "custom_hierarchy"
        },
        "custom_path_tree_reversed": {
          "tokenizer": "custom_hierarchy_reversed"
        }
      },
      "tokenizer": {
        "custom_hierarchy": {
          "type": "path_hierarchy",
          "delimiter": "/"
        },
        "custom_hierarchy_reversed": {
          "type": "path_hierarchy",
          "delimiter": "/",
          "reverse": "true"
        }
      }
    }
  },
  "mappings": {
    "beamlogs": {
    "properties": {
      "object": {
        "type": "text",
        "fields": {
          "tree": {
            "type": "text",
            "analyzer": "custom_path_tree"
          },
          "tree_reversed": {
            "type": "text",
            "analyzer": "custom_path_tree_reversed"
          }
        }
      },
      "referral": {
        "type": "text",
        "fields": {
          "tree": {
            "type": "text",
            "analyzer": "custom_path_tree"
          },
          "tree_reversed": {
            "type": "text",
            "analyzer": "custom_path_tree_reversed"
          }
        }
      },
      "@timestamp" : {
            "type" : "date"
      },
      "action" : {
            "type" : "text",
            "fields" : {
              "keyword" : {
                "type" : "keyword"
              }
            }
          },
          "datetime" : {
            "type" : "date",
            "format": "time_no_millis",
            "fields" : {
              "keyword" : {
                "type": "keyword"
              }
            }
          },
          "id" : {
            "type" : "text",
            "fields" : {
              "keyword" : {
                "type" : "keyword"
              }
            }
          },
          "info" : {
            "type" : "text",
            "fields" : {
              "keyword" : {
                "type" : "keyword"
              }
            }
          },
          "message" : {
            "type" : "text",
            "fields" : {
              "keyword" : {
                "type" : "keyword"
              }
            }
          },
          "page" : {
            "type" : "text",
            "fields" : {
              "keyword" : {
                "type" : "keyword"
              }
            }
          },
          "path" : {
            "type" : "text",
            "fields" : {
              "keyword" : {
                "type" : "keyword"
              }
            }
          },
          "result" : {
            "type" : "long"
          },
          "s_direct" : {
            "type" : "text",
            "fields" : {
              "keyword" : {
                "type" : "keyword"
              }
            }
          },
          "s_limit" : {
            "type" : "text",
            "fields" : {
              "keyword" : {
                "type" : "keyword"
              }
            }
          },
          "s_mobile" : {
            "type" : "text",
            "fields" : {
              "keyword" : {
                "type" : "keyword"
              }
            }
          },
          "s_terms" : {
            "type" : "text",
            "fields" : {
              "keyword" : {
                "type" : "keyword"
              }
            }
          },
          "size" : {
            "type" : "long"
          },
          "sort" : {
            "type" : "text",
            "fields" : {
              "keyword" : {
                "type" : "keyword"
              }
            }
          }
      }
    }
  }
}

After indexing my data this is part of what I get with http://localhost:9200/_all/_mapping?pretty=1

"datetime" : {
            "type" : "text",
            "fields" : {
              "keyword" : {
                "type" : "keyword",
                "ignore_above" : 256
              }
            }
          },
"object" : {
            "type" : "text",
            "fields" : {
              "keyword" : {
                "type" : "keyword",
                "ignore_above" : 256
              }
            }
          },

datetime should not have the type text. But worse than that, fields like objet.tree are not even created.

I really don't care about the wrong mapping for datetime, but I need to get the Path Hierarchy Analyzer to work. I just don't know what to do anymore.


So. What I just tried was creating the index template in Kibana.

PUT _template/beam_custom
/followed by what is in my template.json

I then checked if the template was created.

GET _template/beam_custom

The output was this:

    {
      "beam_custom": {
        "order": 100,
        "template": "beam_custom",
        "settings": {
          "index": {
            "analysis": {
              "analyzer": {
                "custom_path_tree_reversed": {
                  "tokenizer": "custom_hierarchy_reversed"
                },
                "custom_path_tree": {
                  "tokenizer": "custom_hierarchy"
                }
              },
              "tokenizer": {
                "custom_hierarchy": {
                  "type": "path_hierarchy",
                  "delimiter": "/"
                },
        ...

So I guess creating the template worked.

Then I created an index

    PUT beam-2019-07-15

But when I checked the index, I got this:

    {
  "beam-2019.07.15": {
    "aliases": {},
    "mappings": {},
    "settings": {
      "index": {
        "creation_date": "1563044670605",
        "number_of_shards": "5",
        "number_of_replicas": "1",
        "uuid": "rGzplctSQDmrI_NSlt47hQ",
        "version": {
          "created": "5061699"
        },
        "provided_name": "beam-2019.07.15"
      }
    }
  }
}

Shouldn't the index pattern have been recognized? I think this is the heart of the problem. I thought that my template would have been used and the output should have been something like this instead:

{
  "beam-2019.07.15": {
    "aliases": {},
    "mappings": {
      "logs": {
        "properties": {
          "@timestamp": {
            "type": "date"
          },
          "action": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword"
              }
            }
          },...

Why doesn't it recognize the pattern?

1

1 Answers

2
votes

So, I found the mistake.

When I looked up how to build my own template, at some point I looked at the documentation for the current version. But in 5.2., "index_patterns =>" doesn't exist.

"template": "beam_custom",
"index_patterns": "beam-*",

This doesn't work then, of course.

Instead, I dropped the "index_patterns" line and defined my pattern in the template-parameter.

"template": ["beam-*"],
//rest

This fixed the problem. After that, my pattern was recognized.

Yet I am facing a different problem now. The Path Hierarchy Analyzer is not working properly. object.tree and the rest of the fields I want are not being created.

GET beam-*/_search
{
"query": {
"term": {
"object.tree": "/belletristik/"
}
}
}

yields nothing, though I should have a few hundred hits. Looking at my data, there are no analyzed fields for my paths. Any ideas?