-
Notifications
You must be signed in to change notification settings - Fork 33
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #176 from vamsi-amazon/main
Add dimensions to cloudwatch metric and metric filter option for CWSink.
- Loading branch information
Showing
7 changed files
with
223 additions
and
41 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
96 changes: 96 additions & 0 deletions
96
flint-core/src/main/java/org/opensearch/flint/core/metrics/reporter/DimensionedName.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
package org.opensearch.flint.core.metrics.reporter; | ||
|
||
import com.amazonaws.services.cloudwatch.model.Dimension; | ||
import java.util.Collections; | ||
import java.util.HashMap; | ||
import java.util.HashSet; | ||
import java.util.Map; | ||
import java.util.Objects; | ||
import java.util.Set; | ||
import java.util.regex.Matcher; | ||
import java.util.regex.Pattern; | ||
import java.util.stream.Collectors; | ||
|
||
public class DimensionedName { | ||
private static final Pattern dimensionPattern = Pattern.compile("([\\w.-]+)\\[([\\w\\W]+)]"); | ||
private final String name; | ||
private final Map<String, Dimension> dimensions; | ||
|
||
private String encoded; | ||
|
||
DimensionedName(final String name, final Map<String, Dimension> dimensions) { | ||
this.name = name; | ||
this.dimensions = Collections.unmodifiableMap(dimensions); | ||
} | ||
|
||
public static DimensionedName decode(final String encodedDimensionedName) { | ||
final Matcher matcher = dimensionPattern.matcher(encodedDimensionedName); | ||
if (matcher.find() && matcher.groupCount() == 2) { | ||
final DimensionedNameBuilder builder = new DimensionedNameBuilder(matcher.group(1).trim()); | ||
for (String t : matcher.group(2).split(",")) { | ||
final String[] keyAndValue = t.split(":"); | ||
builder.withDimension(keyAndValue[0].trim(), keyAndValue[1].trim()); | ||
} | ||
return builder.build(); | ||
} else { | ||
return new DimensionedNameBuilder(encodedDimensionedName).build(); | ||
} | ||
} | ||
|
||
public static DimensionedNameBuilder withName(String name) { | ||
return new DimensionedNameBuilder(name); | ||
} | ||
|
||
public DimensionedNameBuilder withDimension(final String name, final String value) { | ||
return new DimensionedNameBuilder(this.name, new HashMap<>(this.dimensions)).withDimension(name, value); | ||
} | ||
|
||
public String getName() { | ||
return name; | ||
} | ||
|
||
public Set<Dimension> getDimensions() { | ||
return new HashSet<>(dimensions.values()); | ||
} | ||
|
||
public synchronized String encode() { | ||
if (this.encoded == null) { | ||
if (!dimensions.isEmpty()) { | ||
final StringBuilder sb = new StringBuilder(this.name); | ||
sb.append('['); | ||
sb.append(this.dimensions.values().stream() | ||
.map(dimension -> dimension.getName() + ":" + dimension.getValue()) | ||
.collect(Collectors.joining(","))); | ||
sb.append(']'); | ||
|
||
this.encoded = sb.toString(); | ||
} else { | ||
this.encoded = this.name; | ||
} | ||
} | ||
return this.encoded; | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return this.encode(); | ||
} | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) { | ||
return true; | ||
} | ||
if (o == null || getClass() != o.getClass()) { | ||
return false; | ||
} | ||
final DimensionedName that = (DimensionedName) o; | ||
return Objects.equals(name, that.name) && | ||
Objects.equals(dimensions, that.dimensions); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(name, dimensions); | ||
} | ||
} |
28 changes: 28 additions & 0 deletions
28
...core/src/main/java/org/opensearch/flint/core/metrics/reporter/DimensionedNameBuilder.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package org.opensearch.flint.core.metrics.reporter; | ||
|
||
import com.amazonaws.services.cloudwatch.model.Dimension; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
|
||
public class DimensionedNameBuilder { | ||
private final String name; | ||
private Map<String, Dimension> dimensions; | ||
|
||
DimensionedNameBuilder(final String name) { | ||
this(name, new HashMap<>()); | ||
} | ||
|
||
DimensionedNameBuilder(final String name, final Map<String, Dimension> dimensions) { | ||
this.name = name; | ||
this.dimensions = dimensions; | ||
} | ||
|
||
public DimensionedName build() { | ||
return new DimensionedName(this.name, this.dimensions); | ||
} | ||
|
||
public DimensionedNameBuilder withDimension(final String name, final String value) { | ||
this.dimensions.put(name, new Dimension().withName(name).withValue(value)); | ||
return this; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
55 changes: 55 additions & 0 deletions
55
flint-core/src/test/java/opensearch/flint/core/metrics/reporter/DimensionedNameTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
package opensearch.flint.core.metrics.reporter; | ||
|
||
import static org.hamcrest.CoreMatchers.hasItems; | ||
|
||
import com.amazonaws.services.cloudwatch.model.Dimension; | ||
import org.hamcrest.MatcherAssert; | ||
import org.junit.jupiter.api.Assertions; | ||
import org.junit.jupiter.api.Test; | ||
import org.opensearch.flint.core.metrics.reporter.DimensionedName; | ||
|
||
public class DimensionedNameTest { | ||
@Test | ||
public void canDecodeDimensionedString() { | ||
final String dimensioned = "test[key1:val1,key2:val2,key3:val3]"; | ||
|
||
final DimensionedName dimensionedName = DimensionedName.decode(dimensioned); | ||
|
||
Assertions.assertEquals("test", dimensionedName.getName()); | ||
Assertions.assertEquals(3, dimensionedName.getDimensions().size()); | ||
|
||
MatcherAssert.assertThat(dimensionedName.getDimensions(), hasItems( | ||
new Dimension().withName("key1").withValue("val1"), | ||
new Dimension().withName("key2").withValue("val2"), | ||
new Dimension().withName("key3").withValue("val3"))); | ||
} | ||
|
||
@Test | ||
public void canEncodeDimensionedNameToString() { | ||
final DimensionedName dimensionedName = DimensionedName.withName("test") | ||
.withDimension("key1", "val1") | ||
.withDimension("key2", "val2") | ||
.withDimension("key3", "val3") | ||
.build(); | ||
|
||
Assertions.assertEquals("test[key1:val1,key2:val2,key3:val3]", dimensionedName.encode()); | ||
} | ||
|
||
@Test | ||
public void canDeriveDimensionedNameFromCurrent() { | ||
final DimensionedName dimensionedName = DimensionedName.withName("test") | ||
.withDimension("key1", "val1") | ||
.withDimension("key2", "val2") | ||
.withDimension("key3", "val3") | ||
.build(); | ||
|
||
|
||
final DimensionedName derivedDimensionedName = dimensionedName | ||
.withDimension("key3", "new_value") | ||
.withDimension("key4", "val4").build(); | ||
|
||
Assertions.assertEquals("test[key1:val1,key2:val2,key3:val3]", dimensionedName.encode()); | ||
Assertions.assertEquals("test[key1:val1,key2:val2,key3:new_value,key4:val4]", | ||
derivedDimensionedName.encode()); | ||
} | ||
} |