# How can I add this ruby code?

**URL:** https://discuss.elastic.co/t/how-can-i-add-this-ruby-code/152580
**Category:** Logstash
**Created:** [October 16, 2018, 2:41am UTC](https://discuss.elastic.co/t/how-can-i-add-this-ruby-code/152580 "2018-10-16T02:41:54Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![Sjaak01](https://avatars.discourse-cdn.com/v4/letter/s/73ab20/32.png) [@Sjaak01](https://discuss.elastic.co/u/Sjaak01)
#### Post date: [October 16, 2018, 2:41am UTC](https://discuss.elastic.co/t/how-can-i-add-this-ruby-code/152580/1 "2018-10-16T02:41:54Z")

</div>

Hi,

I have GPS coordinates in DMS (degree minute second) that I need to convert to DD (decimal degrees) so they can be used in Elastic as geo points.

I already wrote I probably not very good filter to convert South and West values to negatives.

```
if [gps_lat] =~ /[SW]$/ {
 mutate {
      gsub => [
      "gps_lat", "\D", " "
    ]
      strip => ["gps_lat"]
      #add_field => { "gps_lat2" => "-%{gps_lat}" }

```

Output:  
11 22 33  
Or  
-11 22 33

Now I need a way to perform the following calculations to convert the values.

North/East

```auto
deg + (min / 60.0) + (sec / 3600.0)

```

South/West

```auto
deg - (min / 60.0) - (sec / 3600.0)

```

I found this ruby code online but simply copy/pasting it to a ruby code block doesn't work. No surprise. How can I get logstash to perform the calculation on the gps fields?

```auto
   @to_decimal = lambda do |str|
     deg, min, sec = str.split(" ").map(&:to_f)
     if deg >= 0
       output = deg + (min / 60.0) + (sec / 3600.0)
     elsif deg < #HARD EARNED KNOWLEDGE HERE
       output = deg - (min / 60.0) - (sec / 3600.0)
     end
     raise "something is wrong" if output.abs > 180
     output
   end

```

Source: [https://stackoverflow.com/questions/1774781/how-do-i-convert-coordinates-to-google-friendly-coordinates](https://stackoverflow.com/questions/1774781/how-do-i-convert-coordinates-to-google-friendly-coordinates)

---

<div class="post-metadata">

### Author: ![OphyTe](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/ophyte/32/36444_2.png) [@OphyTe](https://discuss.elastic.co/u/OphyTe)
#### Post date: [October 16, 2018, 8:55am UTC](https://discuss.elastic.co/t/how-can-i-add-this-ruby-code/152580/2 "2018-10-16T08:55:09Z")

</div>

Hi Sjaak,

Did you try to put it in a ruby file like explain in [the doc](https://www.elastic.co/guide/en/logstash/current/plugins-filters-ruby.html#_using_a_ruby_script_file) ?

For instance you set your ruby plugin like this :

```
filter {
  ruby {
    path => "/usr/share/logstash/dms2dd.rb"
    script_params => { "gps_lat" => #{gps_lat2} }
  }
}

```

And you create the `/usr/share/logstash/dms2dd.rb` ruby file :

```
# the value of `params` is the value of the hash passed to `script_params`
# in the logstash configuration
def register(params)
    @str = params["gps_lat"]
end

# the filter method receives an event and must return a list of events.
# Dropping an event means not including it in the return array,
# while creating new ones only requires you to add a new instance of
# LogStash::Event to the returned array
def filter(event)
    deg, min, sec = @str.split(" ").map(&:to_f)
    if deg >= 0
        output = deg + (min / 60.0) + (sec / 3600.0)
    elsif deg < #HARD EARNED KNOWLEDGE HERE
        output = deg - (min / 60.0) - (sec / 3600.0)
    end
    raise "something is wrong" if output.abs > 180
    event.set("dd", output)
    return [event]
end

```

You should have your converted coordinates in the "dd" field.

---

<div class="post-metadata">

### Author: ![Sjaak01](https://avatars.discourse-cdn.com/v4/letter/s/73ab20/32.png) [@Sjaak01](https://discuss.elastic.co/u/Sjaak01)
#### Post date: [October 17, 2018, 12:43am UTC](https://discuss.elastic.co/t/how-can-i-add-this-ruby-code/152580/3 "2018-10-17T00:43:58Z")

</div>

Thanks @OphyTe, but unfortunately I can't get it working.

```auto
script_params => { "gps_lat" => #{gps_lat2} }

```

Causes configuration errors. If I change it to "gps\_lat2" then the ruby filter fails with

> Could not process event: undefined method `/' for nil:NilClass

Looks like somehow it can't get the gps\_lat value? I tried looking at some examples and read the docs but there isn't much information about what is what.

I did manage to make a very ugly version myself by using a if conditional to check the location (N/E/S/W), then apply a grok filter to slice up the value in three fields, use a ruby calculation on each field, and finally a mutate to put it all back together.

It works but the whole thing is like 150 lines... Would much rather get it working through this .rb.

---

<div class="post-metadata">

### Author: ![OphyTe](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/ophyte/32/36444_2.png) [@OphyTe](https://discuss.elastic.co/u/OphyTe)
#### Post date: [October 17, 2018, 9:59am UTC](https://discuss.elastic.co/t/how-can-i-add-this-ruby-code/152580/4 "2018-10-17T09:59:03Z")

</div>

Hi Sjaak,

You're probably right, it should be `script_params => { "gps_lat" => gps_lat2 }`.

For the next issue, I'm not a ruby master and I'm really not comfortable with the first lines syntax of the code block you gave in your first message. I've just copied it . Have you tried something really simple like

```
def register(params)
    @str = params["gps_lat"]
end

def filter(event)
    puts "str = @str"
    return [event]
end

```

And then if it works, try to put you logic in it ...  
For the record I would have written it like this 😊 :

```
 def register(params)
    @str = params["gps_lat"]
end

def filter(event)
    ddArray = @str.split(" ").map(&:to_f)
    deg = ddArray[0]
    min = ddArray[1]
    sec = ddArray[2]
    if deg >= 0
        output = deg + (min / 60.0) + (sec / 3600.0)
    else
        output = deg - (min / 60.0) - (sec / 3600.0)
    end
    raise "something is wrong" if output.abs > 180
    event.set("dd", output)
    return [event]
end
```

---

<div class="post-metadata">

### Author: ![Sjaak01](https://avatars.discourse-cdn.com/v4/letter/s/73ab20/32.png) [@Sjaak01](https://discuss.elastic.co/u/Sjaak01)
#### Post date: [October 21, 2018, 11:33pm UTC](https://discuss.elastic.co/t/how-can-i-add-this-ruby-code/152580/5 "2018-10-21T23:33:10Z")

</div>

Thanks, I will try it out.

---

<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: [November 18, 2018, 11:33pm UTC](https://discuss.elastic.co/t/how-can-i-add-this-ruby-code/152580/6 "2018-11-18T23:33:14Z")

</div>

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