Skip to content

Commit db13aa6

Browse files
bjrarayiyuan-hepxawsadebayor123harrryr
authored
Release v1.32.5 (#941)
*Description of changes:* 1. [Switch isEmpty() to .isPresent() for Optionals Type #939](#939) 1. [Comment out E2E Operator Test #940](#940) 1. [Add Application Signals runtime metrics #892](#892) 1. [Update Dockerfile for corretto-slim build #924](#924) By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license. --------- Co-authored-by: Michael He <[email protected]> Co-authored-by: Ping Xiang <[email protected]> Co-authored-by: Reno Seo <[email protected]> Co-authored-by: Harry <[email protected]> Co-authored-by: Min Xia <[email protected]>
1 parent d7eb5bf commit db13aa6

File tree

10 files changed

+246
-32
lines changed

10 files changed

+246
-32
lines changed

.github/workflows/main-build.yml

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -157,19 +157,22 @@ jobs:
157157
echo "ref=terraform" >> $GITHUB_OUTPUT
158158
fi
159159
160-
e2e-operator-test:
161-
concurrency:
162-
group: e2e-adot-agent-operator-test
163-
cancel-in-progress: false
164-
needs: [ build, create-test-ref, default-region-output ]
165-
uses: ./.github/workflows/e2e-tests-with-operator.yml
166-
secrets: inherit
167-
with:
168-
aws-region: ${{ needs.default-region-output.outputs.aws_default_region }}
169-
image_tag: ${{ needs.build.outputs.java_agent_tag }}
170-
image_uri: ${{ needs.build.outputs.staging_registry }}/${{ needs.build.outputs.staging_repository }}
171-
test_ref: ${{ needs.create-test-ref.outputs.testRef }}
172-
caller-workflow-name: 'main-build'
160+
# TODO: This test is currently failing due to infrastructure problems. Commented it out because we are ignoring it during release.
161+
# Need to fix in the future. Ex: https://github.com/aws-observability/aws-otel-java-instrumentation/actions/runs/11525535146/job/32241628521
162+
163+
# e2e-operator-test:
164+
# concurrency:
165+
# group: e2e-adot-agent-operator-test
166+
# cancel-in-progress: false
167+
# needs: [ build, create-test-ref, default-region-output ]
168+
# uses: ./.github/workflows/e2e-tests-with-operator.yml
169+
# secrets: inherit
170+
# with:
171+
# aws-region: ${{ needs.default-region-output.outputs.aws_default_region }}
172+
# image_tag: ${{ needs.build.outputs.java_agent_tag }}
173+
# image_uri: ${{ needs.build.outputs.staging_registry }}/${{ needs.build.outputs.staging_repository }}
174+
# test_ref: ${{ needs.create-test-ref.outputs.testRef }}
175+
# caller-workflow-name: 'main-build'
173176

174177
# E2E tests where SampleApp has Java Agent
175178
e2e-test:

.github/workflows/owasp.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,15 +77,15 @@ jobs:
7777
id: high_scan
7878
uses: ./.github/actions/image_scan
7979
with:
80-
image-ref: "public.ecr.aws/aws-observability/adot-autoinstrumentation-java:v1.32.3"
80+
image-ref: "public.ecr.aws/aws-observability/adot-autoinstrumentation-java:v1.32.4"
8181
severity: 'CRITICAL,HIGH'
8282

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

9191
- name: Configure AWS Credentials for emitting metrics

appsignals-tests/contract-tests/src/test/java/software/amazon/opentelemetry/appsignals/test/base/ContractTestBase.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ public abstract class ContractTestBase {
7979
.withEnv("JAVA_TOOL_OPTIONS", "-javaagent:/opentelemetry-javaagent-all.jar")
8080
.withEnv("OTEL_METRIC_EXPORT_INTERVAL", "100") // 100 ms
8181
.withEnv("OTEL_AWS_APPLICATION_SIGNALS_ENABLED", "true")
82+
.withEnv("OTEL_AWS_APPLICATION_SIGNALS_RUNTIME_ENABLED", isRuntimeEnabled())
8283
.withEnv("OTEL_METRICS_EXPORTER", "none")
8384
.withEnv("OTEL_BSP_SCHEDULE_DELAY", "0") // Don't wait to export spans to the collector
8485
.withEnv(
@@ -159,4 +160,8 @@ protected String getApplicationOtelServiceName() {
159160
protected String getApplicationOtelResourceAttributes() {
160161
return "service.name=" + getApplicationOtelServiceName();
161162
}
163+
164+
protected String isRuntimeEnabled() {
165+
return "false";
166+
}
162167
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License").
5+
* You may not use this file except in compliance with the License.
6+
* A copy of the License is located at
7+
*
8+
* http://aws.amazon.com/apache2.0
9+
*
10+
* or in the "license" file accompanying this file. This file is distributed
11+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
* express or implied. See the License for the specific language governing
13+
* permissions and limitations under the License.
14+
*/
15+
16+
package software.amazon.opentelemetry.appsignals.test.misc;
17+
18+
import static org.assertj.core.api.Assertions.assertThat;
19+
20+
import io.opentelemetry.proto.metrics.v1.Metric;
21+
import java.util.List;
22+
import java.util.Set;
23+
import org.junit.jupiter.api.Nested;
24+
import org.junit.jupiter.api.Test;
25+
import org.junit.jupiter.api.TestInstance;
26+
import org.testcontainers.junit.jupiter.Testcontainers;
27+
import software.amazon.opentelemetry.appsignals.test.base.ContractTestBase;
28+
import software.amazon.opentelemetry.appsignals.test.utils.AppSignalsConstants;
29+
import software.amazon.opentelemetry.appsignals.test.utils.ResourceScopeMetric;
30+
31+
public class RuntimeMetricsTest {
32+
private abstract static class RuntimeMetricsContractTestBase extends ContractTestBase {
33+
@Override
34+
protected String getApplicationImageName() {
35+
return "aws-appsignals-tests-http-server-spring-mvc";
36+
}
37+
38+
@Override
39+
protected String isRuntimeEnabled() {
40+
return "true";
41+
}
42+
43+
protected String getApplicationWaitPattern() {
44+
return ".*Started Application.*";
45+
}
46+
47+
protected void doTestRuntimeMetrics() {
48+
var response = appClient.get("/success").aggregate().join();
49+
50+
assertThat(response.status().isSuccess()).isTrue();
51+
assertRuntimeMetrics();
52+
}
53+
54+
protected void assertRuntimeMetrics() {
55+
var metrics =
56+
mockCollectorClient.getRuntimeMetrics(
57+
Set.of(
58+
AppSignalsConstants.JVM_GC_DURATION,
59+
AppSignalsConstants.JVM_GC_COUNT,
60+
AppSignalsConstants.JVM_HEAP_USED,
61+
AppSignalsConstants.JVM_NON_HEAP_USED,
62+
AppSignalsConstants.JVM_AFTER_GC,
63+
AppSignalsConstants.JVM_POOL_USED,
64+
AppSignalsConstants.JVM_THREAD_COUNT,
65+
AppSignalsConstants.JVM_CLASS_LOADED,
66+
AppSignalsConstants.JVM_CPU_TIME,
67+
AppSignalsConstants.JVM_CPU_UTILIZATION,
68+
AppSignalsConstants.LATENCY_METRIC,
69+
AppSignalsConstants.ERROR_METRIC,
70+
AppSignalsConstants.FAULT_METRIC));
71+
72+
testResourceAttributes(metrics);
73+
for (String metricName : List.of(AppSignalsConstants.JVM_POOL_USED)) {
74+
testGaugeMetrics(metrics, metricName, "name");
75+
}
76+
for (String metricName :
77+
List.of(
78+
AppSignalsConstants.JVM_HEAP_USED,
79+
AppSignalsConstants.JVM_NON_HEAP_USED,
80+
AppSignalsConstants.JVM_AFTER_GC,
81+
AppSignalsConstants.JVM_THREAD_COUNT,
82+
AppSignalsConstants.JVM_CLASS_LOADED,
83+
AppSignalsConstants.JVM_CPU_UTILIZATION)) {
84+
testGaugeMetrics(metrics, metricName, "");
85+
}
86+
for (String metricName :
87+
List.of(AppSignalsConstants.JVM_GC_DURATION, AppSignalsConstants.JVM_GC_COUNT)) {
88+
testCounterMetrics(metrics, metricName, "name");
89+
}
90+
for (String metricName : List.of(AppSignalsConstants.JVM_CPU_TIME)) {
91+
testCounterMetrics(metrics, metricName, "");
92+
}
93+
}
94+
95+
private void testGaugeMetrics(
96+
List<ResourceScopeMetric> resourceScopeMetrics, String metricName, String attributeKey) {
97+
for (ResourceScopeMetric rsm : resourceScopeMetrics) {
98+
Metric metric = rsm.getMetric();
99+
if (metricName.equals(metric.getName())) {
100+
assertThat(metric.getGauge().getDataPointsList())
101+
.as(metricName + " is not empty")
102+
.isNotEmpty();
103+
assertThat(metric.getGauge().getDataPointsList())
104+
.as(metricName + " is valid")
105+
.allMatch(
106+
dp -> {
107+
boolean valid = true;
108+
if (!attributeKey.isEmpty()) {
109+
valid =
110+
dp.getAttributesList().stream()
111+
.anyMatch(attribute -> attribute.getKey().equals(attributeKey));
112+
}
113+
return valid && dp.getAsInt() >= 0;
114+
});
115+
}
116+
}
117+
}
118+
119+
private void testCounterMetrics(
120+
List<ResourceScopeMetric> resourceScopeMetrics, String metricName, String attributeKey) {
121+
for (ResourceScopeMetric rsm : resourceScopeMetrics) {
122+
Metric metric = rsm.getMetric();
123+
if (metricName.equals(metric.getName())) {
124+
assertThat(metric.getSum().getDataPointsList())
125+
.as(metricName + " is not empty")
126+
.isNotEmpty();
127+
assertThat(metric.getSum().getDataPointsList())
128+
.as(metricName + " is valid")
129+
.allMatch(
130+
dp -> {
131+
boolean valid = true;
132+
if (!attributeKey.isEmpty()) {
133+
valid =
134+
dp.getAttributesList().stream()
135+
.anyMatch(attribute -> attribute.getKey().equals(attributeKey));
136+
}
137+
return valid && dp.getAsInt() >= 0;
138+
});
139+
}
140+
}
141+
}
142+
143+
private void testResourceAttributes(List<ResourceScopeMetric> resourceScopeMetrics) {
144+
for (ResourceScopeMetric rsm : resourceScopeMetrics) {
145+
assertThat(rsm.getResource().getResource().getAttributesList())
146+
.anyMatch(
147+
attr ->
148+
attr.getKey().equals(AppSignalsConstants.AWS_LOCAL_SERVICE)
149+
&& attr.getValue()
150+
.getStringValue()
151+
.equals(getApplicationOtelServiceName()));
152+
}
153+
}
154+
}
155+
156+
@Testcontainers(disabledWithoutDocker = true)
157+
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
158+
@Nested
159+
class ValidateRuntimeMetricsTest extends RuntimeMetricsContractTestBase {
160+
@Test
161+
void testRuntimeMetrics() {
162+
doTestRuntimeMetrics();
163+
}
164+
}
165+
}

appsignals-tests/contract-tests/src/test/java/software/amazon/opentelemetry/appsignals/test/utils/AppSignalsConstants.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,16 @@ public class AppSignalsConstants {
3333
public static final String AWS_REMOTE_RESOURCE_IDENTIFIER = "aws.remote.resource.identifier";
3434
public static final String AWS_SPAN_KIND = "aws.span.kind";
3535
public static final String AWS_REMOTE_DB_USER = "aws.remote.db.user";
36+
37+
// JVM Metrics
38+
public static final String JVM_GC_DURATION = "jvm.gc.collections.elapsed";
39+
public static final String JVM_GC_COUNT = "jvm.gc.collections.count";
40+
public static final String JVM_HEAP_USED = "jvm.memory.heap.used";
41+
public static final String JVM_NON_HEAP_USED = "jvm.memory.nonheap.used";
42+
public static final String JVM_AFTER_GC = "jvm.memory.pool.used_after_last_gc";
43+
public static final String JVM_POOL_USED = "jvm.memory.pool.used";
44+
public static final String JVM_THREAD_COUNT = "jvm.threads.count";
45+
public static final String JVM_CLASS_LOADED = "jvm.classes.loaded";
46+
public static final String JVM_CPU_TIME = "jvm.cpu.time";
47+
public static final String JVM_CPU_UTILIZATION = "jvm.cpu.recent_utilization";
3648
}

appsignals-tests/contract-tests/src/test/java/software/amazon/opentelemetry/appsignals/test/utils/MockCollectorClient.java

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -133,13 +133,21 @@ public List<ResourceScopeSpan> getTraces() {
133133
.collect(toImmutableList());
134134
}
135135

136+
public List<ResourceScopeMetric> getRuntimeMetrics(Set<String> presentMetrics) {
137+
return fetchMetrics(presentMetrics, false);
138+
}
139+
140+
public List<ResourceScopeMetric> getMetrics(Set<String> presentMetrics) {
141+
return fetchMetrics(presentMetrics, true);
142+
}
143+
136144
/**
137145
* Get all metrics that are currently stored in the mock collector.
138146
*
139147
* @return List of `ResourceScopeMetric` which is a flat list containing all metrics and their
140148
* related scope and resources.
141149
*/
142-
public List<ResourceScopeMetric> getMetrics(Set<String> presentMetrics) {
150+
private List<ResourceScopeMetric> fetchMetrics(Set<String> presentMetrics, boolean exactMatch) {
143151
List<ExportMetricsServiceRequest> exportedMetrics =
144152
waitForContent(
145153
"/get-metrics",
@@ -152,9 +160,14 @@ public List<ResourceScopeMetric> getMetrics(Set<String> presentMetrics) {
152160
.flatMap(x -> x.getMetricsList().stream())
153161
.map(x -> x.getName())
154162
.collect(Collectors.toSet());
155-
156-
return (!exported.isEmpty() && current.size() == exported.size())
157-
&& receivedMetrics.containsAll(presentMetrics);
163+
if (!exported.isEmpty() && receivedMetrics.containsAll(presentMetrics)) {
164+
if (exactMatch) {
165+
return current.size() == exported.size();
166+
} else {
167+
return true;
168+
}
169+
}
170+
return false;
158171
});
159172

160173
return exportedMetrics.stream()

awsagentprovider/src/main/java/software/amazon/opentelemetry/javaagent/providers/AwsApplicationSignalsCustomizerProvider.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,8 @@ private boolean isApplicationSignalsEnabled(ConfigProperties configProps) {
104104
}
105105

106106
private boolean isApplicationSignalsRuntimeEnabled(ConfigProperties configProps) {
107-
return false;
107+
return isApplicationSignalsEnabled(configProps)
108+
&& configProps.getBoolean(APPLICATION_SIGNALS_RUNTIME_ENABLED_CONFIG, true);
108109
}
109110

110111
private Map<String, String> customizeProperties(ConfigProperties configProps) {

awsagentprovider/src/main/java/software/amazon/opentelemetry/javaagent/providers/AwsMetricAttributeGenerator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,7 @@ private static void setRemoteResourceTypeAndIdentifier(SpanData span, Attributes
502502
remoteResourceIdentifier = getDbConnection(span);
503503
}
504504

505-
if (cloudformationPrimaryIdentifier.isEmpty()) {
505+
if (!cloudformationPrimaryIdentifier.isPresent()) {
506506
cloudformationPrimaryIdentifier = remoteResourceIdentifier;
507507
}
508508

instrumentation/jmx-metrics/src/main/resources/jmx/rules/jvm.yaml

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ rules:
2323
unit: ms
2424
desc: The approximate accumulated collection elapsed time in milliseconds
2525
- bean: java.lang:type=Memory
26-
unit: by
26+
unit: By
2727
prefix: jvm.memory.
2828
type: gauge
2929
mapping:
@@ -52,12 +52,15 @@ rules:
5252
metric: nonheap.max
5353
desc: The maximum amount of memory can be used for non-heap purposes
5454
- bean: java.lang:type=MemoryPool,name=*
55-
unit: by
55+
unit: By
5656
prefix: jvm.memory.pool.
5757
type: gauge
5858
metricAttribute:
5959
name: param(name)
6060
mapping:
61+
CollectionUsage.used:
62+
metric: used_after_last_gc
63+
desc: Memory used after the most recent gc event
6164
Usage.init:
6265
metric: init
6366
desc: The initial amount of memory that the JVM requests from the operating system for the memory pool
@@ -81,37 +84,49 @@ rules:
8184
metric: jvm.daemon_threads.count
8285
desc: Number of daemon threads
8386
- bean: java.lang:type=OperatingSystem
84-
type: gauge
8587
mapping:
8688
TotalSwapSpaceSize:
8789
metric: jvm.system.swap.space.total
88-
desc: The host swap memory size in bytes
89-
unit: by
90+
type: gauge
91+
desc: The host swap memory size in Bytes
92+
unit: By
9093
FreeSwapSpaceSize:
9194
metric: jvm.system.swap.space.free
92-
desc: The amount of available swap memory in bytes
93-
unit: by
95+
type: gauge
96+
desc: The amount of available swap memory in Bytes
97+
unit: By
9498
TotalPhysicalMemorySize:
9599
metric: jvm.system.physical.memory.total
100+
type: gauge
96101
desc: The total physical memory size in host
97-
unit: by
102+
unit: By
98103
FreePhysicalMemorySize:
99104
metric: jvm.system.physical.memory.free
105+
type: gauge
100106
desc: The amount of free physical memory in host
101-
unit: by
107+
unit: By
102108
AvailableProcessors:
103109
metric: jvm.system.available.processors
110+
type: gauge
104111
desc: The number of available processors
105112
unit: "1"
106113
SystemCpuLoad:
107114
metric: jvm.system.cpu.utilization
115+
type: gauge
108116
desc: The current load of CPU in host
109117
unit: "1"
118+
ProcessCpuTime:
119+
metric: jvm.cpu.time
120+
type: counter
121+
unit: ns
122+
desc: CPU time used
110123
ProcessCpuLoad:
111124
metric: jvm.cpu.recent_utilization
125+
type: gauge
112126
unit: "1"
113127
desc: Recent CPU utilization for the process
114128
OpenFileDescriptorCount:
115129
metric: jvm.open_file_descriptor.count
130+
type: gauge
116131
desc: The number of opened file descriptors
117132
unit: "1"

0 commit comments

Comments
 (0)