From 9df64aff8d8d4cb25b48ef4d5c28fb7e6cd42ad3 Mon Sep 17 00:00:00 2001 From: Paul Schellenberg Date: Wed, 5 Jun 2024 13:52:26 -0700 Subject: [PATCH 1/6] Allow for STDOUT overrides when using an AgentBasedEnvironment --- examples/README.md | 1 + .../environment/AgentBasedEnvironment.java | 45 +++++---- .../AgentBasedEnvironmentTest.java | 91 +++++++++++++++++++ 3 files changed, 120 insertions(+), 17 deletions(-) create mode 100644 src/test/java/software/amazon/cloudwatchlogs/emf/environment/AgentBasedEnvironmentTest.java diff --git a/examples/README.md b/examples/README.md index 359d61e3..593af7c1 100644 --- a/examples/README.md +++ b/examples/README.md @@ -38,6 +38,7 @@ With Docker images, using the `awslogs` log driver will send your container logs ## ECS and Fargate With ECS and Fargate, you can use the `awslogs` log driver to have your logs sent to CloudWatch Logs on your behalf. After configuring your task to use the `awslogs` log driver, you may write your EMF logs to STDOUT and they will be processed. +To write your EMF logs to STDOUT, set the environment variable `WRITE_TO_STDOUT=true` [ECS documentation on `awslogs` log driver](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/using_awslogs.html) diff --git a/src/main/java/software/amazon/cloudwatchlogs/emf/environment/AgentBasedEnvironment.java b/src/main/java/software/amazon/cloudwatchlogs/emf/environment/AgentBasedEnvironment.java index 232f54fa..0ae4998a 100644 --- a/src/main/java/software/amazon/cloudwatchlogs/emf/environment/AgentBasedEnvironment.java +++ b/src/main/java/software/amazon/cloudwatchlogs/emf/environment/AgentBasedEnvironment.java @@ -20,7 +20,9 @@ import lombok.extern.slf4j.Slf4j; import software.amazon.cloudwatchlogs.emf.Constants; import software.amazon.cloudwatchlogs.emf.config.Configuration; +import software.amazon.cloudwatchlogs.emf.config.SystemWrapper; import software.amazon.cloudwatchlogs.emf.sinks.AgentSink; +import software.amazon.cloudwatchlogs.emf.sinks.ConsoleSink; import software.amazon.cloudwatchlogs.emf.sinks.Endpoint; import software.amazon.cloudwatchlogs.emf.sinks.ISink; import software.amazon.cloudwatchlogs.emf.sinks.SocketClientFactory; @@ -28,11 +30,16 @@ @Slf4j public abstract class AgentBasedEnvironment implements Environment { + private static final String WRITE_TO_STDOUT = "WRITE_TO_STDOUT"; + private final boolean shouldWriteToStdout; private final Configuration config; private ISink sink; protected AgentBasedEnvironment(Configuration config) { this.config = config; + shouldWriteToStdout = Optional.ofNullable(SystemWrapper.getenv(WRITE_TO_STDOUT)) + .map(Boolean::parseBoolean) + .orElse(false); } @Override @@ -67,27 +74,31 @@ public String getLogStreamName() { @Override public ISink getSink() { if (sink == null) { - Endpoint endpoint; - if (config.getAgentEndpoint().isPresent()) { - endpoint = Endpoint.fromURL(config.getAgentEndpoint().get()); + if (shouldWriteToStdout) { + sink = new ConsoleSink(); } else { - log.info( + Endpoint endpoint; + if (config.getAgentEndpoint().isPresent()) { + endpoint = Endpoint.fromURL(config.getAgentEndpoint().get()); + } else { + log.info( "Endpoint is not defined. Using default: {}", Endpoint.DEFAULT_TCP_ENDPOINT); - endpoint = Endpoint.DEFAULT_TCP_ENDPOINT; - } - sink = + endpoint = Endpoint.DEFAULT_TCP_ENDPOINT; + } + sink = new AgentSink( - getLogGroupName(), - getLogStreamName(), - endpoint, - new SocketClientFactory(), - config.getAsyncBufferSize(), - () -> - new FibonacciRetryStrategy( - Constants.MIN_BACKOFF_MILLIS, - Constants.MAX_BACKOFF_MILLIS, - Constants.MAX_BACKOFF_JITTER)); + getLogGroupName(), + getLogStreamName(), + endpoint, + new SocketClientFactory(), + config.getAsyncBufferSize(), + () -> + new FibonacciRetryStrategy( + Constants.MIN_BACKOFF_MILLIS, + Constants.MAX_BACKOFF_MILLIS, + Constants.MAX_BACKOFF_JITTER)); + } } return sink; } diff --git a/src/test/java/software/amazon/cloudwatchlogs/emf/environment/AgentBasedEnvironmentTest.java b/src/test/java/software/amazon/cloudwatchlogs/emf/environment/AgentBasedEnvironmentTest.java new file mode 100644 index 00000000..ce5bcc89 --- /dev/null +++ b/src/test/java/software/amazon/cloudwatchlogs/emf/environment/AgentBasedEnvironmentTest.java @@ -0,0 +1,91 @@ +package software.amazon.cloudwatchlogs.emf.environment; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import software.amazon.cloudwatchlogs.emf.config.Configuration; +import software.amazon.cloudwatchlogs.emf.config.SystemWrapper; +import software.amazon.cloudwatchlogs.emf.model.MetricsContext; +import software.amazon.cloudwatchlogs.emf.sinks.AgentSink; +import software.amazon.cloudwatchlogs.emf.sinks.ConsoleSink; +import software.amazon.cloudwatchlogs.emf.sinks.Endpoint; +import software.amazon.cloudwatchlogs.emf.sinks.ISink; + +import static org.junit.Assert.assertEquals; +import static org.powermock.api.mockito.PowerMockito.mock; + +@RunWith(PowerMockRunner.class) +@PrepareForTest( {SystemWrapper.class, AgentBasedEnvironment.class} ) +public class AgentBasedEnvironmentTest { + public static class AgentBasedEnvironmentTestImplementation extends AgentBasedEnvironment { + protected AgentBasedEnvironmentTestImplementation(Configuration config) { super(config); } + @Override + public boolean probe() { return false; } + @Override + public String getType() { return null; } + @Override + public void configureContext(MetricsContext context) { } + } + + private Configuration configuration; + + @Before + public void setup() { + this.configuration = new Configuration(); + } + + @Test + public void testGetSinkWithDefaultEndpoint() throws Exception { + AgentSink mockedSink = mock(AgentSink.class); + PowerMockito.whenNew(AgentSink.class).withAnyArguments().then(invocation -> { + Endpoint endpoint = invocation.getArgument(2); + assertEquals(Endpoint.DEFAULT_TCP_ENDPOINT, endpoint); + return mockedSink; + }); + + AgentBasedEnvironment env = new AgentBasedEnvironmentTestImplementation(configuration); + ISink sink = env.getSink(); + + assertEquals(mockedSink, sink); + } + + @Test + public void testGetSinkWithConfiguredEndpoint() throws Exception { + String endpointUrl = "http://configured-endpoint:1234"; + configuration.setAgentEndpoint(endpointUrl); + AgentSink mockedSink = mock(AgentSink.class); + PowerMockito.whenNew(AgentSink.class).withAnyArguments().then(invocation -> { + Endpoint endpoint = invocation.getArgument(2); + assertEquals(Endpoint.fromURL(endpointUrl), endpoint); + return mockedSink; + }); + + AgentBasedEnvironment env = new AgentBasedEnvironmentTestImplementation(configuration); + ISink sink = env.getSink(); + + assertEquals(mockedSink, sink); + } + + @Test + public void testGetSinkOverrideToStdOut() { + PowerMockito.mockStatic(SystemWrapper.class); + PowerMockito.when(SystemWrapper.getenv("WRITE_TO_STDOUT")).thenReturn("true"); + + AgentBasedEnvironment env = new AgentBasedEnvironmentTestImplementation(configuration); + ISink sink = env.getSink(); + + assertEquals(ConsoleSink.class, sink.getClass()); + } + + @Test + public void testGetSinkOverrideToStdOutFailFastOnImproperOverride() throws Exception { + PowerMockito.mockStatic(SystemWrapper.class); + // Will only override if this env is explicitly "true" + PowerMockito.when(SystemWrapper.getenv("WRITE_TO_STDOUT")).thenReturn("notABool"); + + testGetSinkWithDefaultEndpoint(); + } +} From d2efe2c8409eaaddcbc47bd05e032c2d7de88feb Mon Sep 17 00:00:00 2001 From: Paul Schellenberg Date: Wed, 5 Jun 2024 13:54:24 -0700 Subject: [PATCH 2/6] replace double space indents with 4 space indents --- .../AgentBasedEnvironmentTest.java | 136 +++++++++--------- 1 file changed, 68 insertions(+), 68 deletions(-) diff --git a/src/test/java/software/amazon/cloudwatchlogs/emf/environment/AgentBasedEnvironmentTest.java b/src/test/java/software/amazon/cloudwatchlogs/emf/environment/AgentBasedEnvironmentTest.java index ce5bcc89..c2f74a5d 100644 --- a/src/test/java/software/amazon/cloudwatchlogs/emf/environment/AgentBasedEnvironmentTest.java +++ b/src/test/java/software/amazon/cloudwatchlogs/emf/environment/AgentBasedEnvironmentTest.java @@ -20,72 +20,72 @@ @RunWith(PowerMockRunner.class) @PrepareForTest( {SystemWrapper.class, AgentBasedEnvironment.class} ) public class AgentBasedEnvironmentTest { - public static class AgentBasedEnvironmentTestImplementation extends AgentBasedEnvironment { - protected AgentBasedEnvironmentTestImplementation(Configuration config) { super(config); } - @Override - public boolean probe() { return false; } - @Override - public String getType() { return null; } - @Override - public void configureContext(MetricsContext context) { } - } - - private Configuration configuration; - - @Before - public void setup() { - this.configuration = new Configuration(); - } - - @Test - public void testGetSinkWithDefaultEndpoint() throws Exception { - AgentSink mockedSink = mock(AgentSink.class); - PowerMockito.whenNew(AgentSink.class).withAnyArguments().then(invocation -> { - Endpoint endpoint = invocation.getArgument(2); - assertEquals(Endpoint.DEFAULT_TCP_ENDPOINT, endpoint); - return mockedSink; - }); - - AgentBasedEnvironment env = new AgentBasedEnvironmentTestImplementation(configuration); - ISink sink = env.getSink(); - - assertEquals(mockedSink, sink); - } - - @Test - public void testGetSinkWithConfiguredEndpoint() throws Exception { - String endpointUrl = "http://configured-endpoint:1234"; - configuration.setAgentEndpoint(endpointUrl); - AgentSink mockedSink = mock(AgentSink.class); - PowerMockito.whenNew(AgentSink.class).withAnyArguments().then(invocation -> { - Endpoint endpoint = invocation.getArgument(2); - assertEquals(Endpoint.fromURL(endpointUrl), endpoint); - return mockedSink; - }); - - AgentBasedEnvironment env = new AgentBasedEnvironmentTestImplementation(configuration); - ISink sink = env.getSink(); - - assertEquals(mockedSink, sink); - } - - @Test - public void testGetSinkOverrideToStdOut() { - PowerMockito.mockStatic(SystemWrapper.class); - PowerMockito.when(SystemWrapper.getenv("WRITE_TO_STDOUT")).thenReturn("true"); - - AgentBasedEnvironment env = new AgentBasedEnvironmentTestImplementation(configuration); - ISink sink = env.getSink(); - - assertEquals(ConsoleSink.class, sink.getClass()); - } - - @Test - public void testGetSinkOverrideToStdOutFailFastOnImproperOverride() throws Exception { - PowerMockito.mockStatic(SystemWrapper.class); - // Will only override if this env is explicitly "true" - PowerMockito.when(SystemWrapper.getenv("WRITE_TO_STDOUT")).thenReturn("notABool"); - - testGetSinkWithDefaultEndpoint(); - } + public static class AgentBasedEnvironmentTestImplementation extends AgentBasedEnvironment { + protected AgentBasedEnvironmentTestImplementation(Configuration config) { super(config); } + @Override + public boolean probe() { return false; } + @Override + public String getType() { return null; } + @Override + public void configureContext(MetricsContext context) { } + } + + private Configuration configuration; + + @Before + public void setup() { + this.configuration = new Configuration(); + } + + @Test + public void testGetSinkWithDefaultEndpoint() throws Exception { + AgentSink mockedSink = mock(AgentSink.class); + PowerMockito.whenNew(AgentSink.class).withAnyArguments().then(invocation -> { + Endpoint endpoint = invocation.getArgument(2); + assertEquals(Endpoint.DEFAULT_TCP_ENDPOINT, endpoint); + return mockedSink; + }); + + AgentBasedEnvironment env = new AgentBasedEnvironmentTestImplementation(configuration); + ISink sink = env.getSink(); + + assertEquals(mockedSink, sink); + } + + @Test + public void testGetSinkWithConfiguredEndpoint() throws Exception { + String endpointUrl = "http://configured-endpoint:1234"; + configuration.setAgentEndpoint(endpointUrl); + AgentSink mockedSink = mock(AgentSink.class); + PowerMockito.whenNew(AgentSink.class).withAnyArguments().then(invocation -> { + Endpoint endpoint = invocation.getArgument(2); + assertEquals(Endpoint.fromURL(endpointUrl), endpoint); + return mockedSink; + }); + + AgentBasedEnvironment env = new AgentBasedEnvironmentTestImplementation(configuration); + ISink sink = env.getSink(); + + assertEquals(mockedSink, sink); + } + + @Test + public void testGetSinkOverrideToStdOut() { + PowerMockito.mockStatic(SystemWrapper.class); + PowerMockito.when(SystemWrapper.getenv("WRITE_TO_STDOUT")).thenReturn("true"); + + AgentBasedEnvironment env = new AgentBasedEnvironmentTestImplementation(configuration); + ISink sink = env.getSink(); + + assertEquals(ConsoleSink.class, sink.getClass()); + } + + @Test + public void testGetSinkOverrideToStdOutFailFastOnImproperOverride() throws Exception { + PowerMockito.mockStatic(SystemWrapper.class); + // Will only override if this env is explicitly "true" + PowerMockito.when(SystemWrapper.getenv("WRITE_TO_STDOUT")).thenReturn("notABool"); + + testGetSinkWithDefaultEndpoint(); + } } From 4ed951a76bb10e668d49321c528a1c9f97b1967d Mon Sep 17 00:00:00 2001 From: Paul Schellenberg Date: Wed, 5 Jun 2024 14:23:31 -0700 Subject: [PATCH 3/6] read WRITE_TO_STDOUT env var to the Configuration object --- .../cloudwatchlogs/emf/config/Configuration.java | 6 ++++++ .../cloudwatchlogs/emf/config/ConfigurationKeys.java | 1 + .../emf/config/EnvironmentConfigurationProvider.java | 3 ++- .../emf/environment/AgentBasedEnvironment.java | 7 +------ .../config/EnvironmentConfigurationProviderTest.java | 12 ++++++++++++ .../emf/environment/AgentBasedEnvironmentTest.java | 7 ++----- 6 files changed, 24 insertions(+), 12 deletions(-) diff --git a/src/main/java/software/amazon/cloudwatchlogs/emf/config/Configuration.java b/src/main/java/software/amazon/cloudwatchlogs/emf/config/Configuration.java index a65b0e71..769cf648 100644 --- a/src/main/java/software/amazon/cloudwatchlogs/emf/config/Configuration.java +++ b/src/main/java/software/amazon/cloudwatchlogs/emf/config/Configuration.java @@ -59,6 +59,8 @@ public class Configuration { /** Queue length for asynchronous sinks. */ @Setter @Getter int asyncBufferSize = Constants.DEFAULT_ASYNC_BUFFER_SIZE; + @Setter private boolean shouldWriteToStdout; + public Optional getServiceName() { return getStringOptional(serviceName); } @@ -92,4 +94,8 @@ private Optional getStringOptional(String value) { } return Optional.of(value); } + + public boolean shouldWriteToStdout() { + return shouldWriteToStdout; + } } diff --git a/src/main/java/software/amazon/cloudwatchlogs/emf/config/ConfigurationKeys.java b/src/main/java/software/amazon/cloudwatchlogs/emf/config/ConfigurationKeys.java index e6247497..5e0bb618 100644 --- a/src/main/java/software/amazon/cloudwatchlogs/emf/config/ConfigurationKeys.java +++ b/src/main/java/software/amazon/cloudwatchlogs/emf/config/ConfigurationKeys.java @@ -28,4 +28,5 @@ public class ConfigurationKeys { public static final String AGENT_ENDPOINT = "AGENT_ENDPOINT"; public static final String ENVIRONMENT_OVERRIDE = "ENVIRONMENT"; public static final String ASYNC_BUFFER_SIZE = "ASYNC_BUFFER_SIZE"; + public static final String WRITE_TO_STDOUT = "WRITE_TO_STDOUT"; } diff --git a/src/main/java/software/amazon/cloudwatchlogs/emf/config/EnvironmentConfigurationProvider.java b/src/main/java/software/amazon/cloudwatchlogs/emf/config/EnvironmentConfigurationProvider.java index 910e6e67..0af3f7f5 100644 --- a/src/main/java/software/amazon/cloudwatchlogs/emf/config/EnvironmentConfigurationProvider.java +++ b/src/main/java/software/amazon/cloudwatchlogs/emf/config/EnvironmentConfigurationProvider.java @@ -42,7 +42,8 @@ static Configuration createConfig() { getEnvVar(ConfigurationKeys.AGENT_ENDPOINT), getEnvironmentOverride(), getIntOrDefault( - ConfigurationKeys.ASYNC_BUFFER_SIZE, Constants.DEFAULT_ASYNC_BUFFER_SIZE)); + ConfigurationKeys.ASYNC_BUFFER_SIZE, Constants.DEFAULT_ASYNC_BUFFER_SIZE), + Boolean.parseBoolean(getEnvVar(ConfigurationKeys.WRITE_TO_STDOUT))); } private static Environments getEnvironmentOverride() { diff --git a/src/main/java/software/amazon/cloudwatchlogs/emf/environment/AgentBasedEnvironment.java b/src/main/java/software/amazon/cloudwatchlogs/emf/environment/AgentBasedEnvironment.java index 0ae4998a..827bec93 100644 --- a/src/main/java/software/amazon/cloudwatchlogs/emf/environment/AgentBasedEnvironment.java +++ b/src/main/java/software/amazon/cloudwatchlogs/emf/environment/AgentBasedEnvironment.java @@ -30,16 +30,11 @@ @Slf4j public abstract class AgentBasedEnvironment implements Environment { - private static final String WRITE_TO_STDOUT = "WRITE_TO_STDOUT"; - private final boolean shouldWriteToStdout; private final Configuration config; private ISink sink; protected AgentBasedEnvironment(Configuration config) { this.config = config; - shouldWriteToStdout = Optional.ofNullable(SystemWrapper.getenv(WRITE_TO_STDOUT)) - .map(Boolean::parseBoolean) - .orElse(false); } @Override @@ -74,7 +69,7 @@ public String getLogStreamName() { @Override public ISink getSink() { if (sink == null) { - if (shouldWriteToStdout) { + if (config.shouldWriteToStdout()) { sink = new ConsoleSink(); } else { Endpoint endpoint; diff --git a/src/test/java/software/amazon/cloudwatchlogs/emf/config/EnvironmentConfigurationProviderTest.java b/src/test/java/software/amazon/cloudwatchlogs/emf/config/EnvironmentConfigurationProviderTest.java index 9e686070..f916781a 100644 --- a/src/test/java/software/amazon/cloudwatchlogs/emf/config/EnvironmentConfigurationProviderTest.java +++ b/src/test/java/software/amazon/cloudwatchlogs/emf/config/EnvironmentConfigurationProviderTest.java @@ -40,6 +40,7 @@ public void getGetConfig() { putEnv("AWS_EMF_AGENT_ENDPOINT", "Endpoint"); putEnv("AWS_EMF_ENVIRONMENT", "Agent"); putEnv("AWS_EMF_ASYNC_BUFFER_SIZE", "9999"); + putEnv("AWS_EMF_WRITE_TO_STDOUT", "true"); Configuration config = EnvironmentConfigurationProvider.createConfig(); @@ -50,6 +51,7 @@ public void getGetConfig() { assertEquals("Endpoint", config.getAgentEndpoint().get()); assertEquals(Environments.Agent, config.getEnvironmentOverride()); assertEquals(9999, config.getAsyncBufferSize()); + assertTrue(config.shouldWriteToStdout()); } @Test @@ -59,10 +61,20 @@ public void invalidEnvironmentValuesFallbackToExpectedDefaults() { // act putEnv("AWS_EMF_ASYNC_BUFFER_SIZE", "NaN"); + putEnv("AWS_EMF_WRITE_TO_STDOUT", "notABool"); // assert Configuration config = EnvironmentConfigurationProvider.createConfig(); assertEquals(100, config.getAsyncBufferSize()); + assertFalse(config.shouldWriteToStdout()); + } + + @Test + public void emptyEnvironmentValuesFallbackToExpectedDefaults() { + // assert + Configuration config = EnvironmentConfigurationProvider.createConfig(); + assertEquals(100, config.getAsyncBufferSize()); + assertFalse(config.shouldWriteToStdout()); } private void putEnv(String key, String value) { diff --git a/src/test/java/software/amazon/cloudwatchlogs/emf/environment/AgentBasedEnvironmentTest.java b/src/test/java/software/amazon/cloudwatchlogs/emf/environment/AgentBasedEnvironmentTest.java index c2f74a5d..25a85d0a 100644 --- a/src/test/java/software/amazon/cloudwatchlogs/emf/environment/AgentBasedEnvironmentTest.java +++ b/src/test/java/software/amazon/cloudwatchlogs/emf/environment/AgentBasedEnvironmentTest.java @@ -71,8 +71,7 @@ public void testGetSinkWithConfiguredEndpoint() throws Exception { @Test public void testGetSinkOverrideToStdOut() { - PowerMockito.mockStatic(SystemWrapper.class); - PowerMockito.when(SystemWrapper.getenv("WRITE_TO_STDOUT")).thenReturn("true"); + configuration.setShouldWriteToStdout(true); AgentBasedEnvironment env = new AgentBasedEnvironmentTestImplementation(configuration); ISink sink = env.getSink(); @@ -82,9 +81,7 @@ public void testGetSinkOverrideToStdOut() { @Test public void testGetSinkOverrideToStdOutFailFastOnImproperOverride() throws Exception { - PowerMockito.mockStatic(SystemWrapper.class); - // Will only override if this env is explicitly "true" - PowerMockito.when(SystemWrapper.getenv("WRITE_TO_STDOUT")).thenReturn("notABool"); + configuration.setShouldWriteToStdout(false); testGetSinkWithDefaultEndpoint(); } From e4ece5836d28b545a1548809e9a92a8018d5d436 Mon Sep 17 00:00:00 2001 From: Paul Schellenberg Date: Wed, 5 Jun 2024 14:27:53 -0700 Subject: [PATCH 4/6] add AWS_EMF_ prefix to the stdout docs --- examples/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/README.md b/examples/README.md index 593af7c1..a94bea5d 100644 --- a/examples/README.md +++ b/examples/README.md @@ -38,7 +38,7 @@ With Docker images, using the `awslogs` log driver will send your container logs ## ECS and Fargate With ECS and Fargate, you can use the `awslogs` log driver to have your logs sent to CloudWatch Logs on your behalf. After configuring your task to use the `awslogs` log driver, you may write your EMF logs to STDOUT and they will be processed. -To write your EMF logs to STDOUT, set the environment variable `WRITE_TO_STDOUT=true` +To write your EMF logs to STDOUT, set the environment variable `AWS_EMF_WRITE_TO_STDOUT=true` [ECS documentation on `awslogs` log driver](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/using_awslogs.html) From ed48e5491f902ed24917a943d5b90485e8e9ca14 Mon Sep 17 00:00:00 2001 From: Paul Schellenberg Date: Thu, 6 Jun 2024 11:35:08 -0700 Subject: [PATCH 5/6] add blump in README for how the new environment variable will work --- README.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/README.md b/README.md index 9083606f..8342e39c 100644 --- a/README.md +++ b/README.md @@ -373,6 +373,24 @@ config.setAgentEndpoint("udp://127.0.0.1:1000"); AWS_EMF_AGENT_ENDPOINT="udp://127.0.0.1:1000" ``` +**WriteToStdout**: For agent-based platforms, setting this configuration to `true` will make the `MetricsLogger` write to `stdout` rather than sending them to the agent. The default value for this configuration is `false`. This configuration has no effect for non-agent-based platforms. + +If an `EnvironmentOverride` is provided, this configuration will apply to the overriden environment if the environment is an agent-based platform + +Example: + +```java +// in process +import software.amazon.cloudwatchlogs.emf.config.Configuration; +import software.amazon.cloudwatchlogs.emf.config.EnvironmentConfigurationProvider; + +Configuration config = EnvironmentConfigurationProvider.getConfig(); +config.setShouldWriteToStdout(true); + +// environment +AWS_EMF_WRITE_TO_STDOUT="true" +``` + ## Thread-safety ### Internal Synchronization From c5a377af6c8d89efa0a55a9966985731e1740824 Mon Sep 17 00:00:00 2001 From: Paul Schellenberg Date: Thu, 13 Jun 2024 10:46:54 -0700 Subject: [PATCH 6/6] run spotlessApply --- .../environment/AgentBasedEnvironment.java | 27 +++++----- .../AgentBasedEnvironmentTest.java | 51 ++++++++++++------- 2 files changed, 46 insertions(+), 32 deletions(-) diff --git a/src/main/java/software/amazon/cloudwatchlogs/emf/environment/AgentBasedEnvironment.java b/src/main/java/software/amazon/cloudwatchlogs/emf/environment/AgentBasedEnvironment.java index 827bec93..c578368a 100644 --- a/src/main/java/software/amazon/cloudwatchlogs/emf/environment/AgentBasedEnvironment.java +++ b/src/main/java/software/amazon/cloudwatchlogs/emf/environment/AgentBasedEnvironment.java @@ -20,7 +20,6 @@ import lombok.extern.slf4j.Slf4j; import software.amazon.cloudwatchlogs.emf.Constants; import software.amazon.cloudwatchlogs.emf.config.Configuration; -import software.amazon.cloudwatchlogs.emf.config.SystemWrapper; import software.amazon.cloudwatchlogs.emf.sinks.AgentSink; import software.amazon.cloudwatchlogs.emf.sinks.ConsoleSink; import software.amazon.cloudwatchlogs.emf.sinks.Endpoint; @@ -77,22 +76,22 @@ public ISink getSink() { endpoint = Endpoint.fromURL(config.getAgentEndpoint().get()); } else { log.info( - "Endpoint is not defined. Using default: {}", - Endpoint.DEFAULT_TCP_ENDPOINT); + "Endpoint is not defined. Using default: {}", + Endpoint.DEFAULT_TCP_ENDPOINT); endpoint = Endpoint.DEFAULT_TCP_ENDPOINT; } sink = - new AgentSink( - getLogGroupName(), - getLogStreamName(), - endpoint, - new SocketClientFactory(), - config.getAsyncBufferSize(), - () -> - new FibonacciRetryStrategy( - Constants.MIN_BACKOFF_MILLIS, - Constants.MAX_BACKOFF_MILLIS, - Constants.MAX_BACKOFF_JITTER)); + new AgentSink( + getLogGroupName(), + getLogStreamName(), + endpoint, + new SocketClientFactory(), + config.getAsyncBufferSize(), + () -> + new FibonacciRetryStrategy( + Constants.MIN_BACKOFF_MILLIS, + Constants.MAX_BACKOFF_MILLIS, + Constants.MAX_BACKOFF_JITTER)); } } return sink; diff --git a/src/test/java/software/amazon/cloudwatchlogs/emf/environment/AgentBasedEnvironmentTest.java b/src/test/java/software/amazon/cloudwatchlogs/emf/environment/AgentBasedEnvironmentTest.java index 25a85d0a..28eeea2e 100644 --- a/src/test/java/software/amazon/cloudwatchlogs/emf/environment/AgentBasedEnvironmentTest.java +++ b/src/test/java/software/amazon/cloudwatchlogs/emf/environment/AgentBasedEnvironmentTest.java @@ -1,5 +1,8 @@ package software.amazon.cloudwatchlogs.emf.environment; +import static org.junit.Assert.assertEquals; +import static org.powermock.api.mockito.PowerMockito.mock; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -14,20 +17,26 @@ import software.amazon.cloudwatchlogs.emf.sinks.Endpoint; import software.amazon.cloudwatchlogs.emf.sinks.ISink; -import static org.junit.Assert.assertEquals; -import static org.powermock.api.mockito.PowerMockito.mock; - @RunWith(PowerMockRunner.class) -@PrepareForTest( {SystemWrapper.class, AgentBasedEnvironment.class} ) +@PrepareForTest({SystemWrapper.class, AgentBasedEnvironment.class}) public class AgentBasedEnvironmentTest { public static class AgentBasedEnvironmentTestImplementation extends AgentBasedEnvironment { - protected AgentBasedEnvironmentTestImplementation(Configuration config) { super(config); } + protected AgentBasedEnvironmentTestImplementation(Configuration config) { + super(config); + } + @Override - public boolean probe() { return false; } + public boolean probe() { + return false; + } + @Override - public String getType() { return null; } + public String getType() { + return null; + } + @Override - public void configureContext(MetricsContext context) { } + public void configureContext(MetricsContext context) {} } private Configuration configuration; @@ -40,11 +49,14 @@ public void setup() { @Test public void testGetSinkWithDefaultEndpoint() throws Exception { AgentSink mockedSink = mock(AgentSink.class); - PowerMockito.whenNew(AgentSink.class).withAnyArguments().then(invocation -> { - Endpoint endpoint = invocation.getArgument(2); - assertEquals(Endpoint.DEFAULT_TCP_ENDPOINT, endpoint); - return mockedSink; - }); + PowerMockito.whenNew(AgentSink.class) + .withAnyArguments() + .then( + invocation -> { + Endpoint endpoint = invocation.getArgument(2); + assertEquals(Endpoint.DEFAULT_TCP_ENDPOINT, endpoint); + return mockedSink; + }); AgentBasedEnvironment env = new AgentBasedEnvironmentTestImplementation(configuration); ISink sink = env.getSink(); @@ -57,11 +69,14 @@ public void testGetSinkWithConfiguredEndpoint() throws Exception { String endpointUrl = "http://configured-endpoint:1234"; configuration.setAgentEndpoint(endpointUrl); AgentSink mockedSink = mock(AgentSink.class); - PowerMockito.whenNew(AgentSink.class).withAnyArguments().then(invocation -> { - Endpoint endpoint = invocation.getArgument(2); - assertEquals(Endpoint.fromURL(endpointUrl), endpoint); - return mockedSink; - }); + PowerMockito.whenNew(AgentSink.class) + .withAnyArguments() + .then( + invocation -> { + Endpoint endpoint = invocation.getArgument(2); + assertEquals(Endpoint.fromURL(endpointUrl), endpoint); + return mockedSink; + }); AgentBasedEnvironment env = new AgentBasedEnvironmentTestImplementation(configuration); ISink sink = env.getSink();