Logstash ConfigurationError - Expect character - logstash

i've this pattern that match correctly on https://grokconstructor.appspot.com :
"%{TIMESTAMP_ISO8601:timestamp}"\|"%{DATA:tz}"\|"%{GREEDYDATA:trans}\: %{GREEDYDATA:transId}"\|"%{GREEDYDATA:req}\: %{GREEDYDATA:reqId}"\|"%{IP:ip}"\|"%{GREEDYDATA:path}\=%{GREEDYDATA:codF}"\|"%{DATA:httpver}"\|"%{DATA:app}"\|"%{WORD:verb}"\|"%{GREEDYDATA:gw}\: %{GREEDYDATA:gw_status}"\|"%{GREEDYDATA:be}\: %{GREEDYDATA:be_status}"\|"%{DATA:unknown}"\|"%{DATA:postman}"\|"%{DATA:link}"\|"%{GREEDYDATA:tok}\: %{GREEDYDATA:token}"
When i configure logstash with this filter:
filter {
grok {
match => { "message" => "%{TIMESTAMP_ISO8601:timestamp}"\|"%{DATA:tz}"\|"%{GREEDYDATA:trans}\: %{GREEDYDATA:transId}"\|"%{GREEDYDATA:req}\: %{GREEDYDATA:reqId}"\|"%{IP:ip}"\|"%{GREEDYDATA:path}\=%{GREEDYDATA:codF}"\|"%{DATA:httpver}"\|"%{DATA:app}"\|"%{WORD:verb}"\|"%{GREEDYDATA:gw}\: %{GREEDYDATA:gw_status}"\|"%{GREEDYDATA:be}\: %{GREEDYDATA:be_status}"\|"%{DATA:unknown}"\|"%{DATA:postman}"\|"%{DATA:link}"\|"%{GREEDYDATA:tok}\: %{GREEDYDATA:token}" }
add_field => [ "grok_state", "match" ]
}
}
I get this error:
Failed to execute action
{:action=>LogStash::PipelineAction::Create/pipeline_id:main,
:exception=>"LogStash::ConfigurationError", :message=>"Expected one of
[ \t\r\n], "#", "{", "}" at line 10, column 61 (byte 158)
after filter {\n grok {\n match => { "message" =>
"%{TIMESTAMP_ISO8601:timestamp}"",
:backtrace=>["/usr/share/logstash/logstash-core/lib/logstash/compiler.rb:32:in
compile_imperative'", "org/logstash/execution/AbstractPipelineExt.java:182:in initialize'",
"org/logstash/execution/JavaBasePipelineExt.java:72:in initialize'", "/usr/share/logstash/logstash-core/lib/logstash/java_pipeline.rb:48:in initialize'",
"/usr/share/logstash/logstash-core/lib/logstash/pipeline_action/create.rb:50:in
execute'", "/usr/share/logstash/logstash-core/lib/logstash/agent.rb:386:in block
in converge_state'"]}
I tried to escape the " but have same error, any ideas?
Thank you
UPDATE
Example of log:
"2022-11-28 09:14:59:514"|"+0100"|"transId: xxx"|"reqId: xxx"|"1.1.1.1"|"/path/codF=xxxxxxxxxxx"|"HTTP/1.1"|"SAP"|"GET"|"gateway status: 200"|"backend status: 200"|""|"Runtime/7.29.2"|"client"|"token: xxxx-xxxx-xxxx"

I solved, the entire block of the pattern must be enclosed in double quotes and double quotes escaped within the pattern:
filter {
grok {
match => { "message" => "\"%{TIMESTAMP_ISO8601:timestamp}\"\|\"%{DATA:tz}\"\|\"%{GREEDYDATA:trans}\: %{GREEDYDATA:transId}\"\|\"%{GREEDYDATA:req}\: %{GREEDYDATA:reqId}\"\|\"%{IP:ip}\"\|\"%{GREEDYDATA:path}\=%{GREEDYDATA:codF}\"\|\"%{DATA:httpver}\"\|\"%{DATA:app}\"\|\"%{WORD:verb}\"\|\"%{GREEDYDATA:gw}\: %{GREEDYDATA:gw_status}\"\|\"%{GREEDYDATA:be}\: %{GREEDYDATA:be_status}\"\|\"%{DATA:unknown}\"\|\"%{DATA:postman}\"\|\"%{DATA:link}\"\|\"%{GREEDYDATA:tok}\: %{GREEDYDATA:token}\"" }
add_field => [ "grok_state", "match" ]
}
}
Thanks all

Related

match pattern before and after delimiter in grok

I have a pattern similar to "ApplicationID##EVENTREFERENCE" and I need to split it as key - before the delimiter ## - and value after ##
I tried through grok debugger:
(?[^##]*) but this match the value before ##
Expected results:
{
"ApplicationID": [
[
"EVENTREFERENCE"
]
]
}
You can use the common option "add_filter" at the end of your Grok filter after you have matched your data to create a new field that contains the data that you matched.
It should look something like this:
filter {
grok {
match => { "message" => "%{DATA:key}#\#%{GREEDYDATA:value}" }
add_field => { "%{key}" => "%{value}" }
}
}

Issue with GROK match for access logs

I am getting a grokparsefailure on some of these apache logs, that is not making sense to me. One of the kibana tags for these is the grokparsefailure. Obviously something is wrong here but I am having trouble figuring out what that is.
Example log entry that resulted in a failure:
127.0.0.1 - - [10/Oct/2016:19:05:54 +0000] "POST /v1/api/query.random HTTP/1.1" 201 - "-" "-" 188
Logstash output config file:
filter {
if [type] == "access" {
grok {
match => { "message" => "%{COMBINEDAPACHELOG}" }
}
}
}
filter {
if [type] == "requests" {
grok {
match => { "message" => "%{COMBINEDAPACHELOG}" }
}
}
}
output {
elasticsearch {
hosts => ["http://ESCLUSTER:9200"]
index => "%{[#metadata][beat]}-%{+YYYY.MM.dd}"
document_type => "[type]"
}
stdout {
codec => rubydebug
}
}
There are two spaces instead of one between the two - and between the - and the [: 127.0.0.1 - - [.
The pattern (%{IPORHOST:clientip} %{HTTPDUSER:ident} %{HTTPDUSER:auth}) expect only one space at this points.
So either you correct your log format so that all logs are of the same format, or you replace %{COMBINEDAPACHELOG} by
%{IPORHOST:clientip} %{HTTPDUSER:ident}%{SPACE}%{HTTPDUSER:auth}%{SPACE}\[%{HTTPDATE:timestamp}\] \"(?:%{WORD:verb} %{NOTSPACE:request}(?: HTTP/%{NUMBER:httpversion})?|%{DATA:rawrequest})\" %{NUMBER:response} (?:%{NUMBER:bytes}|-) %{QS:referrer} %{QS:agent}
This pattern is equivalent to the COMBINEDAPACHELOG pattern, but I replace the space at the beginning by the %{SPACE} pattern which match one or more space.

Logstash does not update #timestamp from apache log

If you are backfilling logs into logstash you are supposed to try and pull somehow the proper timestamps. Otherwise they get assigned to the time the log line was received by logstash.
This is achieved using date filter like:
date { match => [ "timestamp", "dd/MMM/yyyy:HH:mm:ss Z" ] }
But unfortunately this does not work for me.
So i have the following apache logline:
10.80.161.251 - - [15/Oct/2015:09:13:45 +0000] "- -" "POST /xxx HTTP/1.1" 200 696 29416 "-" "xxx" 4026
And the following pattern
ACCESS_LOG %{IPORHOST:clientip} %{USER:ident} %{USER:auth} \[%{HTTPDATE:[#metadata][timestamp]}\] "(?:TLSv%{NUMBER:tlsversion}|-) (?:%{NOTSPACE:cypher}|-)" "(?:%{WORD:verb} %{NOTSPACE:request}(?: HTTP/%{NUMBER:httpversion})?|%{DATA:rawrequest})" %{NUMBER:response} (?:%{NUMBER:bytes_in}|-) (?:%{NUMBER:bytes_out}|-) %{QS:referrer} %{QS:agent} %{NUMBER:tts}
And the following logstash config
# INPUTS
input {
file {
path => '/var/log/test.log'
type => 'apache-access'
}
}
# filter/mix/match
filter {
if [type] == 'apache-access' {
grok {
patterns_dir => [ '/root/logstash-patterns' ]
match => [ "message", "%{ACCESS_LOG}" ]
}
if !("_grokparsefailure" in [tags]) {
mutate { add_field => ["timestamp_submitted", "%{#timestamp}"] }
date {
match => [ "timestamp", "dd/MMM/yyyy:HH:mm:ss Z" ]
}
}
}
}
# now output
output {
stdout { codec => rubydebug }
}
What i am doing wrong here. I tried adding timezones, locales and what not. And it still does not work. Any help is greatly appreciated (plus a drink of choice if you happen to be in sofia, bulgaria).
Note to self: read more carefully
The issue here is not matching against the proper field.
Because of the default pattern for apache logs the timestamp from the logline is in [#metadata][timestamp] and not in timestamp
So the date match filter should be:
date {
match => [ "[#metadata][timestamp]", "dd/MMM/yyyy:HH:mm:ss Z" ]
}

logstash grok multiline - how to merge to previous line any line that doesn't start with timestamp

sometimes I print to log indented pretty jsons which printed in multiple lines. so I need to be able to tell logstash to append these prints to the original line of the original event.
example:
xxx p:INFO d:2015-07-21 11:11:58,906 sourceThread:3iMind-Atlas-akka.actor.default-dispatcher-2 queryUserId: queryId: hrvJobId:6c1a4d60-e5e6-40d8-80aa-a4dc00e9f0c4 etlStreamId:70 etlOmdId: etlDocId: logger:tim.atlas.module.etl.mq.MQConnectorEtl msg:(st:Consuming) received NotifyMQ. sending to [openmind_exchange/job_ack] message:
{
"JobId" : "6c1a4d60-e5e6-40d8-80aa-a4dc00e9f0c4",
"Time" : "2015-07-21T11:11:58.904Z",
"Errors" : [ ],
"FeedItemSchemaCounts" : {
"Document" : 1,
"DocumentMetadata" : 1
},
"OtherSchemaCounts" : { }
}
Since I've set a special log4j appender to function solely as logstash input, this task should be quiet easy. I control the layout of the log, so I can add as many prefix/suffix indicators as I please.
here's how my appender look like:
log4j.appender.logstash-input.layout.ConversionPattern=xxx p:%p d:%d{yyyy-MM-dd HH:mm:ss,SSS}{UTC} sourceThread:%X{sourceThread} queryUserId:%X{userId} queryId:%X{queryId} hrvJobId:%X{hrvJobId} etlStreamId:%X{etlStreamId} etlOmdId:%X{etlOmdId} etlDocId:%X{etlDocId} logger:%c msg:%m%n
as you can see I've prefixed every message with 'xxx' so I could tell logstash to append any line which doesn't start with 'xxx' to the previous line
here's my logstash configuration:
if [type] == "om-svc-atlas" {
grok {
match => [ "message" , "(?m)p:%{LOGLEVEL:loglevel} d:%{TIMESTAMP_ISO8601:logdate} sourceThread:%{GREEDYDATA:sourceThread} queryUserId:%{GREEDYDATA:userId} queryId:%{GREEDYDATA:queryId} hrvJobId:%{GREEDYDATA:hrvJobId} etlStreamId:%{GREEDYDATA:etlStreamId} etlOmdId:%{GREEDYDATA:etlOmdId} etlDocId:%{GREEDYDATA:etlDocId} logger:%{GREEDYDATA:logger} msg:%{GREEDYDATA:msg}" ]
add_tag => "om-svc-atlas"
}
date {
match => [ "logdate" , "YYYY-MM-dd HH:mm:ss,SSS" ]
timezone => "UTC"
}
multiline {
pattern => "<please tell me what to put here to tell logstash to append any line which doesnt start with xxx to the previous line>"
what => "previous"
}
}
yes it was easy indeed :
if [type] == "om-svc-atlas" {
grok {
match => [ "message" , "(?m)p:%{LOGLEVEL:loglevel} d:%{TIMESTAMP_ISO8601:logdate} sourceThread:%{GREEDYDATA:sourceThread} queryUserId:%{GREEDYDATA:userId} queryId:%{GREEDYDATA:queryId} hrvJobId:%{GREEDYDATA:hrvJobId} etlStreamId:%{GREEDYDATA:etlStreamId} etlOmdId:%{GREEDYDATA:etlOmdId} etlDocId:%{GREEDYDATA:etlDocId} logger:%{GREEDYDATA:logger} msg:%{GREEDYDATA:msg}" ]
add_tag => "om-svc-atlas"
}
date {
match => [ "logdate" , "YYYY-MM-dd HH:mm:ss,SSS" ]
timezone => "UTC"
}
multiline {
pattern => "^(?!xxx).+"
what => "previous"
}
}

Logstash 1.4.2 grok filter: _grokparsefailure

i am trying to parse this log line:
- 2014-04-29 13:04:23,733 [main] INFO (api.batch.ThreadPoolWorker) Command-line options for this run:
here's the logstash config file i use:
input {
stdin {}
}
filter {
grok {
match => [ "message", " - %{TIMESTAMP_ISO8601:time} \[%{WORD:main}\] %{LOGLEVEL:loglevel} %{JAVACLASS:class} %{DATA:mydata} "]
}
date {
match => [ "timestamp" , "dd/MMM/yyyy:HH:mm:ss Z" ]
}
output {
elasticsearch {
host => "localhost"
}
stdout { codec => rubydebug }
}
Here's the output i get:
{
"message" => " - 2014-04-29 13:04:23,733 [main] INFO (api.batch.ThreadPoolWorker) Commans run:",
"#version" => "1",
"#timestamp" => "2015-02-02T10:53:58.282Z",
"host" => "NAME_001.corp.com",
"tags" => [
[0] "_grokparsefailure"
]
}
Please if anyone can help me find where the problem is on the gork pattern.
I tried to parse that line in http://grokdebug.herokuapp.com/ but it parses only the timestamp, %{WORD} and %{LOGLEVEL} the rest is ignored!
There are two error in your config.
First
The error in GROK is the JAVACLASS, you have to include ( ) in the pattern, For example: \(%{JAVACLASS:class}\.
Second
The date filter match have two value, first is the field you want to parse, so in your example it is time, not timestamp. The second value is the date pattern. You can refer to here
Here is the config
input {
stdin {
}
}
filter {
grok {
match => [ "message", " - %{TIMESTAMP_ISO8601:time} \[%{WORD:main}\] %{LOGLEVEL:loglevel} \(%{JAVACLASS:class}\) %{GREEDYDATA:mydata}"
]
}
date {
match => [ "time" , "YYYY-MM-dd HH:mm:ss,SSS" ]
}
}
output
{
stdout {
codec => rubydebug
}
}
FYI. Hope this can help you.

Resources