Skip to content

Commit 1a27fcb

Browse files
authored
Default environment (#3)
* Added default environment and configuration * Remove unused dependencies
1 parent bde7e5d commit 1a27fcb

File tree

55 files changed

+1305
-38
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+1305
-38
lines changed

build.gradle

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,12 @@ dependencies {
3333
implementation 'com.fasterxml.jackson.core:jackson-core:2.11.1'
3434
implementation 'com.fasterxml.jackson.core:jackson-annotations:2.11.1'
3535
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.11.1'
36+
implementation 'org.slf4j:slf4j-api:1.7.30'
3637

3738
// Use JUnit test framework
3839
testImplementation 'junit:junit:4.13'
3940
testImplementation 'org.apache.commons:commons-lang3:3.10'
4041
testImplementation "org.mockito:mockito-core:2.+"
42+
testImplementation "org.powermock:powermock-module-junit4:2.0.2"
43+
testImplementation "org.powermock:powermock-api-mockito2:2.0.2"
4144
}

examples/ErrorHandlingExample.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
import software.amazon.awssdk.services.cloudwatchlogs.CloudWatchLogsClient;
44
import software.amazon.awssdk.services.cloudwatchlogs.emf.logger.EMFLogger;
55
import software.amazon.awssdk.services.cloudwatchlogs.emf.logger.FlushException;
6-
import software.amazon.awssdk.services.cloudwatchlogs.emf.logger.sinks.CloudWatchLogsClientSink;
7-
import software.amazon.awssdk.services.cloudwatchlogs.emf.logger.sinks.ConsoleSink;
8-
import software.amazon.awssdk.services.cloudwatchlogs.emf.logger.sinks.MultiSink;
6+
import software.amazon.awssdk.services.cloudwatchlogs.emf.sinks.CloudWatchLogsClientSink;
7+
import software.amazon.awssdk.services.cloudwatchlogs.emf.sinks.ConsoleSink;
8+
import software.amazon.awssdk.services.cloudwatchlogs.emf.sinks.MultiSink;
99
import software.amazon.awssdk.services.cloudwatchlogs.emf.model.CloudwatchMetricCollection;
1010
import software.amazon.awssdk.services.cloudwatchlogs.emf.model.EMFLogItem;
1111

examples/Examples.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66
import software.amazon.awssdk.services.cloudwatchlogs.CloudWatchLogsClient;
77
import software.amazon.awssdk.services.cloudwatchlogs.emf.logger.EMFLogger;
88
import software.amazon.awssdk.services.cloudwatchlogs.emf.logger.FlushException;
9-
import software.amazon.awssdk.services.cloudwatchlogs.emf.logger.sinks.CloudWatchLogsClientSink;
10-
import software.amazon.awssdk.services.cloudwatchlogs.emf.logger.sinks.ConsoleSink;
11-
import software.amazon.awssdk.services.cloudwatchlogs.emf.logger.sinks.MultiSink;
9+
import software.amazon.awssdk.services.cloudwatchlogs.emf.sinks.CloudWatchLogsClientSink;
10+
import software.amazon.awssdk.services.cloudwatchlogs.emf.sinks.ConsoleSink;
11+
import software.amazon.awssdk.services.cloudwatchlogs.emf.sinks.MultiSink;
1212
import software.amazon.awssdk.services.cloudwatchlogs.emf.model.Aggregation;
1313
import software.amazon.awssdk.services.cloudwatchlogs.emf.model.CloudwatchMetricCollection;
1414
import software.amazon.awssdk.services.cloudwatchlogs.emf.model.EMFLogItem;

integ/software/amazon/awssdk/services/cloudwatchlogs/emf/IntegrationTestBase.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import software.amazon.awssdk.services.cloudwatch.CloudWatchClient;
55
import software.amazon.awssdk.services.cloudwatchlogs.CloudWatchLogsClient;
66
import software.amazon.awssdk.services.cloudwatchlogs.emf.logger.EMFLogger;
7-
import software.amazon.awssdk.services.cloudwatchlogs.emf.logger.sinks.CloudWatchLogsClientSink;
7+
import software.amazon.awssdk.services.cloudwatchlogs.emf.sinks.CloudWatchLogsClientSink;
88
import software.amazon.awssdk.services.cloudwatchlogs.emf.testutils.EMFTestUtilities;
99

1010
public class IntegrationTestBase {

integ/software/amazon/awssdk/services/cloudwatchlogs/emf/LogItemSizeTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import software.amazon.awssdk.services.cloudwatchlogs.emf.logger.CloudWatchLimits;
66
import software.amazon.awssdk.services.cloudwatchlogs.emf.logger.EMFLogger;
77
import software.amazon.awssdk.services.cloudwatchlogs.emf.logger.FlushException;
8-
import software.amazon.awssdk.services.cloudwatchlogs.emf.logger.sinks.SinkUtilities;
8+
import software.amazon.awssdk.services.cloudwatchlogs.emf.sinks.SinkUtilities;
99
import software.amazon.awssdk.services.cloudwatchlogs.emf.model.CloudwatchMetricCollection;
1010
import software.amazon.awssdk.services.cloudwatchlogs.emf.model.EMFLogItem;
1111
import software.amazon.awssdk.services.cloudwatchlogs.model.GetLogEventsRequest;
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package software.amazon.awssdk.services.cloudwatchlogs.emf.config;
2+
3+
import lombok.AllArgsConstructor;
4+
import lombok.Getter;
5+
import lombok.Setter;
6+
import software.amazon.awssdk.services.cloudwatchlogs.emf.environment.Environments;
7+
8+
import java.util.Optional;
9+
10+
@AllArgsConstructor
11+
public class Configuration {
12+
/**
13+
* Whether or not internal logging should be enabled.
14+
*/
15+
@Getter @Setter
16+
boolean debuggingLoggingEnabled;
17+
18+
/**
19+
* The name of the service to use in the default dimensions.
20+
*/
21+
@Getter @Setter
22+
Optional<String> serviceName;
23+
24+
/**
25+
* The type of the service to use in the default dimensions.
26+
*/
27+
@Getter @Setter
28+
Optional<String> serviceType;
29+
30+
/**
31+
* The LogGroup name to use. This is only used for the Cloudwatch Agent in agent-based environment.
32+
*/
33+
@Getter @Setter
34+
Optional<String> logGroupName;
35+
36+
/**
37+
* The LogStream name to use. This will be ignored when using the
38+
* Lambda scope.
39+
*/
40+
@Getter @Setter
41+
Optional<String> logStreamName;
42+
43+
/**
44+
* The endpoint to use to connect to the CloudWatch Agent
45+
*/
46+
@Getter @Setter
47+
Optional<String> agentEndpoint;
48+
49+
/**
50+
* Environment override. This will short circuit auto-environment detection.
51+
* Valid values include:
52+
* - Local: no decoration and sends over stdout
53+
* - Lambda: decorates logs with Lambda metadata and sends over stdout
54+
* - Agent: no decoration and sends over TCP
55+
* - EC2: decorates logs with EC2 metadata and sends over TCP
56+
*/
57+
@Getter @Setter
58+
Environments environmentOverride;
59+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package software.amazon.awssdk.services.cloudwatchlogs.emf.config;
2+
3+
public class ConfigurationKeys {
4+
5+
public static final String ENV_VAR_PREFIX = "AWS_EMF";
6+
7+
public static final String ENABLE_DEBUG_LOGGING = "ENABLE_DEBUG_LOGGING";
8+
public static final String SERVICE_NAME = "SERVICE_NAME";
9+
public static final String SERVICE_TYPE = "SERVICE_TYPE";
10+
public static final String LOG_GROUP_NAME = "LOG_GROUP_NAME";
11+
public static final String LOG_STREAM_NAME = "LOG_STREAM_NAME";
12+
public static final String AGENT_ENDPOINT = "AGENT_ENDPOINT";
13+
public static final String ENVIRONMENT_OVERRIDE = "ENVIRONMENT";
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package software.amazon.awssdk.services.cloudwatchlogs.emf.config;
2+
3+
import software.amazon.awssdk.services.cloudwatchlogs.emf.environment.Environments;
4+
5+
import java.util.Optional;
6+
7+
/**
8+
* Loads configuration from environment variables
9+
*/
10+
public class EnvironmentConfigurationProvider {
11+
private static Configuration config;
12+
13+
protected EnvironmentConfigurationProvider() {}
14+
15+
public static Configuration getConfig() {
16+
if (config == null) {
17+
config = new Configuration(
18+
getBoolEnvVar(ConfigurationKeys.ENABLE_DEBUG_LOGGING),
19+
getEnvVar(ConfigurationKeys.SERVICE_NAME),
20+
getEnvVar(ConfigurationKeys.SERVICE_TYPE),
21+
getEnvVar(ConfigurationKeys.LOG_GROUP_NAME),
22+
getEnvVar(ConfigurationKeys.LOG_STREAM_NAME),
23+
getEnvVar(ConfigurationKeys.AGENT_ENDPOINT),
24+
getEnvironmentOverride()
25+
);
26+
}
27+
return config;
28+
}
29+
30+
private static Optional<String> getEnvVar(String key) {
31+
String name = String.join("", ConfigurationKeys.ENV_VAR_PREFIX, "_", key);
32+
return Optional.ofNullable(getEnv(name));
33+
}
34+
35+
private static boolean getBoolEnvVar(String key) {
36+
String name = String.join("", ConfigurationKeys.ENV_VAR_PREFIX, "_", key);
37+
return Optional.ofNullable(getEnv(name)).map(str -> str.equalsIgnoreCase("true")).orElse(false);
38+
}
39+
40+
private static Environments getEnvironmentOverride() {
41+
Optional<String> environmentName = getEnvVar(ConfigurationKeys.ENVIRONMENT_OVERRIDE);
42+
if (!environmentName.isPresent()) {
43+
return Environments.Unknown;
44+
}
45+
46+
try {
47+
return Environments.valueOf(environmentName.get());
48+
} catch (Exception e) {
49+
return Environments.Unknown;
50+
}
51+
}
52+
53+
private static String getEnv(String name) {
54+
return SystemWrapper.getenv(name);
55+
}
56+
57+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package software.amazon.awssdk.services.cloudwatchlogs.emf.config;
2+
3+
class SystemWrapper {
4+
static String getenv(String name) {
5+
return System.getenv(name);
6+
}
7+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package software.amazon.awssdk.services.cloudwatchlogs.emf.environment;
2+
3+
import lombok.extern.slf4j.Slf4j;
4+
import software.amazon.awssdk.services.cloudwatchlogs.emf.config.Configuration;
5+
import software.amazon.awssdk.services.cloudwatchlogs.emf.sinks.AgentSink;
6+
import software.amazon.awssdk.services.cloudwatchlogs.emf.sinks.Endpoint;
7+
import software.amazon.awssdk.services.cloudwatchlogs.emf.sinks.ISink;
8+
import software.amazon.awssdk.services.cloudwatchlogs.emf.model.MetricsContext;
9+
import software.amazon.awssdk.services.cloudwatchlogs.emf.sinks.SocketClientFactory;
10+
11+
12+
@Slf4j
13+
public class DefaultEnvironment implements Environment {
14+
private Configuration config;
15+
private ISink sink;
16+
17+
public DefaultEnvironment(Configuration config) {
18+
this.config = config;
19+
}
20+
21+
22+
@Override
23+
public boolean probe() {
24+
return true;
25+
}
26+
27+
@Override
28+
public String getName() {
29+
if (!config.getServiceName().isPresent()) {
30+
log.info("Unknown ServiceName");
31+
return "Unknown";
32+
}
33+
return config.getServiceName().get();
34+
}
35+
36+
@Override
37+
public String getType() {
38+
if (!config.getServiceType().isPresent()) {
39+
log.info("Unknown ServiceType");
40+
return "Unknown";
41+
}
42+
return config.getServiceType().get();
43+
}
44+
45+
public String getLogStreamName() {
46+
return config.getLogStreamName().orElse(getName() + "-stream");
47+
}
48+
49+
@Override
50+
public String getLogGroupName() {
51+
return config.getLogGroupName().orElse(getName() + "-metrics");
52+
}
53+
54+
@Override
55+
public void configureContext(MetricsContext context) {
56+
// no-op
57+
}
58+
59+
@Override
60+
public ISink getSink() {
61+
if (sink == null) {
62+
Endpoint endpoint;
63+
if (!config.getAgentEndpoint().isPresent()) {
64+
log.info("Endpoint is not defined. Using default: {}", Endpoint.DEFAULT_TCP_ENDPOINT);
65+
endpoint = Endpoint.DEFAULT_TCP_ENDPOINT;
66+
} else {
67+
endpoint = Endpoint.fromURL(config.getAgentEndpoint().get());
68+
}
69+
sink = new AgentSink(getLogGroupName(), getLogStreamName(), endpoint, new SocketClientFactory());
70+
}
71+
return sink;
72+
}
73+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package software.amazon.awssdk.services.cloudwatchlogs.emf.environment;
2+
3+
import software.amazon.awssdk.services.cloudwatchlogs.emf.sinks.ISink;
4+
import software.amazon.awssdk.services.cloudwatchlogs.emf.model.MetricsContext;
5+
6+
/**
7+
* A runtime environment (e.g. Lambda, EKS, ECS, EC2)
8+
*/
9+
public interface Environment {
10+
/**
11+
* Determines whether or not we are executing in this environment
12+
*/
13+
boolean probe();
14+
15+
/**
16+
* Get the environment name. This will be used to set the ServiceName dimension.
17+
*/
18+
String getName();
19+
20+
/**
21+
* Get the environment type. This will be used to set the ServiceType dimension.
22+
*/
23+
String getType();
24+
25+
/**
26+
* Get log group name. This will be used to set the LogGroup dimension.
27+
*/
28+
String getLogGroupName();
29+
30+
/**
31+
* Configure the context with environment properties.
32+
*
33+
* @param context
34+
*/
35+
void configureContext(MetricsContext context);
36+
37+
/**
38+
* Create the appropriate sink for this environment.
39+
*/
40+
ISink getSink();
41+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package software.amazon.awssdk.services.cloudwatchlogs.emf.environment;
2+
3+
import software.amazon.awssdk.services.cloudwatchlogs.emf.config.EnvironmentConfigurationProvider;
4+
5+
public class EnvironmentProvider {
6+
7+
//TODO: Support more environments
8+
public Environment resolveEnvironment() {
9+
return new DefaultEnvironment(EnvironmentConfigurationProvider.getConfig());
10+
}
11+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package software.amazon.awssdk.services.cloudwatchlogs.emf.environment;
2+
3+
public enum Environments {
4+
Local, Lambda, Agent, EC2, ECS, Unknown
5+
}

src/main/java/software/amazon/awssdk/services/cloudwatchlogs/emf/logger/EMFLogger.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import lombok.Builder;
55
import lombok.Getter;
66
import lombok.NonNull;
7-
import software.amazon.awssdk.services.cloudwatchlogs.emf.logger.sinks.ISink;
7+
import software.amazon.awssdk.services.cloudwatchlogs.emf.sinks.ISink;
88
import software.amazon.awssdk.services.cloudwatchlogs.emf.model.EMFLogItem;
99

1010
import java.util.ArrayList;

src/main/java/software/amazon/awssdk/services/cloudwatchlogs/emf/logger/FlushException.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ public FlushException(List<EMFLogItem> failedLogItems, List<EMFLogItem> unproces
5151
this.unprocessedLogItems = unprocessedLogItems;
5252
}
5353

54+
public FlushException(String message, Throwable cause) {
55+
super(message, cause);
56+
}
57+
5458
// Internal constructor for handling errors before all information is available
5559
protected FlushException(String message) {
5660
super(message);

0 commit comments

Comments
 (0)