[plugin]support log4j2 AsyncLogger (#3715)
This commit is contained in:
parent
d9fcda1325
commit
a4078194d7
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF 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 org.apache.skywalking.apm.toolkit.activation.log.log4j.v2.x.async;
|
||||
|
||||
import net.bytebuddy.description.method.MethodDescription;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch;
|
||||
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName;
|
||||
|
||||
|
||||
/**
|
||||
* @author songxiaoyue
|
||||
*/
|
||||
public class RingBufferLogEventInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
|
||||
private static final String INTERCEPT_CLASS = "org.apache.skywalking.apm.toolkit.activation.log.log4j.v2.x.async.RingBufferLogEventMethodInterceptor";
|
||||
private static final String ENHANCE_CLASS = "org.apache.logging.log4j.core.async.RingBufferLogEvent";
|
||||
private static final String ENHANCE_METHOD = "setMessage";
|
||||
@Override
|
||||
public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
|
||||
return new ConstructorInterceptPoint[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
|
||||
return new InstanceMethodsInterceptPoint[]{
|
||||
new InstanceMethodsInterceptPoint() {
|
||||
@Override
|
||||
public ElementMatcher<MethodDescription> getMethodsMatcher() {
|
||||
return named(ENHANCE_METHOD);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMethodsInterceptor() {
|
||||
return INTERCEPT_CLASS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOverrideArgs() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ClassMatch enhanceClass() {
|
||||
return byName(ENHANCE_CLASS);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF 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 org.apache.skywalking.apm.toolkit.activation.log.log4j.v2.x.async;
|
||||
|
||||
import org.apache.skywalking.apm.agent.core.context.ContextManager;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* <p>Pass the global trace Id into the _sw field of RingBufferLogEvent instance after enhancing</p>
|
||||
*
|
||||
* @author songxiaoyue
|
||||
*/
|
||||
|
||||
public class RingBufferLogEventMethodInterceptor implements InstanceMethodsAroundInterceptor {
|
||||
|
||||
|
||||
@Override
|
||||
public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
|
||||
MethodInterceptResult result) throws Throwable {
|
||||
objInst.setSkyWalkingDynamicField(ContextManager.getGlobalTraceId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments,
|
||||
Class<?>[] argumentsTypes, Object ret) throws Throwable {
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,
|
||||
Class<?>[] argumentsTypes, Throwable t) {
|
||||
}
|
||||
}
|
||||
|
|
@ -17,3 +17,4 @@
|
|||
toolkit-log4j2=org.apache.skywalking.apm.toolkit.activation.log.log4j.v2.x.TraceIdConverterActivation
|
||||
toolkit-log4j2=org.apache.skywalking.apm.toolkit.activation.log.log4j.v2.x.async.AsyncLoggerConfigInstrumentation
|
||||
toolkit-log4j2=org.apache.skywalking.apm.toolkit.activation.log.log4j.v2.x.async.Log4jLogEventInstrumentation
|
||||
toolkit-log4j2=org.apache.skywalking.apm.toolkit.activation.log.log4j.v2.x.async.RingBufferLogEventInstrumentation
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
</Appenders>
|
||||
```
|
||||
|
||||
* Support log4j2 AsyncRoot (AsyncAppender not supported for now), No additional configuration is required. Refer to the demo of log4j2.xml below. For details: [Log4j2 Async Loggers](https://logging.apache.org/log4j/2.x/manual/async.html)
|
||||
* Support log4j2 AsyncRoot , No additional configuration is required. Refer to the demo of log4j2.xml below. For details: [Log4j2 Async Loggers](https://logging.apache.org/log4j/2.x/manual/async.html)
|
||||
```xml
|
||||
<Configuration>
|
||||
<Appenders>
|
||||
|
|
@ -31,5 +31,56 @@
|
|||
</Loggers>
|
||||
</Configuration>
|
||||
```
|
||||
* Support log4j2 AsyncAppender , No additional configuration is required. Refer to the demo of log4j2.xml below.
|
||||
|
||||
For details: [All Loggers Async](https://logging.apache.org/log4j/2.x/manual/async.html#AllAsync)
|
||||
|
||||
Log4j-2.9 and higher require disruptor-3.3.4.jar or higher on the classpath. Prior to Log4j-2.9, disruptor-3.0.0.jar or higher was required.
|
||||
This is simplest to configure and gives the best performance. To make all loggers asynchronous, add the disruptor jar to the classpath and
|
||||
set the system property `log4j2.contextSelector` to `org.apache.logging.log4j.core.async.AsyncLoggerContextSelector`.
|
||||
```xml
|
||||
<Configuration status="WARN">
|
||||
<Appenders>
|
||||
<!-- Async Loggers will auto-flush in batches, so switch off immediateFlush. -->
|
||||
<RandomAccessFile name="RandomAccessFile" fileName="async.log" immediateFlush="false" append="false">
|
||||
<PatternLayout>
|
||||
<Pattern>%d %p %c{1.} [%t] [%traceId] %m %ex%n</Pattern>
|
||||
</PatternLayout>
|
||||
</RandomAccessFile>
|
||||
</Appenders>
|
||||
<Loggers>
|
||||
<Root level="info" includeLocation="false">
|
||||
<AppenderRef ref="RandomAccessFile"/>
|
||||
</Root>
|
||||
</Loggers>
|
||||
</Configuration>
|
||||
```
|
||||
For details: [Mixed Sync & Async](https://logging.apache.org/log4j/2.x/manual/async.html#MixedSync-Async)
|
||||
|
||||
Log4j-2.9 and higher require disruptor-3.3.4.jar or higher on the classpath. Prior to Log4j-2.9, disruptor-3.0.0.jar or higher was required.
|
||||
There is no need to set system property `Log4jContextSelector` to any value.
|
||||
|
||||
```xml
|
||||
<Configuration status="WARN">
|
||||
<Appenders>
|
||||
<!-- Async Loggers will auto-flush in batches, so switch off immediateFlush. -->
|
||||
<RandomAccessFile name="RandomAccessFile" fileName="asyncWithLocation.log"
|
||||
immediateFlush="false" append="false">
|
||||
<PatternLayout>
|
||||
<Pattern>%d %p %class{1.} [%t] [%traceId] %location %m %ex%n</Pattern>
|
||||
</PatternLayout>
|
||||
</RandomAccessFile>
|
||||
</Appenders>
|
||||
<Loggers>
|
||||
<!-- pattern layout actually uses location, so we need to include it -->
|
||||
<AsyncLogger name="com.foo.Bar" level="trace" includeLocation="true">
|
||||
<AppenderRef ref="RandomAccessFile"/>
|
||||
</AsyncLogger>
|
||||
<Root level="info" includeLocation="true">
|
||||
<AppenderRef ref="RandomAccessFile"/>
|
||||
</Root>
|
||||
</Loggers>
|
||||
</Configuration>
|
||||
```
|
||||
|
||||
* When you use `-javaagent` to active the sky-walking tracer, log4j2 will output **traceId**, if it existed. If the tracer is inactive, the output will be `TID: N/A`.
|
||||
|
|
|
|||
Loading…
Reference in New Issue