# Grok parse failure after successful debug

**URL:** <https://discuss.elastic.co/t/grok-parse-failure-after-successful-debug/39407>\
**Category:** Logstash\
**Created:** [January 17, 2016, 9:46pm UTC](https://discuss.elastic.co/t/grok-parse-failure-after-successful-debug/39407 "2016-01-17T21:46:47Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Freddy\_Kasprzykowski](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/freddy_kasprzykowski/32/7205_2.png) [@Freddy\_Kasprzykowski](https://discuss.elastic.co/u/Freddy_Kasprzykowski)\
**Post date:** [January 17, 2016, 9:46pm UTC](https://discuss.elastic.co/t/grok-parse-failure-after-successful-debug/39407/1 "2016-01-17T21:46:47Z")

</div>

I have used [http://grokdebug.herokuapp.com/](http://grokdebug.herokuapp.com/) to create the grok match statements based on tcpdump of the syslog strips the ELK box is receiving. However, when checking Kibana, the logs are not parsed. i have used service logstash configtest and got confirmation the syntax is correct.

(IPs and other info are fake, but strings are intact).

TCPDUMP 1:  
15:51:23.173798 IP firewall.local.46932 \> elk.local.syslog: SYSLOG local7.notice, length: 316  
E..XC'@.@.r=.........T...Dx-\<189\>Jan 17 15:51:23 2016 firewall src="10.10.1.202:61227" dst="8.8.8.8:53" msg="priority:16, from LAN1 to WAN, UDP, service DNS\_UDP, ACCEPT" note="ACCESS FORWARD" user="unknown" devID="yyyyyyy" cat="Firewall" class="Access Control" ob="0" ob\_mac="000000000000" dir="LAN1:WAN" protoID=17 proto="DNS\_UDP"

SYSLOG STRIP 1: \<189\>Jan 17 15:51:23 2016 firewall src="10.10.1.202:61227" dst="8.8.8.8:53" msg="priority:16, from LAN1 to WAN, UDP, service DNS\_UDP, ACCEPT" note="ACCESS FORWARD" user="unknown" devID="yyyyyyy" cat="Firewall" class="Access Control" ob="0" ob\_mac="000000000000" dir="LAN1:WAN" protoID=17 proto="DNS\_UDP"\<%{NUMBER:syslog\_index}\>%{SYSLOGTIMESTAMP:syslog\_timestamp} %{YEAR:YEAR} %{WORD:device} src="%{IP:source\_ip}:%{BASE10NUM:source\_port}" dst="%{IP:destination\_ip}:%{BASE10NUM:destination\_port}" msg="%{DATA:log\_type}" note="%{DATA:log\_note}" user="%{DATA:user}" devID="%{DATA:device\_id}" cat="%{DATA:log\_category}" class=%{DATA:class} ob=%{DATA:ob} ob\_mac=%{DATA:ob\_mac} dir="%{DATA:traffic\_direction}" protoID=%{DATA:protocol\_number} proto="%{DATA:protocol\_service}"

GROK STATEMENT 1: \<%{NUMBER:syslog\_index}\>%{SYSLOGTIMESTAMP:syslog\_timestamp} %{YEAR:YEAR} %{WORD:device} src="%{IP:source\_ip}:%{BASE10NUM:source\_port}" dst="%{IP:destination\_ip}:%{BASE10NUM:destination\_port}" msg="%{DATA:log\_type}" note="%{DATA:log\_note}" user="%{DATA:user}" devID="%{DATA:device\_id}" cat="%{DATA:log\_category}" class=%{DATA:class} ob=%{DATA:ob} ob\_mac=%{DATA:ob\_mac} dir="%{DATA:traffic\_direction}" protoID=%{DATA:protocol\_number} proto="%{DATA:protocol\_service}"

TCPDUMP 2:  
15:51:23.295700 IP firewall.local.46932 \> elk.local.syslog: SYSLOG [local7.info](http://local7.info), length: 249  
E...C)@.@.r~.........T....2.\<190\>Jan 17 15:51:23 2016 firewall src="10.10.1.212:38942" dst="8.8.8.8:40020" msg="Traffic Log" note="Traffic Log" user="unknown" devID="yyyyyyy" cat="Traffic Log" duration=300 sent=157 rcvd=49 dir="lan1:wan1" protoID=17 proto="others"

SYSLOG STRIP 2: \<190\>Jan 17 15:36:05 2016 firewall src="10.10.1.212:38942" dst="8.8.8.8:40007" msg="Traffic Log" note="Traffic Log" user="unknown" devID="yyyyyyy" cat="Traffic Log" duration=300 sent=158 rcvd=49 dir="lan1:wan1" protoID=17 proto="others"

GROK STATEMENT 2: \<%{NUMBER:syslog\_index}\>%{SYSLOGTIMESTAMP:syslog\_timestamp} %{YEAR:YEAR} %{WORD:device} src="%{IP:source\_ip}:%{BASE10NUM:source\_port}" dst="%{IP:destination\_ip}:%{BASE10NUM:destination\_port}" msg="%{DATA:log\_type}" note="%{DATA:log\_note}" user="%{DATA:user}" devID="%{DATA:device\_id}" cat="%{DATA:log\_category}" duration=%{DATA:duration} sent=%{DATA:sent} rcvd=%{DATA:received} dir="%{DATA:traffic\_direction}" protoID=%{DATA:protocol\_number} proto="%{DATA:protocol\_service}"

logstash.conf

input {  
syslog {  
port =\> 5514  
type =\> "syslog"  
}  
}  
filter {  
if [type] == "syslog" {  
grok {  
match =\> ["message" , "\<%{NUMBER:syslog\_index}\>%{SYSLOGTIMESTAMP:syslog\_timestamp} %{YEAR:YEAR} %{WORD:device} src="%{IP:source\_ip}:%{BASE10NUM:source\_port}" dst="%{IP:destination\_ip}:%{BASE10NUM:destination\_port}" msg="%{DATA:log\_type}" note="%{DATA:log\_note}" user="%{DATA:user}" devID="%{DATA:device\_id}" cat="%{DATA:log\_category}" class=%{DATA:class} ob=%{DATA:ob} ob\_mac=%{DATA:ob\_mac} dir="%{DATA:traffic\_direction}" protoID=%{DATA:protocol\_number} proto="%{DATA:protocol\_service}""]  
}  
grok {  
match =\> ["message" , "\<%{NUMBER:syslog\_index}\>%{SYSLOGTIMESTAMP:syslog\_timestamp} %{YEAR:YEAR} %{WORD:device} src="%{IP:source\_ip}:%{BASE10NUM:source\_port}" dst="%{IP:destination\_ip}:%{BASE10NUM:destination\_port}" msg="%{DATA:log\_type}" note="%{DATA:log\_note}" user="%{DATA:user}" devID="%{DATA:device\_id}" cat="%{DATA:log\_category}" duration=%{DATA:duration} sent=%{DATA:sent} rcvd=%{DATA:received} dir="%{DATA:traffic\_direction}" protoID=%{DATA:protocol\_number} proto="%{DATA:protocol\_service}""]  
}  
}  
output {  
elasticsearch { hosts =\> ["localhost:9200"] }  
stdout { codec =\> rubydebug }  
}

---

<div class="post-metadata">

**Author:** ![magnusbaeck](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/magnusbaeck/32/44943_2.png) [@magnusbaeck](https://discuss.elastic.co/u/magnusbaeck)\
**Post date:** [January 18, 2016, 7:35am UTC](https://discuss.elastic.co/t/grok-parse-failure-after-successful-debug/39407/2 "2016-01-18T07:35:59Z")

</div>

Be systematic. Start with the simplest possible expression:

```
^<%{NUMBER:syslog_index}>

```

Does that work? Yes? Continue:

```
^<%{NUMBER:syslog_index}>%{SYSLOGTIMESTAMP:syslog_timestamp}

```

Keep on going until it breaks. Use the stdout output for debugging. Ignore Kibana until stdout looks good.

(Shameless plug: You may find [https://github.com/magnusbaeck/logstash-filter-verifier](https://github.com/magnusbaeck/logstash-filter-verifier) useful for testing filters, both for the initial filter implementation and for making sure future changes don't introduce regressions.)

---

<div class="post-metadata">

**Author:** ![Freddy\_Kasprzykowski](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/freddy_kasprzykowski/32/7205_2.png) [@Freddy\_Kasprzykowski](https://discuss.elastic.co/u/Freddy_Kasprzykowski)\
**Post date:** [January 18, 2016, 3:20pm UTC](https://discuss.elastic.co/t/grok-parse-failure-after-successful-debug/39407/3 "2016-01-18T15:20:17Z")

</div>

Thank you so much. By looking at /var/log/logstash/logstash.stdout I learned that the message had the syslog number and the time stamp removed. I have adjusted the filter and all attributes are parsing just fine. One last thing though, why is it inserting \_grokparsefailure tag still?

filter {  
if [type] == "syslog" {  
grok {  
match =\> { "message" =\> "%{WORD:host\_name} src="%{IP:source\_ip}:%{BASE10NUM:source\_port}" dst="%{IP:destination\_ip}:%{BASE10NUM:destination\_port}" msg="%{DATA:log\_type}" note="%{DATA:log\_note}" user="%{DATA:user}" devID="%{DATA:device\_id}" cat="%{DATA:log\_category}" duration=%{DATA:duration} sent=%{DATA:sent} rcvd=%{DATA:received} dir="%{DATA:traffic\_direction}" protoID=%{DATA:protocol\_number} proto="%{DATA:protocol\_service}"" }  
add\_field =\> ["received\_at", "%{@timestamp}"]  
add\_field =\> ["received\_from", "%{host\_name}"]  
}  
grok {  
match =\> { "message" =\> "%{WORD:host\_name} src="%{IP:source\_ip}:%{BASE10NUM:source\_port}" dst="%{IP:destination\_ip}:%{BASE10NUM:destination\_port}" msg="%{DATA:log\_type}" note="%{DATA:log\_note}" user="%{DATA:user}" devID="%{DATA:device\_id}" cat="%{DATA:log\_category}" class=%{DATA:class} ob=%{DATA:ob} ob\_mac=%{DATA:ob\_mac} dir="%{DATA:traffic\_direction}" protoID=%{DATA:protocol\_number} proto="%{DATA:protocol\_service}"" }  
add\_field =\> ["received\_at", "%{@timestamp}"]  
add\_field =\> ["received\_from", "%{host\_name}"]  
}

```
syslog_pri { }
date {
  match => ["syslog_timestamp", "MMM d HH:mm:ss", "MMM dd HH:mm:ss"]
}

```

}  
}

---

<div class="post-metadata">

**Author:** ![magnusbaeck](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/magnusbaeck/32/44943_2.png) [@magnusbaeck](https://discuss.elastic.co/u/magnusbaeck)\
**Post date:** [January 18, 2016, 6:17pm UTC](https://discuss.elastic.co/t/grok-parse-failure-after-successful-debug/39407/4 "2016-01-18T18:17:16Z")

</div>

One of the grok expressions is successful and the other one fails. To try multiple grok expressions and break after the first match, follow this pattern:

```auto
grok {
  match => {
    "message" => [
      "%{WORD:host_name} ... class=%{DATA:class} ob=%{DATA:ob} ...",
      "%{WORD:host_name} ... duration=%{DATA:duration} sent=%{DATA:sent} ..."
    ]
  }
}

```

---

<div class="post-metadata">

**Author:** ![Freddy\_Kasprzykowski](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/freddy_kasprzykowski/32/7205_2.png) [@Freddy\_Kasprzykowski](https://discuss.elastic.co/u/Freddy_Kasprzykowski)\
**Post date:** [January 19, 2016, 2:11am UTC](https://discuss.elastic.co/t/grok-parse-failure-after-successful-debug/39407/5 "2016-01-19T02:11:53Z")

</div>

And... it works!

I checked the documentation and it is correct: [https://www.elastic.co/guide/en/logstash/current/plugins-filters-grok.html](https://www.elastic.co/guide/en/logstash/current/plugins-filters-grok.html)

I am not sure why there are several posts lingering around claiming the syntax is:  
match =\> [ "message", format1,  
"message", format2 ]

Thank you very much. If there is anything I can do to help the community, let me know.

Best Regards

---

<div class="post-metadata">

**Author:** ![magnusbaeck](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/magnusbaeck/32/44943_2.png) [@magnusbaeck](https://discuss.elastic.co/u/magnusbaeck)\
**Post date:** [January 19, 2016, 6:41am UTC](https://discuss.elastic.co/t/grok-parse-failure-after-successful-debug/39407/6 "2016-01-19T06:41:38Z")

</div>

> I am not sure why there are several posts lingering around claiming the syntax is:  
> match =\> [ "message", format1,  
> "message", format2 ]

Both are acceptable;

```
match => ["field", "pattern1", ..., "patternN"]

```

is equivalent to

```
match => { "field" => ["pattern1", ..., "patternn"] }

```

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [July 6, 2017, 5:15am UTC](https://discuss.elastic.co/t/grok-parse-failure-after-successful-debug/39407/7 "2017-07-06T05:15:16Z")

</div>


