How to Make Epoch Time which is there in the middle of my log as #timestamp in Logstash? - logstash

I have the below log
1 iCEXnXWuShGYRlDbHEADlQ 1 3 sara482 1573151463576 1.5 13.8 0.0 0 0 62.6||
my grok pattern is below
"message", "%{NUMBER:log_Level} (?[^\s]+) %{NUMBER:mcty} %{NUMBER:agty} (?[^\s]+) %{INT:ts} %{NUMBER:cpu} %{NUMBER:mem} %{NUMBER:swap} %{NUMBER:diskr} %{NUMBER:diskw} %{NUMBER:diskc}\|\|%{GREEDYDATA:appc}"
How can I make filed ts as #timestamp, currently if I check the field mappings for the index these logs getting stored in Elastic Search, the ts filed is mapped as string, I am able to mutate rest of fields as Num/Float however only field ts I am not able to convert or match as #timestamp.
I have tried converting the filed as UNIX/UNIX_MS however my logstash is breaking if I try map ito any thing other than NUM/INT

you can add this to logstash config:
date {
match => [ "ts", "UNIX" ]
target => "ts"
}

Related

Regex group from within custom grok pattern

I'm trying to create custom grok patterns to extract various data using logstash and am wracking my brain getting the syntax correct to pull the regex group 1 equivalent from my log rows. I've looked at a ton of threads on this over the past 2 days, but nothing's out there that fits my example, and none of the canned grok patterns seem like they will pull the value I need.
3 example log file rows look similar to this (with abbreviated data for the examples):
2022-04-07 12:52:06,184:INFO :Thread-70_SCHEDULE.0001: MsgID=63759111848731967
2022-04-07 07:23:39,876:INFO :Thread-53_OrderInterfaceIntServer: MsgID=21316889724753182|
07:23:40,482 INFO [stdout] (http-/0.0.0.0:8080-20) 2022-04-07 07:23:40,482:ERROR
I want to create a custom grok pattern called SERVICE that extracts a pattern match using a regex match string:
Thread-[0-9]{2}_(.*?)\:
that for the 3 rows would return:
SCHEDULE.0001
OrderInterfaceIntServer
""
In the log:
SERVICE will always be prefixed by "Thread-xx_" where xx = 2-digit number followed by underscore. Some logs may not have this pattern at all (like row 3). In that case, no match.
SERVICE is always followed by a colon
In grok, I can define this in 2 ways:
SERVICE Thread-[0-9]{2}_(.*?)\:
or as a field using (?<service>Thread-[0-9]{2}_(.*?)\:)
however, for row 1, I get the response value of:
{
"service": [
[
"Thread-70_SCHEDULE.0001:"
]
]
}
What I want is:
{
"service": [
[
"SCHEDULE.0001"
]
]
}
Which is the equivalent of the regex group 1 response. I can't figure out how to manage the grok patterns to get the result I need.
You do not have to include all of the pattern in the capture group. You can use
grok { match => { "message" => "Thread-[0-9]{2}_(?<service>.*?):" } }
That will result in
"service" => "SCHEDULE.0001",
"service" => "OrderInterfaceIntServer",
and a "_grokparsefailure" tag on the third event.

Logstash - filter based on a dedicated time field for the last 30 days

