From 95dcd3927b709a714ad61a32186d1df376f2454c Mon Sep 17 00:00:00 2001 From: wusheng Date: Sat, 1 Jul 2017 21:12:48 +0800 Subject: [PATCH] Finish the skeleton codes of sending segments to collector. --- .../apm/agent/core/boot/BootService.java | 6 +- .../apm/agent/core/boot/ServiceManager.java | 14 ++- .../agent/core/context/ContextManager.java | 7 +- .../core/datacarrier/DataBufferService.java | 56 --------- .../discovery/CollectorDiscoveryService.java | 16 ++- .../core/remote/GRPCChannelListener.java | 1 + .../agent/core/remote/GRPCChannelManager.java | 22 +++- .../agent/core/remote/GRPCChannelStatus.java | 8 ++ .../core/remote/GRPCStreamServiceStatus.java | 48 ++++++++ .../remote/TraceSegmentServiceClient.java | 107 +++++++++++++++++- .../agent/core/sampling/SamplingService.java | 9 +- ...skywalking.apm.agent.core.boot.BootService | 2 +- 12 files changed, 227 insertions(+), 69 deletions(-) delete mode 100644 apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/datacarrier/DataBufferService.java create mode 100644 apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/remote/GRPCChannelStatus.java create mode 100644 apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/remote/GRPCStreamServiceStatus.java diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/boot/BootService.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/boot/BootService.java index 524bff9c7..d3538f915 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/boot/BootService.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/boot/BootService.java @@ -3,12 +3,14 @@ package org.skywalking.apm.agent.core.boot; /** * The BootService is an interface to all remote, which need to boot when plugin mechanism begins to * work. - * {@link #bootUp()} will be called when BootService start up. + * {@link #boot()} will be called when BootService start up. * * @author wusheng */ public interface BootService { - void bootUp() throws Throwable; + void beforeBoot() throws Throwable; + + void boot() throws Throwable; void afterBoot() throws Throwable; } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/boot/ServiceManager.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/boot/ServiceManager.java index 35a9e1eac..06283a8ef 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/boot/ServiceManager.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/boot/ServiceManager.java @@ -22,6 +22,8 @@ public enum ServiceManager { public void boot() { bootedServices = loadAllServices(); + + beforeBoot(); startup(); afterBoot(); } @@ -36,10 +38,20 @@ public enum ServiceManager { return bootedServices; } + private void beforeBoot() { + for (BootService service : bootedServices.values()) { + try { + service.beforeBoot(); + } catch (Throwable e) { + logger.error(e, "ServiceManager try to pre-start [{}] fail.", service.getClass().getName()); + } + } + } + private void startup() { for (BootService service : bootedServices.values()) { try { - service.bootUp(); + service.boot(); } catch (Throwable e) { logger.error(e, "ServiceManager try to start [{}] fail.", service.getClass().getName()); } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/ContextManager.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/ContextManager.java index 9ef71920a..13a28e9d8 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/ContextManager.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/ContextManager.java @@ -109,7 +109,12 @@ public class ContextManager implements TracingContextListener, BootService, Igno } @Override - public void bootUp() { + public void beforeBoot() throws Throwable { + + } + + @Override + public void boot() { TracingContext.ListenerManager.add(this); IgnoredTracerContext.ListenerManager.add(this); } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/datacarrier/DataBufferService.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/datacarrier/DataBufferService.java deleted file mode 100644 index c8c081fb2..000000000 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/datacarrier/DataBufferService.java +++ /dev/null @@ -1,56 +0,0 @@ -package org.skywalking.apm.agent.core.datacarrier; - -import java.util.List; -import org.skywalking.apm.agent.core.boot.BootService; -import org.skywalking.apm.agent.core.context.TracingContext; -import org.skywalking.apm.agent.core.context.TracingContextListener; -import org.skywalking.apm.agent.core.context.trace.TraceSegment; -import org.skywalking.apm.agent.core.datacarrier.buffer.BufferStrategy; -import org.skywalking.apm.agent.core.datacarrier.consumer.IConsumer; - -import static org.skywalking.apm.agent.core.conf.Config.Buffer.BUFFER_SIZE; -import static org.skywalking.apm.agent.core.conf.Config.Buffer.CHANNEL_SIZE; - -/** - * @author wusheng - */ -public class DataBufferService implements BootService, IConsumer, TracingContextListener { - private volatile DataCarrier carrier; - - @Override - public void bootUp() throws Throwable { - carrier = new DataCarrier(CHANNEL_SIZE, BUFFER_SIZE); - carrier.setBufferStrategy(BufferStrategy.IF_POSSIBLE); - carrier.consume(this, 1); - } - - @Override - public void afterBoot() throws Throwable { - TracingContext.ListenerManager.add(this); - } - - @Override - public void init() { - - } - - @Override - public void consume(List data) { - - } - - @Override - public void onError(List data, Throwable t) { - - } - - @Override - public void onExit() { - - } - - @Override - public void afterFinished(TraceSegment traceSegment) { - carrier.produce(traceSegment); - } -} diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/discovery/CollectorDiscoveryService.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/discovery/CollectorDiscoveryService.java index c94885610..6022a700f 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/discovery/CollectorDiscoveryService.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/discovery/CollectorDiscoveryService.java @@ -1,5 +1,6 @@ package org.skywalking.apm.agent.core.discovery; +import org.skywalking.apm.agent.core.boot.BootService; import org.skywalking.apm.agent.core.remote.DiscoveryRestServiceClient; /** @@ -7,10 +8,21 @@ import org.skywalking.apm.agent.core.remote.DiscoveryRestServiceClient; * * @author wusheng */ -public class CollectorDiscoveryService extends StatusBootService { +public class CollectorDiscoveryService implements BootService { @Override - protected void bootUpWithStatus() throws Exception { + public void beforeBoot() throws Throwable { + + } + + @Override + public void boot() throws Throwable { Thread collectorClientThread = new Thread(new DiscoveryRestServiceClient(), "collectorClientThread"); + collectorClientThread.setDaemon(true); collectorClientThread.start(); } + + @Override + public void afterBoot() throws Throwable { + + } } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/remote/GRPCChannelListener.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/remote/GRPCChannelListener.java index 792d62571..3b3887395 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/remote/GRPCChannelListener.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/remote/GRPCChannelListener.java @@ -4,4 +4,5 @@ package org.skywalking.apm.agent.core.remote; * @author wusheng */ public interface GRPCChannelListener { + void statusChanged(GRPCChannelStatus status); } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/remote/GRPCChannelManager.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/remote/GRPCChannelManager.java index 6dd129fcb..93899e4cd 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/remote/GRPCChannelManager.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/remote/GRPCChannelManager.java @@ -4,6 +4,9 @@ import io.grpc.ManagedChannel; import io.grpc.ManagedChannelBuilder; import io.grpc.internal.DnsNameResolverProvider; import io.grpc.netty.NettyChannelBuilder; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; import java.util.Random; import org.skywalking.apm.agent.core.boot.BootService; import org.skywalking.apm.agent.core.conf.RemoteDownstreamConfig; @@ -19,9 +22,15 @@ public class GRPCChannelManager implements BootService, Runnable { private volatile Thread channelManagerThread = null; private volatile ManagedChannel managedChannel = null; private Random random = new Random(); + private List listeners = Collections.synchronizedList(new LinkedList()); @Override - public void bootUp() throws Throwable { + public void beforeBoot() throws Throwable { + + } + + @Override + public void boot() throws Throwable { this.startupInBackground(); } @@ -61,6 +70,9 @@ public class GRPCChannelManager implements BootService, Runnable { .maxInboundMessageSize(1024 * 1024 * 50) .usePlaintext(true); managedChannel = channelBuilder.build(); + for (GRPCChannelListener listener : listeners) { + listener.statusChanged(GRPCChannelStatus.CONNECTED); + } break; } catch (Throwable t) { logger.error(t, "Create channel to {} fail.", server); @@ -73,6 +85,14 @@ public class GRPCChannelManager implements BootService, Runnable { } } + public void addChannelListener(GRPCChannelListener listener){ + listeners.add(listener); + } + + public ManagedChannel getManagedChannel() { + return managedChannel; + } + /** * Try to sleep, and ignore the {@link InterruptedException} * diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/remote/GRPCChannelStatus.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/remote/GRPCChannelStatus.java new file mode 100644 index 000000000..78060a69a --- /dev/null +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/remote/GRPCChannelStatus.java @@ -0,0 +1,8 @@ +package org.skywalking.apm.agent.core.remote; + +/** + * @author wusheng + */ +public enum GRPCChannelStatus { + CONNECTED; +} diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/remote/GRPCStreamServiceStatus.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/remote/GRPCStreamServiceStatus.java new file mode 100644 index 000000000..0717e59ac --- /dev/null +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/remote/GRPCStreamServiceStatus.java @@ -0,0 +1,48 @@ +package org.skywalking.apm.agent.core.remote; + +/** + * @author wusheng + */ +public class GRPCStreamServiceStatus { + private volatile boolean status; + + public GRPCStreamServiceStatus(boolean status) { + this.status = status; + } + + public boolean isStatus() { + return status; + } + + public void setStatus(boolean status) { + this.status = status; + } + + /** + * + * @param maxTimeout max wait time, milliseconds. + */ + public void wait4Finish(long maxTimeout) { + long time = 0; + while (status == false) { + if (time > maxTimeout) { + break; + } + try2Sleep(50); + time += 50; + } + } + + /** + * 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) { + + } + } +} diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/remote/TraceSegmentServiceClient.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/remote/TraceSegmentServiceClient.java index 76bc6cc58..cbc312782 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/remote/TraceSegmentServiceClient.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/remote/TraceSegmentServiceClient.java @@ -1,14 +1,115 @@ package org.skywalking.apm.agent.core.remote; +import io.grpc.ManagedChannel; +import io.grpc.stub.StreamObserver; +import java.util.List; +import org.skywalking.apm.agent.core.boot.BootService; +import org.skywalking.apm.agent.core.boot.ServiceManager; +import org.skywalking.apm.agent.core.context.TracingContext; +import org.skywalking.apm.agent.core.context.TracingContextListener; +import org.skywalking.apm.agent.core.context.trace.TraceSegment; +import org.skywalking.apm.agent.core.datacarrier.DataCarrier; +import org.skywalking.apm.agent.core.datacarrier.buffer.BufferStrategy; +import org.skywalking.apm.agent.core.datacarrier.consumer.IConsumer; +import org.skywalking.apm.logging.ILog; +import org.skywalking.apm.logging.LogManager; +import org.skywalking.apm.network.collecor.proto.Downstream; +import org.skywalking.apm.network.trace.proto.TraceSegmentServiceGrpc; +import org.skywalking.apm.network.trace.proto.UpstreamSegment; + +import static org.skywalking.apm.agent.core.conf.Config.Buffer.BUFFER_SIZE; +import static org.skywalking.apm.agent.core.conf.Config.Buffer.CHANNEL_SIZE; +import static org.skywalking.apm.agent.core.remote.GRPCChannelStatus.CONNECTED; + /** * @author wusheng */ -public class TraceSegmentServiceClient { - public void start() { +public class TraceSegmentServiceClient implements BootService, IConsumer, TracingContextListener, GRPCChannelListener { + private static final ILog logger = LogManager.getLogger(TraceSegmentServiceClient.class); + + private volatile DataCarrier carrier; + private volatile TraceSegmentServiceGrpc.TraceSegmentServiceStub serviceStub; + + @Override + public void beforeBoot() throws Throwable { + ServiceManager.INSTANCE.findService(GRPCChannelManager.class).addChannelListener(this); + } + + @Override + public void boot() throws Throwable { + carrier = new DataCarrier(CHANNEL_SIZE, BUFFER_SIZE); + carrier.setBufferStrategy(BufferStrategy.IF_POSSIBLE); + carrier.consume(this, 1); + } + + @Override + public void afterBoot() throws Throwable { + TracingContext.ListenerManager.add(this); + } + + @Override + public void init() { } - public void switchChannel(){ + @Override + public void consume(List data) { + final GRPCStreamServiceStatus status = new GRPCStreamServiceStatus(false); + StreamObserver upstreamSegmentStreamObserver = serviceStub.collect(new StreamObserver() { + @Override + public void onNext(Downstream downstream) { + } + + @Override + public void onError(Throwable throwable) { + status.setStatus(true); + } + + @Override + public void onCompleted() { + status.setStatus(true); + } + }); + + try { + for (TraceSegment segment : data) { + //TODO + // segment to PROTOBUF object + upstreamSegmentStreamObserver.onNext(null); + } + } catch (Throwable t) { + logger.error(t, "Send UpstreamSegment to collector fail."); + } + upstreamSegmentStreamObserver.onCompleted(); + + status.wait4Finish(30 * 1000); + + if (logger.isDebugEnable()) { + logger.debug("{} trace segments have been sent to collector.", data.size()); + } + } + + @Override + public void onError(List data, Throwable t) { + logger.error(t, "Try to send {} trace segments to collector, with unexpected exception.", data.size()); + } + + @Override + public void onExit() { + + } + + @Override + public void afterFinished(TraceSegment traceSegment) { + carrier.produce(traceSegment); + } + + @Override + public void statusChanged(GRPCChannelStatus status) { + if (CONNECTED.equals(status)) { + ManagedChannel channel = ServiceManager.INSTANCE.findService(GRPCChannelManager.class).getManagedChannel(); + serviceStub = TraceSegmentServiceGrpc.newStub(channel); + } } } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/sampling/SamplingService.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/sampling/SamplingService.java index 993a3e4ce..8f3adab55 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/sampling/SamplingService.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/sampling/SamplingService.java @@ -28,10 +28,15 @@ public class SamplingService implements BootService { private volatile ScheduledFuture scheduledFuture; @Override - public void bootUp() throws Throwable { + public void beforeBoot() throws Throwable { + + } + + @Override + public void boot() throws Throwable { if (scheduledFuture != null) { /** - * If {@link #bootUp()} invokes twice, mostly in test cases, + * If {@link #boot()} invokes twice, mostly in test cases, * cancel the old one. */ scheduledFuture.cancel(true); diff --git a/apm-sniffer/apm-agent-core/src/main/resources/META-INF/services/org.skywalking.apm.agent.core.boot.BootService b/apm-sniffer/apm-agent-core/src/main/resources/META-INF/services/org.skywalking.apm.agent.core.boot.BootService index 1b0c29fba..91b545ba1 100644 --- a/apm-sniffer/apm-agent-core/src/main/resources/META-INF/services/org.skywalking.apm.agent.core.boot.BootService +++ b/apm-sniffer/apm-agent-core/src/main/resources/META-INF/services/org.skywalking.apm.agent.core.boot.BootService @@ -1,4 +1,4 @@ -org.skywalking.apm.agent.core.datacarrier.DataBufferService +org.skywalking.apm.agent.core.remote.TraceSegmentServiceClient org.skywalking.apm.agent.core.context.ContextManager org.skywalking.apm.agent.core.discovery.CollectorDiscoveryService org.skywalking.apm.agent.core.sampling.SamplingService