Logstash-plugin elasticsearch: apply executing searches in logstash - elasticsearch

Here is my excuting search to query my elasticsearch database (it works fine):
curl -XPOST 'localhost:9200/test/_search?pretty' -d '
{
"size":1,
"query": {
"match": {
"log.device":"xxxx"
}
},
"sort" : [ {
"_timestamp" :
{
"order":"desc"
}
}]
}'
I want to do the same thing through logstash with the plugin elasticsearch. However, there is no "size" option available in the website https://www.elastic.co/guide/en/logstash/current/plugins-filters-elasticsearch.html
elasticsearch {
hosts => ["localhost:9200/test"]
query => "log.device:%{[log][device]}"
sort => "#timestamp:desc"
}
Do you how to manage this problem ?
Thank you for your attention and for your help.
Joe

Since the size is hardcoded to 1 in that plugin, you don't have to add any size parameter.
Also make sure to sort on _timestamp not #timestamp.
Finally, the hosts parameter doesn't take any index.
So:
elasticsearch {
hosts => ["localhost:9200"]
query => "log.device:%{[log][device]}"
sort => "_timestamp:desc"
}
If you really need to specify an index, this is not supported yet, but I've created a PR last week in order to support this. So until this gets merged and released, you'll be able to use my version instead of the official one:
$> git clone http://github.com/consulthys/logstash-filter-elasticsearch
$> cd logstash-filter-elasticsearch
$> gem build logstash-filter-elasticsearch.gemspec
$> $LS_HOME/bin/plugin -install logstash-filter-elasticsearch-2.0.4.gem
After installing the amended plugin, you'll be able to work on a specific index:
elasticsearch {
hosts => ["localhost:9200"]
index => "test"
query => "log.device:%{[log][device]}"
sort => "_timestamp:desc"
}

Related

Using Elasticsearch filter in logstash

