Logstash conditional output using environment variable not working - configuration

I'm using Logstash to send log data to Elasticsearch (of course), but some of my end users also want the data sent to a secondary csv file so they can do their own processing. I am trying to use an environment variable to determine if we need to output to a secondary file and if so, where that file should live.
My Logstash looks like this:
input {
. . .
}
filter {
. . .
}
output {
elasticsearch {
. . .
}
if "${SECONDARY_OUTPUT_FILE:noval}" != "noval" {
csv {
fields => . . .
path => "${ SECONDARY_OUTPUT_FILE:noval}"
}
}
}
When SECONDARY_OUTPUT_FILE has a value, it works fine. When it does not, Logstash writes csv output to a file named "noval". My conclusion is that the if statement is not working correctly with the environment variable.
I'm using Logstash version 2.3.2 on a Windows 7 machine.
Any suggestions or insights would be appreciated.

Actually that is a very good question, there is still an ongoing enhancement opened on this topic on github, as mentioned by IrlJidel on the issue, a workaround to the issue would be:
mutate {
add_field => { "[#metadata][SECONDARY_OUTPUT_FILE]" => "${SECONDARY_OUTPUT_FILE:noval}" }
}
if [#metadata][SECONDARY_OUTPUT_FILE] != "noval" {
csv {
fields => . . .
path => "${SECONDARY_OUTPUT_FILE}"
}
}

just a quick update, since Logstash 7.17 using variables in conditionals work as expected: https://github.com/elastic/logstash/issues/5115#issuecomment-1022123571

Related

Filter Kafka JSON messages with Logstash grok

I try to filter kafka json messages only for Germany (DE). To do that I have to write a grok expression. Can anyone help me in writing a grok pattern for this json?
{"table":"ORDERS","type":"I","payload":{"ID":"28112","COUNTRY":"DE","AMT":15.36}}
{"table":"ORDERS","type":"I","payload":{"ID":"28114","COUNTRY":"US","AMT":25.75}}
Sorry, that I'm new to these technologies. Here is what my logstash.conf looks like:
input {
kafka {topics => [ "test" ] auto_offset_reset => "earliest" }
}
filter {
grok {
match => { "message" => "?????????" }
if [message] =~ "*COUNTRY*DE*" {
drop{}
}
}
}
output { file { path => "./test.txt" } }
In the end I just wanna file with the Germany orders. Hope to get some help, thanks!
Do you need to use Logstash?
If not, I would suggest a simple KSQL statement
CREATE STREAM GERMAN_ORDERS AS SELECT * FROM ORDERS WHERE COUNTRY='DE';
This creates a Kafka topic that is streamed from the first, and has just the data that you want on it. From the Kafka topic you can use Kafka Connect to land it to a file if you want that as part of your processing pipeline.
Read an example of using KSQL here, and try it out here

Logstash output plugin for JDBC/mySQL

I am collecting Twitter and Instagram data using Logstash and I want to save it to Elasticsearch, MongoDB, and MySQL. There are Logstash output plugins available for Elasticsearch and MongoDB but not for MySQL (it is a requirement to save this data to multiple databases).
Any workaround for this?
Thanks!
You should install plugin ouput-jdbc for logstash. Download from https://github.com/theangryangel/logstash-output-jdbc/tree/master And build、install 。
And then you can use like this:
input {
stdin{}
}
filter{
json{
source => "message"
}
}
output {
stdout{
codec=>rubydebug{}
}
jdbc {
connection_string => "jdbc:mysql://192.168.119.202:3306/outMysql?user=root&password=root"
statement => ["INSERT INTO user(userName,ip) values(?,?)","userName","ip"]
}
}

Logstash - convert JSON to readable format - during logging to a file

I have a Logstash configuration as given below:
input {
udp {
port => 5043
codec => json
}
}
output {
file {
path => "/logfile.log"
}
}
I am trying to log messages in the "logfile.log" which are more readable.
So if my input data is like {"attr1":"val1","attr2":"val2"}
I want to write it in the log as:
attr1_val1 | attr2_val2
Basically converting data from JSON to a readable format.
What should I be modifying in my Logstash configuration to do that?
The message_format option of the file output allows you to specify how each message should be formatted. If the keys of your messages are fixed and known you can simply do this:
output {
file {
message_format => "attr1_%{attr1} | attr2_%{attr2}"
...
}
}
To handle arbitrary fields you'll probably have to write some custom Ruby code using the ruby filter. The following filter, for example, produces the same results as above but doesn't require you to hardcode the names of the fields:
filter {
ruby {
code => '
values = []
event.to_hash.each { |k, v|
next if k.start_with? "#"
values << "#{k}_#{v.to_s}"
}
event["myfield"] = values.join(" | ")
'
}
}
output {
file {
message_format => "%{myfield}"
...
}
}

JSON Variants (Log4J) with LogStash

