Logback support AsyncAppender print tid (#2750)
* AsyncAppender * improve performance * fix mdc issue * fix mdc * add Async demo
This commit is contained in:
parent
0225711e26
commit
1e25678b9e
|
|
@ -40,10 +40,10 @@ public class LogbackMDCPatternConverter extends MDCConverter {
|
|||
}
|
||||
@Override
|
||||
public String convert(ILoggingEvent iLoggingEvent) {
|
||||
return convert4TID ? convertTID() : super.convert(iLoggingEvent);
|
||||
return convert4TID ? convertTID(iLoggingEvent) : super.convert(iLoggingEvent);
|
||||
}
|
||||
|
||||
public String convertTID() {
|
||||
public String convertTID(ILoggingEvent iLoggingEvent) {
|
||||
return "TID: N/A";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ import org.apache.skywalking.apm.agent.core.plugin.interceptor.StaticMethodsInte
|
|||
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.bytebuddy.ArgumentTypeNameMatch.takesArgumentWithType;
|
||||
import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName;
|
||||
|
||||
/**
|
||||
|
|
@ -70,7 +71,7 @@ public class LogbackPatternConverterActivation extends ClassInstanceMethodsEnhan
|
|||
new InstanceMethodsInterceptPoint() {
|
||||
@Override
|
||||
public ElementMatcher<MethodDescription> getMethodsMatcher() {
|
||||
return named(ENHANCE_METHOD);
|
||||
return named(ENHANCE_METHOD).and(takesArgumentWithType(0,"ch.qos.logback.classic.spi.ILoggingEvent"));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -19,12 +19,13 @@
|
|||
|
||||
package org.apache.skywalking.apm.toolkit.activation.log.logback.v1.x;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
|
||||
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;
|
||||
|
||||
/**
|
||||
* Created by wusheng on 2016/12/7.
|
||||
*/
|
||||
|
|
@ -37,6 +38,14 @@ public class PrintTraceIdInterceptor implements InstanceMethodsAroundInterceptor
|
|||
|
||||
@Override public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments,
|
||||
Class<?>[] argumentsTypes, Object ret) throws Throwable {
|
||||
if (!ContextManager.isActive()) {
|
||||
if (allArguments[0] instanceof EnhancedInstance) {
|
||||
String tid = (String) ((EnhancedInstance) allArguments[0]).getSkyWalkingDynamicField();
|
||||
if (tid != null) {
|
||||
return "TID:" + tid;
|
||||
}
|
||||
}
|
||||
}
|
||||
return "TID:" + ContextManager.getGlobalTraceId();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* 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.logback.v1.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 zhaoyuguang
|
||||
*/
|
||||
|
||||
public class AsyncAppenderBaseInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
|
||||
@Override
|
||||
protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
|
||||
return new ConstructorInterceptPoint[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
|
||||
return new InstanceMethodsInterceptPoint[]{
|
||||
new InstanceMethodsInterceptPoint() {
|
||||
@Override
|
||||
public ElementMatcher<MethodDescription> getMethodsMatcher() {
|
||||
return named("put");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMethodsInterceptor() {
|
||||
return "org.apache.skywalking.apm.toolkit.activation.log.logback.v1.x.async.AsyncAppenderBaseMethodInterceptor";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOverrideArgs() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ClassMatch enhanceClass() {
|
||||
return byName("ch.qos.logback.core.AsyncAppenderBase");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* 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.logback.v1.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;
|
||||
|
||||
/**
|
||||
* @author zhaoyuguang
|
||||
*/
|
||||
|
||||
public class AsyncAppenderBaseMethodInterceptor implements InstanceMethodsAroundInterceptor {
|
||||
|
||||
|
||||
@Override
|
||||
public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
|
||||
MethodInterceptResult result) throws Throwable {
|
||||
if (allArguments[0] instanceof EnhancedInstance) {
|
||||
EnhancedInstance instances = (EnhancedInstance) allArguments[0];
|
||||
instances.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) {
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* 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.logback.v1.x.async;
|
||||
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceConstructorInterceptor;
|
||||
|
||||
/**
|
||||
* LoggingEvent implements ILoggingEvent,
|
||||
* which is a message in the blockingQueue of the AsyncAppenderBase.class.
|
||||
* The LoggingEvent is enhanced to carry the tid in the synchronization thread using `dynamicField`.
|
||||
*
|
||||
* @author zhaoyuguang
|
||||
*/
|
||||
|
||||
public class LoggingEventConstructorInterceptor implements InstanceConstructorInterceptor {
|
||||
|
||||
@Override
|
||||
public void onConstruct(EnhancedInstance objInst, Object[] allArguments) {
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* 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.logback.v1.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.any;
|
||||
import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName;
|
||||
|
||||
/**
|
||||
* @author zhaoyuguang
|
||||
*/
|
||||
|
||||
public class LoggingEventInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
|
||||
@Override
|
||||
protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
|
||||
return new ConstructorInterceptPoint[]{
|
||||
new ConstructorInterceptPoint() {
|
||||
@Override
|
||||
public ElementMatcher<MethodDescription> getConstructorMatcher() {
|
||||
return any();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getConstructorInterceptor() {
|
||||
return "org.apache.skywalking.apm.toolkit.activation.log.logback.v1.x.async.LoggingEventConstructorInterceptor";
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
|
||||
return new InstanceMethodsInterceptPoint[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ClassMatch enhanceClass() {
|
||||
return byName("ch.qos.logback.classic.spi.LoggingEvent");
|
||||
}
|
||||
}
|
||||
|
|
@ -27,6 +27,7 @@ import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterc
|
|||
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.bytebuddy.ArgumentTypeNameMatch.takesArgumentWithType;
|
||||
|
||||
/**
|
||||
* Support MDC https://logback.qos.ch/manual/mdc.html
|
||||
|
|
@ -49,7 +50,7 @@ public class MDCConverterActivation extends ClassInstanceMethodsEnhancePluginDef
|
|||
new InstanceMethodsInterceptPoint() {
|
||||
@Override
|
||||
public ElementMatcher<MethodDescription> getMethodsMatcher() {
|
||||
return named(ENHANCE_METHOD);
|
||||
return named(ENHANCE_METHOD).and(takesArgumentWithType(0,"ch.qos.logback.classic.spi.ILoggingEvent"));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -18,8 +18,8 @@
|
|||
|
||||
package org.apache.skywalking.apm.toolkit.activation.log.logback.v1.x.mdc;
|
||||
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
|
||||
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;
|
||||
|
||||
|
|
@ -36,6 +36,14 @@ public class PrintMDCTraceIdInterceptor implements InstanceMethodsAroundIntercep
|
|||
|
||||
@Override public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments,
|
||||
Class<?>[] argumentsTypes, Object ret) throws Throwable {
|
||||
if (!ContextManager.isActive()) {
|
||||
if (allArguments[0] instanceof EnhancedInstance) {
|
||||
String tid = (String) ((EnhancedInstance) allArguments[0]).getSkyWalkingDynamicField();
|
||||
if (tid != null) {
|
||||
return "TID:" + tid;
|
||||
}
|
||||
}
|
||||
}
|
||||
return "TID:" + ContextManager.getGlobalTraceId();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,3 +16,5 @@
|
|||
|
||||
toolkit-logback=org.apache.skywalking.apm.toolkit.activation.log.logback.v1.x.LogbackPatternConverterActivation
|
||||
toolkit-logback=org.apache.skywalking.apm.toolkit.activation.log.logback.v1.x.mdc.MDCConverterActivation
|
||||
toolkit-logback=org.apache.skywalking.apm.toolkit.activation.log.logback.v1.x.async.AsyncAppenderBaseInstrumentation
|
||||
toolkit-logback=org.apache.skywalking.apm.toolkit.activation.log.logback.v1.x.async.LoggingEventInstrumentation
|
||||
|
|
|
|||
|
|
@ -18,4 +18,40 @@
|
|||
</appender>
|
||||
```
|
||||
|
||||
* with the MDC, set `%X{tid}` in `Pattern` section of logback.xml
|
||||
```xml
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
|
||||
<layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.mdc.TraceIdMDCPatternLogbackLayout">
|
||||
<Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%X{tid}] [%thread] %-5level %logger{36} -%msg%n</Pattern>
|
||||
</layout>
|
||||
</encoder>
|
||||
</appender>
|
||||
```
|
||||
|
||||
|
||||
* Support logback AsyncAppender(MDC also support), No additional configuration is required. Refer to the demo of logback.xml below. For details: [Logback AsyncAppender](https://logback.qos.ch/manual/appenders.html#AsyncAppender)
|
||||
```xml
|
||||
<configuration scan="true" scanPeriod=" 5 seconds">
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
|
||||
<layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.mdc.TraceIdMDCPatternLogbackLayout">
|
||||
<Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%X{tid}] [%thread] %-5level %logger{36} -%msg%n</Pattern>
|
||||
</layout>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
|
||||
<discardingThreshold>0</discardingThreshold>
|
||||
<queueSize>1024</queueSize>
|
||||
<neverBlock>true</neverBlock>
|
||||
<appender-ref ref="STDOUT"/>
|
||||
</appender>
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="ASYNC"/>
|
||||
</root>
|
||||
</configuration>
|
||||
```
|
||||
|
||||
* When you use `-javaagent` to active the sky-walking tracer, logback will output **traceId**, if it existed. If the tracer is inactive, the output will be `TID: N/A`.
|
||||
|
|
|
|||
Loading…
Reference in New Issue