# Replacing all instances of a string in nested JSON

**URL:** <https://discuss.elastic.co/t/replacing-all-instances-of-a-string-in-nested-json/299152>\
**Category:** Logstash\
**Created:** [March 9, 2022, 12:40am UTC](https://discuss.elastic.co/t/replacing-all-instances-of-a-string-in-nested-json/299152 "2022-03-09T00:40:14Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![7armyant](https://avatars.discourse-cdn.com/v4/letter/7/53a042/32.png) [@7armyant](https://discuss.elastic.co/u/7armyant)\
**Post date:** [March 9, 2022, 12:40am UTC](https://discuss.elastic.co/t/replacing-all-instances-of-a-string-in-nested-json/299152/1 "2022-03-09T00:40:14Z")

</div>

Hi Gurus,

I'm new to logstash and have had little success with the following.  
I have been trying to relace all instances of a sting in nested JSON.  
Below is the JSON in question:

```auto
"{"totalCount":
	2,
"nextPageKey":
	null,
"resolution":
	"Inf",
"result":[
	{"metricId":
		"builtin:synthetic.browser.availability.location.totalWoMaintenanceWindow",
	"data":[
		{"dimensions":
			["SYNTHETIC_TEST-XXXXXXXXXXXX","GEOLOCATION-YYYYYYYYYYYYY"],
		"dimensionMap":
			{"dt.entity.synthetic_test":
				"SYNTHETIC_TEST-XXXXXXXXXXXX",
			"dt.entity.geolocation\":
				"GEOLOCATION-YYYYYYYYYYYYY"},
		"timestamps":
			[1646705640000],
		"values":
			[100]
		},

		{"dimensions":[
			"SYNTHETIC_TEST-XXXXXXXXXXXX","GEOLOCATION-XXXXXXXXXXXX"],
		"dimensionMap":
			{"dt.entity.synthetic_test":
				"SYNTHETIC_TEST-XXXXXXXXXXXX",
			"dt.entity.geolocation":
				"GEOLOCATION-XXXXXXXXXXXX"},
		"timestamps":
			[1646705640000],
		"values":
			[100]
	}
	]}
]}"

```

The values I need to replace are the SYNTHETIC\_TEST-XXXXXXXXXXXX and GEOLOCATION-XXXXXXXXXXXX values with a variable in the logstash config.

I then need to pull out each of the "values" and create a field like such:  
{GEOVAR1} =\> 100  
{GEOVAR2} =\> 100

Any help would be greatly appreciated.

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:** [March 9, 2022, 1:43am UTC](https://discuss.elastic.co/t/replacing-all-instances-of-a-string-in-nested-json/299152/2 "2022-03-09T01:43:20Z")

</div>

> [@7armyant](#):
>
> The values I need to replace are the SYNTHETIC\_TEST-XXXXXXXXXXXX and GEOLOCATION-XXXXXXXXXXXX values with a variable in the logstash config.

What do you mean by "variable"? Is it the value of another field?

---

<div class="post-metadata">

**Author:** ![7armyant](https://avatars.discourse-cdn.com/v4/letter/7/53a042/32.png) [@7armyant](https://discuss.elastic.co/u/7armyant)\
**Post date:** [March 9, 2022, 2:29am UTC](https://discuss.elastic.co/t/replacing-all-instances-of-a-string-in-nested-json/299152/3 "2022-03-09T02:29:04Z")

</div>

Hi Badger,

I have recently taken over the administration of our logstash instances.

We currently have an environment file that is loaded on the start of the logstash instance.  
That file contains a number of variables that are used in various pipelines for things such as environments or authentication tokens.  
I was hoping to populate that file with variables for the GEOLOCATIONS to save time building and maintaining the many pipelines ill be building as part of this.

If this is not recommended then specifying them in the pipelines is also fine.

---

<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:** [March 9, 2022, 3:20am UTC](https://discuss.elastic.co/t/replacing-all-instances-of-a-string-in-nested-json/299152/4 "2022-03-09T03:20:51Z")

</div>

Using environment variables is fine. You can [reference them](https://www.elastic.co/guide/en/logstash/current/environment-variables.html) in the configuration.

If there are always two entries in the array you could do it using

```
    json { source => "message" remove_field => ["message"] }
    mutate {
        gsub => [
            "[result][0][data][0][dimensions][0]", "SYNTHETIC_TEST-\w+", "${SYNTHETIC_TEST}",
            "[result][0][data][0][dimensions][1]", "GEOLOCATION-\w+", "${GEOLOCATION}",
            "[result][0][data][0][dimensionMap][dt.entity.synthetic_test]", "SYNTHETIC_TEST-\w+", "${SYNTHETIC_TEST}",
            "[result][0][data][0][dimensionMap][dt.entity.geolocation]", "GEOLOCATION-\w+", "${GEOLOCATION}",

            "[result][0][data][1][dimensions][0]", "SYNTHETIC_TEST-\w+", "${SYNTHETIC_TEST}",
            "[result][0][data][1][dimensions][1]", "GEOLOCATION-\w+", "${GEOLOCATION}",
            "[result][0][data][1][dimensionMap][dt.entity.synthetic_test]", "SYNTHETIC_TEST-\w+", "${SYNTHETIC_TEST}",
            "[result][0][data][1][dimensionMap][dt.entity.geolocation]", "GEOLOCATION-\w+", "${GEOLOCATION}"
        ]
    }
    mutate {
        add_field => {
            "GEOVAR1" => "%{[result][0][data][0][values][0]}"
            "GEOVAR2" => "%{[result][0][data][1][values][0]}"
        }
    }

```

If the array ever changes size then I would iterate over it in ruby...

```
    json { source => "message" remove_field => ["message"] }
    ruby {
        code => '
            result = event.get("result")
            if result.is_a? Array
                data = result[0]["data"]
                if data.is_a? Array
                    data.each_index { |i|
                        event.set("GEOVAR#{i+1}", data[i]["values"][0])

                        data[i]["dimensions"][0] =
                            data[i]["dimensions"][0].sub(/SYNTHETIC_TEST-\w+/, ENV["SYNTHETIC_TEST"])
                        data[i]["dimensionMap"]["dt.entity.synthetic_test"] =
                            data[i]["dimensionMap"]["dt.entity.synthetic_test"].sub(/SYNTHETIC_TEST-\w+/, ENV["SYNTHETIC_TEST"])

                        data[i]["dimensions"][1] =
                            data[i]["dimensions"][1].sub(/GEOLOCATION-\w+/, ENV["GEOLOCATION"])
                        data[i]["dimensionMap"]["dt.entity.geolocation"] =
                            data[i]["dimensionMap"]["dt.entity.geolocation"].sub(/GEOLOCATION-\w+/, ENV["GEOLOCATION"])
                    }
                    event.set("[result][0][data]", data)
                end
            end
        '
    }
```

---

<div class="post-metadata">

**Author:** ![7armyant](https://avatars.discourse-cdn.com/v4/letter/7/53a042/32.png) [@7armyant](https://discuss.elastic.co/u/7armyant)\
**Post date:** [March 9, 2022, 4:39am UTC](https://discuss.elastic.co/t/replacing-all-instances-of-a-string-in-nested-json/299152/5 "2022-03-09T04:39:17Z")

</div>

You are a man of magic.  
That worked for me perfectly.

Thank you so much.

---

<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:** [April 6, 2022, 4:39am UTC](https://discuss.elastic.co/t/replacing-all-instances-of-a-string-in-nested-json/299152/6 "2022-04-06T04:39:19Z")

</div>

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