logstash output not showing the desired timestamp - logstash

I am trying to get the desired time stamp format from logstash output. I can''t get that if I use this format in syslog
Please share your thoughts about convert to the other format that’s in the _source field like Yyyy-mm-ddThh:mm:ss.sssZ format?
filter {
grok {
match => [ "logdate", "Yyyy-mm-ddThh:mm:ss.sssZ" ]
overwrite => ["host", "message"]
}
_source: {
message: "activity_log: {"created_at":1421114642210,"actor_ip":"192.168.1.1","note":"From system","user":"4561c9d7aaa9705a25f66d","user_id":null,"actor":"4561c9d7aaa9705a25f66d","actor_id":null,"org_id":null,"action":"user.failed_login","data":{"transaction_id":"d6768c473e366594","name":"user.failed_login","timing":{"start":1422127860691,"end":14288720480691,"duration":0.00257},"actor_locatio
I am using this code in syslog file
filter {
if [message] =~ /^activity_log: / {
grok {
match => ["message", "^activity_log: %{GREEDYDATA:json_message}"]
}
json {
source => "json_message"
remove_field => "json_message"
}
date {
match => ["created_at", "UNIX_MS"]
}
mutate {
rename => ["[json][repo]", "repo"]
remove_field => "json"
}
}
}
output {
elasticsearch { host => localhost }
stdout { codec => rubydebug }
}
thanks
"message" => "<134>feb 1 20:06:12 {\"created_at\":1422765535789, pid=5450 tid=28643 version=b0b45ac proto=http ip=192.168.1.1 duration_ms=0.165809 fs_sent=0 fs_recv=0 client_recv=386 client_sent=0 log_level=INFO msg=\"http op done: (401)\" code=401" }
"#version" => "1",
"#timestamp" => "2015-02-01T20:06:12.726Z",
"type" => "activity_log",
"host" => "192.168.1.1"

The pattern in your grok filter doesn't make sense. You're using a Joda-Time pattern (normally used for the date filter) and not a grok pattern.
It seems your message field contains a JSON object. That's good, because it makes it easy to parse. Extract the part that comes after "activity_log: " to a temporary json_message field,
grok {
match => ["message", "^activity_log: %{GREEDYDATA:json_message}"]
}
and parse that field as JSON with the json filter (removing the temporary field if the operation was successful):
json {
source => "json_message"
remove_field => ["json_message"]
}
Now you should have the fields from the original message field at the top level of your message, including the created_at field with the timestamp you want to extract. That number is the number of milliseconds since the epoch so you can use the UNIX_MS pattern in a date filter to extract it into #timestamp:
date {
match => ["created_at", "UNIX_MS"]
}

Related

Logstash date is not working with HH:mm:ss.SSS but working with HH:mm:ss,SSS

when i check the elasticsearch output it seems not correct with timestamp it is displaying
For HH:mm:ss.SSS (not working correctly) -> apache.log
"message" : "[DEBUG] 2020-12-05 12:26:18.254...
"#timestamp" : "2021-01-11T03:31:10.314Z",
For HH:mm:ss,SSS (working correctly) -> eai_new.log
"timestamp" : "2020-11-23 06:05:05,297",
"message" : "2020-11-23 06:05:05,297
"#timestamp" : "2020-11-22T22:05:05.297Z"
Besides that what the difference between timestamp and #timestamp?
Below is my logstash code
filter {
if [name_of_log] in ["apache"] {
grok {
match => { "message" => "\[%{LOGLEVEL:level}\] %{TIMESTAMP_ISO8601:timestamp} %{GREEDYDATA:msg}" }
}
date {
match => [ "timestamp" , "yyyy-MM-dd HH:mm:ss.SSS" ]
}
} else {
grok {
match => { "message" => "%{TIMESTAMP_ISO8601:timestamp} %{LOGLEVEL:level} %{GREEDYDATA:msg}" }
}
date {
match => [ "timestamp" , "yyyy-MM-dd HH:mm:ss,SSS" ]
}
}
}
The date filter in logstash have a targeted field where it put the value that just will be parsed. This name of the default field is #timestamp.
So when data parsing is ok, the result of the parsing process is saved in the field #timestamp.
You have more details here about the date filter of logstash.
If the parsing operation doesn't work, the #timestamp is put by elsaticsearch himself and the value corresponding of the date of insertion into elasticsearch side. This is the default behaviour if you haven't set a specific configuration (for mapping) in your elasticsearch example.
The timestamp field is set during your grok operation. In your code, this set the timestamp field {TIMESTAMP_ISO8601:timestamp} in this part of logstash filter configuration:
grok {
match => { "message" => "\[%{LOGLEVEL:level}\] %{TIMESTAMP_ISO8601:timestamp} %{GREEDYDATA:msg}" }
}

Logstash 6.2.4 - match time does not default to current date

I am using logstash 6.2.4 with the following config:
input {
stdin { }
}
filter {
date {
match => [ "message","HH:mm:ss" ]
}
}
output {
stdout { }
}
With the following input:
10:15:20
I get this output:
{
"message" => "10:15:20",
"#version" => "1",
"host" => "DESKTOP-65E12L2",
"#timestamp" => 2019-01-01T09:15:20.000Z
}
I have just a time information, but would like to parse it as current date.
Note that current date is 1. March 2019, so I guess that 2019-01-01 is some sort of default ?
How can I parse time information and add current date information to it ?
I am not really interested in any replace or other blocks as according to the documentation, parsing the time should default to current date.
You need to add a new field merging the current date with the field that contains your time information, which in your example is the message field, then your date filter will need to be tested against this new field, you can do this using the following configuration.
filter {
mutate {
add_field => { "current_date" => "%{+YYYY-MM-dd} %{message}" }
}
date {
match => ["current_date", "YYYY-MM-dd HH:mm:ss" ]
}
}
The result will be something like this:
{
"current_date" => "2019-03-03 10:15:20",
"#timestamp" => 2019-03-03T13:15:20.000Z,
"host" => "elk",
"message" => "10:15:20",
"#version" => "1"
}

_dateparsefailure when the date already has a match

I'm trying to config logstash to process some test log, but I keep getting a dateparsefailure and I don't understand why. My input is
2016-09-18 00:00:02,013 UTC, idf="639b26a731284b43beac8b26f829bcab"
And my config (I've also tried including the timezone into the pattern):
input {
file {
path => "/tmp/test.log"
start_position => "beginning"
}
}
filter {
date {
match => ["message", "yyyy-MM-dd HH:mm:ss,SSS"]
timezone => "UTC"
add_field => { "debug" => "timestampMatched"}
}
grok {
match => { "message" => "%{YEAR:year}-%{MONTHNUM:month}-%{MONTHDAY:day} %{HOUR:hour}:%{MINUTE:minute}:%{SECOND:second},%{NUMBER:milis} UTC, idf=\"%{WORD:idf}\""}
}
}
output {
elasticsearch {
hosts => ["localhost:9200"]
}
stdout {
codec => rubydebug
}
}
Finaly, the error:
{:timestamp=>"2016-09-21T10:04:32.060000+0000", :message=>"Failed parsing date from field", :field=>"message", :value=>"2016-09-18 00:00:02,013 UTC, idf=\"639b26a731284b43beac8b26f829bcab\"", :exception=>"Invalid format: \"2016-09-18 00:00:02,013 UTC, idf=\"639b26a731284b4...\" is malformed at \" UTC, idf=\"639b26a731284b4...\"", :config_parsers=>"yyyy-MM-dd HH:mm:ss,SSS", :config_locale=>"default=en_US", :level=>:warn, :file=>"logstash/filters/date.rb", :line=>"354", :method=>"filter"}
It says that the date it is malformed after the end of it. Why does this happen, shouldn't it 'stop searching' since the date has already a match?
Before you can use the date filter, you first have to use grok to separate the date and the rest of the message. The date filter only accepts a timestamp. If you have any other information in the field the error you are describing will occur.
Using your provided logline I would recommend this:
filter {
grok {
match => { "message" => "%{TIMESTAMP_ISO8601:timedate} %{GREEDYDATA}"}
}
date {
match => [ "timedate" => "yyyy-MM-dd HH:mm:ss,SSS"]
}
}
In this minimal example I match the timestamp in the timedate field and then crunch it trough the date filter.

Kibana does not show fields from grok filter in filebeat

I have log file with apache logs that i want to show in Kibana.
The logs start with IP. I have debuged my pattern and it passes.
I'm trying to add fields in the beats input configuration file, but are not show in Kibana even after refresh of the fields.
Here is the configuration file
filter {
if[type] == "apache" {
grok {
match => { "message" => "%{HOST:log_host}%{GREEDYDATA:remaining}" }
add_field => { "testip" => "%{log_host}" }
add_field => { "data_left" => "%{remaining}" }
}
}
...
Just to add that I have restarted all the services: logstash, elasticsearch, kibana after the new configuration.
The issue could be that your grok pattern is using too rigid of patterns.
Chances are that HOST should be IPORHOST based on your test_ip field's name.
Assuming that the data is actually coming in with the type defined as apache, then it should be:
filter {
if [type] == "apache" {
grok {
match => {
message => "%{IPORHOST:log_host}%{GREEDYDATA:remaining}"
}
add_field => {
testip => "%{log_host}"
data_left => "%{remaining}"
}
}
}
}
Having said that, your usage of add_field is completely unnecessary. The grok pattern itself is creating two fields: log_host and remaining, so there's no need to define extra fields called testip and data_left.
Perhaps even more usefully, you don't need to craft your own Apache web log grok pattern. The COMBINEDAPACHELOG pattern already exists, which gives all of the standard fields automatically.
filter {
if [type] == "apache" {
grok {
match => { "message" => "%{COMBINEDAPACHELOG}" }
}
# Set #timestamp to the log's time and drop the unneeded timestamp
date {
match => [ "timestamp" , "dd/MMM/yyyy:HH:mm:ss Z" ]
remove_field => "timestamp"
}
}
}
You can see this in a more complete example in the Logstash documentation here.

LogStash: How to make a copy of the #timestamp field while maintaining the same time format?

I would like to create a copy of the #timestamp field such that it uses the same format as #timestamp.
I've tried the following:
mutate
{
add_field => ["read_time", "%{#timestamp}"]
}
but while #timestamp is in the format: 2014-08-01T18:34:46.824Z,
the read_time is in this format 2014-08-01 18:34:46.824 UTC
This is an issue as Kibana doesn't understand the "UTC" format for histograms.
Is there a way using the date filter to do this?
Kibana can't understand because the read_time field is a string, not a timestamp!
You can use ruby filter to do what you need. Just copy the #timestamp to a new field read_time and the field time is in timestamp, not string. The add_field is add a new field with string type!
Here is my config:
input {
stdin{}
}
filter {
ruby {
code => "event['read_time'] = event['#timestamp']"
}
mutate
{
add_field => ["read_time_string", "%{#timestamp}"]
}
}
output {
stdout {
codec => "rubydebug"
}
}
You can try and see the output, the output is:
{
"message" => "3243242",
"#version" => "1",
"#timestamp" => "2014-08-08T01:09:49.647Z",
"host" => "BENLIM",
"read_time" => "2014-08-08T01:09:49.647Z",
"read_time_string" => "2014-08-08 01:09:49 UTC"
}
Hope this can help you.
You don't need to run any Ruby code. You can just use the add_field setting of the Mutate filter plugin:
mutate {
# Preserve "#timestamp" as "logstash_intake_timestamp"
add_field => { "logstash_intake_timestamp"=> "%{#timestamp}" }
}
date {
# Redefines "#timestamp" field from parsed timestamp, rather than its default value (time of ingestion by Logstash)
# FIXME: include timezone:
match => [ "timestamp_in_weird_custom_format", "YYYY-MM-dd HH:mm:ss:SSS" ]
tag_on_failure => ["timestamp_parse_failed"]
target => "#timestamp"
}

Resources