# Extract

**URL:** <https://discuss.elastic.co/t/extract/126754>\
**Category:** Logstash\
**Created:** [April 4, 2018, 2:09pm UTC](https://discuss.elastic.co/t/extract/126754 "2018-04-04T14:09:41Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![proximator](https://avatars.discourse-cdn.com/v4/letter/p/c68b51/32.png) [@proximator](https://discuss.elastic.co/u/proximator)\
**Post date:** [April 4, 2018, 2:09pm UTC](https://discuss.elastic.co/t/extract/126754/1 "2018-04-04T14:09:41Z")

</div>

Hi

I would like to build a new field from my error messages using some grok patterns, the idea is to extract the class name from the first line and then from each single line that starts with "Caused by:"

In the example below, the value of my new field should be: **java.lang.RuntimeException/java.lang.IllegalStateException/java.lang.UnsupportedOperationException**

```
Exception in thread "main" java.lang.RuntimeException: error message
    at Exceptions.main(Exceptions.java:4)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
Caused by: java.lang.IllegalStateException: Some message
    at Exceptions.main(Exceptions.java:3)
    ... 5 more
Caused by: java.lang.UnsupportedOperationException: Some other message 
    at Exceptions.main(Exceptions.java:10)
    ... 5 more

```

filebeat is sending the full stack trace using multiline already.  
Any suggestion how can I achieve this with with minimum code?

Cheers

---

<div class="post-metadata">

**Author:** ![Badger](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/badger/32/25190_2.png) [@Badger](https://discuss.elastic.co/u/Badger)\
**Post date:** [April 4, 2018, 3:02pm UTC](https://discuss.elastic.co/t/extract/126754/2 "2018-04-04T15:02:14Z")

</div>

So if that whole stack comes in as a single event then exactly which pieces of text do you want to extract?

---

<div class="post-metadata">

**Author:** ![proximator](https://avatars.discourse-cdn.com/v4/letter/p/c68b51/32.png) [@proximator](https://discuss.elastic.co/u/proximator)\
**Post date:** [April 4, 2018, 3:05pm UTC](https://discuss.elastic.co/t/extract/126754/3 "2018-04-04T15:05:09Z")

</div>

I want to extract the java class name of the first line and all the java class name of the lines that starts with "Caused by: " and concatenate all of them

So in the example above, I should get: **java.lang.RuntimeException/java.lang.IllegalStateException/java.lang.UnsupportedOperationException**

---

<div class="post-metadata">

**Author:** ![Jenni](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/jenni/32/29684_2.png) [@Jenni](https://discuss.elastic.co/u/Jenni)\
**Post date:** [April 4, 2018, 4:23pm UTC](https://discuss.elastic.co/t/extract/126754/4 "2018-04-04T16:23:10Z")

</div>

There is probably a prettier and better solution, but, if the full error message is in one field, this would create your desired string:

```
grok {
    match => { "testmessage" => ".*\"\s(?<error>[^\:]+).+?(?=Caused by: )Caused by: (?<cause>.*)" }
  }
  mutate {
    gsub => [
      "cause", "[\n]", "",
      "cause", ":.*Caused\sby:\s", "/",
      "cause", ":.*$", ""
    ]
    add_field => { "full_error" => "%{error}/%{cause}"}
  }

```

"full\_error" =\> "java.lang.RuntimeException/java.lang.IllegalStateException/java.lang.UnsupportedOperationException"

---

<div class="post-metadata">

**Author:** ![Badger](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/badger/32/25190_2.png) [@Badger](https://discuss.elastic.co/u/Badger)\
**Post date:** [April 4, 2018, 4:31pm UTC](https://discuss.elastic.co/t/extract/126754/5 "2018-04-04T16:31:08Z")

</div>

Just dealing with the multiple 'Caused by' lines... When you use a capture group in String.scan the array you get back contains arrays, not strings, so we need to flatten before doing a join.

```auto
  ruby {
    code => "
      s = event.get('message')
      r = s.scan(/Caused by: ([^:]+):/)
      r = r.flatten
      event.set('causedby', r.join('/'))
    "
  }

```

---

<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:** [May 2, 2018, 4:31pm UTC](https://discuss.elastic.co/t/extract/126754/6 "2018-05-02T16:31:27Z")

</div>

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.
