How to apply sub-filter in logstash - filter

the logstash allows to extract patterns via grok filter. My question is how I can use it in sub-sequent filter? For instance, the apache log provides the URI path of the query, something like /path/api?param1=1&param2. I can extract the whole thing in grok filter and assign to attribute request. Now I want to decompose it into different parts. My question is how I can use request attribute and split it further in order to get /path, api, params? Can someone provide an example?
Thanks,
Valentin.

You can use a second grok filter on a newly created field, like this:
grok {
match => { "request" => Your pattern here }
}

Related

How to get Json in Grok Logstash

So currently I'm building a log system using ELK Stack. Before building this ELK, I already have custom log format for my apps, so that it can be easily read by human. My log is formatted something like this
Method: POST
URL: https://localhost:8888/api
Body: {
"field1":"value1",
"field2":[
{
"field3":"value2",
"field4":"value3"
},
{
"field3":"value2",
"field4":"value3"
},
]
}
using grok pattern, I can get the Method and the URL, but how can I get the full body json in grok / logstash so that i can send them to elasticsearch?
Since the length of the json is not fixed and can be longer or shorter each log
Thank you
You can use the JSON Filter.
It should parse the JSON for you, and put it into a structured format so you can then send it where ever you need (e.g. Elasticsearch, another pipeline)
From the docs
It takes an existing field which contains JSON and expands it into an actual data
structure within the Logstash event.
There are also some other questions here on SO that could be helpful. An example: Using JSON with LogStash

access fields from log using ruby filter

What I am trying to do is pass my grok fields in some way or another to an external ruby filter-script and set based on these fields specific tags. The problem is that I can only get the whole log message with the event API.
My question is: is it possible to access fields from the already processed log message in the ruby filter or do I have to parse the whole message myself, which would not be optimal because every log message is processed twice? Alternatively I could completely dump the grok filter and do everything myself in the script.
Yes, it is possible.
You can get read-only access to any field using Event API
filter {
ruby {
code => 'event.get("foo" )'
}
}
field can also be a nested field reference such as [field][bar].
event.get("[foo][bar]")

How to format logs in filebeat

I am very new to filebeat and elasticsearch. I am doing a hobby project and I want to parse my data files. each data files contains the information's as mentioned below format,
<name>
<question>
<ans1>
<ans2>
<ans3>
..etc
I want to read this data and store in es like
{
id : <separate_id_for_each_file>,
name: <name>,
question: <question>,
ans1: <ans1>, ..etc
}
How can I do this with filebeat?
As of now, you can't do this with filebeat.
You will need to send your log to logstash, then transform it usign a plugin like grok and then send it to elastic, if you wish to add a id to the log, you can use something like the uuid plugin before sending it to grok.
Filebeat aims only to be the harvest witch will read your logs and send then forward
So your flow would be something like: filebeat > LOGSTASH[uuid,grok] > ElasticSearch
If you need examples of grok patterns, these can be usefull:
Collection of grok patterns:
https://github.com/logstash-plugins/logstash-patterns-core/blob/master/patterns/grok-patterns
Grok pattern tester:
http://grokconstructor.appspot.com/do/match

Spring MVC REST API to Filter/Search from Collection

I have a REST service /accounts which returns all the accounts data (Number, Name).
Requirement :
Should Support the below search/filter pattern with any combination of "And" or "OR" rather than retruning the entire collection.
startsWith
endsWith
Contains
Question 1 : Are these below API design correct(RESTful) or any better way to do the same
e.g -
/accounts?name^My Account 123**or**number~ACC1234
(^"==> Starts with , "~"==> ends with)
/accounts?name^My Account 123**and**number~ACC1234
(^"==> Starts with "~"==> ends with)
/accounts?name$ACC123
($ ==> account collection contains ACC123)
Spring Controller:
Planning to get these Filter (Query Parameter) pattern as #RequestParam and have a Regex to parse the pattern and then apply & retrieve it from the data store. The downside is any new filter pattern would need a change in the Controller class.
Question 2: Is there any out of the box features available in Spring 3 to do search / filter from a collection?
Thanks!
From a design perspective, using Query parameters to specify search / filter parameters is fine. However, for more complex cases such as yours, I typically define a new end point, that only deals with searches.
As an example, if my logic for search is strictly "or" and "contains", I would define a book search as such:
GET /books/?author=john&keywords=how%20to%20use%20spring
Here, my API is strictly going to search for books where the author's name contains "john" and the words "how to use spring" appear in the content. The Search logic stays consistent, and the client has no flexibility.
In your case, if the client has the ability to specific their own search criteria, you need to build out a new end point, something like:
POST /books/search
And in the request body, post your own search criteria DSL like name^My Account 123**and**number~ACC1234

Grok pattern for Logstash using HTTP POST request as input

I'm using Logstash to process my logs and store them to Elastic Search.
I'm using http as input plugin for my logstash.
My http post request is:
$http.post(url, {type: 'reference error', message: 'y is not defined'});
I would like to store the type and message key as different fields in Elastic Search.
Currently all of the post data is stored as a single field like:
"message":"{\"type\":\"ReferenceError\",\"message\":\"y is not
defined\"}"
I think this can be done using grok filter but I have not been able to find a way to do this.
Any help is highly appreciated.
Thanks.
If you use the json codec, the information should be split out into fields for you automatically.
EDIT:
As Alain mentioned it is the best way to use the json codec which can be set directly in your http input plugin. If that is not possible for some reason you can use the grok filter.
If I understand you correctly your incoming event looks like this:
{"type": "reference error", "message": "y is not defined"}
Then a corresponding grok pattern would look like this:
{"type": %{QUOTEDSTRING:http_type}, "message": %{QUOTEDSTRING:http_message}}
In your logstash configuration:
grok {
match => [ "message", "{\"type\": %{QUOTEDSTRING:http_type}, \"message\": %{QUOTEDSTRING:http_message}}" ]
}
Then the result will have the two fields http_type and http_message.

Resources