|
14 | 14 | import io.opentelemetry.instrumentation.log4j.appender.v2_17.internal.ContextDataAccessor; |
15 | 15 | import io.opentelemetry.instrumentation.log4j.appender.v2_17.internal.LogEventMapper; |
16 | 16 | import io.opentelemetry.javaagent.bootstrap.internal.AgentInstrumentationConfig; |
| 17 | +import java.lang.invoke.MethodHandle; |
| 18 | +import java.lang.invoke.MethodHandles; |
| 19 | +import java.lang.invoke.MethodType; |
17 | 20 | import java.time.Instant; |
18 | 21 | import java.util.List; |
19 | 22 | import java.util.Map; |
|
24 | 27 | import org.apache.logging.log4j.Marker; |
25 | 28 | import org.apache.logging.log4j.ThreadContext; |
26 | 29 | import org.apache.logging.log4j.message.Message; |
27 | | -import org.apache.logging.log4j.util.StackLocator; |
28 | 30 |
|
29 | 31 | public final class Log4jHelper { |
30 | 32 |
|
31 | 33 | private static final LogEventMapper<Map<String, String>> mapper; |
32 | | - |
33 | 34 | private static final boolean captureExperimentalAttributes; |
| 35 | + private static final MethodHandle stackTraceMethodHandle = getStackTraceMethodHandle(); |
34 | 36 |
|
35 | 37 | static { |
36 | 38 | InstrumentationConfig config = AgentInstrumentationConfig.get(); |
@@ -98,12 +100,53 @@ public static void capture( |
98 | 100 | threadName, |
99 | 101 | threadId, |
100 | 102 | () -> |
101 | | - location != null ? location : StackLocator.getInstance().calcLocation(loggerClassName), |
| 103 | + location != null ? location : getLocation(loggerClassName), |
102 | 104 | Context.current()); |
103 | 105 | builder.setTimestamp(Instant.now()); |
104 | 106 | builder.emit(); |
105 | 107 | } |
106 | 108 |
|
| 109 | + private static StackTraceElement getLocation(String loggerClassName) { |
| 110 | + if (stackTraceMethodHandle == null) { |
| 111 | + return null; |
| 112 | + } |
| 113 | + |
| 114 | + try { |
| 115 | + return (StackTraceElement) stackTraceMethodHandle.invoke(loggerClassName); |
| 116 | + } catch (Throwable exception) { |
| 117 | + return null; |
| 118 | + } |
| 119 | + } |
| 120 | + |
| 121 | + private static MethodHandle getStackTraceMethodHandle() { |
| 122 | + // since 2.9.0 |
| 123 | + Class<?> stackTraceClass = null; |
| 124 | + try { |
| 125 | + stackTraceClass = Class.forName("org.apache.logging.log4j.util.StackLocatorUtil"); |
| 126 | + } catch (ClassNotFoundException exception) { |
| 127 | + // ignore |
| 128 | + } |
| 129 | + if (stackTraceClass == null) { |
| 130 | + try { |
| 131 | + stackTraceClass = Class.forName("org.apache.logging.log4j.core.impl.Log4jLogEvent"); |
| 132 | + } catch (ClassNotFoundException exception) { |
| 133 | + // ignore |
| 134 | + } |
| 135 | + } |
| 136 | + if (stackTraceClass == null) { |
| 137 | + return null; |
| 138 | + } |
| 139 | + try { |
| 140 | + return MethodHandles.lookup() |
| 141 | + .findStatic( |
| 142 | + stackTraceClass, |
| 143 | + "calcLocation", |
| 144 | + MethodType.methodType(StackTraceElement.class, String.class)); |
| 145 | + } catch (Exception exception) { |
| 146 | + return null; |
| 147 | + } |
| 148 | + } |
| 149 | + |
107 | 150 | private enum ContextDataAccessorImpl implements ContextDataAccessor<Map<String, String>> { |
108 | 151 | INSTANCE; |
109 | 152 |
|
|
0 commit comments