提交 1fd5873a 编写于 作者: P pengys5

Merge remote-tracking branch 'origin/feature/3.0' into feature/collector

......@@ -91,12 +91,14 @@
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${compiler.version}</source>
<target>${compiler.version}</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
<version>3.6.1</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
......
package com.a.eye.skywalking.trace;
import com.a.eye.skywalking.trace.TraceId.PropagatedTraceId;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.TypeAdapter;
import com.google.gson.annotations.JsonAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import java.io.IOException;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
/**
* The <code>SegmentsMessage</code> is a set of {@link TraceSegment},
* this set provides a container, when several {@link TraceSegment}s are going to uplink to server.
*
*
* @author wusheng
*/
@JsonAdapter(SegmentsMessage.Serializer.class)
public class SegmentsMessage {
private List<TraceSegment> segments;
public SegmentsMessage(){
segments = new LinkedList<TraceSegment>();
}
public void append(TraceSegment segment){
this.segments.add(segment);
}
public List<TraceSegment> getSegments() {
return Collections.unmodifiableList(segments);
}
public static class Serializer extends TypeAdapter<SegmentsMessage>{
@Override
public void write(JsonWriter out, SegmentsMessage value) throws IOException {
Gson gson = new GsonBuilder()
.excludeFieldsWithoutExposeAnnotation()
.create();
out.beginArray();
try {
for (TraceSegment segment : value.segments) {
out.jsonValue(gson.toJson(segment));
}
}finally {
out.endArray();
}
}
@Override
public SegmentsMessage read(JsonReader in) throws IOException {
SegmentsMessage message = new SegmentsMessage();
in.beginArray();
Gson gson = new GsonBuilder()
.excludeFieldsWithoutExposeAnnotation()
.create();
try {
while (in.hasNext()) {
TraceSegment traceSegment = gson.fromJson(in, TraceSegment.class);
message.append(traceSegment);
}
} finally {
in.endArray();
}
return message;
}
}
}
package com.a.eye.skywalking.trace.TraceId;
import com.google.gson.TypeAdapter;
import com.google.gson.annotations.JsonAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import java.io.IOException;
/**
* The <code>DistributedTraceId</code> presents a distributed call chain.
*
......@@ -19,7 +13,6 @@ import java.io.IOException;
*
* @author wusheng
*/
@JsonAdapter(DistributedTraceId.Serializer.class)
public abstract class DistributedTraceId {
private String id;
......@@ -47,22 +40,4 @@ public abstract class DistributedTraceId {
public int hashCode() {
return id != null ? id.hashCode() : 0;
}
public static class Serializer extends TypeAdapter<DistributedTraceId> {
@Override
public void write(JsonWriter out, DistributedTraceId value) throws IOException {
out.beginArray();
out.value(value.get());
out.endArray();
}
@Override
public DistributedTraceId read(JsonReader in) throws IOException {
in.beginArray();
PropagatedTraceId traceId = new PropagatedTraceId(in.nextString());
in.endArray();
return traceId;
}
}
}
package com.a.eye.skywalking.trace.TraceId;
import com.google.gson.TypeAdapter;
import com.google.gson.annotations.JsonAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import java.io.IOException;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
/**
* @author wusheng
*/
@JsonAdapter(DistributedTraceIds.Serializer.class)
public class DistributedTraceIds {
private LinkedList<DistributedTraceId> relatedGlobalTraces;
public DistributedTraceIds() {
relatedGlobalTraces = new LinkedList<DistributedTraceId>();
}
public List<DistributedTraceId> getRelatedGlobalTraces() {
return Collections.unmodifiableList(relatedGlobalTraces);
}
public void append(DistributedTraceId distributedTraceId) {
if (relatedGlobalTraces.size() > 0 && relatedGlobalTraces.getFirst() instanceof NewDistributedTraceId) {
relatedGlobalTraces.removeFirst();
}
if (!relatedGlobalTraces.contains(distributedTraceId)) {
relatedGlobalTraces.add(distributedTraceId);
}
}
public static class Serializer extends TypeAdapter<DistributedTraceIds> {
@Override
public void write(JsonWriter out, DistributedTraceIds value) throws IOException {
List<DistributedTraceId> globalTraces = value.getRelatedGlobalTraces();
if (globalTraces.size() > 0) {
out.beginArray();
for (DistributedTraceId trace : globalTraces) {
out.value(trace.get());
}
out.endArray();
}
}
@Override
public DistributedTraceIds read(JsonReader in) throws IOException {
DistributedTraceIds distributedTraceIds = new DistributedTraceIds();
in.beginArray();
try {
while (in.hasNext()) {
PropagatedTraceId traceId = new PropagatedTraceId(in.nextString());
distributedTraceIds.append(traceId);
}
} finally {
in.endArray();
}
return distributedTraceIds;
}
}
}
package com.a.eye.skywalking.trace;
import com.a.eye.skywalking.trace.TraceId.DistributedTraceId;
import com.a.eye.skywalking.trace.TraceId.DistributedTraceIds;
import com.a.eye.skywalking.trace.TraceId.NewDistributedTraceId;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
......@@ -86,7 +87,7 @@ public class TraceSegment {
*/
@Expose
@SerializedName(value="gt")
private LinkedList<DistributedTraceId> relatedGlobalTraces;
private DistributedTraceIds relatedGlobalTraces;
/**
* Create a trace segment, by given segmentId.
......@@ -94,18 +95,18 @@ public class TraceSegment {
*/
public TraceSegment(String applicationCode) {
this();
this.traceSegmentId = GlobalIdGenerator.generate(ID_TYPE);
this.applicationCode = applicationCode;
this.startTime = System.currentTimeMillis();
}
/**
* Create a default/empty trace segment
*/
public TraceSegment() {
this.startTime = System.currentTimeMillis();
this.traceSegmentId = GlobalIdGenerator.generate(ID_TYPE);
this.spans = new LinkedList<Span>();
this.relatedGlobalTraces = new LinkedList<DistributedTraceId>();
this.relatedGlobalTraces.add(new NewDistributedTraceId());
this.relatedGlobalTraces = new DistributedTraceIds();
this.relatedGlobalTraces.append(new NewDistributedTraceId());
}
/**
......@@ -126,13 +127,8 @@ public class TraceSegment {
if (distributedTraceIds == null || distributedTraceIds.size() == 0) {
return;
}
if (relatedGlobalTraces.getFirst() instanceof NewDistributedTraceId) {
relatedGlobalTraces.removeFirst();
}
for (DistributedTraceId distributedTraceId : distributedTraceIds) {
if(!relatedGlobalTraces.contains(distributedTraceId)){
relatedGlobalTraces.add(distributedTraceId);
}
relatedGlobalTraces.append(distributedTraceId);
}
}
......@@ -176,7 +172,7 @@ public class TraceSegment {
}
public List<DistributedTraceId> getRelatedGlobalTraces() {
return Collections.unmodifiableList(relatedGlobalTraces);
return relatedGlobalTraces.getRelatedGlobalTraces();
}
public List<Span> getSpans() {
......@@ -187,7 +183,8 @@ public class TraceSegment {
return applicationCode;
}
@Override public String toString() {
@Override
public String toString() {
return "TraceSegment{" +
"traceSegmentId='" + traceSegmentId + '\'' +
", startTime=" + startTime +
......
......@@ -106,11 +106,15 @@ public class TraceSegmentTestCase {
.excludeFieldsWithoutExposeAnnotation()
.create();
String json = gson.toJson(segment);
SegmentsMessage message = new SegmentsMessage();
message.append(segment);
String json = gson.toJson(message);
System.out.println(json);
message = gson.fromJson(json, SegmentsMessage.class);
TraceSegment newSegment = gson.fromJson(json, TraceSegment.class);
TraceSegment newSegment = message.getSegments().get(0);
Assert.assertEquals(segment.getSpans().size(), newSegment.getSpans().size());
Assert.assertEquals(segment.getRefs().get(0).getTraceSegmentId(), newSegment.getRefs().get(0).getTraceSegmentId());
......
......@@ -45,41 +45,13 @@
<pattern>${shade.com.lmax.disruptor.source}</pattern>
<shadedPattern>${shade.com.lmax.disruptor.target}</shadedPattern>
</relocation>
<relocation>
<pattern>${shade.akka.source}</pattern>
<shadedPattern>${shade.akka.target}</shadedPattern>
</relocation>
<relocation>
<pattern>${shade.com.google.source}</pattern>
<shadedPattern>${shade.com.google.target}</shadedPattern>
</relocation>
<relocation>
<pattern>${shade.org.agrona.source}</pattern>
<shadedPattern>${shade.org.agrona.target}</shadedPattern>
</relocation>
<relocation>
<pattern>${shade.org.jboss.netty.source}</pattern>
<shadedPattern>${shade.org.jboss.netty.target}</shadedPattern>
</relocation>
<relocation>
<pattern>${shade.org.reactivestreams.source}</pattern>
<shadedPattern>${shade.org.reactivestreams.target}</shadedPattern>
</relocation>
<relocation>
<pattern>${shade.org.uncommons.maths.source}</pattern>
<shadedPattern>${shade.org.uncommons.maths.target}</shadedPattern>
</relocation>
<relocation>
<pattern>${shade.scala.source}</pattern>
<shadedPattern>${shade.scala.target}</shadedPattern>
</relocation>
<relocation>
<pattern>${shade.io.aeron.source}</pattern>
<shadedPattern>${shade.io.aeron.target}</shadedPattern>
</relocation>
<relocation>
<pattern>${shade.com.typesafe.source}</pattern>
<shadedPattern>${shade.com.typesafe.target}</shadedPattern>
<pattern>${shade.org.apache.source}</pattern>
<shadedPattern>${shade.org.apache.target}</shadedPattern>
</relocation>
</relocations>
</configuration>
......@@ -148,8 +120,17 @@
</repository>
</distributionManagement>
<properties>
<shade.org.apache.source>org.apache</shade.org.apache.source>
<shade.package>com.a.eye.skywalking.dependencies</shade.package>
<shade.com.google.source>com.google</shade.com.google.source>
<shade.net.bytebuddy.target>${shade.package}.${shade.net.bytebuddy.source}</shade.net.bytebuddy.target>
<shade.com.lmax.disruptor.target>${shade.package}.${shade.com.lmax.disruptor.source}</shade.com.lmax.disruptor.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<shade.net.bytebuddy.source>net.bytebuddy</shade.net.bytebuddy.source>
<shade.com.google.target>${shade.package}.${shade.com.google.source}</shade.com.google.target>
<shade.org.apache.target>${shade.package}.${shade.org.apache.source}</shade.org.apache.target>
<premain.class>com.a.eye.skywalking.agent.SkyWalkingAgent</premain.class>
<shade.com.lmax.disruptor.source>com.lmax.disruptor</shade.com.lmax.disruptor.source>
</properties>
</project>
......@@ -22,9 +22,12 @@
<shade.net.bytebuddy.source>net.bytebuddy</shade.net.bytebuddy.source>
<shade.net.bytebuddy.target>${shade.package}.${shade.net.bytebuddy.source}</shade.net.bytebuddy.target>
<shade.com.lmax.disruptor.source>com.lmax.disruptor</shade.com.lmax.disruptor.source>
<shade.com.lmax.disruptor.target>${shade.package}.${shade.com.lmax.disruptor.source}</shade.com.lmax.disruptor.target>
<shade.com.lmax.disruptor.target>${shade.package}.${shade.com.lmax.disruptor.source}
</shade.com.lmax.disruptor.target>
<shade.com.google.source>com.google</shade.com.google.source>
<shade.com.google.target>${shade.package}.${shade.com.google.source}</shade.com.google.target>
<shade.org.apache.source>org.apache</shade.org.apache.source>
<shade.org.apache.target>${shade.package}.${shade.org.apache.source}</shade.org.apache.target>
</properties>
<dependencies>
......@@ -133,6 +136,10 @@
<pattern>${shade.com.google.source}</pattern>
<shadedPattern>${shade.com.google.target}</shadedPattern>
</relocation>
<relocation>
<pattern>${shade.org.apache.source}</pattern>
<shadedPattern>${shade.org.apache.target}</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
......
......@@ -8,7 +8,6 @@
<version>3.0-2017</version>
</parent>
<artifactId>skywalking-api</artifactId>
<packaging>jar</packaging>
......@@ -17,6 +16,7 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<jetty.version>9.4.2.v20170220</jetty.version>
</properties>
<dependencies>
......@@ -35,22 +35,37 @@
<artifactId>byte-buddy</artifactId>
<version>1.5.7</version>
</dependency>
<dependency>
<groupId>net.bytebuddy</groupId>
<artifactId>byte-buddy-agent</artifactId>
<version>1.5.7</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.lmax</groupId>
<artifactId>disruptor</artifactId>
<version>3.3.6</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.3</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>${jetty.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
<version>${jetty.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
......@@ -59,20 +74,6 @@
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
<plugin>
<!-- 源码插件 -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<!-- 发布时自动将源码同时发布的配置 -->
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
......@@ -8,5 +8,5 @@ package com.a.eye.skywalking.api.boot;
* @author wusheng
*/
public interface BootService {
void bootUp() throws Exception;
void bootUp() throws Throwable;
}
......@@ -23,14 +23,14 @@ public enum ServiceManager {
public void boot() {
if (!isStarted) {
try {
bootedServices = new HashMap<>();
bootedServices = new HashMap<Class, BootService>();
Iterator<BootService> serviceIterator = load().iterator();
while (serviceIterator.hasNext()) {
BootService bootService = serviceIterator.next();
try {
bootService.bootUp();
bootedServices.put(bootService.getClass(), bootService);
} catch (Exception e) {
} catch (Throwable e) {
logger.error(e, "ServiceManager try to start [{}] fail.", bootService.getClass().getName());
}
}
......
......@@ -18,7 +18,7 @@ public abstract class StatusBootService implements BootService {
}
@Override
public final void bootUp() throws Exception{
public final void bootUp() throws Throwable{
try {
bootUpWithStatus();
started = true;
......
package com.a.eye.skywalking.api.client;
import com.a.eye.skywalking.api.boot.ServiceManager;
import com.a.eye.skywalking.api.queue.TraceSegmentProcessQueue;
import com.a.eye.skywalking.logging.ILog;
import com.a.eye.skywalking.logging.LogManager;
import com.a.eye.skywalking.trace.TraceSegment;
import java.util.List;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultConnectionKeepAliveStrategy;
import org.apache.http.impl.client.HttpClients;
/**
* The <code>CollectorClient</code> runs as an independency thread.
* It retrieves cached {@link TraceSegment} from {@link TraceSegmentProcessQueue},
* and send to collector by HTTP-RESTFUL-SERVICE: POST /skywalking/trace/segment
*
* @author wusheng
*/
public class CollectorClient implements Runnable {
private static ILog logger = LogManager.getLogger(CollectorClient.class);
private static long SLEEP_TIME_MILLIS = 500;
private CloseableHttpClient httpclient;
public CollectorClient() {
httpclient = HttpClients.custom()
.setKeepAliveStrategy(new DefaultConnectionKeepAliveStrategy())
.build();
}
@Override
public void run() {
while (true) {
try {
long sleepTime = -1;
TraceSegmentProcessQueue segmentProcessQueue = ServiceManager.INSTANCE.findService(TraceSegmentProcessQueue.class);
List<TraceSegment> cachedTraceSegments = segmentProcessQueue.getCachedTraceSegments();
if (cachedTraceSegments.size() > 0) {
for (TraceSegment segment : cachedTraceSegments) {
/**
* No receiver found, means collector server is off-line.
*/
sleepTime = SLEEP_TIME_MILLIS * 10;
break;
}
} else {
sleepTime = SLEEP_TIME_MILLIS;
}
if (sleepTime > 0) {
try2Sleep(sleepTime);
}
} catch (Throwable t) {
logger.error(t, "Send trace segments to collector failure.");
}
}
}
/**
* Try to sleep, and ignore the {@link InterruptedException}
*
* @param millis the length of time to sleep in milliseconds
*/
private void try2Sleep(long millis) {
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
}
}
}
package com.a.eye.skywalking.api.client;
import com.a.eye.skywalking.api.boot.ServiceManager;
import com.a.eye.skywalking.api.boot.StatusBootService;
import com.a.eye.skywalking.api.queue.TraceSegmentProcessQueue;
import com.a.eye.skywalking.logging.ILog;
import com.a.eye.skywalking.logging.LogManager;
import com.a.eye.skywalking.trace.TraceSegment;
import java.util.List;
/**
* The <code>CollectorClientService</code> is responsible for start {@link CollectorClient}.
*
* @author wusheng
*/
public class CollectorClientService extends StatusBootService implements Runnable {
private static ILog logger = LogManager.getLogger(CollectorClientService.class);
private static long SLEEP_TIME_MILLIS = 500;
public class CollectorClientService extends StatusBootService {
/**
* Start a new {@link Thread} to get finished {@link TraceSegment} by {@link TraceSegmentProcessQueue#getCachedTraceSegments()}
*/
@Override
protected void bootUpWithStatus() throws Exception {
Thread collectorClientThread = new Thread(this, "collectorClientThread");
Thread collectorClientThread = new Thread(new CollectorClient(), "collectorClientThread");
collectorClientThread.start();
}
@Override
public void run() {
while (true) {
try {
long sleepTime = -1;
TraceSegmentProcessQueue segmentProcessQueue = ServiceManager.INSTANCE.findService(TraceSegmentProcessQueue.class);
List<TraceSegment> cachedTraceSegments = segmentProcessQueue.getCachedTraceSegments();
if (cachedTraceSegments.size() > 0) {
for (TraceSegment segment : cachedTraceSegments) {
/**
* No receiver found, means collector server is off-line.
*/
sleepTime = SLEEP_TIME_MILLIS * 10;
break;
}
} else {
sleepTime = SLEEP_TIME_MILLIS;
}
if (sleepTime > 0) {
try2Sleep(sleepTime);
}
} catch (Throwable t) {
logger.error(t, "Send trace segments to collector failure.");
}
}
}
/**
* Try to sleep, and ignore the {@link InterruptedException}
*
* @param millis the length of time to sleep in milliseconds
*/
private void try2Sleep(long millis) {
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
}
}
}
......@@ -11,6 +11,7 @@ public class Config {
public static String SERVERS = "";
public static String SERVICE_NAME = "/segments";
}
public static class Disruptor{
......
......@@ -165,7 +165,7 @@ public class ContextCarrier implements Serializable {
return null;
}
String[] propagationTraceIdValues = text.split(",");
List<DistributedTraceId> traceIds = new LinkedList<>();
List<DistributedTraceId> traceIds = new LinkedList<DistributedTraceId>();
for (String propagationTraceIdValue : propagationTraceIdValues) {
traceIds.add(new PropagatedTraceId(propagationTraceIdValue));
}
......
......@@ -18,7 +18,7 @@ import com.a.eye.skywalking.trace.TraceSegment;
* Created by wusheng on 2017/2/17.
*/
public class ContextManager implements TracerContextListener, BootService {
private static ThreadLocal<TracerContext> CONTEXT = new ThreadLocal<>();
private static ThreadLocal<TracerContext> CONTEXT = new ThreadLocal<TracerContext>();
private static TracerContext get() {
TracerContext segment = CONTEXT.get();
......
......@@ -186,7 +186,7 @@ public final class TracerContext {
}
public static class ListenerManager {
private static List<TracerContextListener> listeners = new LinkedList<>();
private static List<TracerContextListener> listeners = new LinkedList<TracerContextListener>();
/**
* Add the given {@link TracerContextListener} to {@link #listeners} list.
......
......@@ -31,7 +31,7 @@ public class PluginBootstrap {
if (resources == null || resources.size() == 0) {
logger.info("no plugin files (skywalking-plugin.properties) found, continue to start application.");
return new ArrayList<>();
return new ArrayList<AbstractClassEnhancePluginDefine>();
}
for (URL pluginUrl : resources) {
......
......@@ -46,7 +46,7 @@ public class ClassInstanceMethodsInterceptor {
*/
@RuntimeType
public Object intercept(@This Object obj, @AllArguments Object[] allArguments, @Origin Method method, @SuperCall Callable<?> zuper,
@FieldValue(ClassEnhancePluginDefine.contextAttrName) EnhancedClassInstanceContext instanceContext) throws Exception {
@FieldValue(ClassEnhancePluginDefine.contextAttrName) EnhancedClassInstanceContext instanceContext) throws Throwable {
InstanceMethodsAroundInterceptor interceptor = InterceptorInstanceLoader
.load(instanceMethodsAroundInterceptorClassName, obj.getClass().getClassLoader());
......
......@@ -46,7 +46,7 @@ public class ClassStaticMethodsInterceptor {
* or unexpected exception in sky-walking ( This is a bug, if anything triggers this condition ).
*/
@RuntimeType
public Object intercept(@Origin Class<?> clazz, @AllArguments Object[] allArguments, @Origin Method method, @SuperCall Callable<?> zuper) throws Exception {
public Object intercept(@Origin Class<?> clazz, @AllArguments Object[] allArguments, @Origin Method method, @SuperCall Callable<?> zuper) throws Throwable {
StaticMethodsAroundInterceptor interceptor = InterceptorInstanceLoader
.load(staticMethodsAroundInterceptorClassName, clazz.getClassLoader());
......
......@@ -30,7 +30,7 @@ import java.util.concurrent.locks.ReentrantLock;
public class InterceptorInstanceLoader {
private static ILog logger = LogManager.getLogger(InterceptorInstanceLoader.class);
private static ConcurrentHashMap<String, Object> INSTANCE_CACHE = new ConcurrentHashMap<>();
private static ConcurrentHashMap<String, Object> INSTANCE_CACHE = new ConcurrentHashMap<String, Object>();
private static ReentrantLock instanceLoadLock = new ReentrantLock();
......
......@@ -30,7 +30,7 @@ public class TraceSegmentProcessQueue extends StatusBootService implements Trace
private volatile int cacheIndex;
public TraceSegmentProcessQueue() {
disruptor = new Disruptor<>(TraceSegmentHolder.Factory.INSTANCE, Config.Disruptor.BUFFER_SIZE, DaemonThreadFactory.INSTANCE);
disruptor = new Disruptor<TraceSegmentHolder>(TraceSegmentHolder.Factory.INSTANCE, Config.Disruptor.BUFFER_SIZE, DaemonThreadFactory.INSTANCE);
secondLevelCache = new TraceSegment[Config.Disruptor.BUFFER_SIZE];
cacheIndex = 0;
disruptor.handleEventsWith(this);
......@@ -83,7 +83,7 @@ public class TraceSegmentProcessQueue extends StatusBootService implements Trace
}
public List<TraceSegment> getCachedTraceSegments(){
List<TraceSegment> segmentList = new LinkedList<>();
List<TraceSegment> segmentList = new LinkedList<TraceSegment>();
for (int i = 0; i < secondLevelCache.length; i++) {
TraceSegment segment = secondLevelCache[i];
if(segment != null){
......
package com.a.eye.skywalking.api.client;
import java.io.BufferedReader;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultConnectionKeepAliveStrategy;
import org.apache.http.impl.client.HttpClients;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler;
/**
* This is a small application, test for http restful service.
* Use APACHE HttpClient as client, nanohttpd as server.
*
* @author wusheng
*/
public class HTTPRestServiceTestApp {
public static void main(String[] args) throws Exception {
CloseableHttpClient client = null;
Server server = null;
try {
HTTPRestServiceTestApp test = new HTTPRestServiceTestApp();
server = test.startServer();
client = test.send();
} finally {
if (client != null) {
client.close();
}
if (server != null) {
server.stop();
}
}
}
private CloseableHttpClient send() {
CloseableHttpClient httpclient = HttpClients.custom()
.setKeepAliveStrategy(new DefaultConnectionKeepAliveStrategy())
.build();
HttpPost post = new HttpPost("http://localhost:7000/segments");
StringEntity entity = new StringEntity("[{'abc'}]", ContentType.APPLICATION_JSON);
post.setEntity(entity);
try {
CloseableHttpResponse httpResponse = httpclient.execute(post);
System.out.println(httpResponse.getStatusLine().getStatusCode());
} catch (IOException e) {
e.printStackTrace();
}
return httpclient;
}
private Server startServer() throws Exception {
Server server = new Server(7000);
server.setHandler(new AbstractHandler() {
@Override
public void handle(String target, Request baseRequest, HttpServletRequest request,
HttpServletResponse response) throws IOException, ServletException {
BufferedReader br = request.getReader();
String str, wholeStr = "";
while ((str = br.readLine()) != null) {
wholeStr += str;
}
System.out.println(wholeStr);
response.setContentType("text/html; charset=utf-8");
response.setStatus(HttpServletResponse.SC_OK);
baseRequest.setHandled(true);
}
});
//server.start();
return server;
}
}
......@@ -18,7 +18,7 @@ public class ContextCarrierTestCase {
carrier.setSpanId(100);
carrier.setApplicationCode("REMOTE_APP");
carrier.setPeerHost("10.2.3.16:8080");
List<DistributedTraceId> ids = new LinkedList<>();
List<DistributedTraceId> ids = new LinkedList<DistributedTraceId>();
ids.add(new PropagatedTraceId("Trace.global.id.123"));
carrier.setDistributedTraceIds(ids);
......
......@@ -77,7 +77,7 @@ public class TracerContextTestCase {
carrier.setSpanId(5);
carrier.setApplicationCode("REMOTE_APP");
carrier.setPeerHost("10.2.3.16:8080");
List<DistributedTraceId> ids = new LinkedList<>();
List<DistributedTraceId> ids = new LinkedList<DistributedTraceId>();
ids.add(new PropagatedTraceId("Trace.global.id.123"));
carrier.setDistributedTraceIds(ids);
......
package com.a.eye.skywalking.api.plugin;
import com.a.eye.skywalking.api.plugin.utility.ClassFileExtraction;
import net.bytebuddy.agent.ByteBuddyAgent;
import net.bytebuddy.agent.builder.AgentBuilder;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.dynamic.DynamicType;
import net.bytebuddy.dynamic.loading.ByteArrayClassLoader;
import net.bytebuddy.dynamic.loading.PackageDefinitionStrategy;
import net.bytebuddy.matcher.ElementMatchers;
import org.hamcrest.CoreMatchers;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.modules.junit4.PowerMockRunner;
import java.lang.instrument.ClassFileTransformer;
import static net.bytebuddy.matcher.ElementMatchers.none;
import static org.hamcrest.MatcherAssert.assertThat;
@RunWith(PowerMockRunner.class)
public class AbstractClassEnhancePluginDefineTest {
static final String WEAVE_CLASS = "com.a.eye.skywalking.api.plugin.TargetObject";
static final String INTERCEPTOR_CLASS = "com.a.eye.skywalking.api.plugin.MockPluginInterceptor";
static final String WEAVE_INSTANCE_METHOD_NAME = "instanceMethod";
static final String WEAVE_INSTANCE_WITH_EXCEPTION_METHOD_NAME = "instanceMethodWithException";
static final String WEAVE_STATIC_METHOD_NAME = "staticMethod";
private ClassLoader classLoader;
@Before
public void setUp() throws Exception {
classLoader = new ByteArrayClassLoader.ChildFirst(getClass().getClassLoader(),
ClassFileExtraction.of(TargetObject.class),
null,
ByteArrayClassLoader.PersistenceHandler.MANIFEST,
PackageDefinitionStrategy.NoOp.INSTANCE);
}
@Test
public void weaveInstanceMethod() throws Exception {
ByteBuddyAgent.install();
ClassFileTransformer classFileTransformer = new AgentBuilder.Default()
.with(AgentBuilder.PoolStrategy.Default.FAST)
.ignore(none())
.type(ElementMatchers.is(TargetObject.class), ElementMatchers.is(classLoader)).transform(new MockTargetObjectTransformer())
.installOnByteBuddyAgent();
try {
Class<?> type = classLoader.loadClass(TargetObject.class.getName());
assertThat(type.getDeclaredMethod(WEAVE_INSTANCE_METHOD_NAME).invoke(type.getDeclaredConstructor(String.class).newInstance("a"))
, CoreMatchers.<Object>is(WEAVE_INSTANCE_METHOD_NAME + "a"));
} finally {
ByteBuddyAgent.getInstrumentation().removeTransformer(classFileTransformer);
}
}
@Test(expected = RuntimeException.class)
public void weaveInstanceMethodWITEXCEPTION() throws Exception {
ByteBuddyAgent.install();
ClassFileTransformer classFileTransformer = new AgentBuilder.Default()
.with(AgentBuilder.PoolStrategy.Default.FAST)
.ignore(none())
.type(ElementMatchers.is(TargetObject.class), ElementMatchers.is(classLoader)).transform(new MockTargetObjectTransformer())
.installOnByteBuddyAgent();
try {
Class<?> type = classLoader.loadClass(TargetObject.class.getName());
type.getDeclaredMethod(WEAVE_INSTANCE_WITH_EXCEPTION_METHOD_NAME).invoke(type.getDeclaredConstructor(String.class).newInstance("a"));
} finally {
ByteBuddyAgent.getInstrumentation().removeTransformer(classFileTransformer);
}
}
@Test
public void weaveStaticMethod() throws Exception {
ByteBuddyAgent.install();
ClassFileTransformer classFileTransformer = new AgentBuilder.Default()
.with(AgentBuilder.PoolStrategy.Default.FAST)
.ignore(none())
.type(ElementMatchers.is(TargetObject.class), ElementMatchers.is(classLoader)).transform(new MockTargetObjectTransformer())
.installOnByteBuddyAgent();
try {
Class<?> type = classLoader.loadClass(TargetObject.class.getName());
assertThat(type.getDeclaredMethod(WEAVE_STATIC_METHOD_NAME).invoke(type), CoreMatchers.<Object>is(WEAVE_STATIC_METHOD_NAME + "_STATIC"));
} finally {
ByteBuddyAgent.getInstrumentation().removeTransformer(classFileTransformer);
}
}
public static class MockTargetObjectTransformer implements AgentBuilder.Transformer {
@Override
public DynamicType.Builder<?> transform(DynamicType.Builder<?> builder, TypeDescription typeDescription, ClassLoader classLoader) {
try {
DynamicType.Builder newBuilder = transformInstanceMethod(builder);
return transformStaticMethod(newBuilder);
} catch (Exception exception) {
throw new AssertionError(exception);
}
}
private DynamicType.Builder<?> transformStaticMethod(DynamicType.Builder newBuilder) {
MockPluginStaticMethodInstrumentation staticMethodInstrumentation = new MockPluginStaticMethodInstrumentation();
return staticMethodInstrumentation.define(WEAVE_CLASS, newBuilder);
}
private DynamicType.Builder transformInstanceMethod(DynamicType.Builder<?> builder) {
MockPluginInstanceMethodInstrumentation instrumentation = new MockPluginInstanceMethodInstrumentation();
return instrumentation.define(WEAVE_CLASS, builder);
}
}
}
\ No newline at end of file
package com.a.eye.skywalking.api.plugin;
import com.a.eye.skywalking.api.plugin.bytebuddy.AllObjectDefaultMethodsMatch;
import com.a.eye.skywalking.api.plugin.interceptor.ConstructorInterceptPoint;
import com.a.eye.skywalking.api.plugin.interceptor.InstanceMethodsInterceptPoint;
import com.a.eye.skywalking.api.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.matcher.ElementMatcher;
import static com.a.eye.skywalking.api.plugin.AbstractClassEnhancePluginDefineTest.INTERCEPTOR_CLASS;
import static com.a.eye.skywalking.api.plugin.AbstractClassEnhancePluginDefineTest.WEAVE_CLASS;
import static com.a.eye.skywalking.api.plugin.AbstractClassEnhancePluginDefineTest.WEAVE_INSTANCE_METHOD_NAME;
import static com.a.eye.skywalking.api.plugin.AbstractClassEnhancePluginDefineTest.WEAVE_INSTANCE_WITH_EXCEPTION_METHOD_NAME;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.not;
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
public class MockPluginInstanceMethodInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
@Override
protected String enhanceClassName() {
return WEAVE_CLASS;
}
@Override
protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
return new ConstructorInterceptPoint[]{
new ConstructorInterceptPoint() {
@Override
public ElementMatcher<MethodDescription> getConstructorMatcher() {
return takesArgument(0, String.class);
}
@Override
public String getConstructorInterceptor() {
return INTERCEPTOR_CLASS;
}
}
};
}
@Override
protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
return new InstanceMethodsInterceptPoint[]{
new InstanceMethodsInterceptPoint() {
@Override
public ElementMatcher<MethodDescription> getMethodsMatcher() {
return named(WEAVE_INSTANCE_METHOD_NAME).and(not(AllObjectDefaultMethodsMatch.INSTANCE));
}
@Override
public String getMethodsInterceptor() {
return INTERCEPTOR_CLASS;
}
},
new InstanceMethodsInterceptPoint() {
@Override
public ElementMatcher<MethodDescription> getMethodsMatcher() {
return named(WEAVE_INSTANCE_WITH_EXCEPTION_METHOD_NAME);
}
@Override
public String getMethodsInterceptor() {
return INTERCEPTOR_CLASS;
}
}
};
}
}
package com.a.eye.skywalking.api.plugin;
import com.a.eye.skywalking.api.plugin.interceptor.EnhancedClassInstanceContext;
import com.a.eye.skywalking.api.plugin.interceptor.enhance.ConstructorInvokeContext;
import com.a.eye.skywalking.api.plugin.interceptor.enhance.InstanceConstructorInterceptor;
import com.a.eye.skywalking.api.plugin.interceptor.enhance.InstanceMethodInvokeContext;
import com.a.eye.skywalking.api.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
import com.a.eye.skywalking.api.plugin.interceptor.enhance.MethodInterceptResult;
import com.a.eye.skywalking.api.plugin.interceptor.enhance.MethodInvokeContext;
import com.a.eye.skywalking.api.plugin.interceptor.enhance.StaticMethodInvokeContext;
import com.a.eye.skywalking.api.plugin.interceptor.enhance.StaticMethodsAroundInterceptor;
public class MockPluginInterceptor implements InstanceMethodsAroundInterceptor, StaticMethodsAroundInterceptor, InstanceConstructorInterceptor {
@Override
public void beforeMethod(StaticMethodInvokeContext interceptorContext, MethodInterceptResult result) {
}
@Override
public Object afterMethod(StaticMethodInvokeContext interceptorContext, Object ret) {
return ret + "_STATIC";
}
@Override
public void handleMethodException(Throwable t, MethodInvokeContext interceptorContext) {
}
@Override
public void beforeMethod(EnhancedClassInstanceContext context, InstanceMethodInvokeContext interceptorContext, MethodInterceptResult result) {
}
@Override
public Object afterMethod(EnhancedClassInstanceContext context, InstanceMethodInvokeContext interceptorContext, Object ret) {
return ret + String.valueOf(context.get("VALUE"));
}
@Override
public void handleMethodException(Throwable t, EnhancedClassInstanceContext context, InstanceMethodInvokeContext interceptorContext) {
}
@Override
public void onConstruct(EnhancedClassInstanceContext context, ConstructorInvokeContext interceptorContext) {
context.set("VALUE" , interceptorContext.allArguments()[0]);
}
}
package com.a.eye.skywalking.api.plugin;
import com.a.eye.skywalking.api.plugin.interceptor.StaticMethodsInterceptPoint;
import com.a.eye.skywalking.api.plugin.interceptor.enhance.ClassStaticMethodsEnhancePluginDefine;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.matcher.ElementMatcher;
import static com.a.eye.skywalking.api.plugin.AbstractClassEnhancePluginDefineTest.INTERCEPTOR_CLASS;
import static com.a.eye.skywalking.api.plugin.AbstractClassEnhancePluginDefineTest.WEAVE_CLASS;
import static com.a.eye.skywalking.api.plugin.AbstractClassEnhancePluginDefineTest.WEAVE_STATIC_METHOD_NAME;
import static net.bytebuddy.matcher.ElementMatchers.named;
public class MockPluginStaticMethodInstrumentation extends ClassStaticMethodsEnhancePluginDefine {
@Override
protected String enhanceClassName() {
return WEAVE_CLASS;
}
@Override
protected StaticMethodsInterceptPoint[] getStaticMethodsInterceptPoints() {
return new StaticMethodsInterceptPoint[]{
new StaticMethodsInterceptPoint() {
@Override
public ElementMatcher<MethodDescription> getMethodsMatcher() {
return named(WEAVE_STATIC_METHOD_NAME);
}
@Override
public String getMethodsInterceptor() {
return INTERCEPTOR_CLASS;
}
}
};
}
}
......@@ -11,7 +11,7 @@ import org.junit.Test;
public class PluginFinderTest {
@Test
public void testFind(){
ArrayList<AbstractClassEnhancePluginDefine> defines = new ArrayList<>();
ArrayList<AbstractClassEnhancePluginDefine> defines = new ArrayList<AbstractClassEnhancePluginDefine>();
defines.add(new NewTestPlugin());
defines.add(new NewTestPlugin2());
PluginFinder finder = new PluginFinder(defines);
......@@ -22,7 +22,7 @@ public class PluginFinderTest {
@Test(expected = PluginException.class)
public void testCanNotFind(){
ArrayList<AbstractClassEnhancePluginDefine> defines = new ArrayList<>();
ArrayList<AbstractClassEnhancePluginDefine> defines = new ArrayList<AbstractClassEnhancePluginDefine>();
defines.add(new NewTestPlugin());
PluginFinder finder = new PluginFinder(defines);
......
package com.a.eye.skywalking.api.plugin;
public class TargetObject {
private String value;
public TargetObject(String value) {
this.value = value;
}
public String instanceMethod() {
return "instanceMethod";
}
public String instanceMethodWithException() {
throw new RuntimeException("test exception");
}
public static String staticMethod() {
return "staticMethod";
}
}
package com.a.eye.skywalking.api.plugin.utility;
import net.bytebuddy.ClassFileVersion;
import net.bytebuddy.asm.AsmVisitorWrapper;
import net.bytebuddy.description.field.FieldDescription;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.implementation.Implementation;
import net.bytebuddy.implementation.auxiliary.AuxiliaryType;
import net.bytebuddy.implementation.bytecode.StackManipulation;
import net.bytebuddy.jar.asm.ClassReader;
import net.bytebuddy.jar.asm.ClassWriter;
import net.bytebuddy.pool.TypePool;
import org.junit.Test;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
public class ClassFileExtraction {
private static final int CA = 0xCA, FE = 0xFE, BA = 0xBA, BE = 0xBE;
public static Map<String, byte[]> of(Class<?>... type) throws IOException {
Map<String, byte[]> result = new HashMap<String, byte[]>();
for (Class<?> aType : type) {
result.put(aType.getName(), extract(aType));
}
return result;
}
public static byte[] extract(Class<?> type, AsmVisitorWrapper asmVisitorWrapper) throws IOException {
ClassReader classReader = new ClassReader(type.getName());
ClassWriter classWriter = new ClassWriter(classReader, AsmVisitorWrapper.NO_FLAGS);
classReader.accept(asmVisitorWrapper.wrap(new TypeDescription.ForLoadedType(type),
classWriter,
new IllegalContext(),
TypePool.Empty.INSTANCE,
AsmVisitorWrapper.NO_FLAGS,
AsmVisitorWrapper.NO_FLAGS), AsmVisitorWrapper.NO_FLAGS);
return classWriter.toByteArray();
}
public static byte[] extract(Class<?> type) throws IOException {
return extract(type, new AsmVisitorWrapper.Compound());
}
@Test
public void testClassFileExtraction() throws Exception {
byte[] binaryFoo = extract(Foo.class);
assertThat(binaryFoo.length > 4, is(true));
assertThat(binaryFoo[0], is(new Integer(CA).byteValue()));
assertThat(binaryFoo[1], is(new Integer(FE).byteValue()));
assertThat(binaryFoo[2], is(new Integer(BA).byteValue()));
assertThat(binaryFoo[3], is(new Integer(BE).byteValue()));
}
private static class Foo {
/* empty */
}
private static class IllegalContext implements Implementation.Context {
@Override
public TypeDescription register(AuxiliaryType auxiliaryType) {
throw new AssertionError("Did not expect method call");
}
@Override
public FieldDescription.InDefinedShape cache(StackManipulation fieldValue, TypeDescription fieldType) {
throw new AssertionError("Did not expect method call");
}
@Override
public TypeDescription getInstrumentedType() {
throw new AssertionError("Did not expect method call");
}
@Override
public ClassFileVersion getClassFileVersion() {
throw new AssertionError("Did not expect method call");
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册