Skip to content

Commit 864e4e2

Browse files
authored
Logging custom facade (elastic#2390)
1 parent 641c501 commit 864e4e2

File tree

150 files changed

+1430
-669
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

150 files changed

+1430
-669
lines changed

CHANGELOG.asciidoc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,13 @@ endif::[]
2828
* Exceptions that are logged using the fatal log level are now captured (log4j2 only) - {pull}2377[#2377]
2929
* Replaced `authorization` in the default value of `sanitize_field_names` with `*auth*` - {pull}2326[#2326]
3030
* Unsampled transactions are dropped and not sent to the APM-Server if the APM-Server version is 8.0+ - {pull}2329[#2329]
31+
* Adding agent logging capabilities to our SDK, making it available for external plugins - {pull}2390[#2390]
3132
3233
[float]
3334
===== Bug fixes
3435
* Fix runtime attach with some docker images - {pull}2385[#2385]
3536
* Restore dynamic capability to `log_level` config for plugin loggers - {pull}2384[#2384]
37+
* Fix slf4j-related `LinkageError` - {pull}2390[#2390]
3638
3739
[[release-notes-1.x]]
3840
=== Java Agent version 1.x

NOTICE

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
Elastic APM Java Agent
2-
Copyright 2018-2019 Elasticsearch B.V.
2+
Copyright 2018-2022 Elasticsearch B.V.
33

44
###############################################################################
55

@@ -14,6 +14,7 @@ following sources:
1414
- JCTools
1515
- https://github.com/jvm-profiling-tools/async-profiler
1616
- https://github.com/real-logic/agrona
17+
- Apache Log4j 2 - https://logging.apache.org/log4j/2.x/license.html
1718

1819
------------------------------------------------------------------------------
1920
stagemonitor NOTICE
@@ -130,6 +131,27 @@ information: Portions Copyright [yyyy] [name of copyright owner]
130131

131132
CDDL HEADER END
132133

134+
------------------------------------------------------------------------------
135+
Apache Log4j NOTICE
136+
137+
Apache Log4j
138+
Copyright 1999-2021 Apache Software Foundation
139+
140+
This product includes software developed at
141+
The Apache Software Foundation (http://www.apache.org/).
142+
143+
ResolverUtil.java
144+
Copyright 2005-2006 Tim Fennell
145+
146+
Dumbster SMTP test server
147+
Copyright 2004 Jason Paul Kitchen
148+
149+
TypeUtil.java
150+
Copyright 2002-2012 Ramnivas Laddad, Juergen Hoeller, Chris Beams
151+
152+
picocli (http://picocli.info)
153+
Copyright 2017 Remko Popma
154+
133155
------------------------------------------------------------------------------
134156

135157
Apache License
@@ -369,7 +391,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
369391

370392
###############################################################################
371393

372-
This product includes code from slf4j, under MIT License
394+
This product includes code from slf4j, under MIT License.
395+
It also includes code that is based on some slf4j interfaces.
373396

374397
Copyright (c) 2004-2011 QOS.ch
375398
All rights reserved.

apm-agent-core/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,11 @@
6969
<artifactId>log4j-slf4j-impl</artifactId>
7070
<version>${version.log4j}</version>
7171
</dependency>
72+
<dependency>
73+
<groupId>org.slf4j</groupId>
74+
<artifactId>slf4j-api</artifactId>
75+
<version>${version.slf4j}</version>
76+
</dependency>
7277
<dependency>
7378
<groupId>co.elastic.logging</groupId>
7479
<artifactId>log4j2-ecs-layout</artifactId>

apm-agent-core/src/main/java/co/elastic/apm/agent/bci/ElasticApmAgent.java

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@
5858
import net.bytebuddy.matcher.ElementMatchers;
5959
import net.bytebuddy.pool.TypePool;
6060
import net.bytebuddy.utility.JavaModule;
61-
import org.slf4j.Logger;
62-
import org.slf4j.LoggerFactory;
61+
import co.elastic.apm.agent.sdk.logging.Logger;
62+
import co.elastic.apm.agent.sdk.logging.LoggerFactory;
6363
import org.stagemonitor.configuration.ConfigurationOption;
6464
import org.stagemonitor.configuration.source.ConfigurationSource;
6565

@@ -526,12 +526,9 @@ private static void validateAdviceReturnAndParameterTypes(MethodDescription.InDe
526526
String adviceMethod = advice.getInternalName();
527527
try {
528528
checkNotAgentType(advice.getReturnType(), "return type", adviceClass, adviceMethod);
529-
checkNotSlf4jType(advice.getReturnType(), "return type", adviceClass, adviceMethod);
530529

531530
for (ParameterDescription.InDefinedShape parameter : advice.getParameters()) {
532531
checkNotAgentType(parameter.getType(), "parameter", adviceClass, adviceMethod);
533-
checkNotSlf4jType(parameter.getType(), "parameter", adviceClass, adviceMethod);
534-
535532
AnnotationDescription.Loadable<Advice.Return> returnAnnotation = parameter.getDeclaredAnnotations().ofType(Advice.Return.class);
536533
if (returnAnnotation != null && !returnAnnotation.load().readOnly()) {
537534
throw new IllegalStateException("Advice parameter must not use '@Advice.Return(readOnly=false)', use @Advice.AssignReturned.ToReturned instead");
@@ -552,15 +549,6 @@ private static void checkNotAgentType(TypeDescription.Generic type, String descr
552549
}
553550
}
554551

555-
private static void checkNotSlf4jType(TypeDescription.Generic type, String description, String adviceClass, String adviceMethod) {
556-
// When trying to instrument slf4j classes from the application, advices would instead resolve the types from the agent class loader
557-
// This would lead to errors on indy bootstrap, similar to the ones reported at https://github.com/elastic/apm-agent-java/issues/2163
558-
String name = type.asRawType().getTypeName();
559-
if (name.startsWith("org.slf4j.")) {
560-
throw new IllegalStateException(String.format("Advice %s in %s#%s must not reference slf4j types: %s", description, adviceClass, adviceMethod, name));
561-
}
562-
}
563-
564552
private static MatcherTimer getOrCreateTimer(Class<? extends ElasticApmInstrumentation> adviceClass) {
565553
final String name = adviceClass.getName();
566554
MatcherTimer timer = matcherTimers.get(name);

apm-agent-core/src/main/java/co/elastic/apm/agent/bci/IndyBootstrap.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@
2727
import net.bytebuddy.asm.Advice;
2828
import net.bytebuddy.dynamic.ClassFileLocator;
2929
import net.bytebuddy.dynamic.loading.ClassInjector;
30-
import org.slf4j.Logger;
31-
import org.slf4j.LoggerFactory;
30+
import co.elastic.apm.agent.sdk.logging.Logger;
31+
import co.elastic.apm.agent.sdk.logging.LoggerFactory;
3232
import org.stagemonitor.configuration.ConfigurationOptionProvider;
3333
import org.stagemonitor.util.IOUtils;
3434

apm-agent-core/src/main/java/co/elastic/apm/agent/bci/IndyPluginClassLoaderFactory.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@
2323
import net.bytebuddy.dynamic.ClassFileLocator;
2424
import net.bytebuddy.matcher.ElementMatcher;
2525
import net.bytebuddy.pool.TypePool;
26-
import org.slf4j.Logger;
27-
import org.slf4j.LoggerFactory;
26+
import co.elastic.apm.agent.sdk.logging.Logger;
27+
import co.elastic.apm.agent.sdk.logging.LoggerFactory;
2828

2929
import javax.annotation.Nullable;
3030
import java.io.IOException;

apm-agent-core/src/main/java/co/elastic/apm/agent/bci/MatcherTimerLifecycleListener.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@
2020

2121
import co.elastic.apm.agent.bci.bytebuddy.MatcherTimer;
2222
import co.elastic.apm.agent.context.AbstractLifecycleListener;
23-
import org.slf4j.Logger;
24-
import org.slf4j.LoggerFactory;
23+
import co.elastic.apm.agent.sdk.logging.Logger;
24+
import co.elastic.apm.agent.sdk.logging.LoggerFactory;
2525

2626
import java.util.ArrayList;
2727
import java.util.Collections;

apm-agent-core/src/main/java/co/elastic/apm/agent/bci/bytebuddy/CustomElementMatchers.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@
2727
import net.bytebuddy.description.annotation.AnnotationSource;
2828
import net.bytebuddy.description.method.MethodDescription;
2929
import net.bytebuddy.matcher.ElementMatcher;
30-
import org.slf4j.Logger;
31-
import org.slf4j.LoggerFactory;
30+
import co.elastic.apm.agent.sdk.logging.Logger;
31+
import co.elastic.apm.agent.sdk.logging.LoggerFactory;
3232

3333
import javax.annotation.Nullable;
3434
import java.io.File;

apm-agent-core/src/main/java/co/elastic/apm/agent/bci/bytebuddy/ErrorLoggingListener.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@
2020

2121
import net.bytebuddy.agent.builder.AgentBuilder;
2222
import net.bytebuddy.utility.JavaModule;
23-
import org.slf4j.Logger;
24-
import org.slf4j.LoggerFactory;
23+
import co.elastic.apm.agent.sdk.logging.Logger;
24+
import co.elastic.apm.agent.sdk.logging.LoggerFactory;
2525

2626
public class ErrorLoggingListener extends AgentBuilder.Listener.Adapter {
2727

apm-agent-core/src/main/java/co/elastic/apm/agent/bci/classloading/IndyPluginClassLoader.java

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -59,18 +59,16 @@ private static ClassLoader getParent(@Nullable ClassLoader targetClassLoader, Cl
5959
agentClassLoader, startsWith("co.elastic.apm.agent").or(startsWith("net.bytebuddy")),
6060
targetClassLoader, ElementMatchers.<String>any());
6161
} else {
62-
// in prod, always search in the agent class loader first
63-
// this ensures that we're referencing the agent bundled classes in advices rather than the ones form the application
64-
// (for example for slf4j, Byte Buddy, or even dependencies that are bundled in external plugins etc.)
62+
// In prod, always search in the agent class loader first.
63+
// This ensures that we're referencing the agent bundled classes in advices rather than the ones form the application
64+
// (for example Byte Buddy, or even dependencies that are bundled in external plugins etc.)
6565
// However, we need to avoid looking up classes from the agent class loader that we want to instrument.
6666
// For example, we're instrumenting log4j2 to support ecs_log_reformatting which is also available within the agent class loader.
6767
// Within the context of an instrumentation plugin, referencing log4j2 should always reference the instrumented types, not the ones shipped with the agent.
6868
// The list of packages not to load should correspond with matching dependency exclusions from the apm-agent-core in apm-agent-plugins/pom.xml
69-
// As we're using slf4j as the logging facade, plugins don't need to refer to the agent-bundled log4j2.
70-
// This implies, we can't reference instrumented slf4j classes in plugins, though.
71-
// We ensure this by validating that advice method signatures don't contain slf4j classes.
69+
// As we're using a custom logging facade, plugins don't need to refer to the agent-bundled log4j2 or slf4j.
7270
return new DiscriminatingMultiParentClassLoader(
73-
agentClassLoader, not(startsWith("org.apache.logging.log4j")),
71+
agentClassLoader, not(startsWith("org.apache.logging.log4j").and(not(startsWith("org.slf4j")))),
7472
targetClassLoader, ElementMatchers.<String>any());
7573
}
7674
}

0 commit comments

Comments
 (0)