Search code examples
pythonelasticsearchmetricbeat

How to Query Elasticsearch to get specific metricbeatdata?


In my current setup I have elasticsearch running in my network on 192.168.1.35:9200 And a metricbeat on 192.168.1.40 that is gathering metrics from that machine (192.168.1.40). My metricbeat.yml looks like this

metricbeat.modules:
- module: system
  metricsets:
    - core
    - cpu
    - filesystem
    - memory
    - network
    - process
  cgroups: true
  enabled: true
  period: 10
  procs: [".*"]
  cpu_ticks: false


output.elasticsearch:
  hosts: ['192.68.1.35:9200']

In my python code I'm using the Elasticsearch API to query my Elasticsearch:

def es_match_all():
    elasticsearch = Elasticsearch(
    ['192.168.1.35'],
    port=9200,
    )
    result = elasticsearch.search(index='metricbeat-*', body={"query":{"match_all": {}}})
    print(result)

When this method is called, I get the results I want. I printed a shorter version underneath:

{"hits": {"total": 2375277, "hits": [{"_id": "AVmI873zkPW_EI4mzGOc", "_source": {"beat": {"hostname": "ip-172-31-53-117", "name": "ip-172-31-53-117", "version": "5.1.1"}, "system": {"memory": {"total": 3945406464, "free": 2389319680, "swap": {"total": 0, "free": 0, "used": {"bytes": 0, "pct": 0.0}}, "used": {"bytes": 1556086784, "pct": 0.3944}, "actual": {"free": 3663335424, "used": {"bytes": 282071040, "pct": 0.0715}}}}, "type": "metricsets", "@timestamp": "2017-01-10T15:16:32.108Z", "metricset": {"module": "system", "name": "memory", "rtt": 97}}, "_score": 1.0, "_type": "metricsets", "_index": "metricbeat-2017.01.10"} ...

Now I want to query ES to get just some infromation for a specific hostname (ip-172-31-53-117):

def es_match_hostname():
    elasticsearch = Elasticsearch(
    ['192.168.1.35'],
    port=9200,
    )
    result = elasticsearch.search(
        index='metricbeat-*',
        body={"query": {"match": {'hostname': "ip-172-31-53-117"}}}
        )

but then I got the following result when the method was called:

{"hits": {"total": 0, "hits": [], "max_score": null}, "_shards": {"total": 10, "failed": 0, "successful": 10}, "took": 11, "timed_out": false}

So my ES configuration and index are right but I don't find how to write the right query to get that information. What should I use as my body in my elasticsearch.search call


Solution

  • I found a solution where you use querystring instead of match. I visualized my metricbeat in Kibana and noticed that I could query there if I used beat.name or beat.hostname. I got this code:

    def es_match_hostname():
        elasticsearch = Elasticsearch(
        ['192.168.1.35'],
        port=9200,
        )
        match = "beat.name: ip-172-31-53-117*"
        result = elasticsearch.search(
            index='metricbeat-*',
            body={"query":{"query_string":{"query": match, "analyze_wildcard":True}}}
            )
    

    By doing this I only got the results from that specific beat.