I have an application that receives logs remotely from IoT devices. Those logs have timestamps from when they really happened - I process and log these logs and therefore have a specific time field original-log-time in my JSON logs.
So every one of my log files has the known #timestamp field of when this line was written to the file and an original-log-time field that contains the original log time.
Now I would like to only forward logs to elastic search if the original log time is less than 30 days in the past. The reason for this is, that logs from each day get their own index and only the last 30 indices are warm - the others are actually closed and I don't want them to be reopened.
What I am trying:
if [original_log_time].compareTo(ctx._source.time.plusDays(30)) <= 0 {
elasticsearch {
hosts => ["${ELASTICSEARCH_HOSTS:?ELASTICSEARCH_HOSTS environment variable is required}"]
index => "my-logs-" + original_log_time
user => "${ELASTICSEARCH_USERNAME:}"
password => "${ELASTICSEARCH_PASSWORD:}"
}
}
But this leads to the following error
Expected one of [, #, in, not , ==, !=, <=, >=, <, >, =~, !~, and, or, xor, nand, { at line 28, column 24*(byte 512) after output if [log_index_date]"
I read about Logstash ignore_older but it looks like I can't specify which timestamp it should take into account for that check? Any smarter solution?
UPDATE
As I got some errors that there is neither a compareTonor a plusDaysin logstash I tried another approach I read here: https://discuss.elastic.co/t/adding-1-day-to-the-date/129168
which was a filter
filter {
date {
match => [ "log_index_date", "dd.MM.yyyy" ]
target => "log_index_plus_thirty"
}
ruby {
code => 'event.set("log_index_plus_thirty", LogStash::Timestamp.new(event.get("log_index_plus_thirty")+86400*30))'
}
}
with the following if condition:
if [#timestamp] <= [log_index_plus_thirty] {
elasticsearch {
hosts => ["${ELASTICSEARCH_HOSTS:?ELASTICSEARCH_HOSTS environment variable is required}"]
index => "device-logs-" + log_index_date
user => "${ELASTICSEARCH_USERNAME:}"
password => "${ELASTICSEARCH_PASSWORD:}"
}
}
but this complains at the _plus_thirty part of the if condition as if that variable would not exist.
Also log_index_date is an optional field so not sure if that leads to a problem as well?

Grok parsing negative numbers into Kibana custom fields

Been banging my head against the wall over this - started out with logstash and Grok 2 days ago and made a bit of progress but i've been stuck looking at this particular problem all evening.
I have the following lines of input from a log file being ingested into logstash.
'John Pence ':'decrease':-0.01:-1.03093: 0.96: 0.97
'Dave Pound':'increase':0.04:1.04000: 0.97: 0.93
With the following grok filter matches:
match => { "message" => "%{QS:name}:%{QS:activity}:%{BASE16FLOAT:Change}:%{BASE16FLOAT:Percentage}: %{BASE16FLOAT:CurrentPrice}: %{BASE16FLOAT:PreviousPrice}" }
match => { "message" => "%{QS:Name}:%{QS:Activity}:-%{BASE16FLOAT:Change}:-%{BASE16FLOAT:Percentage}: %{BASE16FLOAT:CurrentPrice}: %{BASE16FLOAT:PreviousPrice}" }
This produces the following output in Kibana:
As you can see - I can't get the negative numbers to display correctly, how would one correctly show the minus sign in a grok filter?
Would greatly appreciate some help!
You can simply use the NUMBER grok pattern instead of BASE16FLOAT
The following grok pattern works perfectly on your input:
grok {
"match" => {"message" => "%{QS:name}:%{QS:activity}:%{NUMBER:Change}:%{NUMBER:Percentage}: %{NUMBER:CurrentPrice}: %{NUMBER:PreviousPrice}"}
}

Logstash Filter : syntax

Ive recently began learning logstash and the syntax is confusing me.
eg : for match i have various codes:
match => [ "%{[date]}" , "YYYY-MM-dd HH:mm:ss" ]
match => { "message" => "%{COMBINEDAPACHELOG}" }
match => [ "timestamp" , "dd/MMM/yyyy:HH:mm:ss Z" ]
What does each of these keys ("%{[date]}", "message", "timestamp") mean. And where can i find a proper documentation that explains all the keywords and syntax.
Please help and provide links if possible.
The grok{} filter has a match parameter that takes a field and a pattern. It will apply the pattern, trying to extract new fields from it. Your second example is from grok, so it will try to apply the COMBINEDAPACHELOG pattern against the text in the "message" field.
The doc for grok{} is here, and there are detailed blogs, too.
The other two examples look like they're from the date{} filter, which does a similar thing. It takes a field containing a string that represents a date, applies the given pattern to that field, and (by default) replaces the value in the #timestamp field.
The doc for date{} is here and examples here.

Converting date MMM dd HH:mm:ss for logstash

I have a logfile with a custom format, the date field looks like this:
Dec 4 23:59:21
Nov 21 23:59:21
in my logstash config I have this for the filter:
date {
type => "custom"
# tell it the format
custom_timestamp => ["MMM d HH:mm:ss", "MMM dd HH:mm:ss"]
# locale didn't help
locale => "en"
}
mutate{
type => "custom"
# replace the timestamp
replace => ["#timestamp", "%{custom_timestamp}"]
}
which supposedly replaces the logstash timestamp with the custom one from the logs (I am backfilling it from old logs at the moment to test).
If I turn on the debug flag and output to stdout, it shows me that #timestamp has been replaced with custom_timestamp but I get an error message telling me that it cannot be imported:
:exception=>java.lang.IllegalArgumentException: Invalid format: "Dec 4 23:59:21"
what do I have to do to convert the date format?
Turns out that the sample I was working from is wrong. You do not need the mutate replacement, the config is this now:
date {
type => "custom"
# tell it the format
custom_timestamp => ["MMM d HH:mm:ss", "MMM dd HH:mm:ss"]
# date format is english, computer might not be
locale => "en"
}
mutate{
type => "custom"
#other mutations go here
}
Two misconceptions in this post:
The java exception is generated because there is no YEAR in your format, therefore it cannot parse the date safely.
You need to run a mutate if you want other applications to see your old imported logs as a coherent timeline. Otherwise, when you import all your old logs, you'll only see a few minutes of events concentrated (during the import).
Other than that, good question/answer, it helped me get back on track on my particular problem ;)

Resources