Add Light4j plugin (#3323)
* Add Light4J 1.6.x plug-in * Add unit test for Light4J plug-in * Add missing id to server-starter * Remove mentions of version 1.6.x Some local testing showed that the plugin successfully generated traces for a light4j project built with light-codegen v2.x. Therefore, there is no need for a separate plugin for v2.x and no distinction needs to be made with light4j v1.6.x. * Update supported light4j versions * Use ContextSnapshot to maintain trace In a typical Light4j project, the ExceptionHandler#handleRequest is the asynchronous execution point. The flow is ExceptionHandler#handleRequest -> HttpServerExchange#dispatch -> ... -> ExceptionHandler#handleRequest. This means that handleRequest is being intercepted twice and each time a LocalSpan is created. Without handling thread propagation, the trace segment gets split up. By saving a ContextSnapshot into the enhanced object (ExceptionHandler), we can determine if it is necessary to continue the segment. * Update logic for span creation in trace By default, the Light4J plugin now overrides the Undertow plugin's entry span with its own. This new entry span is created just before execution of the ExceptionHandler#handleRequest in the I/O thread. The entry span is generated here because it is considered the starting point of the Light4J handler chain. There is now also the option to enable detailed span creation when tracing requests through Light4J. These local spans mark which middleware and business handlers are involved with handling the HTTP request to a Light4J service. * Update skywalking version * Update light4j version * Fix LightInstrumentation javadoc * Remove import violating checkstyle This import was added from the link reference in the javadoc. The javadoc has now been changed to just reference the method name. * Move light4j agent config property * Sync UI
This commit is contained in:
parent
ad45a94ab7
commit
72f07b812a
|
|
@ -134,4 +134,6 @@ public class ComponentsDefine {
|
|||
|
||||
public static final OfficialComponent CASSANDRA_JAVA_DRIVER = new OfficialComponent(69, "cassandra-java-driver");
|
||||
|
||||
public static final OfficialComponent LIGHT_4J = new OfficialComponent(71, "Light4J");
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -287,5 +287,13 @@ public class Config {
|
|||
public static Map<String, String> RULE = new HashMap<String, String>();
|
||||
}
|
||||
}
|
||||
|
||||
public static class Light4J {
|
||||
/**
|
||||
* If true, trace all middleware/business handlers that are part of the Light4J handler chain for a request,
|
||||
* generating a local span for each.
|
||||
*/
|
||||
public static boolean TRACE_HANDLER_CHAIN = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,51 @@
|
|||
<!--
|
||||
~ 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.
|
||||
~
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>light4j-plugins</artifactId>
|
||||
<groupId>org.apache.skywalking</groupId>
|
||||
<version>6.5.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>apm-light4j-plugin</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>light4j-plugin</name>
|
||||
<url>http://maven.apache.org</url>
|
||||
|
||||
<properties>
|
||||
<version.light4j>1.6.9</version.light4j>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.networknt</groupId>
|
||||
<artifactId>handler</artifactId>
|
||||
<version>${version.light4j}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.networknt</groupId>
|
||||
<artifactId>exception</artifactId>
|
||||
<version>${version.light4j}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
* 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.plugin.light4j;
|
||||
|
||||
import com.networknt.exception.ExceptionHandler;
|
||||
import com.networknt.handler.MiddlewareHandler;
|
||||
import com.networknt.handler.OrchestrationHandler;
|
||||
import io.undertow.server.HttpServerExchange;
|
||||
import io.undertow.util.HeaderMap;
|
||||
import org.apache.skywalking.apm.agent.core.conf.Config;
|
||||
import org.apache.skywalking.apm.agent.core.context.CarrierItem;
|
||||
import org.apache.skywalking.apm.agent.core.context.ContextCarrier;
|
||||
import org.apache.skywalking.apm.agent.core.context.ContextManager;
|
||||
import org.apache.skywalking.apm.agent.core.context.ContextSnapshot;
|
||||
import org.apache.skywalking.apm.agent.core.context.tag.Tags;
|
||||
import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
|
||||
import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer;
|
||||
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 org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* {@link HandleRequestInterceptor} creates an entry span before the execution of
|
||||
* {@link com.networknt.exception.ExceptionHandler#handleRequest(HttpServerExchange)} in the I/O thread.
|
||||
*
|
||||
* If the {@link Config.Plugin.Light4J#TRACE_HANDLER_CHAIN} flag is set, additionally a local span is produced for each
|
||||
* {@link com.networknt.handler.MiddlewareHandler} and business handler before their respective
|
||||
* {@link com.networknt.handler.LightHttpHandler#handleRequest(HttpServerExchange)} method executes.
|
||||
* Since {@link com.networknt.handler.LightHttpHandler} is implemented by various middleware and business handlers and
|
||||
* the Light4J framework delegates to these in succession, a chain of
|
||||
* {@link org.apache.skywalking.apm.agent.core.context.trace.LocalSpan}s will be produced.
|
||||
*
|
||||
* @author tsuilouis
|
||||
*/
|
||||
public class HandleRequestInterceptor implements InstanceMethodsAroundInterceptor {
|
||||
|
||||
@Override
|
||||
public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
|
||||
MethodInterceptResult result) {
|
||||
if (isExceptionHandler(objInst)) {
|
||||
HttpServerExchange exchange = (HttpServerExchange) allArguments[0];
|
||||
|
||||
if (exchange.isInIoThread()) {
|
||||
|
||||
String operationName = exchange.getRequestPath() + "@" + exchange.getRequestMethod();
|
||||
final HeaderMap headers = exchange.getRequestHeaders();
|
||||
final ContextCarrier contextCarrier = new ContextCarrier();
|
||||
|
||||
CarrierItem next = contextCarrier.items();
|
||||
while (next.hasNext()) {
|
||||
next = next.next();
|
||||
next.setHeadValue(headers.getFirst(next.getHeadKey()));
|
||||
}
|
||||
|
||||
AbstractSpan span = ContextManager.createEntrySpan(operationName, contextCarrier);
|
||||
Tags.URL.set(span, exchange.getRequestURL());
|
||||
Tags.HTTP.METHOD.set(span, exchange.getRequestMethod().toString());
|
||||
span.setComponent(ComponentsDefine.LIGHT_4J);
|
||||
SpanLayer.asHttp(span);
|
||||
|
||||
if (exchange.getStatusCode() >= 400) {
|
||||
span.errorOccurred();
|
||||
Tags.STATUS_CODE.set(span, String.valueOf(exchange.getStatusCode()));
|
||||
}
|
||||
|
||||
ContextManager.stopSpan(span);
|
||||
|
||||
objInst.setSkyWalkingDynamicField(ContextManager.capture());
|
||||
} else if (Config.Plugin.Light4J.TRACE_HANDLER_CHAIN) {
|
||||
String operationName = objInst.getClass().getName() + "." + method.getName();
|
||||
|
||||
ContextSnapshot snapshot = (ContextSnapshot) objInst.getSkyWalkingDynamicField();
|
||||
ContextManager.createLocalSpan(operationName)
|
||||
.setComponent(ComponentsDefine.LIGHT_4J);
|
||||
|
||||
ContextManager.continued(snapshot);
|
||||
}
|
||||
} else if (Config.Plugin.Light4J.TRACE_HANDLER_CHAIN &&
|
||||
(isMiddlewareHandler(objInst) || isBusinessHandler(objInst))) {
|
||||
String operationName = objInst.getClass().getName() + "." + method.getName();
|
||||
|
||||
ContextManager.createLocalSpan(operationName)
|
||||
.setComponent(ComponentsDefine.LIGHT_4J);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
|
||||
Object ret) {
|
||||
if (isExceptionHandler(objInst)) {
|
||||
HttpServerExchange exchange = (HttpServerExchange) allArguments[0];
|
||||
|
||||
if (Config.Plugin.Light4J.TRACE_HANDLER_CHAIN && !exchange.isInIoThread()) {
|
||||
ContextManager.stopSpan();
|
||||
}
|
||||
} else if (Config.Plugin.Light4J.TRACE_HANDLER_CHAIN &&
|
||||
(isMiddlewareHandler(objInst) || isBusinessHandler(objInst))) {
|
||||
ContextManager.stopSpan();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,
|
||||
Class<?>[] argumentsTypes,
|
||||
Throwable t) {
|
||||
ContextManager.activeSpan().errorOccurred().log(t);
|
||||
}
|
||||
|
||||
private boolean isBusinessHandler(EnhancedInstance objInst) {
|
||||
return !objInst.getClass().getInterfaces()[0].equals(MiddlewareHandler.class) && !objInst.getClass().equals(OrchestrationHandler.class);
|
||||
}
|
||||
|
||||
private boolean isMiddlewareHandler(EnhancedInstance objInst) {
|
||||
return objInst.getClass().getInterfaces()[0].equals(MiddlewareHandler.class);
|
||||
}
|
||||
|
||||
private boolean isExceptionHandler(EnhancedInstance objInst) {
|
||||
return objInst.getClass().equals(ExceptionHandler.class);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* 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.plugin.light4j.define;
|
||||
|
||||
import net.bytebuddy.description.method.MethodDescription;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
import net.bytebuddy.matcher.ElementMatchers;
|
||||
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 org.apache.skywalking.apm.agent.core.plugin.match.HierarchyMatch;
|
||||
|
||||
/**
|
||||
* This instrumentation is applied to the handleRequest method of {@link com.networknt.handler.LightHttpHandler}
|
||||
* using {@link org.apache.skywalking.apm.plugin.light4j.HandleRequestInterceptor}.
|
||||
*
|
||||
* @author tsuilouis
|
||||
*/
|
||||
public class LightInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
|
||||
|
||||
private static final String ENHANCE_CLASS = "com.networknt.handler.LightHttpHandler";
|
||||
private static final String ENHANCE_METHOD = "handleRequest";
|
||||
private static final String INTERCEPTOR_CLASS = "org.apache.skywalking.apm.plugin.light4j.HandleRequestInterceptor";
|
||||
|
||||
@Override
|
||||
protected ClassMatch enhanceClass() {
|
||||
return HierarchyMatch.byHierarchyMatch(new String[] {ENHANCE_CLASS});
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
|
||||
return new InstanceMethodsInterceptPoint[] {
|
||||
new InstanceMethodsInterceptPoint() {
|
||||
@Override
|
||||
public ElementMatcher<MethodDescription> getMethodsMatcher() {
|
||||
return ElementMatchers.named(ENHANCE_METHOD);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMethodsInterceptor() {
|
||||
return INTERCEPTOR_CLASS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOverrideArgs() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
# 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.
|
||||
|
||||
light4j=org.apache.skywalking.apm.plugin.light4j.define.LightInstrumentation
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* 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.plugin.light4j;
|
||||
|
||||
import com.networknt.exception.ExceptionHandler;
|
||||
import io.undertow.server.HttpServerExchange;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
|
||||
import org.apache.skywalking.apm.agent.test.tools.*;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.powermock.modules.junit4.PowerMockRunner;
|
||||
import org.powermock.modules.junit4.PowerMockRunnerDelegate;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
/**
|
||||
* @author tsuilouis
|
||||
*/
|
||||
@RunWith(PowerMockRunner.class)
|
||||
@PowerMockRunnerDelegate(TracingSegmentRunner.class)
|
||||
public class HandleRequestInterceptorTest {
|
||||
|
||||
private HandleRequestInterceptor handleRequestInterceptor;
|
||||
|
||||
@SegmentStoragePoint
|
||||
private SegmentStorage segmentStorage;
|
||||
|
||||
@Rule
|
||||
public AgentServiceRule serviceRule = new AgentServiceRule();
|
||||
|
||||
@Mock
|
||||
private MethodInterceptResult methodInterceptResult;
|
||||
|
||||
private EnhancedInstance enhancedInstance;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
handleRequestInterceptor = new HandleRequestInterceptor();
|
||||
|
||||
enhancedInstance = new EnhancedInstance() {
|
||||
@Override
|
||||
public Object getSkyWalkingDynamicField() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSkyWalkingDynamicField(Object value) {
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHandleRequest() throws Throwable {
|
||||
Method method = ExceptionHandler.class.getMethod("handleRequest", HttpServerExchange.class);
|
||||
|
||||
handleRequestInterceptor.beforeMethod(enhancedInstance, method, null, null, methodInterceptResult);
|
||||
handleRequestInterceptor.afterMethod(enhancedInstance, null, null, null, null);
|
||||
|
||||
assertThat(segmentStorage.getTraceSegments().size(), is(0));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ 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.
|
||||
~
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.apache.skywalking</groupId>
|
||||
<artifactId>apm-sdk-plugin</artifactId>
|
||||
<version>6.5.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>light4j-plugins</artifactId>
|
||||
<modules>
|
||||
<module>light4j-plugin</module>
|
||||
</modules>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<name>light4j-plugins</name>
|
||||
<url>http://maven.apache.org</url>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<sdk.plugin.related.dir>/..</sdk.plugin.related.dir>
|
||||
</properties>
|
||||
</project>
|
||||
|
|
@ -75,6 +75,7 @@
|
|||
<module>resteasy-plugin</module>
|
||||
<module>solrj-7.x-plugin</module>
|
||||
<module>cassandra-java-driver-3.x-plugin</module>
|
||||
<module>light4j-plugins</module>
|
||||
</modules>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
|
|
|
|||
|
|
@ -102,6 +102,7 @@ property key | Description | Default |
|
|||
`plugin.mysql.sql_parameters_max_length`|If set to positive number, the `db.sql.parameters` would be truncated to this length, otherwise it would be completely saved, which may cause performance problem.|`512`|
|
||||
`plugin.solrj.trace_statement`|If true, trace all the query parameters(include deleteByIds and deleteByQuery) in Solr query request, default is false.|`false`|
|
||||
`plugin.solrj.trace_ops_params`|If true, trace all the operation parameters in Solr request, default is false.|`false`|
|
||||
`plugin.light4j.trace_handler_chain`|If true, trace all middleware/business handlers that are part of the Light4J handler chain for a request.|false|
|
||||
`plugin.opgroup.*`|Support operation name customize group rules in different plugins. Read [Group rule supported plugins](op_name_group_rule.md)|Not set|
|
||||
|
||||
## Optional Plugins
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
* [Undertow](http://undertow.io/) 2.0.0.Final -> 2.0.13.Final
|
||||
* [RESTEasy](https://resteasy.github.io/) 3.1.0.Final -> 3.7.0.Final
|
||||
* [Play Framework](https://www.playframework.com/) 2.6.x -> 2.7.x (Optional²)
|
||||
* [Light4J Microservices Framework](https://doc.networknt.com/) 1.6.x -> 2.x
|
||||
* HTTP Client
|
||||
* [Feign](https://github.com/OpenFeign/feign) 9.x
|
||||
* [Netflix Spring Cloud Feign](https://github.com/spring-cloud/spring-cloud-netflix/tree/master/spring-cloud-starter-feign) 1.1.x, 1.2.x, 1.3.x
|
||||
|
|
|
|||
|
|
@ -221,6 +221,9 @@ cassandra-java-driver:
|
|||
Cassandra:
|
||||
id: 70
|
||||
languages: Java
|
||||
Light4J:
|
||||
id: 71
|
||||
languages: Java
|
||||
|
||||
# .NET/.NET Core components
|
||||
# [3000, 4000) for C#/.NET only
|
||||
|
|
|
|||
|
|
@ -239,6 +239,9 @@ cassandra-java-driver:
|
|||
Cassandra:
|
||||
id: 70
|
||||
languages: Java
|
||||
Light4J:
|
||||
id: 71
|
||||
languages: Java
|
||||
|
||||
|
||||
# .NET/.NET Core components
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit 05556dc723d1baed8755bab1a7ec5d029debdb6f
|
||||
Subproject commit 206a514ae71267e5b29ac58dba2dbfeaf71a7b2d
|
||||
Loading…
Reference in New Issue