-
Notifications
You must be signed in to change notification settings - Fork 828
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Muzzle logs should be logged using the io.opentelemetry.* logger name (…
- Loading branch information
Mateusz Rzeszutek
committed
Jan 12, 2023
1 parent
cd47008
commit bb7a12d
Showing
3 changed files
with
114 additions
and
88 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
111 changes: 111 additions & 0 deletions
111
...oling/src/main/java/io/opentelemetry/javaagent/tooling/instrumentation/MuzzleMatcher.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
/* | ||
* Copyright The OpenTelemetry Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package io.opentelemetry.javaagent.tooling.instrumentation; | ||
|
||
import static java.util.logging.Level.FINE; | ||
import static java.util.logging.Level.WARNING; | ||
import static net.bytebuddy.dynamic.loading.ClassLoadingStrategy.BOOTSTRAP_LOADER; | ||
|
||
import io.opentelemetry.instrumentation.api.internal.cache.Cache; | ||
import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; | ||
import io.opentelemetry.javaagent.tooling.TransformSafeLogger; | ||
import io.opentelemetry.javaagent.tooling.Utils; | ||
import io.opentelemetry.javaagent.tooling.config.AgentConfig; | ||
import io.opentelemetry.javaagent.tooling.muzzle.Mismatch; | ||
import io.opentelemetry.javaagent.tooling.muzzle.ReferenceMatcher; | ||
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; | ||
import java.security.ProtectionDomain; | ||
import java.util.List; | ||
import java.util.concurrent.atomic.AtomicBoolean; | ||
import java.util.logging.Level; | ||
import java.util.logging.Logger; | ||
import net.bytebuddy.agent.builder.AgentBuilder; | ||
import net.bytebuddy.description.type.TypeDescription; | ||
import net.bytebuddy.utility.JavaModule; | ||
|
||
/** | ||
* A ByteBuddy matcher that decides whether this instrumentation should be applied. Calls generated | ||
* {@link ReferenceMatcher}: if any mismatch with the passed {@code classLoader} is found this | ||
* instrumentation is skipped. | ||
*/ | ||
class MuzzleMatcher implements AgentBuilder.RawMatcher { | ||
|
||
private static final Logger muzzleLogger = Logger.getLogger(MuzzleMatcher.class.getName()); | ||
|
||
private final TransformSafeLogger instrumentationLogger; | ||
private final InstrumentationModule instrumentationModule; | ||
private final Level muzzleLogLevel; | ||
private final AtomicBoolean initialized = new AtomicBoolean(false); | ||
private final Cache<ClassLoader, Boolean> matchCache = Cache.weak(); | ||
private volatile ReferenceMatcher referenceMatcher; | ||
|
||
MuzzleMatcher( | ||
TransformSafeLogger instrumentationLogger, | ||
InstrumentationModule instrumentationModule, | ||
ConfigProperties config) { | ||
this.instrumentationLogger = instrumentationLogger; | ||
this.instrumentationModule = instrumentationModule; | ||
this.muzzleLogLevel = AgentConfig.isDebugModeEnabled(config) ? WARNING : FINE; | ||
} | ||
|
||
@Override | ||
public boolean matches( | ||
TypeDescription typeDescription, | ||
ClassLoader classLoader, | ||
JavaModule module, | ||
Class<?> classBeingRedefined, | ||
ProtectionDomain protectionDomain) { | ||
if (classLoader == BOOTSTRAP_LOADER) { | ||
classLoader = Utils.getBootstrapProxy(); | ||
} | ||
return matchCache.computeIfAbsent(classLoader, this::doesMatch); | ||
} | ||
|
||
private boolean doesMatch(ClassLoader classLoader) { | ||
ReferenceMatcher muzzle = getReferenceMatcher(); | ||
boolean isMatch = muzzle.matches(classLoader); | ||
|
||
if (!isMatch) { | ||
MuzzleFailureCounter.inc(); | ||
if (muzzleLogger.isLoggable(muzzleLogLevel)) { | ||
muzzleLogger.log( | ||
muzzleLogLevel, | ||
"Instrumentation skipped, mismatched references were found: {0} [class {1}] on {2}", | ||
new Object[] { | ||
instrumentationModule.instrumentationName(), | ||
instrumentationModule.getClass().getName(), | ||
classLoader | ||
}); | ||
List<Mismatch> mismatches = muzzle.getMismatchedReferenceSources(classLoader); | ||
for (Mismatch mismatch : mismatches) { | ||
muzzleLogger.log(muzzleLogLevel, "-- {0}", mismatch); | ||
} | ||
} | ||
} else { | ||
if (instrumentationLogger.isLoggable(FINE)) { | ||
instrumentationLogger.log( | ||
FINE, | ||
"Applying instrumentation: {0} [class {1}] on {2}", | ||
new Object[] { | ||
instrumentationModule.instrumentationName(), | ||
instrumentationModule.getClass().getName(), | ||
classLoader | ||
}); | ||
} | ||
} | ||
|
||
return isMatch; | ||
} | ||
|
||
// ReferenceMatcher is lazily created to avoid unnecessarily loading the muzzle references from | ||
// the module during the agent setup | ||
private ReferenceMatcher getReferenceMatcher() { | ||
if (initialized.compareAndSet(false, true)) { | ||
referenceMatcher = ReferenceMatcher.of(instrumentationModule); | ||
} | ||
return referenceMatcher; | ||
} | ||
} |