Skip to content

Commit

Permalink
Fix log injection of xray ID. (#102)
Browse files Browse the repository at this point in the history
  • Loading branch information
Anuraag Agrawal authored Oct 19, 2021
1 parent 1e5ce35 commit 795b02e
Show file tree
Hide file tree
Showing 5 changed files with 147 additions and 26 deletions.
6 changes: 4 additions & 2 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ allprojects {

spotless {
java {
googleJavaFormat("1.8")
googleJavaFormat()

if (!project.path.startsWith(":sample-apps:")) {
licenseHeaderFile("${rootProject.projectDir}/config/license/header.java")
Expand Down Expand Up @@ -157,9 +157,11 @@ allprojects {

plugins.withId("com.github.johnrengelman.shadow") {
tasks {
named<ShadowJar>("shadowJar") {
withType<ShadowJar>().configureEach {
exclude("**/module-info.class")

mergeServiceFiles()

// rewrite library instrumentation dependencies
relocate("io.opentelemetry.instrumentation", "io.opentelemetry.javaagent.shaded.instrumentation")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public AwsXrayLog4jInstrumentationModule() {
// The SPI will be merged with what's in the agent so we don't need to inject it, only our
// provider implementation.
@Override
public List<String> helperResourceNames() {
public List<String> getMuzzleHelperClassNames() {
return Collections.singletonList(
"software.amazon.opentelemetry.javaagent.instrumentation.log4j_2_13_2."
+ "AwsXrayContextDataProvider");
Expand Down
64 changes: 42 additions & 22 deletions otelagent/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
* permissions and limitations under the License.
*/

import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar

plugins {
java
`maven-publish`
Expand All @@ -27,7 +29,18 @@ java {
}

base {
archivesBaseName = "aws-opentelemetry-agent"
archivesName.set("aws-opentelemetry-agent")
}

val javaagentLibs by configurations.creating {
isCanBeResolved = true
isCanBeConsumed = false

exclude("io.opentelemetry", "opentelemetry-api")
exclude("io.opentelemetry", "opentelemetry-api-metrics")
exclude("io.opentelemetry", "opentelemetry-sdk")
exclude("io.opentelemetry", "opentelemetry-sdk-common")
exclude("io.opentelemetry", "opentelemetry-semconv")
}

val shadowClasspath by configurations.creating {
Expand All @@ -43,38 +56,30 @@ dependencies {
val agentDep = create("io.opentelemetry.javaagent", "opentelemetry-javaagent", classifier = "all")
shadowClasspath(agentDep)
compileOnly(agentDep)
}

val bundledProjects = listOf(
project(":awsagentprovider"),
project(":instrumentation:log4j-2.13.2"),
project(":instrumentation:logback-1.0")
)

for (bundled in bundledProjects) {
evaluationDependsOn(bundled.path)
javaagentLibs(project(":awsagentprovider"))
javaagentLibs(project(":instrumentation:log4j-2.13.2"))
javaagentLibs(project(":instrumentation:logback-1.0"))
}

tasks {
processResources {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE

for (bundled in bundledProjects) {
val task = bundled.tasks.named<Jar>("shadowJar").get()
val providerArchive = task.archiveFile
from(zipTree(providerArchive)) {
into("inst")
rename("(^.*)\\.class$", "$1.classdata")
}
dependsOn(task)
}
val relocateJavaagentLibs by registering(ShadowJar::class) {
configurations = listOf(javaagentLibs)

duplicatesStrategy = DuplicatesStrategy.FAIL

archiveFileName.set("javaagentLibs-relocated.jar")
}

shadowJar {
dependsOn(relocateJavaagentLibs)

archiveClassifier.set("")

configurations = listOf(shadowClasspath)

isolateClasses(relocateJavaagentLibs.get().outputs.files)

exclude("**/module-info.class")

mergeServiceFiles("inst/META-INF/services")
Expand Down Expand Up @@ -130,3 +135,18 @@ jib {
}
containerizingMode = "packaged"
}

fun CopySpec.isolateClasses(jars: Iterable<File>) {
jars.forEach {
from(zipTree(it)) {
// important to keep prefix "inst" short, as it is prefixed to lots of strings in runtime mem
into("inst")
rename("(^.*)\\.class\$", "\$1.classdata")
// Rename LICENSE file since it clashes with license dir on non-case sensitive FSs (i.e. Mac)
rename("""^LICENSE$""", "LICENSE.renamed")
exclude("META-INF/INDEX.LIST")
exclude("META-INF/*.DSA")
exclude("META-INF/*.SF")
}
}
}
2 changes: 1 addition & 1 deletion settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

pluginManagement {
plugins {
id("com.diffplug.spotless") version "5.14.3"
id("com.diffplug.spotless") version "5.17.0"
id("com.github.ben-manes.versions") version "0.39.0"
id("com.github.jk1.dependency-license-report") version "1.17"
id("com.github.johnrengelman.shadow") version "7.0.0"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/*
* 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 io.awsobservability.instrumentation.smoketests.runner;

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

import com.linecorp.armeria.client.WebClient;
import java.util.regex.Pattern;
import org.junit.jupiter.api.Test;
import org.slf4j.LoggerFactory;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.output.Slf4jLogConsumer;
import org.testcontainers.containers.output.ToStringConsumer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.testcontainers.utility.MountableFile;

@Testcontainers(disabledWithoutDocker = true)
class LogInjectionTest {

private static final ToStringConsumer log4jString = new ToStringConsumer();
private static final ToStringConsumer logbackString = new ToStringConsumer();

private static final String AGENT_PATH =
System.getProperty("io.awsobservability.instrumentation.smoketests.runner.agentPath");

@Container
private static final GenericContainer<?> log4jApp =
new GenericContainer<>(
"public.ecr.aws/aws-otel-test/aws-otel-java-spark:f8f1ee321a1dc7f306f8354aca357ecbedfe8133")
.withExposedPorts(4567)
.withLogConsumer(new Slf4jLogConsumer(LoggerFactory.getLogger("log4j")))
.withLogConsumer(log4jString)
.withCopyFileToContainer(
MountableFile.forHostPath(AGENT_PATH), "/opentelemetry-javaagent-all.jar")
.withEnv("JAVA_TOOL_OPTIONS", "-javaagent:/opentelemetry-javaagent-all.jar")
.withEnv("OTEL_JAVAAGENT_DEBUG", "true")
.withEnv("AWS_REGION", "us-west-2")
.withEnv("LISTEN_ADDRESS", "0.0.0.0:4567");

@Container
private static final GenericContainer<?> logbackApp =
new GenericContainer<>(
"public.ecr.aws/aws-otel-test/aws-otel-java-springboot:f8f1ee321a1dc7f306f8354aca357ecbedfe8133")
.withExposedPorts(8080)
.withLogConsumer(new Slf4jLogConsumer(LoggerFactory.getLogger("logback")))
.withLogConsumer(logbackString)
.withCopyFileToContainer(
MountableFile.forHostPath(AGENT_PATH), "/opentelemetry-javaagent-all.jar")
.withEnv("JAVA_TOOL_OPTIONS", "-javaagent:/opentelemetry-javaagent-all.jar")
.withEnv("OTEL_JAVAAGENT_DEBUG", "true")
.withEnv("AWS_REGION", "us-west-2")
.withEnv("LISTEN_ADDRESS", "0.0.0.0:8080");

private WebClient appClient;

@Test
void log4j() {
WebClient.of("http://localhost:" + log4jApp.getMappedPort(4567))
.get("/outgoing-http-call")
.aggregate()
.join();

// Log message has X-Ray trace ID.
assertThat(log4jString.toUtf8String())
.matches(
Pattern.compile(
".*1-[0-9a-f]{8}-[0-9a-f]{24}@[0-9a-f]{16} - Executing outgoing-http-call.*",
Pattern.DOTALL));
}

@Test
void logback() {
WebClient.of("http://localhost:" + logbackApp.getMappedPort(8080))
.get("/outgoing-http-call")
.aggregate()
.join();

// Log message has X-Ray trace ID.
assertThat(logbackString.toUtf8String())
.matches(
Pattern.compile(
".*1-[0-9a-f]{8}-[0-9a-f]{24}@[0-9a-f]{16} : Executing outgoing-http-call.*",
Pattern.DOTALL));
}
}

0 comments on commit 795b02e

Please sign in to comment.