configuring the logstash-output-csv - logstash

I am pretty new to logstash and I have been trying to convert an existing log into a csv format using the logstash-output-csv plugin.
My input log string looks as follows which is a custom log written in our application.
'128.111.111.11/cpu0/log:5988:W/"00601654e51a15472-76":687358:<9>2015/08/18 21:06:56.05: comp/45 55% of memory in use: 2787115008 bytes (change of 0)'
I wrote a quick regex and added it to the patterns_dir using the grok plugin.
My pattern is as follows :
IP_ADDRESS [0-9,.]+
CPU [0-9]
NSFW \S+
NUMBER [0-9]
DATE [0-9,/]+\s+[0-9]+[:]+[0-9]+[:]+[0-9,.]+
TIME \S+
COMPONENT_ID \S+
LOG_MESSAGE .+
without adding any csv filters I was able to get this output.
{
"message" => "128.111.111.11/cpu0/log:5988:W/"00601654e51a15472-76":687358:<9>2015/08/18 21:06:56.05: comp/45 55% of memory in use: 2787115008 bytes (change of 0)",
"#version" => "1",
"#timestamp" => "2015-08-18T21:06:56.05Z",
"host" => "hostname",
"path" => "/usr/phd/raveesh/sample.log_20150819000609",
"tags" => [
[0] "_grokparsefailure"
]
}
This is my configuration in order to get the csv as an output
input {
file {
path => "/usr/phd/raveesh/temporary.log_20150819000609"
start_position => beginning
}
}
filter {
grok {
patterns_dir => "./patterns"
match =>["message", "%{IP_ADDRESS:ipaddress}/%{CPU:cpu}/%{NSFW:nsfw}<%{NUMBER:number}>%{DATE}:%{SPACE:space}%{COMPONENT_ID:componentId}%{SPACE:space}%{LOG_MESSAGE:logmessage}" ]
break_on_match => false
}
csv {
add_field =>{"ipaddress" => "%{ipaddress}" }
}
}
output {
# Print each event to stdout.
csv {
fields => ["ipaddress"]
path => "./logs/firmwareEvents.log"
}
stdout {
# Enabling 'rubydebug' codec on the stdout output will make logstash
# pretty-print the entire event as something similar to a JSON representation.
codec => rubydebug
}
}
The above configuration does not seem to give the output. I am trying only to print the ipaddress in a csv file but finally I need to print all the captured patterns in a csv file. so I need the output as follows :
128.111.111.111,cpu0,nsfw, ....
Could you please let me know the changes i need to make. ?
Thanks in advance
EDIT:
I fixed the regex as suggested using the tool http://grokconstructor.appspot.com/do/match#result
Now my regex filter looks as follows :
%{IP:client}\/%{WORD:cpu}\/%{NOTSPACE:nsfw}<%{NUMBER:number}>%{YEAR:year}\/%{MONTHNUM:month}\/%{MONTHDAY:day}%{SPACE:space}%{TIME:time}:%{SPACE:space2}%{NOTSPACE:comp}%{SPACE:space3}%{GREEDYDATA:messagetext}
How do I capture the individual splits and save it as a csv ?
Thanks
EDIT:
I finally resolved this using the File plugin .
output {
file{
path => "./logs/sample.log"
message_pattern =>"%{client},%{number}"
}
}

The csv tag in the filter section is for parsing the input and exploding the message to key/value pairs.
In your case you are already parsing the input with the grok, so I bet you don't need the csv filter.
But in the output we can see there is a gorkfailure
{
"message" => "128.111.111.11/cpu0/log:5988:W/"00601654e51a15472-76":687358:<9>2015/08/18 21:06:56.05: comp/45 55% of memory in use: 2787115008 bytes (change of 0)",
"#version" => "1",
"#timestamp" => "2015-08-18T21:06:56.05Z",
"host" => "hostname",
"path" => "/usr/phd/raveesh/sample.log_20150819000609",
"tags" => [
[0] "****_grokparsefailure****"
]
}
That means your grok expression cannot parse the input.
You should fix the expression according to your input and then the csv will output properly.
Checkout http://grokconstructor.appspot.com/do/match for some help
BTW, are you sure the patterns NSFW, CPU, COMPONENT_ID, ... are defined somewhere ?
HIH

Related

logstash GROK filter along with KV plugin couldn't able to process the events