I'm not sure if this is a follow-up or separate question to this one. There is some piece about LogStash that is not clicking. For that, I apologize for a related question. Still, I'm going out of my mind here.
I have an app that writes logs to a file. Each log entry is a JSON object. An example of my .json file looks like the following:
{
"logger":"com.myApp.ClassName",
"timestamp":"1456976539634",
"level":"ERROR",
"thread":"pool-3-thread-19",
"message":"Danger. There was an error",
"throwable":"java.Exception"
},
{
"logger":"com.myApp.ClassName",
"timestamp":"1456976539649",
"level":"ERROR",
"thread":"pool-3-thread-16",
"message":"I cannot go on",
"throwable":"java.Exception"
}
This format is what's created from Log4J2's JsonLayout. I'm trying my damnedest to get the log entries into LogStash. In an attempt to do this, I've created the following LogStash configuration file:
input {
file {
type => "log4j"
path => "/logs/mylogs.log"
}
}
output {
file {
path => "/logs/out.log"
}
}
When I open /logs/out.log, I see a mess. There's JSON. However, I do not see the "level" property or "thread" property that Log4J generates. An example of a record can be seen here:
{"message":"Danger. There was an error","#version":"1","#timestamp":"2014-04-08T17:20:10.035Z","type":"log4j","host":"ip-myAddress","path":"/logs/mylogs.log"}
Sometimes I even get parse errors. I need my properties to still be properties. I do not want them crammed into the message portion or the output. I have a hunch this has something to do with Codecs. Yet, I'm not sure. I'm not sure if I should change the codec on the logstash input configuration. Or, if I should change the input on the output configuration. I would sincerely appreciate any help as I'm getting desperate at this point.
Can you change your log format?
After I change your log format to
{ "logger":"com.myApp.ClassName", "timestamp":"1456976539634", "level":"ERROR", "thread":"pool-3-thread-19", "message":"Danger. There was an error", "throwable":"java.Exception" }
{ "logger":"com.myApp.ClassName", "timestamp":"1456976539649", "level":"ERROR", "thread":"pool-3-thread-16", "message":"I cannot go on", "throwable":"java.Exception" }
One json log per one line and without the "," at the end of the log, I can use the configuration below to parse the json message to correspond field.
input {
file {
type => "log4j"
path => "/logs/mylogs.log"
codec => json
}
}
input {
file {
codec => json_lines { charset => "UTF-8" }
...
}
}
should do the trick
Use Logstash's log4j input.
http://logstash.net/docs/1.4.2/inputs/log4j
Should look something like this:
input {
log4j {
port => xxxx
}
}
This worked for me, good luck!
I think #Ben Lim was right, your Logstash config is fine, just need to properly format input JSON to have each log event in a single line. This is very simple with Log4J2's JsonLayout, just set eventEol=true and compact=true. (reference)

Having Logstash reading JSON

I am trying to use logstash for analyzing a file containing JSON objects as follows:
{"Query":{"project_id":"a7565b911f324a9199a91854ea18de7e","timestamp":1392076800,"tx_id":"2e20a255448742cebdd2ccf5c207cd4e","token":"3F23A788D06DD5FE9745D140C264C2A4D7A8C0E6acf4a4e01ba39c66c7c9cbd6a123588b22dc3a24"}}
{"Response":{"result_code":"Success","project_id":"a7565b911f324a9199a91854ea18de7e","timestamp":1392076801,"http_status_code":200,"tx_id":"2e20a255448742cebdd2ccf5c207cd4e","token":"3F23A788D06DD5FE9745D140C264C2A4D7A8C0E6acf4a4e01ba39c66c7c9cbd6a123588b22dc3a24","targets":[]}}
{"Query":{"project_id":"a7565b911f324a9199a91854ea18de7e","timestamp":1392076801,"tx_id":"f7f68c7fb14f4959a1db1a206c88a5b7","token":"3F23A788D06DD5FE9745D140C264C2A4D7A8C0E6acf4a4e01ba39c66c7c9cbd6a123588b22dc3a24"}}
Ideally i'd expect Logstash to understand the JSON.
I used the following config:
input {
file {
type => "recolog"
format => json_event
# Wildcards work, here :)
path => [ "/root/isaac/DailyLog/reco.log" ]
}
}
output {
stdout { debug => true }
elasticsearch { embedded => true }
}
I built this file based on this Apache recipe
When running logstash with debug = true, it reads the objects like this:
How could i see stats in the kibana GUI based on my JSON file, for example number of Query objects and even queries based on timestamp.
For now it looks like it understand a very basic version of the data not the structure of it.
Thx in advance
I found out that logstash will automatically detect JSON byt using the codec field within the file input as follows:
input {
stdin {
type => "stdin-type"
}
file {
type => "prodlog"
# Wildcards work, here :)
path => [ "/root/isaac/Mylogs/testlog.log"]
codec => json
}
}
output {
stdout { debug => true }
elasticsearch { embedded => true }
}
Then Kibana showed the fields of the JSON perfectly.