# Logstash dynamically create field name

**URL:** <https://discuss.elastic.co/t/logstash-dynamically-create-field-name/246326>\
**Category:** Logstash\
**Created:** [August 25, 2020, 4:42pm UTC](https://discuss.elastic.co/t/logstash-dynamically-create-field-name/246326 "2020-08-25T16:42:35Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![elasticforme](https://avatars.discourse-cdn.com/v4/letter/e/f05b48/32.png) [@elasticforme](https://discuss.elastic.co/u/elasticforme)\
**Post date:** [August 25, 2020, 4:42pm UTC](https://discuss.elastic.co/t/logstash-dynamically-create-field-name/246326/1 "2020-08-25T16:42:35Z")

</div>

this is my input  
{"dataflow":[{"gate": "v204.06", "attrmath":"v206.07"}]}

I want output like  
dataflow.m1: gate  
dataflow.m1\_version: v204.06  
dataflow.m2: attrmath  
dataflow.m2\_version: v206.07

I want this m1, m2, m3 .... dynamically created as this might have 20+ such k/v pair no exact number

how do I do this. I am trying this

```
if [dataflow] {
   ruby {
     code => '
         event.get("[dataflow][0]").each { |k,v|
           event.set("dataflow.m", k)
           event.set("dataflow.m_version", v)
         }
         event.remove("dataflow")
   '
   }
}

```

but how do I make m to m1, m2 m3.....

---

<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:** [August 25, 2020, 4:45pm UTC](https://discuss.elastic.co/t/logstash-dynamically-create-field-name/246326/2 "2020-08-25T16:45:24Z")

</div>

I would try something like

```
if [dataflow] {
   ruby {
     code => '
         index = 1
         event.get("[dataflow][0]").each { |k,v|
           event.set("dataflow.m#{index}", k)
           event.set("dataflow.m#{index}_version", v)
           index += 1
         }
         event.remove("dataflow")
   '
   }
}
```

---

<div class="post-metadata">

**Author:** ![elasticforme](https://avatars.discourse-cdn.com/v4/letter/e/f05b48/32.png) [@elasticforme](https://discuss.elastic.co/u/elasticforme)\
**Post date:** [August 26, 2020, 4:07am UTC](https://discuss.elastic.co/t/logstash-dynamically-create-field-name/246326/3 "2020-08-26T04:07:04Z")

</div>

someone just change this format of message, now I have array but fixed length

dataflow":[{"name":"out","version":"v211.01","Instances":1346560,"elapsed":"0.23"},{"name":"attributes","version":"v207.05","Instances":1346560,elapsed":"0.06"}]

now I have to loop through this array and this k,v pair

output should be  
dataflow.m1=out  
dataflow.m1\_versin=v211.01  
dataflow.m1\_instance=1346560  
dataflow.m1\_elapsed=0.23

dataflow.m2=attributes .........

as you can see I want only first key as value, all other key are not usable.

sorry for confusing out whole thing.

---

<div class="post-metadata">

**Author:** ![elasticforme](https://avatars.discourse-cdn.com/v4/letter/e/f05b48/32.png) [@elasticforme](https://discuss.elastic.co/u/elasticforme)\
**Post date:** [August 26, 2020, 5:32pm UTC](https://discuss.elastic.co/t/logstash-dynamically-create-field-name/246326/4 "2020-08-26T17:32:25Z")

</div>

now I want to rotate in this dataflow[0], dataflow[1], dataflow[2] to the end of array  
and further loop inside for each k,v pair

```
if [dataflow] {
   ruby {
     code => '
         [dataflow].each_with_index { |value,index|
            event.get(value).each { |k, v|
               event.set("dataflow_m#{index}_#{k}", v)
            }
         }
         event.remove("dataflow")
   '
   }
}

```

this should give me something like  
dataflow.m0\_name=out  
dataflow.m0\_version=v211.01  
dataflow.m0\_instance=1346560  
dataflow.m0\_elapsed=0.23

but it does not. gives ruby exception.

---

<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:** [August 26, 2020, 5:57pm UTC](https://discuss.elastic.co/t/logstash-dynamically-create-field-name/246326/5 "2020-08-26T17:57:34Z")

</div>

> [@elasticforme](#):
>
> gives ruby exception.

What is the exception?

---

<div class="post-metadata">

**Author:** ![elasticforme](https://avatars.discourse-cdn.com/v4/letter/e/f05b48/32.png) [@elasticforme](https://discuss.elastic.co/u/elasticforme)\
**Post date:** [August 26, 2020, 6:07pm UTC](https://discuss.elastic.co/t/logstash-dynamically-create-field-name/246326/6 "2020-08-26T18:07:50Z")

</div>

sorry I meant to say it was not assigning value.

here is new code that I have comeup with lot of testing  
I just simplify this. so I will get

dataflow.m0\_name=out  
dataflow.m0\_version=v211.01  
dataflow.m0\_instance=1346560  
dataflow.m0\_elapsed=0.23

```
if [dataflow] {
       ruby {
         code => '
             event.get("dataflow").each { |item| ---> work till here, as I can print item which is whole array
                  index=1
                  event.get("item").each { |k, v|
                       event.set("dataflow_m#{index}_#{k}", v)
                }
                index += 1 
             }
       '
       }
    }

```

something I am missing which is not creating new field.

---

<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:** [August 26, 2020, 6:20pm UTC](https://discuss.elastic.co/t/logstash-dynamically-create-field-name/246326/7 "2020-08-26T18:20:16Z")

</div>

> [@elasticforme](#):
>
> `event.get("item")`

You do not have a field called item, so this will not work.

---

<div class="post-metadata">

**Author:** ![elasticforme](https://avatars.discourse-cdn.com/v4/letter/e/f05b48/32.png) [@elasticforme](https://discuss.elastic.co/u/elasticforme)\
**Post date:** [August 26, 2020, 7:17pm UTC](https://discuss.elastic.co/t/logstash-dynamically-create-field-name/246326/8 "2020-08-26T19:17:06Z")

</div>

it actual works. here is test. but anotyher loop with k,v is not working

```
if [dataflow] {
      ruby {
         code => '
             index=1
             event.get("dataflow").each { |item|
                event.set("flag_#{index}", item["name"])
                index += 1
             }
       '
       }
    }

    output
             "flag_2" => "attributes",
             "flag_1" => "out",
```

---

<div class="post-metadata">

**Author:** ![elasticforme](https://avatars.discourse-cdn.com/v4/letter/e/f05b48/32.png) [@elasticforme](https://discuss.elastic.co/u/elasticforme)\
**Post date:** [August 26, 2020, 10:00pm UTC](https://discuss.elastic.co/t/logstash-dynamically-create-field-name/246326/9 "2020-08-26T22:00:42Z")

</div>

@Badger

I try this and divided this, as test and I got what I need. but I do not know how many array element will I have in dataflow, hence I can't delete them or run iterate on second for loop

any other recommendation?

```
#### this code is dividing array in to { key,value) pairs
         ruby {
             code => '
                 event.get("dataflow").each_with_index { |val,index |
                     event.set("whatisthis_#{index}", val)
                 }
           '
           }

### this one creating new field depending on key and value
        ruby {
           code => '
              for i in 0..1
                 event.get("whatisthis_#{i}").each { |k, v|
                    event.set("dataflow_m#{i}_#{k}", v)
                 }
                event.remove("whatisthis_#{i}")
             end
           '
        }
```

---

<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:** [September 23, 2020, 10:01pm UTC](https://discuss.elastic.co/t/logstash-dynamically-create-field-name/246326/10 "2020-09-23T22:01:06Z")

</div>

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