i am new to ELK. when i onboarded the below log file, it is going to "dead letter queue" in logstash because logstash couldn't able to process the events.I have written the GROK filter to parse the events but logstash still couldn't not process the events. Any help would be appreciated.
Below is the sample log format.
25193662345 [http-nio-8080-exec-44] DEBUG c.s.b.a.m.PerformanceMetricsFilter - method=PUT status=201 appLogicTime=1, streamInTime=0, blobStorageTime=31, totalTime=33 tenantId=b9sdfs-1033-4444-aba5-csdfsdfsf, immutableBlobId=bss_c_586331/Sample_app12-sdas-157123148464.txt, blobSize=2862, domain=abc
2519366789 [http-nio-8080-exec-47] DEBUG q.s.b.y.m.PerformanceMetricsFilter - method=PUT status=201 appLogicTime=1, streamInTime=0, blobStorageTime=32, totalTime=33 tenantId=b0csdfsd-1066-4444-adf4-ce7bsdfssdf, immutableBlobId=bss_c_586334/Sample_app15-615223-157sadas6648465.txt, blobSize=2862, domain=cde
GROK filter:
dissect { mapping => { "message" => "%{NUMBER:number} [%{thread}] %{level} %{class} - %{[#metadata][msg]}" } }
kv { source => "[#metadata][msg]" field_split => "," }
Thanks
You have basically two problems in your configuration.
1.) You are using the dissect filter, not grok, both are used to parse messages, but grok uses regular expressions to validate the value of the field and dissect is just positional, it does not perform any validation, if you have a WORD value in the position of a field that expects a NUMBER, grok will fail, but dissect will not.
If your log lines always have the same pattern, you should continue to use dissect since it is faster and needs less cpu.
Your correct dissect mapping should be:
dissect {
mapping => { "message" => "%{number} [%{thread}] %{level} %{class} - %{[#metadata][msg]}" }
}
2.) The field that contains the kv message is wrong, it has fields separated by space and by comma, kv won't work this way.
After your dissect filter this is the content of [#metadata][msg].
method=PUT status=201 appLogicTime=1, streamInTime=0, blobStorageTime=32, totalTime=33 tenantId=b0csdfsd-1066-4444-adf4-ce7bsdfssdf, immutableBlobId=bss_c_586334/Sample_app15-615223-157sadas6648465.txt, blobSize=2862, domain=cde
To solve this you should use a mutate filter to remove the comma from the [#metadata][msg] and use the kv filter with the default configurations.
This should be your filter configuration
filter {
dissect {
mapping => { "message" => "%{number} [%{thread}] %{level} %{class} - %{[#metadata][msg]}" }
}
mutate {
gsub => ["[#metadata][msg]",",",""]
}
kv {
source => "[#metadata][msg]"
}
}
Your output should be something like this:
{
"number" => "2519366789",
"#timestamp" => 2019-11-03T16:42:11.708Z,
"thread" => "http-nio-8080-exec-47",
"appLogicTime" => "1",
"domain" => "cde",
"method" => "PUT",
"level" => "DEBUG",
"blobSize" => "2862",
"#version" => "1",
"immutableBlobId" => "bss_c_586334/Sample_app15-615223-157sadas6648465.txt",
"streamInTime" => "0",
"status" => "201",
"blobStorageTime" => "32",
"message" => "2519366789 [http-nio-8080-exec-47] DEBUG q.s.b.y.m.PerformanceMetricsFilter - method=PUT status=201 appLogicTime=1, streamInTime=0, blobStorageTime=32, totalTime=33 tenantId=b0csdfsd-1066-4444-adf4-ce7bsdfssdf, immutableBlobId=bss_c_586334/Sample_app15-615223-157sadas6648465.txt, blobSize=2862, domain=cde",
"totalTime" => "33",
"tenantId" => "b0csdfsd-1066-4444-adf4-ce7bsdfssdf",
"class" => "q.s.b.y.m.PerformanceMetricsFilter"
}

logstash - Unable to parse timestamp

I have the following JSON log (new line separated )
{
"logName": "projects/gg-sanbox/logs/appengine.googleapis.com%2Fnginx.request",
"timestamp": "2018-04-02 22:26:02.869 UTC",
"receiveTimestamp":"2018-04-02 22:28:06.742394 UTC",
}
and logstash config
input
{
file {
type => "json"
path => "/logs/mylogs.log"
codec => json
start_position => "beginning"
sincedb_path => "/dev/null"
}
}
filter{
json{
source => "message"
}
date {
match => [ "timestamp", "yyyy-MM-dd HH:mm:ss.SSS Z"]
}
}
output
{
stdout
{
#codec => rubydebug
}
elasticsearch
{
codec => "json_lines"
hosts => ["127.0.0.1:9200"]
# document_id => "%{logstash_checksum}"
index => "appengine_nginx-requests"
}
}
I am getting the following in the logstash output
"#timestamp"=>2018-04-07T15:26:31.857Z, "tags"=>["_dateparsefailure"],
Notice that its falling back to the current data and time instead of the time mentioned in the log line which is actually the event had occured and I want to see in the Kibana timeline.
Not sure what is the problem here.
Take a look at date filter plugin documentation, the format option Z does not match UTC; because alone it's not a timezone (for it to be valid it would need to be +0000). You'll need to add it like so: yyyy-MM-dd HH:mm:ss.SSS 'UTC'
To answer your other question about the precision of the seconds; it's simply not supported to have any precision lower than milliseconds. If you look at link above, you'll find:
Maximum precision is milliseconds (SSS). Beyond that, zeroes are appended.

Logstash grok filter doesn't work for the last field

With Logstash 2.3.3, grok filter doesn't work for the last field.
To reproduce the problem, create test.conf as follows:
input {
file {
path => "/Users/izeye/Applications/logstash-2.3.3/test.log"
}
}
filter {
grok {
match => { "message" => "%{DATA:id1},%{DATA:id2},%{DATA:id3},%{DATA:id4},%{DATA:id5}" }
}
}
output {
stdout {
codec => rubydebug
}
}
Run ./bin/logstash -f test.conf
and after it started, in another terminal run echo "1,2,3,4,5" >> test.log
and I got the following output:
Johnnyui-MacBook-Pro:logstash-2.3.3 izeye$ ./bin/logstash -f test.conf
Settings: Default pipeline workers: 8
Pipeline main started
{
"message" => "1,2,3,4,5",
"#version" => "1",
"#timestamp" => "2016-07-07T07:57:42.830Z",
"path" => "/Users/izeye/Applications/logstash-2.3.3/test.log",
"host" => "Johnnyui-MacBook-Pro.local",
"id1" => "1",
"id2" => "2",
"id3" => "3",
"id4" => "4"
}
You can see the missing id5.
I'm not sure this is a bug or mis-configured.
Any hint will be appreciated.
I think it is because how the DATA pattern is defined. Its regex is .*?, so it's a lazy match.
It's not a bug, it's how regex works (example).
But you might want to ask a regex question in order to have an accurate answer.
As a solution, you can replace the last DATA with NUMBER (or something appropriate to your situation). GREEDYDATA would also work.
Though, in that solution, the csv or dissect filters might be better fit, as easier to configure and more performant.

Logstash - grok multiline

I tried using multiline in grok filters but its not working properly.
My Logs are
H3|15:55:04:760|exception|not working properly
message:space exception
at line number 25
My conf file is
input { file {
path => "logs/test.log"
start_position => beginning
sincedb_path => "/dev/null"
}}
filter{
multiline {
pattern => "^(\s|[A-Z][a-z]).*"
what => "previous"
}
if [message] =~ /H\d+/{
grok {
match => ["message", "(?m)%{USERNAME:level}\|%{TIME:timestamp}\|%{WORD:method}\|%{GREEDYDATA:error_Message}" ]
}
}
else {
grok {
match => ["message", "(?m)%{GREEDYDATA:error_Message}" ]
}
}
}
output {elasticsearch { host => "localhost" protocol => "http" port => "9200" }}
I am able to process the first line of log file, but second line of log file is not working where I would like to use multiline
Output i would like to have
{
"#timestamp" => "2014-06-19 00:00:00,000"
"path" => "logs/test.log"
"level"=>"H3"
"timestamp"=>15:55:04:760
"method"=>exception
"error_message"=>not working properly
},
{
"#timestamp" => "2014-06-19 00:00:00,000"
"path" => "logs/test.log"
"error_message" => "space exception at line 25"
}
Kindly help me to get required output.
Your multiline config says, "if I find this pattern, keep it with the previous line".
Your pattern "^(\s|[A-Z][a-z]).*" says "either a space, or a capital letter followed by a lowercase letter, then followed by other stuff".
So, " foo" or "California" would match, but "H3" wouldn't.
I would suggest a pattern that matches the start of your multiline expression, and use the 'negate' feature to have all lines that don't match that pattern join to the original line:
filter {
multiline {
pattern => "^[A-Z][0-9]\|"
negate => 'true'
what => 'previous'
}
}
}
This would take the "H3|" line as the beginning, and join all other lines to it. Depending on the range of values at the beginning of the line, you may need to edit the regexp.

logstash output not showing the desired timestamp

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"]
}

Resources