Skip to content

Add EMF config that enables adding extra properties to the EMF record#6259

Merged
dlvenable merged 1 commit into
opensearch-project:mainfrom
mzurita-amz:emf-additional-properties-config
Nov 12, 2025
Merged

Add EMF config that enables adding extra properties to the EMF record#6259
dlvenable merged 1 commit into
opensearch-project:mainfrom
mzurita-amz:emf-additional-properties-config

Conversation

@mzurita-amz

Copy link
Copy Markdown
Contributor

Description

Adds EMF configuration to the DataPrepper config schema. This config supports adding additional properties to the EMF record by specifying the following in the config:

emf:
    additional_properties: 
        test_property: "test_value"
        environment": "integration_test"

This will generate an EMF record with the following:

{
  "_aws": {
    "Timestamp": 1762919187031,
    "CloudWatchMetrics": [
      {
        "Namespace": "DataPrepper",
        "Metrics": [
          {"Name": "test-pipeline.s3-source.s3ObjectsFailed.count", "Unit": "Count"},
          // ... other metrics
        ],
        "Dimensions": [[]]
      }
    ]
  },
  "test_property": "test_value",           // ✅ OUR ADDITIONAL PROPERTY!
  "environment": "integration_test",       // ✅ OUR ADDITIONAL PROPERTY!
  "test-pipeline.s3-source.s3ObjectsFailed.count": 1.0,
  "test-pipeline.s3-source.s3ObjectsSucceeded.count": 0.0,
  // ... other metric values
}

Issues Resolved

N/A

Check List

  • New functionality includes testing.
  • [-] New functionality has a documentation issue. Please link to it in this PR.
    • [-] New functionality has javadoc added
  • Commits are signed with a real name per the DCO

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.

@mzurita-amz mzurita-amz force-pushed the emf-additional-properties-config branch from 9ea2b83 to 89e7833 Compare November 12, 2025 03:57
@dlvenable dlvenable added this to the v2.13 milestone Nov 12, 2025

@dlvenable dlvenable left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @mzurita-amz for this metrics improvement! I have a few comments.

final List<MetricTagFilter> metricTagFilters,
@JsonProperty("disabled_metrics")
final List<String> disabledMetrics,
@JsonProperty("emf")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is probably better to rename to emf_metrics to help make it clearer to somebody reading the config.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in next rev

import java.util.Map;

public interface EMFLoggingRegistryConfig extends StepRegistryConfig {
EMFLoggingRegistryConfig DEFAULT = k -> null;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we remove this now?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ADdressed in next rev

final List<MetricsLogger> metricsLoggers = registryWithProperties.metricsLoggers();

assertThat(metricsLoggers.size(), equalTo(1));
// Note: We can't directly verify putProperty calls without mocking the MetricsLogger

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What other options do we have to verify this?

I see that these tests do not currently test the flush() method. But, maybe that would be ideal.

  1. Create a mock for ISink.
  2. Perform a flush.
  3. Extract the MetricsContext provided to your mock.
  4. Assert the property exists on getProperty
  5. Assert there is no dimension in getDimensions

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This works so far, though it is rough code and doesn't completely test it.

    @Test
    void testAdditionalPropertiesAreAddedToMetricsLogger_v2() {
        final Map<String, String> additionalProperties = Map.of("key1", "value1", "key2", "value2");
        final EMFLoggingRegistryConfig config = new EMFLoggingRegistryConfig() {
            @Override
            public String get(String key) {
                return null;
            }

            @Override
            public Map<String, String> additionalProperties() {
                return additionalProperties;
            }
        };

        Environment environment = mock(Environment.class);

        ISink sink = mock(ISink.class);
        when(environment.getSink()).thenReturn(sink);

        final EMFLoggingMeterRegistry registryWithProperties = new EMFLoggingMeterRegistry(
                config, environment, clock);

        registryWithProperties.gauge("test_gauge", 1.0);

        registryWithProperties.publish();

        ArgumentCaptor<MetricsContext> contextArgumentCaptor = ArgumentCaptor.forClass(MetricsContext.class);
        verify(sink).accept(contextArgumentCaptor.capture());

        MetricsContext actualMetricsContext = contextArgumentCaptor.getValue();

        assertThat(actualMetricsContext.getProperty("key1"), equalTo("value1"));
        assertThat(actualMetricsContext.getProperty("key2"), equalTo("value2"));
    }

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ADdressed in next rev. Made the test so it checks specific properties and its values.


@Test
void testAdditionalPropertiesAreAddedToMetricsLogger() {
final Map<String, String> additionalProperties = Map.of("key1", "value1", "key2", "value2");

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use random keys and values for testing.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed next revision


@Override
public Map<String, String> additionalProperties() {
return dataPrepperConfiguration.getEmfAdditionalProperties();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NIT: Don't know if we want to return a copy to avoid mutating the map outside of the object.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or wrap in an unmodifiableMap.

return Collections.unmodifiableMap(dataPrepperConfiguration.getEmfAdditionalProperties());

Comment on lines +381 to +382
// Note: We can't directly verify putProperty calls without mocking the MetricsLogger
// This test verifies the registry can be created with additional properties config

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where can we verify that?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed this test in next revision

@dlvenable dlvenable left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @mzurita-amz !


@Override
public Map<String, String> additionalProperties() {
return dataPrepperConfiguration.getEmfAdditionalProperties();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or wrap in an unmodifiableMap.

return Collections.unmodifiableMap(dataPrepperConfiguration.getEmfAdditionalProperties());

dinujoh
dinujoh previously approved these changes Nov 12, 2025

@viquer viquer left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The small original comment still stands (return a copy, unmodifiable copy, of the properties), but I would not block on that for now.

return new EMFLoggingRegistryConfig() {
@Override
public String get(String key) {
return null;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe it's better to throw an exception if we don't really expect this to be called. A new IllegalStateException("This method should never be called on normal circumstances")

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this method is used internally

@mzurita-amz mzurita-amz force-pushed the emf-additional-properties-config branch 5 times, most recently from ce86802 to 6f71e89 Compare November 12, 2025 18:43
Signed-off-by: Manuel Mangas Zurita <mzurita@amazon.com>
@mzurita-amz mzurita-amz force-pushed the emf-additional-properties-config branch from 6f71e89 to 46973a6 Compare November 12, 2025 19:03

@dlvenable dlvenable left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @mzurita-amz for this improvement!

@dlvenable dlvenable merged commit 6b42c1a into opensearch-project:main Nov 12, 2025
45 of 47 checks passed
@mzurita-amz mzurita-amz deleted the emf-additional-properties-config branch November 13, 2025 22:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants