From 69e6414826ff8ca24ab25cec3bf617ce348d9894 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Oct 2023 09:54:21 +0000 Subject: [PATCH 1/9] Bump version.byte-buddy from 1.14.8 to 1.14.9 (#3361) * Bump version.byte-buddy from 1.14.8 to 1.14.9 Bumps `version.byte-buddy` from 1.14.8 to 1.14.9. Updates `net.bytebuddy:byte-buddy` from 1.14.8 to 1.14.9 - [Release notes](https://github.com/raphw/byte-buddy/releases) - [Changelog](https://github.com/raphw/byte-buddy/blob/master/release-notes.md) - [Commits](https://github.com/raphw/byte-buddy/compare/byte-buddy-1.14.8...byte-buddy-1.14.9) Updates `net.bytebuddy:byte-buddy-agent` from 1.9.16 to 1.14.9 - [Release notes](https://github.com/raphw/byte-buddy/releases) - [Changelog](https://github.com/raphw/byte-buddy/blob/master/release-notes.md) - [Commits](https://github.com/raphw/byte-buddy/compare/byte-buddy-1.9.16...byte-buddy-1.14.9) Updates `net.bytebuddy:byte-buddy-dep` from 1.14.8 to 1.14.9 - [Release notes](https://github.com/raphw/byte-buddy/releases) - [Changelog](https://github.com/raphw/byte-buddy/blob/master/release-notes.md) - [Commits](https://github.com/raphw/byte-buddy/compare/byte-buddy-1.14.8...byte-buddy-1.14.9) --- updated-dependencies: - dependency-name: net.bytebuddy:byte-buddy dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: net.bytebuddy:byte-buddy-agent dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: net.bytebuddy:byte-buddy-dep dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Update pom.xml --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jonas Kunz --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9a6abb73e8..a658c40a84 100644 --- a/pom.xml +++ b/pom.xml @@ -131,7 +131,7 @@ 9.4.11.v20180605 1.0.86 - 1.14.8 + 1.14.9 9.6 5.4.0 From 546da88d55b9e0f66c89072ac696687e54fe7779 Mon Sep 17 00:00:00 2001 From: Jonas Kunz Date: Tue, 17 Oct 2023 15:41:58 +0200 Subject: [PATCH 2/9] Added otel to dependabot config, upgraded dependencies (#3359) * Added otel to dependabot config, upgraded dependencies * Fix semantic attributes lookup --------- Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- .github/dependabot.yml | 2 + .../apm-opentelemetry-plugin/pom.xml | 4 +- .../agent/opentelemetry/SemAttributes.java | 49 +++++++++++++++++++ .../tracing/ElasticOpenTelemetryTest.java | 22 ++++----- .../specs/OTelBridgeStepsDefinitions.java | 2 +- .../opentelemetry/OpenTelemetryVersionIT.java | 1 + apm-agent-plugins/apm-opentelemetry/pom.xml | 3 +- .../external-plugin-otel-test/pom.xml | 2 +- 8 files changed, 69 insertions(+), 16 deletions(-) create mode 100644 apm-agent-plugins/apm-opentelemetry/apm-opentelemetry-plugin/src/test/java/co/elastic/apm/agent/opentelemetry/SemAttributes.java diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 65525c4e40..95d3ce2935 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -36,6 +36,8 @@ updates: - dependency-name: "io.vertx:*" - dependency-name: "org.apache.logging.log4j:*" - dependency-name: "org.springframework.boot:*" + - dependency-name: "io.opentelemetry:*" + - dependency-name: "io.opentelemetry.semconv:*" ignore: - dependency-name: "net.bytebuddy:byte-buddy-agent" # We deliberately want to keep this older version of Byte Buddy for our runtime attach test diff --git a/apm-agent-plugins/apm-opentelemetry/apm-opentelemetry-plugin/pom.xml b/apm-agent-plugins/apm-opentelemetry/apm-opentelemetry-plugin/pom.xml index 8f890f3f34..46544a723f 100644 --- a/apm-agent-plugins/apm-opentelemetry/apm-opentelemetry-plugin/pom.xml +++ b/apm-agent-plugins/apm-opentelemetry/apm-opentelemetry-plugin/pom.xml @@ -23,9 +23,9 @@ - io.opentelemetry + io.opentelemetry.semconv opentelemetry-semconv - ${version.opentelemetry}-alpha + ${version.opentelemetry-semconv} test diff --git a/apm-agent-plugins/apm-opentelemetry/apm-opentelemetry-plugin/src/test/java/co/elastic/apm/agent/opentelemetry/SemAttributes.java b/apm-agent-plugins/apm-opentelemetry/apm-opentelemetry-plugin/src/test/java/co/elastic/apm/agent/opentelemetry/SemAttributes.java new file mode 100644 index 0000000000..7077c599ec --- /dev/null +++ b/apm-agent-plugins/apm-opentelemetry/apm-opentelemetry-plugin/src/test/java/co/elastic/apm/agent/opentelemetry/SemAttributes.java @@ -0,0 +1,49 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License 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 co.elastic.apm.agent.opentelemetry; + +import io.opentelemetry.api.common.AttributeKey; + +/** + * Bridge for integration tests which use {@link io.opentelemetry.semconv.SemanticAttributes} + * which has been moved from {@code io.opentelemetry.semconv.trace.attributes.SemanticAttributes}. + */ +public class SemAttributes { + + public static final AttributeKey HTTP_URL = getAttribute("HTTP_URL"); + public static final AttributeKey HTTP_STATUS_CODE = getAttribute("HTTP_STATUS_CODE"); + public static final AttributeKey HTTP_METHOD = getAttribute("HTTP_METHOD"); + public static final AttributeKey NET_PEER_PORT = getAttribute("NET_PEER_PORT"); + public static final AttributeKey NET_PEER_IP = getAttribute("NET_PEER_IP"); + + @SuppressWarnings("unchecked") + private static AttributeKey getAttribute(String name) { + try { + Class attribClass; + try { + attribClass = Class.forName("io.opentelemetry.semconv.SemanticAttributes"); + } catch (ClassNotFoundException cnf) { + attribClass = Class.forName("io.opentelemetry.semconv.trace.attributes.SemanticAttributes"); + } + return (AttributeKey) attribClass.getField(name).get(null); + }catch (Exception e) { + throw new IllegalStateException(e); + } + } +} diff --git a/apm-agent-plugins/apm-opentelemetry/apm-opentelemetry-plugin/src/test/java/co/elastic/apm/agent/opentelemetry/tracing/ElasticOpenTelemetryTest.java b/apm-agent-plugins/apm-opentelemetry/apm-opentelemetry-plugin/src/test/java/co/elastic/apm/agent/opentelemetry/tracing/ElasticOpenTelemetryTest.java index aa2084f246..08e43d5a4a 100644 --- a/apm-agent-plugins/apm-opentelemetry/apm-opentelemetry-plugin/src/test/java/co/elastic/apm/agent/opentelemetry/tracing/ElasticOpenTelemetryTest.java +++ b/apm-agent-plugins/apm-opentelemetry/apm-opentelemetry-plugin/src/test/java/co/elastic/apm/agent/opentelemetry/tracing/ElasticOpenTelemetryTest.java @@ -22,6 +22,7 @@ import co.elastic.apm.agent.impl.transaction.ElasticContext; import co.elastic.apm.agent.impl.transaction.OTelSpanKind; import co.elastic.apm.agent.impl.transaction.Transaction; +import co.elastic.apm.agent.opentelemetry.SemAttributes; import co.elastic.apm.agent.tracer.Outcome; import co.elastic.apm.agent.tracer.dispatch.TextHeaderSetter; import io.opentelemetry.api.baggage.Baggage; @@ -33,7 +34,6 @@ import io.opentelemetry.context.ContextKey; import io.opentelemetry.context.Scope; import io.opentelemetry.context.propagation.TextMapGetter; -import io.opentelemetry.semconv.trace.attributes.SemanticAttributes; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -571,20 +571,20 @@ public void elasticSpanOverOtelSpan() { public void testOTelSpanAttributesCopiedAsIs() { otelTracer.spanBuilder("transaction").setSpanKind(SpanKind.SERVER) .startSpan() - .setAttribute(SemanticAttributes.HTTP_METHOD, "GET") - .setAttribute(SemanticAttributes.HTTP_URL, "http://example.com:8080/foo?bar") - .setAttribute(SemanticAttributes.HTTP_STATUS_CODE, 200L) - .setAttribute(SemanticAttributes.NET_PEER_PORT, 123456) - .setAttribute(SemanticAttributes.NET_PEER_IP, "192.168.178.1") + .setAttribute(SemAttributes.HTTP_METHOD, "GET") + .setAttribute(SemAttributes.HTTP_URL, "http://example.com:8080/foo?bar") + .setAttribute(SemAttributes.HTTP_STATUS_CODE, 200L) + .setAttribute(SemAttributes.NET_PEER_PORT, 123456) + .setAttribute(SemAttributes.NET_PEER_IP, "192.168.178.1") .end(); assertThat(reporter.getTransactions()).hasSize(1); checkOTelAttributes(reporter.getFirstTransaction(), Map.of( - SemanticAttributes.HTTP_METHOD.getKey(), "GET", - SemanticAttributes.HTTP_URL.getKey(), "http://example.com:8080/foo?bar", - SemanticAttributes.HTTP_STATUS_CODE.getKey(), 200L, - SemanticAttributes.NET_PEER_PORT.getKey(), 123456L, - SemanticAttributes.NET_PEER_IP.getKey(), "192.168.178.1" + SemAttributes.HTTP_METHOD.getKey(), "GET", + SemAttributes.HTTP_URL.getKey(), "http://example.com:8080/foo?bar", + SemAttributes.HTTP_STATUS_CODE.getKey(), 200L, + SemAttributes.NET_PEER_PORT.getKey(), 123456L, + SemAttributes.NET_PEER_IP.getKey(), "192.168.178.1" )); } diff --git a/apm-agent-plugins/apm-opentelemetry/apm-opentelemetry-plugin/src/test/java/specs/OTelBridgeStepsDefinitions.java b/apm-agent-plugins/apm-opentelemetry/apm-opentelemetry-plugin/src/test/java/specs/OTelBridgeStepsDefinitions.java index f951862788..c1d00c1029 100644 --- a/apm-agent-plugins/apm-opentelemetry/apm-opentelemetry-plugin/src/test/java/specs/OTelBridgeStepsDefinitions.java +++ b/apm-agent-plugins/apm-opentelemetry/apm-opentelemetry-plugin/src/test/java/specs/OTelBridgeStepsDefinitions.java @@ -37,7 +37,7 @@ import io.opentelemetry.api.trace.SpanKind; import io.opentelemetry.api.trace.StatusCode; import io.opentelemetry.context.Context; -import io.opentelemetry.semconv.trace.attributes.SemanticAttributes; +import io.opentelemetry.semconv.SemanticAttributes; import javax.annotation.Nullable; import java.util.HashMap; diff --git a/apm-agent-plugins/apm-opentelemetry/apm-opentelemetry-test/src/test/java/co/elastic/apm/agent/opentelemetry/OpenTelemetryVersionIT.java b/apm-agent-plugins/apm-opentelemetry/apm-opentelemetry-test/src/test/java/co/elastic/apm/agent/opentelemetry/OpenTelemetryVersionIT.java index fa4f0098a7..17c8fffb8e 100644 --- a/apm-agent-plugins/apm-opentelemetry/apm-opentelemetry-test/src/test/java/co/elastic/apm/agent/opentelemetry/OpenTelemetryVersionIT.java +++ b/apm-agent-plugins/apm-opentelemetry/apm-opentelemetry-test/src/test/java/co/elastic/apm/agent/opentelemetry/OpenTelemetryVersionIT.java @@ -59,6 +59,7 @@ void testTracingVersion(String version) throws Exception { TestClassWithDependencyRunner runner = new TestClassWithDependencyRunner(dependencies, "co.elastic.apm.agent.opentelemetry.tracing.ElasticOpenTelemetryTest", "co.elastic.apm.agent.opentelemetry.tracing.AbstractOpenTelemetryTest", + "co.elastic.apm.agent.opentelemetry.SemAttributes", "co.elastic.apm.agent.opentelemetry.tracing.ElasticOpenTelemetryTest$MapGetter"); runner.run(); } diff --git a/apm-agent-plugins/apm-opentelemetry/pom.xml b/apm-agent-plugins/apm-opentelemetry/pom.xml index cd5a609d10..cae3ef6876 100644 --- a/apm-agent-plugins/apm-opentelemetry/pom.xml +++ b/apm-agent-plugins/apm-opentelemetry/pom.xml @@ -19,7 +19,8 @@ When updating the version, add the old version to OpenTelemetryVersionIT to make sure that in the future we stay compatible with the previous version. --> - 1.22.0 + 1.31.0 + 1.21.0-alpha 8 8 diff --git a/integration-tests/external-plugin-otel-test/pom.xml b/integration-tests/external-plugin-otel-test/pom.xml index a4e51cd926..3b15c90b26 100644 --- a/integration-tests/external-plugin-otel-test/pom.xml +++ b/integration-tests/external-plugin-otel-test/pom.xml @@ -14,7 +14,7 @@ ${project.basedir}/../.. - 1.20.0 + 1.31.0 8 8 From 45657a0dc3add780a9bc348cbfa3c4fa61fa9fa7 Mon Sep 17 00:00:00 2001 From: Jonas Kunz Date: Tue, 17 Oct 2023 17:02:45 +0200 Subject: [PATCH 3/9] Add guard against invalid end timestamps (#3363) --- CHANGELOG.asciidoc | 4 ++++ .../apm/agent/impl/transaction/AbstractSpan.java | 7 +++++++ .../apm/agent/impl/ElasticApmTracerTest.java | 14 ++++++++++++++ 3 files changed, 25 insertions(+) diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc index f5c09b6aa5..0a8fb52ffb 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -31,6 +31,10 @@ Use subheadings with the "=====" level for adding notes for unreleased changes: === Unreleased +[float] +===== Features +* Added protection against invalid timestamps provided by manual instrumentation - {pull}3363[#3363] + [float] ===== Bug fixes * Fixed too many spans being created for `HTTPUrlConnection` requests with method `HEAD` - {pull}3353[#3353] diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/transaction/AbstractSpan.java b/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/transaction/AbstractSpan.java index 96de90c4c0..7e619455cf 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/transaction/AbstractSpan.java +++ b/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/transaction/AbstractSpan.java @@ -559,6 +559,13 @@ public void end() { public final void end(long epochMicros) { if (!finished) { + + long startTime = timestamp.get(); + if(epochMicros < startTime) { + logger.warn("End called on {} with a timestamp before start! Using start timestamp as end instead.", this); + epochMicros = startTime; + } + this.endTimestamp.set(epochMicros); childDurations.onSpanEnd(epochMicros); diff --git a/apm-agent-core/src/test/java/co/elastic/apm/agent/impl/ElasticApmTracerTest.java b/apm-agent-core/src/test/java/co/elastic/apm/agent/impl/ElasticApmTracerTest.java index 5283795cf5..a5ff19054e 100644 --- a/apm-agent-core/src/test/java/co/elastic/apm/agent/impl/ElasticApmTracerTest.java +++ b/apm-agent-core/src/test/java/co/elastic/apm/agent/impl/ElasticApmTracerTest.java @@ -505,6 +505,20 @@ void testTimestamps() { assertThat(span.getDuration()).isEqualTo(10); } + @Test + void testTimestampSanitization() { + final Transaction transaction = tracerImpl.startChildTransaction(new HashMap<>(), TextHeaderMapAccessor.INSTANCE, ConstantSampler.of(true), 10, null); + final Span span = transaction.createSpan(20); + span.end(10); + + transaction.end(5); + + assertThat(transaction.getTimestamp()).isEqualTo(10); + assertThat(transaction.getDuration()).isEqualTo(0); + assertThat(span.getTimestamp()).isEqualTo(20); + assertThat(span.getDuration()).isEqualTo(0); + } + @Test void testStartSpanAfterTransactionHasEnded() { final Transaction transaction = startTestRootTransaction(); From ba6571128ff932a30df533a789437eec24a1e6c6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 18 Oct 2023 09:43:58 +0200 Subject: [PATCH 4/9] Bump io.micrometer:micrometer-core from 1.11.4 to 1.11.5 (#3360) Bumps [io.micrometer:micrometer-core](https://github.com/micrometer-metrics/micrometer) from 1.11.4 to 1.11.5. - [Release notes](https://github.com/micrometer-metrics/micrometer/releases) - [Commits](https://github.com/micrometer-metrics/micrometer/compare/v1.11.4...v1.11.5) --- updated-dependencies: - dependency-name: io.micrometer:micrometer-core dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- apm-agent-plugins/apm-micrometer-plugin/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apm-agent-plugins/apm-micrometer-plugin/pom.xml b/apm-agent-plugins/apm-micrometer-plugin/pom.xml index 1939b8ca2f..688d25c9a3 100644 --- a/apm-agent-plugins/apm-micrometer-plugin/pom.xml +++ b/apm-agent-plugins/apm-micrometer-plugin/pom.xml @@ -29,7 +29,7 @@ io.micrometer micrometer-core - 1.11.4 + 1.11.5 provided From 6f7086fac85af9b8029b96f7b889049fceda3d04 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 18 Oct 2023 08:40:31 +0000 Subject: [PATCH 5/9] Bump org.apache.logging.log4j:log4j-bom from 2.20.0 to 2.21.0 (#3367) Bumps [org.apache.logging.log4j:log4j-bom](https://github.com/apache/logging-log4j2) from 2.20.0 to 2.21.0. - [Release notes](https://github.com/apache/logging-log4j2/releases) - [Commits](https://github.com/apache/logging-log4j2/compare/rel/2.20.0...rel/2.21.0) --- updated-dependencies: - dependency-name: org.apache.logging.log4j:log4j-bom dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- apm-agent-builds/apm-agent-java8/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apm-agent-builds/apm-agent-java8/pom.xml b/apm-agent-builds/apm-agent-java8/pom.xml index 205971dcc1..2ccc31a115 100644 --- a/apm-agent-builds/apm-agent-java8/pom.xml +++ b/apm-agent-builds/apm-agent-java8/pom.xml @@ -21,7 +21,7 @@ org.apache.logging.log4j log4j-bom - 2.20.0 + 2.21.0 import pom From 673bf42d03843b03a9195cfd8b0874fff794b2e3 Mon Sep 17 00:00:00 2001 From: Victor Martinez Date: Wed, 18 Oct 2023 11:56:26 +0200 Subject: [PATCH 6/9] action: remove leftover from Jenkins (#3368) --- .github/workflows/triggerCI.yml | 28 ---------------------------- 1 file changed, 28 deletions(-) delete mode 100644 .github/workflows/triggerCI.yml diff --git a/.github/workflows/triggerCI.yml b/.github/workflows/triggerCI.yml deleted file mode 100644 index 7228a29346..0000000000 --- a/.github/workflows/triggerCI.yml +++ /dev/null @@ -1,28 +0,0 @@ -name: "Trigger Tests" -on: - pull_request_target: - types: [ready_for_review] - -jobs: - triggerCI: - runs-on: ubuntu-latest - if: ${{ !github.event.pull_request.draft }} - steps: - - name: Check team membership for user - uses: elastic/get-user-teams-membership@v1.0.4 - id: checkUserMember - with: - username: ${{ github.actor }} - team: 'apm' - usernamesToExclude: | - apmmachine - dependabot - dependabot[bot] - GITHUB_TOKEN: ${{ secrets.APM_TECH_USER_TOKEN }} - - name: Add comment to trigger tests - if: steps.checkUserMember.outputs.isTeamMember == 'true' && steps.checkUserMember.outputs.isExcluded != 'true' - uses: wow-actions/auto-comment@v1 - with: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - pullRequestReadyForReview: /test - From d1d76d2ea98bc2a124bd0c81d6ac9e52f8ef396f Mon Sep 17 00:00:00 2001 From: Jonas Kunz Date: Thu, 19 Oct 2023 15:20:12 +0200 Subject: [PATCH 7/9] Fix aws sdk instrumentation (#3373) * Fix aws sdk instrumentation * Updated changelog and docs * Removed argument added only for testing --- CHANGELOG.asciidoc | 1 + .../apm-aws-sdk/apm-aws-sdk-2-plugin/pom.xml | 2 +- ...BaseAsyncClientHandlerInstrumentation.java | 14 ++- .../BaseSyncClientHandlerInstrumentation.java | 15 ++- .../ClientHandlerConfigInstrumentation.java | 95 +++++++++++++++++++ ...ic.apm.agent.sdk.ElasticApmInstrumentation | 3 +- docs/supported-technologies.asciidoc | 6 +- pom.xml | 2 +- 8 files changed, 130 insertions(+), 8 deletions(-) create mode 100644 apm-agent-plugins/apm-aws-sdk/apm-aws-sdk-2-plugin/src/main/java/co/elastic/apm/agent/awssdk/v2/ClientHandlerConfigInstrumentation.java diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc index 0a8fb52ffb..c55082b337 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -34,6 +34,7 @@ Use subheadings with the "=====" level for adding notes for unreleased changes: [float] ===== Features * Added protection against invalid timestamps provided by manual instrumentation - {pull}3363[#3363] +* Added support for AWS SDK 2.21 - {pull}3373[#3373] [float] ===== Bug fixes diff --git a/apm-agent-plugins/apm-aws-sdk/apm-aws-sdk-2-plugin/pom.xml b/apm-agent-plugins/apm-aws-sdk/apm-aws-sdk-2-plugin/pom.xml index 531467cc31..8b8d57c35a 100644 --- a/apm-agent-plugins/apm-aws-sdk/apm-aws-sdk-2-plugin/pom.xml +++ b/apm-agent-plugins/apm-aws-sdk/apm-aws-sdk-2-plugin/pom.xml @@ -13,7 +13,7 @@ ${project.basedir}/../../.. - 2.20.157 + 2.21.1 2.0.0 8 diff --git a/apm-agent-plugins/apm-aws-sdk/apm-aws-sdk-2-plugin/src/main/java/co/elastic/apm/agent/awssdk/v2/BaseAsyncClientHandlerInstrumentation.java b/apm-agent-plugins/apm-aws-sdk/apm-aws-sdk-2-plugin/src/main/java/co/elastic/apm/agent/awssdk/v2/BaseAsyncClientHandlerInstrumentation.java index 8fc839664d..103ff16596 100644 --- a/apm-agent-plugins/apm-aws-sdk/apm-aws-sdk-2-plugin/src/main/java/co/elastic/apm/agent/awssdk/v2/BaseAsyncClientHandlerInstrumentation.java +++ b/apm-agent-plugins/apm-aws-sdk/apm-aws-sdk-2-plugin/src/main/java/co/elastic/apm/agent/awssdk/v2/BaseAsyncClientHandlerInstrumentation.java @@ -22,6 +22,8 @@ import co.elastic.apm.agent.awssdk.v2.helper.S3Helper; import co.elastic.apm.agent.awssdk.v2.helper.SQSHelper; import co.elastic.apm.agent.sdk.ElasticApmInstrumentation; +import co.elastic.apm.agent.sdk.logging.Logger; +import co.elastic.apm.agent.sdk.logging.LoggerFactory; import co.elastic.apm.agent.tracer.GlobalTracer; import co.elastic.apm.agent.tracer.Span; import co.elastic.apm.agent.tracer.Tracer; @@ -35,6 +37,7 @@ import software.amazon.awssdk.core.client.config.SdkClientOption; import software.amazon.awssdk.core.client.handler.ClientExecutionParams; import software.amazon.awssdk.core.http.ExecutionContext; +import software.amazon.awssdk.core.internal.handler.BaseAsyncClientHandler; import software.amazon.awssdk.core.internal.http.TransformingAsyncResponseHandler; import java.net.URI; @@ -70,12 +73,21 @@ public Collection getInstrumentationGroupNames() { @SuppressWarnings({"unchecked", "rawtypes"}) public static class AdviceClass { + private static final Logger logger = LoggerFactory.getLogger(AdviceClass.class); + @Advice.OnMethodEnter(suppress = Throwable.class, inline = false) @Advice.AssignReturned.ToArguments(@Advice.AssignReturned.ToArguments.ToArgument(value = 2)) public static TransformingAsyncResponseHandler enterDoExecute(@Advice.Argument(value = 0) ClientExecutionParams clientExecutionParams, @Advice.Argument(value = 1) ExecutionContext executionContext, @Advice.Argument(value = 2) TransformingAsyncResponseHandler responseHandler, - @Advice.FieldValue("clientConfiguration") SdkClientConfiguration clientConfiguration) { + @Advice.This BaseAsyncClientHandler handler) { + + SdkClientConfiguration clientConfiguration = ClientHandlerConfigInstrumentation.AdviceClass.getConfig(handler); + if(clientConfiguration == null) { + logger.warn("Not tracing AWS request due to being unable to resolve the configuration"); + return responseHandler; + } + String awsService = executionContext.executionAttributes().getAttribute(AwsSignerExecutionAttribute.SERVICE_NAME); SdkRequest sdkRequest = clientExecutionParams.getInput(); URI uri = clientConfiguration.option(SdkClientOption.ENDPOINT); diff --git a/apm-agent-plugins/apm-aws-sdk/apm-aws-sdk-2-plugin/src/main/java/co/elastic/apm/agent/awssdk/v2/BaseSyncClientHandlerInstrumentation.java b/apm-agent-plugins/apm-aws-sdk/apm-aws-sdk-2-plugin/src/main/java/co/elastic/apm/agent/awssdk/v2/BaseSyncClientHandlerInstrumentation.java index b49d4a009b..ccc7dfa58a 100644 --- a/apm-agent-plugins/apm-aws-sdk/apm-aws-sdk-2-plugin/src/main/java/co/elastic/apm/agent/awssdk/v2/BaseSyncClientHandlerInstrumentation.java +++ b/apm-agent-plugins/apm-aws-sdk/apm-aws-sdk-2-plugin/src/main/java/co/elastic/apm/agent/awssdk/v2/BaseSyncClientHandlerInstrumentation.java @@ -24,6 +24,8 @@ import co.elastic.apm.agent.awssdk.v2.helper.sqs.wrapper.MessageListWrapper; import co.elastic.apm.agent.common.JvmRuntimeInfo; import co.elastic.apm.agent.sdk.ElasticApmInstrumentation; +import co.elastic.apm.agent.sdk.logging.Logger; +import co.elastic.apm.agent.sdk.logging.LoggerFactory; import co.elastic.apm.agent.tracer.GlobalTracer; import co.elastic.apm.agent.tracer.Outcome; import co.elastic.apm.agent.tracer.Span; @@ -39,6 +41,8 @@ import software.amazon.awssdk.core.client.config.SdkClientOption; import software.amazon.awssdk.core.client.handler.ClientExecutionParams; import software.amazon.awssdk.core.http.ExecutionContext; +import software.amazon.awssdk.core.internal.handler.BaseAsyncClientHandler; +import software.amazon.awssdk.core.internal.handler.BaseSyncClientHandler; import javax.annotation.Nullable; import java.net.URI; @@ -81,11 +85,20 @@ public Collection getInstrumentationGroupNames() { @SuppressWarnings("rawtypes") public static class AdviceClass { + private static final Logger logger = LoggerFactory.getLogger(AdviceClass.class); + @Nullable @Advice.OnMethodEnter(suppress = Throwable.class, inline = false) public static Object enterDoExecute(@Advice.Argument(value = 0) ClientExecutionParams clientExecutionParams, @Advice.Argument(value = 1) ExecutionContext executionContext, - @Advice.FieldValue("clientConfiguration") SdkClientConfiguration clientConfiguration) { + @Advice.This BaseSyncClientHandler handler) { + + SdkClientConfiguration clientConfiguration = ClientHandlerConfigInstrumentation.AdviceClass.getConfig(handler); + if(clientConfiguration == null) { + logger.warn("Not tracing AWS request due to being unable to resolve the configuration"); + return null; + } + String awsService = executionContext.executionAttributes().getAttribute(AwsSignerExecutionAttribute.SERVICE_NAME); SdkRequest sdkRequest = clientExecutionParams.getInput(); URI uri = clientConfiguration.option(SdkClientOption.ENDPOINT); diff --git a/apm-agent-plugins/apm-aws-sdk/apm-aws-sdk-2-plugin/src/main/java/co/elastic/apm/agent/awssdk/v2/ClientHandlerConfigInstrumentation.java b/apm-agent-plugins/apm-aws-sdk/apm-aws-sdk-2-plugin/src/main/java/co/elastic/apm/agent/awssdk/v2/ClientHandlerConfigInstrumentation.java new file mode 100644 index 0000000000..88f45bd43d --- /dev/null +++ b/apm-agent-plugins/apm-aws-sdk/apm-aws-sdk-2-plugin/src/main/java/co/elastic/apm/agent/awssdk/v2/ClientHandlerConfigInstrumentation.java @@ -0,0 +1,95 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License 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 co.elastic.apm.agent.awssdk.v2; + +import co.elastic.apm.agent.awssdk.v2.helper.DynamoDbHelper; +import co.elastic.apm.agent.awssdk.v2.helper.S3Helper; +import co.elastic.apm.agent.awssdk.v2.helper.SQSHelper; +import co.elastic.apm.agent.awssdk.v2.helper.sqs.wrapper.MessageListWrapper; +import co.elastic.apm.agent.common.JvmRuntimeInfo; +import co.elastic.apm.agent.sdk.ElasticApmInstrumentation; +import co.elastic.apm.agent.sdk.weakconcurrent.WeakConcurrent; +import co.elastic.apm.agent.sdk.weakconcurrent.WeakMap; +import co.elastic.apm.agent.tracer.GlobalTracer; +import co.elastic.apm.agent.tracer.Outcome; +import co.elastic.apm.agent.tracer.Span; +import co.elastic.apm.agent.tracer.Tracer; +import net.bytebuddy.asm.Advice; +import net.bytebuddy.description.method.MethodDescription; +import net.bytebuddy.description.type.TypeDescription; +import net.bytebuddy.matcher.ElementMatcher; +import software.amazon.awssdk.auth.signer.AwsSignerExecutionAttribute; +import software.amazon.awssdk.core.SdkRequest; +import software.amazon.awssdk.core.SdkResponse; +import software.amazon.awssdk.core.client.config.SdkClientConfiguration; +import software.amazon.awssdk.core.client.config.SdkClientOption; +import software.amazon.awssdk.core.client.handler.ClientExecutionParams; +import software.amazon.awssdk.core.http.ExecutionContext; + +import javax.annotation.Nullable; +import java.net.URI; +import java.util.Collection; +import java.util.Collections; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +import static net.bytebuddy.matcher.ElementMatchers.isConstructor; +import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith; +import static net.bytebuddy.matcher.ElementMatchers.named; +import static net.bytebuddy.matcher.ElementMatchers.takesArgument; + +public class ClientHandlerConfigInstrumentation extends ElasticApmInstrumentation { + + + @Override + public ElementMatcher getTypeMatcher() { + return named("software.amazon.awssdk.core.internal.handler.BaseSyncClientHandler") + .or(named("software.amazon.awssdk.core.internal.handler.BaseAsyncClientHandler")); + } + + @Override + public ElementMatcher getMethodMatcher() { + return isConstructor() + .and(takesArgument(0, named("software.amazon.awssdk.core.client.config.SdkClientConfiguration"))); + } + + @Override + public Collection getInstrumentationGroupNames() { + return Collections.singleton("aws-sdk"); + } + + + @SuppressWarnings("rawtypes") + public static class AdviceClass { + + private static final WeakMap configMap = WeakConcurrent.buildMap(); + + @Nullable + public static SdkClientConfiguration getConfig(Object handler) { + return configMap.get(handler); + } + + + @Advice.OnMethodExit(suppress = Throwable.class, inline = false) + public static void exit(@Advice.This Object handler, @Advice.Argument(value = 0) SdkClientConfiguration config) { + configMap.put(handler, config); + } + + } +} diff --git a/apm-agent-plugins/apm-aws-sdk/apm-aws-sdk-2-plugin/src/main/resources/META-INF/services/co.elastic.apm.agent.sdk.ElasticApmInstrumentation b/apm-agent-plugins/apm-aws-sdk/apm-aws-sdk-2-plugin/src/main/resources/META-INF/services/co.elastic.apm.agent.sdk.ElasticApmInstrumentation index 5dcc2147ec..aa3c1f1b14 100644 --- a/apm-agent-plugins/apm-aws-sdk/apm-aws-sdk-2-plugin/src/main/resources/META-INF/services/co.elastic.apm.agent.sdk.ElasticApmInstrumentation +++ b/apm-agent-plugins/apm-aws-sdk/apm-aws-sdk-2-plugin/src/main/resources/META-INF/services/co.elastic.apm.agent.sdk.ElasticApmInstrumentation @@ -1,4 +1,5 @@ co.elastic.apm.agent.awssdk.v2.BaseSyncClientHandlerInstrumentation co.elastic.apm.agent.awssdk.v2.BaseAsyncClientHandlerInstrumentation +co.elastic.apm.agent.awssdk.v2.ClientHandlerConfigInstrumentation co.elastic.apm.agent.awssdk.v2.GetMessagesInstrumentation -co.elastic.apm.agent.awssdk.v2.AmazonSQSMessagingClientWrapperInstrumentation \ No newline at end of file +co.elastic.apm.agent.awssdk.v2.AmazonSQSMessagingClientWrapperInstrumentation diff --git a/docs/supported-technologies.asciidoc b/docs/supported-technologies.asciidoc index fe223cfc0e..06c35e2260 100644 --- a/docs/supported-technologies.asciidoc +++ b/docs/supported-technologies.asciidoc @@ -294,12 +294,12 @@ This provides support for `com.datastax.cassandra:cassandra-driver-core` and |AWS DynamoDB |1.x, 2.x |The agent creates spans for interactions with the AWS DynamoDb service through the AWS Java SDK. -|1.31.0 +|1.31.0, 2.21+ since 1.44.0 |AWS S3 |1.x, 2.x |The agent creates spans for interactions with the AWS S3 service through the AWS Java SDK. -|1.31.0 +|1.31.0, 2.21+ since 1.44.0 |=== @@ -459,7 +459,7 @@ same trace. |AWS SQS |1.x, 2.x |The agent captures SQS Message sends and polling as well as SQS message sends and consumption through JMS. -|1.34.0 +|1.34.0, 2.21+ since 1.44.0 |=== diff --git a/pom.xml b/pom.xml index a658c40a84..338f7d30c6 100644 --- a/pom.xml +++ b/pom.xml @@ -140,7 +140,7 @@ 1.17 - 1.16.3 + 1.19.1 2.38.0 From 4f4b1c71af89fb4fd3e839b8329034e50563b1f8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 19 Oct 2023 14:25:22 +0000 Subject: [PATCH 8/9] Bump version.log4j from 2.12.4 to 2.21.0 (#3366) * Bump version.log4j from 2.12.4 to 2.21.0 Bumps `version.log4j` from 2.12.4 to 2.21.0. Updates `org.apache.logging.log4j:log4j-core` from 2.12.4 to 2.21.0 Updates `org.apache.logging.log4j:log4j-slf4j-impl` from 2.12.4 to 2.21.0 --- updated-dependencies: - dependency-name: org.apache.logging.log4j:log4j-core dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: org.apache.logging.log4j:log4j-slf4j-impl dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Update pom.xml * Update pom.xml --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jonas Kunz Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- apm-agent-plugins/apm-ecs-logging-plugin/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apm-agent-plugins/apm-ecs-logging-plugin/pom.xml b/apm-agent-plugins/apm-ecs-logging-plugin/pom.xml index e61eda6307..e0a68cbc7a 100644 --- a/apm-agent-plugins/apm-ecs-logging-plugin/pom.xml +++ b/apm-agent-plugins/apm-ecs-logging-plugin/pom.xml @@ -48,7 +48,7 @@ org.apache.logging.log4j log4j-core - 2.20.0 + 2.21.0 provided true From 5fcba1047ae2ccff77d0ddb139143c2f6c8bd166 Mon Sep 17 00:00:00 2001 From: Nugusbayev Kanagat <48118512+videnkz@users.noreply.github.com> Date: Tue, 24 Oct 2023 15:37:03 +0600 Subject: [PATCH 9/9] added capturing s3 otel attributes from lamba S3Event (#3364) * added capturing s3 otel attributes from lamba S3Event * added entry to changelog * minor polish --- CHANGELOG.asciidoc | 1 + .../awslambda/helper/S3TransactionHelper.java | 18 +++++++++++++----- .../apm/agent/awslambda/S3EventLambdaTest.java | 13 ++++++++++++- 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc index c55082b337..c8f21ef12b 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -35,6 +35,7 @@ Use subheadings with the "=====" level for adding notes for unreleased changes: ===== Features * Added protection against invalid timestamps provided by manual instrumentation - {pull}3363[#3363] * Added support for AWS SDK 2.21 - {pull}3373[#3373] +* Capture bucket and object key to Lambda transaction as OTel attributes - `aws.s3.bueckt`, `aws.s3.key` - {pull}3364[#3364] [float] ===== Bug fixes diff --git a/apm-agent-plugins/apm-awslambda-plugin/src/main/java/co/elastic/apm/agent/awslambda/helper/S3TransactionHelper.java b/apm-agent-plugins/apm-awslambda-plugin/src/main/java/co/elastic/apm/agent/awslambda/helper/S3TransactionHelper.java index fbfda924cd..e2203a665d 100644 --- a/apm-agent-plugins/apm-awslambda-plugin/src/main/java/co/elastic/apm/agent/awslambda/helper/S3TransactionHelper.java +++ b/apm-agent-plugins/apm-awslambda-plugin/src/main/java/co/elastic/apm/agent/awslambda/helper/S3TransactionHelper.java @@ -78,12 +78,20 @@ protected void setTransactionTriggerData(Transaction transaction, S3Event s3Even cloudOrigin.withRegion(s3NotificationRecord.getAwsRegion()); - if (null != s3NotificationRecord.getS3() && null != s3NotificationRecord.getS3().getBucket()) { + if (null != s3NotificationRecord.getS3()) { S3EventNotification.S3BucketEntity bucket = s3NotificationRecord.getS3().getBucket(); - ServiceOrigin serviceOrigin = transaction.getContext().getServiceOrigin(); - serviceOrigin.withId(bucket.getArn()); - serviceOrigin.withName(bucket.getName()); - serviceOrigin.withVersion(s3NotificationRecord.getEventVersion()); + if (null != bucket) { + ServiceOrigin serviceOrigin = transaction.getContext().getServiceOrigin(); + serviceOrigin.withId(bucket.getArn()); + serviceOrigin.withName(bucket.getName()); + serviceOrigin.withVersion(s3NotificationRecord.getEventVersion()); + + transaction.withOtelAttribute("aws.s3.bucket", bucket.getName()); + } + S3EventNotification.S3ObjectEntity object = s3NotificationRecord.getS3().getObject(); + if (null != object) { + transaction.withOtelAttribute("aws.s3.key", object.getKey()); + } } } } diff --git a/apm-agent-plugins/apm-awslambda-plugin/src/test/java/co/elastic/apm/agent/awslambda/S3EventLambdaTest.java b/apm-agent-plugins/apm-awslambda-plugin/src/test/java/co/elastic/apm/agent/awslambda/S3EventLambdaTest.java index d7d7d47e21..82c737523c 100644 --- a/apm-agent-plugins/apm-awslambda-plugin/src/test/java/co/elastic/apm/agent/awslambda/S3EventLambdaTest.java +++ b/apm-agent-plugins/apm-awslambda-plugin/src/test/java/co/elastic/apm/agent/awslambda/S3EventLambdaTest.java @@ -66,7 +66,8 @@ protected boolean supportsContextPropagation() { private S3EventNotification.S3EventNotificationRecord createS3NotificationRecord() { S3EventNotification.ResponseElementsEntity responseElements = new S3EventNotification.ResponseElementsEntity("xAmzId2", S3_REQUEST_ID); S3EventNotification.S3BucketEntity bucket = new S3EventNotification.S3BucketEntity(S3_BUCKET_NAME, null, S3_BUCKET_ARN); - S3EventNotification.S3Entity s3 = new S3EventNotification.S3Entity("configId", bucket, null, "3.3"); + S3EventNotification.S3ObjectEntity object = new S3EventNotification.S3ObjectEntity("b21b84d653bb07b05b1e6b33684dc11b", 1305107, "b21b84d653bb07b05b1e6b33684dc11b", "0C0F6F405D6ED209E1"); + S3EventNotification.S3Entity s3 = new S3EventNotification.S3Entity("configId", bucket, object, "3.3"); return new S3EventNotification.S3EventNotificationRecord(EVENT_SOURCE_REGION, S3_EVENT_NAME, S3_EVENT_SOURCE, null, S3_EVENT_VERSION, null, responseElements, s3, null); } @@ -102,6 +103,8 @@ public void testBasicCall() { assertThat(faas.getId()).isEqualTo(TestContext.FUNCTION_ARN); assertThat(faas.getTrigger().getType()).isEqualTo("datasource"); assertThat(faas.getTrigger().getRequestId()).isEqualTo(S3_REQUEST_ID); + + verifyOtelAttributes(transaction); } @Test @@ -174,4 +177,12 @@ private void validateResultsForUnspecifiedRecord() { assertThat(faas.getTrigger().getType()).isEqualTo("datasource"); assertThat(faas.getTrigger().getRequestId()).isNull(); } + + private void verifyOtelAttributes(Transaction transaction) { + Object s3keyAttribute = transaction.getOtelAttributes().get("aws.s3.key"); + assertThat(s3keyAttribute).isInstanceOf(String.class).isEqualTo("b21b84d653bb07b05b1e6b33684dc11b"); + + Object s3bucketAttribute = transaction.getOtelAttributes().get("aws.s3.bucket"); + assertThat(s3bucketAttribute).isInstanceOf(String.class).isEqualTo(S3_BUCKET_NAME); + } }