# Logstash filter ruby

**URL:** https://discuss.elastic.co/t/logstash-filter-ruby/235677
**Category:** Logstash
**Created:** [June 4, 2020, 6:34am UTC](https://discuss.elastic.co/t/logstash-filter-ruby/235677 "2020-06-04T06:34:46Z")
**Posts on this page:** 11
**Page:** 1

<div class="post-metadata">

### Author: ![ajayraghuraj](https://avatars.discourse-cdn.com/v4/letter/a/e68b1a/32.png) [@ajayraghuraj](https://discuss.elastic.co/u/ajayraghuraj)
#### Post date: [June 4, 2020, 6:34am UTC](https://discuss.elastic.co/t/logstash-filter-ruby/235677/1 "2020-06-04T06:34:46Z")

</div>

Hi

How do I add a new field which is a percentage calculation using ruby filter ?

new field called 'MemValuePct' should contain the value of 'type\_instance' in percentage

example

MemValuePct  
[free / (free +cached + buffered + used) \* 100]

![image](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1a50c54c33dd9c901761c9cfd82062d60476b9c3.png)

Thanks

---

<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: [June 4, 2020, 1:37pm UTC](https://discuss.elastic.co/t/logstash-filter-ruby/235677/2 "2020-06-04T13:37:19Z")

</div>

Use the [event.get](https://www.elastic.co/guide/en/logstash/current/event-api.html) method to fetch fields from the event and the event.set method to add a new field.

---

<div class="post-metadata">

### Author: ![ajayraghuraj](https://avatars.discourse-cdn.com/v4/letter/a/e68b1a/32.png) [@ajayraghuraj](https://discuss.elastic.co/u/ajayraghuraj)
#### Post date: [June 8, 2020, 11:57am UTC](https://discuss.elastic.co/t/logstash-filter-ruby/235677/3 "2020-06-08T11:57:41Z")

</div>

logs show errors after implementing the ruby filter. I am new to ruby , just wrote the filter based on examples

```
[2020-06-08T19:48:01,428][ERROR][logstash.filters.ruby] Ruby exception occurred: undefined method `each' for 756985856.0:Float
[2020-06-08T19:48:01,434][ERROR][logstash.filters.ruby] Ruby exception occurred: undefined method `each' for 2911322112.0:Float
[2020-06-08T19:48:07,621][ERROR][logstash.filters.ruby] Ruby exception occurred: undefined method `each' for 223920128.0:Float
[2020-06-08T19:48:07,627][ERROR][logstash.filters.ruby] Ruby exception occurred: undefined method `each' for 206065664.0:Float
[2020-06-08T19:48:07,634][ERROR][logstash.filters.ruby] Ruby exception occurred: undefined method `each' for 166301696.0:Float
[2020-06-08T19:48:07,636][ERROR][logstash.filters.ruby] Ruby exception occurred: undefined method `each' for 3544559616.0:Float
[2020-06-08T19:48:11,347][ERROR][logstash.filters.ruby] Ruby exception occurred: undefined method `each' for 235282432.0:Float

```

here is my ruby filter

```
ruby {
code => '
    a = event.get("value")
    if a
        sum = 0
        a.each {
            sum += "value"
        }
        event.set("MemValuePct", [a / sum * 100])
    end
'
 }
```

---

<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: [June 8, 2020, 2:18pm UTC](https://discuss.elastic.co/t/logstash-filter-ruby/235677/4 "2020-06-08T14:18:20Z")

</div>

Apparently [value] is a float, so it does not have a .each method.

---

<div class="post-metadata">

### Author: ![ajayraghuraj](https://avatars.discourse-cdn.com/v4/letter/a/e68b1a/32.png) [@ajayraghuraj](https://discuss.elastic.co/u/ajayraghuraj)
#### Post date: [June 8, 2020, 3:24pm UTC](https://discuss.elastic.co/t/logstash-filter-ruby/235677/5 "2020-06-08T15:24:06Z")

</div>

still getting same errors.

converted to integer  
a = event.get("value").to\_i

then I reconstructed the filter suspecting array syntax is not proper. landed with the same errors

```
ruby {
 code => '
     a = event.get("[value]")
     if a
         sum = 0
         a.each_index { |x|
             sum += a[x]["value"]
         }
         event.set("valuepct", [a / sum * 100])
     end
 '
}
```

---

<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: [June 8, 2020, 3:36pm UTC](https://discuss.elastic.co/t/logstash-filter-ruby/235677/6 "2020-06-08T15:36:24Z")

</div>

[value] is not an array, so you cannot iterate over it.

---

<div class="post-metadata">

### Author: ![ajayraghuraj](https://avatars.discourse-cdn.com/v4/letter/a/e68b1a/32.png) [@ajayraghuraj](https://discuss.elastic.co/u/ajayraghuraj)
#### Post date: [June 9, 2020, 5:02am UTC](https://discuss.elastic.co/t/logstash-filter-ruby/235677/7 "2020-06-09T05:02:41Z")

</div>

okay so how do I loop into the values , add them and calculate the percentage ?

---

<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: [June 9, 2020, 11:21am UTC](https://discuss.elastic.co/t/logstash-filter-ruby/235677/8 "2020-06-09T11:21:07Z")

</div>

These are seperate events with one integer value each, aren't they? So you don't even have access to the data you are trying to process unless you aggregate the events first, calculate the percentages and split them again afterwards.

---

<div class="post-metadata">

### Author: ![ajayraghuraj](https://avatars.discourse-cdn.com/v4/letter/a/e68b1a/32.png) [@ajayraghuraj](https://discuss.elastic.co/u/ajayraghuraj)
#### Post date: [June 9, 2020, 12:17pm UTC](https://discuss.elastic.co/t/logstash-filter-ruby/235677/9 "2020-06-09T12:17:32Z")

</div>

yes they are separate events with integer values. I wrote the aggregate filter . Can someone validate it please ? eventually I need to get a percentage value for 'buffered' 'free' 'used' 'cached' in a separate field like 'valuepct'

```
 aggregate {
 task_id => "%{type_instance}"
 code => "
 map['sum'] ||= 0; map['sum'] += event.get('value').to_i;
 event.set('valuepct', [event.get('value').to_i/event.get('sum').to_i * 100])
 "
}

```

Errors

```
[2020-06-09T20:17:07,491][ERROR][logstash.filters.aggregate] Aggregate exception occurred {:error=>#<ZeroDivisionError: divided by 0>, :code=>"\n\t\t\tmap['sum'] ||= 0; map['sum'] += event.get('value').to_i;\n\t\t\tevent.set('valuepct', [event.get('value').to_i/event.get('sum').to_i * 100])\n\t\t\t", :map=>{"sum"=>9761632256}, :event_data=>{"@timestamp"=>2020-06-09T12:16:57.000Z, "type_instance"=>"free", "plugin"=>"memory", "host"=>"rhel5vm3", "@version"=>"1", "collectd_type"=>"memory", "type"=>"collectd", "value"=>3425472512.0}}
```

---

<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: [June 9, 2020, 1:05pm UTC](https://discuss.elastic.co/t/logstash-filter-ruby/235677/10 "2020-06-09T13:05:06Z")

</div>

1. If you use type\_instance as the task id you will get 4 maps instead of one. The task id has to be a value that the events share.
2. Your event doesn't have a field "sum", your map has.
3. You cannot use the sum while processing the events because it isn't completed at that point. When the first event is beeing processed the sum is only this event's value, so the percentage is 100%. When the second is being processed, the sum is only the sum of these first two events. etc.

I think you will have to collect all the events in your map first, calculcate the sum and percentages and seperate them with a split filter.

---

<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 7, 2020, 1:05pm UTC](https://discuss.elastic.co/t/logstash-filter-ruby/235677/11 "2020-07-07T13:05:07Z")

</div>

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