# Create Helper Functions within Pipeline

**URL:** <https://discuss.elastic.co/t/create-helper-functions-within-pipeline/351581>\
**Category:** Logstash\
**Created:** [January 22, 2024, 10:12pm UTC](https://discuss.elastic.co/t/create-helper-functions-within-pipeline/351581 "2024-01-22T22:12:29Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![michael\_c\_michael](https://avatars.discourse-cdn.com/v4/letter/m/ecccb3/32.png) [@michael\_c\_michael](https://discuss.elastic.co/u/michael_c_michael)\
**Post date:** [January 22, 2024, 10:12pm UTC](https://discuss.elastic.co/t/create-helper-functions-within-pipeline/351581/1 "2024-01-22T22:12:29Z")

</div>

I have a function in my pipeline that does some math and another that does some translation. Is there a way to create a function like in python, so that I don't have to retype the same code everytime I want to do this operation.

i.e. below, I take x,y,z coordinates and get lat,long,altitude.

```auto
    - pipeline.id: entity-state-processing
      config.string: |
        input { pipeline { address => entitystatelogs } }
        filter {
          if [attributes][entityLocation] {
            mutate {
              add_field => {
              "[location]" => "null"
              "[altitude]" => "null"
              }
            }
            # Ruby script to convert the cartesian x,y,z coordinates into lat/long
            ruby {
              init => "
                R = 6360000
                "
              code => "
                x = event.get('[attributes][entityLocation][x]').to_f
                y = event.get('[attributes][entityLocation][y]').to_f
                z = event.get('[attributes][entityLocation][z]').to_f

                range = Math.sqrt(x*x + y*y + z*z)

                lat = 180*Math.asin(z/range)/Math::PI
                long = 180*Math.atan2(y,x)/Math::PI
                alt = range - 6369783.457722581

                event.set('[location]', lat.to_s + ',' + long.to_s)
                event.set('[altitude]', alt.to_s)
                "
            }
          }
          if [attributes][entityType] {
            mutate {
              add_field => {
              "Entity" => "%{[attributes][entityType][entityKind]}.%{[attributes][entityType][domain]}.%{[attributes][entityType][country]}.%{[attributes][entityType][category]}.%{[attributes][entityType][subcategory]}.%{[attributes][entityType][specific]}.%{[attributes][entityType][extra]}"
              }
            }
          }
        translate {
          regex => true
          source => "Entity"
          dictionary_path => "/usr/share/logstash/advanced_mappings.json"
          }
        }
        output {
          # Sends parsed logs to elasticsearch
          elasticsearch {
            hosts => ["${OUTPUT_HOST}"]
            user => "${ELASTIC_USER}"
            password => "${ELASTIC_PASS}"
            index => "{{ .Release.Namespace }}-entity-state-%{+yyyy.MM.dd}"
            }
        }

```

I'm wondering, is there a way to take the ruby script and put it in a function like `get_lla(x, y, z)` that returns `latitude, longitude, altitude`.

Additionally, could I take this function:

```auto
add_field => {
              "Entity" => "%{[attributes][entityType][entityKind]}.%{[attributes][entityType][domain]}.%{[attributes][entityType][country]}.%{[attributes][entityType][category]}.%{[attributes][entityType][subcategory]}.%{[attributes][entityType][specific]}.%{[attributes][entityType][extra]}"
              }

```

and turn it into a function like

```auto
add_field(string first_category, string second_category, list third_categories)

```

---

<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:** [January 22, 2024, 10:15pm UTC](https://discuss.elastic.co/t/create-helper-functions-within-pipeline/351581/2 "2024-01-22T22:15:50Z")

</div>

> [@michael\_c\_michael](#):
>
> so that I don't have to retype the same code everytime I want to do this operation.

Do you mean you want the same ruby filter in multiple pipelines, or multiple instances of very similar ruby filters in the same pipeline? If so, use a [ruby script file](https://www.elastic.co/guide/en/logstash/current/plugins-filters-ruby.html#plugins-filters-ruby-using-script-file).

---

<div class="post-metadata">

**Author:** ![michael\_c\_michael](https://avatars.discourse-cdn.com/v4/letter/m/ecccb3/32.png) [@michael\_c\_michael](https://discuss.elastic.co/u/michael_c_michael)\
**Post date:** [January 24, 2024, 11:36pm UTC](https://discuss.elastic.co/t/create-helper-functions-within-pipeline/351581/3 "2024-01-24T23:36:47Z")

</div>

Okay, so can I change fields from within ruby, like in the following ruby script:

```auto
def ecefToLLA(event)
    R = 6360000
    x = event.get('[attributes][entityLocation][x]').to_f
    y = event.get('[attributes][entityLocation][y]').to_f
    z = event.get('[attributes][entityLocation][z]').to_f 
    range = Math.sqrt(x*x + y*y + z*z)
    lat = 180*Math.asin(z/range)/Math::PI
    long = 180*Math.atan2(y,x)/Math::PI
    alt = range - 6369783.457722581
    event.set('[location]', lat.to_s + ',' + long.to_s)
    event.set('[altitude]', alt.to_s)
    return event

```

And in the pipeline, I would do:

```auto
filter {
    if [attributes][entityLocation] {
        mutate {
            add_field => {
                "location]" => "null"
                "[altitude]" => "null"
            }
            # Ruby script to convert the cartesian x,y,z coordinates into lat/long
            ruby {
                path => "/etc/logstash/ecefToLLA.rb"
            }
        }
    }
}
```

---

<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:** [January 24, 2024, 11:54pm UTC](https://discuss.elastic.co/t/create-helper-functions-within-pipeline/351581/4 "2024-01-24T23:54:40Z")

</div>

> [@michael\_c\_michael](#):
>
> `return event`

That should be `return [event]`, the function has to return an array.

---

<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:** [February 21, 2024, 11:55pm UTC](https://discuss.elastic.co/t/create-helper-functions-within-pipeline/351581/5 "2024-02-21T23:55:33Z")

</div>

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