I'm trying to use the elastic search filter on logstash for make some Data Enrichment.
I got two indexes, and my goal it's get some data from one of them and add it to the other.
I configured a logstash filter who search in my elasticsearch and if there is a match the output goes to the index.
But my filter it's not working propery because when I test the filter i got this error
[WARN ] 2020-10-02 19:23:09.536 [[main]>worker2] elasticsearch - Failed to query elasticsearch for previous event {:index=>"logstash-*", :error=>"Unexpected character ('%' (code 37)): expected a valid value (number, String, array, object, 'true', 'false' or 'null')\n
I think there it's some issue between the variable in the template and the elastic search
my logstash it's a 7.3.2 and my ES an 7.4.2
here it's my settings
Logstash.conf
input {
http{ }
}
filter {
elasticsearch {
hosts => ["127.0.0.1:9200"]
index => "logstash-*"
query_template => "search-by-ip.json"
fields => {
"id" => "[suscriberid]"
}
}
}
output {
stdout { codec => rubydebug }
}
-----------------
search-by-ip.json
{
"size": 1,
"query": { "match":{"IP": %{[ip]} } }
}
-------------------
testcase.sh
curl -XPOST "localhost:8080" -H "Content-Type: application/json" -d '{
"size": 1,
"query": { "match":{"ip": "192.168.1.4" }}
}'
```
Thanks!
If you ever process an event that does not have an [ip] field then the sprintf reference will not be substituted and you will get that error.
Note that ip and IP are different fields. Not sure if the %{[ip]} requires double quotes around it.

Logstash/Elasticsearch keep auto-mapping geoip to object instead of geo_point

I have some logs with the following format(I changed the IPs from public to private, but you get the idea):
192.168.0.1 [20/Nov/2019:16:09:28 +0000] GET /some_path HTTP/1.1 200 2 2
192.168.0.2 [20/Nov/2019:16:09:28 +0000] GET /some_path HTTP/1.1 200 2 2
I then grok these logs using the following pattern:
grok { match => { "message" => "%{IPORHOST:clientip} \[%{HTTPDATE:timestamp}\] %{WORD:method} %{URIPATHPARAM:request} %{DATA:httpversion} %{NUMBER:response} %{NUMBER:duration}" } }
geoip { source => "clientip" }
On my output section, I have the following code:
else if "host.name" in [host][name]{ #if statement with the hostname
elasticsearch {
hosts => "localhost:9200"
manage_template => false
index => "mms18-%{+YYYY.MM.dd}"
user => "admin-user"
password => "admin-password"
}
}
The problem is that when I go to Kibana the geoip.location is mapped as an object, and I can not use it on a map Dashboard.
Since the index's name changed daily, I can not manually put the correct geoip mapping, since I would have to do it every day.
One solution I thought that partially solves the problem is removing the date from the index in Logstash output, so it has a constant index of "mms18" and then using this on Kibana management console:
PUT mms18
{
"mappings": {
"properties": {
"geoip": {
"properties": {
"location": { "type": "geo_point" }
}
}
}
}
}
However, this is not ideal since I want to have the option of showing all the indexes with their respectful dates, and then choosing what to delete and what not.
Is there any way that I can achieve the correct mapping while also preserving the indexes with their dates?
Any help would be appreciated.
Use an index template (with a value for index_patterns like "mms-*") that maps geoip as a geo_point.

add custom mapping for elasticsearch in logstash

I am using logstash to input my logs in elasticsearch. Everyday, it create a new index
here is my output part of my logstash config file
output {
stdout { codec => rubydebug }
elasticsearch {
hosts => ["127.0.0.1"]
index => "logstash-%{+YYYY.MM.dd}"
}
}
I want some fields to be not analysed. But everyday when a new index is created, a new mapping is created and all the fields are analysed. How can I force elasticsearch to use a particular mapping every time a new index is created?
You can do this by assigning templates and managing them, for example my configuration:
elasticsearch {
hosts => ["localhost:9200"]
index => "XXX-%{+YYYY.ww}"
template => "/opt/logstash/templates/XXX.json"
template_name => "XXX"
manage_template => true
}
I believe my configuration may be slightly out of date, as we are sadly on an older version of logstash ... So it would be helpful to read up on this on the docs: https://www.elastic.co/guide/en/logstash/current/plugins-outputs-elasticsearch.html
This is definitely possible inside logstash though.
Artur
You can use a ES index template, which then will be used when creating an index: https://www.elastic.co/guide/en/elasticsearch/reference/2.4/indices-templates.html.
In your case the template would look like this:
{
"template": "logstash-*",
"mappings": {
"_default_": {
...
}
}
}

Insert aggregation results into an index

The goal is to build an Elasticsearch index with only the most recent documents in groups of related documents to track the current state of some monitoring counters and states.
I have crafted a simple Elasticsearch aggregation query:
{
"size": 0,
"aggs": {
"group_by_monitor": {
"terms": {
"field": "monitor_name"
},
"aggs": {
"get_latest": {
"top_hits": {
"size": 1,
"sort": [
{
"timestamp": {
"order": "desc"
}
}
]
}
}
}
}
}
}
It groups related documents into buckets and select the most recent document for each bucket.
Here are the different ideas I had to get the job done:
directly use the aggregation query to push the results into the index, but it does not seem possible : Is it possible to put the results of an ElasticSearch aggregation back into the index?
use the Logstash Elasticsearch input plugin to execute the aggregation query and the Elasticsearch output plugin to push into the index, but seems like the input plugin only looks at the hits field and is unable to handle aggregation results: Aggregation Query possible input ES plugin !
use the Logstash http_poller plugin to get a JSON document, but it does not seem to allow specifying a body for the HTTP request !
use the Logstash exec plugin to execute cURL commands to get the JSON but this seems quite cumbersome and my last resort.
use the NEST API to build a basic application that will do polling, extract results, clean them and inject the resulting documents into the target index, but I'd like to avoid adding a new tool to maintain.
Is there a reasonably complex way of accomplishing this?
Edit the logstash.conf file as follow
input {
elasticsearch {
hosts => "localhost"
index => "source_index_name"
type =>"index_type"
query => '{Query}'
size => 500
scroll => "5m"
docinfo => true
}
}
output {
elasticsearch {
index => "target_index_name"
document_id => "%{[#metadata][_id]}"
}
}

Get elasticsearch indices before specific date

My logstash service sends the logs to elasticsearch as daily indices.
elasticsearch {
hosts => [ "127.0.0.1:9200" ]
index => "%{type}-%{+YYYY.MM.dd}"
}
Does Elasticsearch provides the API to lookup the indices before specific date?
For example, how could I get the indices created before 2015-12-15 ?
The only time I really care about what indexes are created is when I want to close/delete them using curator. Curator has "age" type features built in, if that's also your use case.
I think you are looking for Indices Query have a look here
Here is an example:
GET /_search
{
"query": {
"indices" : {
"query": {
"term": {"description": "*"}
},
"indices" : ["2015-01-*", "2015-12-*"],
"no_match_query": "none"
}
}
}
Each index has a creation_date field.
Since the number of indices is supposed to be quite small there's no such feature as 'searching for indices'. So you just get their metadata and filter them inside your app. The creation_date is also available via _cat API.

Resources