Merge remote-tracking branch 'origin/feature/3.0' into feature/collector
This commit is contained in:
commit
1fd5873ab7
2
pom.xml
2
pom.xml
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,74 @@
|
|||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +1,5 @@
|
|||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,66 @@
|
|||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
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;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,71 @@
|
|||
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) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,67 +1,21 @@
|
|||
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){
|
||||
|
|
|
|||
|
|
@ -0,0 +1,82 @@
|
|||
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);
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,118 @@
|
|||
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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
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;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
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]);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
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);
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
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";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
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");
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue