From 5f6dd33ce1a7b0844a73a9b35a41f453be38b617 Mon Sep 17 00:00:00 2001 From: wusheng Date: Wed, 22 Mar 2017 10:46:33 +0800 Subject: [PATCH 1/8] Fix jedis missing tag: span.kind. --- .../skywalking/api/boot/ServiceManager.java | 33 +++++++++-------- .../api/sampling/SamplingService.java | 7 ++-- .../api/sampling/SamplingServiceTest.java | 36 +++++++++++++++++++ .../jedis/v2/JedisMethodInterceptor.java | 1 + 4 files changed, 57 insertions(+), 20 deletions(-) create mode 100644 skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/sampling/SamplingServiceTest.java diff --git a/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/boot/ServiceManager.java b/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/boot/ServiceManager.java index 1ff1c9820..ea5af0fe6 100644 --- a/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/boot/ServiceManager.java +++ b/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/boot/ServiceManager.java @@ -17,36 +17,35 @@ public enum ServiceManager { INSTANCE; private static ILog logger = LogManager.getLogger(StatusBootService.class); - private volatile boolean isStarted = false; - private Map bootedServices; + private Map bootedServices = new HashMap(); public void boot() { - if (!isStarted) { + bootedServices = loadAllServices(); + } + + private Map loadAllServices() { + HashMap bootedServices = new HashMap(); + Iterator serviceIterator = load().iterator(); + while (serviceIterator.hasNext()) { + BootService bootService = serviceIterator.next(); try { - bootedServices = new HashMap(); - Iterator serviceIterator = load().iterator(); - while (serviceIterator.hasNext()) { - BootService bootService = serviceIterator.next(); - try { - bootService.bootUp(); - bootedServices.put(bootService.getClass(), bootService); - } catch (Throwable e) { - logger.error(e, "ServiceManager try to start [{}] fail.", bootService.getClass().getName()); - } - } - } finally { - isStarted = true; + bootService.bootUp(); + bootedServices.put(bootService.getClass(), bootService); + } catch (Throwable e) { + logger.error(e, "ServiceManager try to start [{}] fail.", bootService.getClass().getName()); } } + return bootedServices; } /** * Find a {@link BootService} implementation, which is already started. + * * @param serviceClass class name. * @param {@link BootService} implementation class. * @return {@link BootService} instance */ - public T findService(Class serviceClass){ + public T findService(Class serviceClass) { return (T)bootedServices.get(serviceClass); } diff --git a/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/sampling/SamplingService.java b/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/sampling/SamplingService.java index 6967c203d..f1701dd37 100644 --- a/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/sampling/SamplingService.java +++ b/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/sampling/SamplingService.java @@ -21,7 +21,7 @@ public class SamplingService implements BootService { private volatile boolean on = false; private volatile int rate = 0; - private volatile int rollingSeed = 0; + private volatile int rollingSeed = 1; @Override public void bootUp() throws Throwable { @@ -39,9 +39,10 @@ public class SamplingService implements BootService { public void trySampling(TraceSegment segment) { if (on) { - if (rollingSeed++ != rate) { + if (rollingSeed % rate != 0) { segment.setSampled(false); } + rollingSeed++; } } @@ -59,7 +60,7 @@ public class SamplingService implements BootService { if(on) { if (!segment.isSampled() && carrier.isSampled()) { segment.setSampled(true); - this.rollingSeed = 0; + this.rollingSeed = 1; } } } diff --git a/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/sampling/SamplingServiceTest.java b/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/sampling/SamplingServiceTest.java new file mode 100644 index 000000000..6fedcb121 --- /dev/null +++ b/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/sampling/SamplingServiceTest.java @@ -0,0 +1,36 @@ +package com.a.eye.skywalking.api.sampling; + +import com.a.eye.skywalking.api.boot.ServiceManager; +import com.a.eye.skywalking.api.conf.Config; +import com.a.eye.skywalking.trace.TraceSegment; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.Test; + +/** + * @author wusheng + */ +public class SamplingServiceTest { + @Test + public void test50Percent(){ + Config.Agent.SAMPLING_RATE = 5000; + ServiceManager.INSTANCE.boot(); + + TraceSegment segment = new TraceSegment(); + Assert.assertTrue(segment.isSampled()); + + SamplingService service = ServiceManager.INSTANCE.findService(SamplingService.class); + service.trySampling(segment); + Assert.assertFalse(segment.isSampled()); + + segment = new TraceSegment(); + service.trySampling(segment); + Assert.assertTrue(segment.isSampled()); + } + + @AfterClass + public static void clear(){ + Config.Agent.SAMPLING_RATE = 10000; + ServiceManager.INSTANCE.boot(); + } +} diff --git a/skywalking-sniffer/skywalking-sdk-plugin/jedis-2.x-plugin/src/main/java/com/a/eye/skywalking/plugin/jedis/v2/JedisMethodInterceptor.java b/skywalking-sniffer/skywalking-sdk-plugin/jedis-2.x-plugin/src/main/java/com/a/eye/skywalking/plugin/jedis/v2/JedisMethodInterceptor.java index 4cb17f016..914823ccf 100644 --- a/skywalking-sniffer/skywalking-sdk-plugin/jedis-2.x-plugin/src/main/java/com/a/eye/skywalking/plugin/jedis/v2/JedisMethodInterceptor.java +++ b/skywalking-sniffer/skywalking-sdk-plugin/jedis-2.x-plugin/src/main/java/com/a/eye/skywalking/plugin/jedis/v2/JedisMethodInterceptor.java @@ -50,6 +50,7 @@ public class JedisMethodInterceptor extends NoCocurrencyAceessObject implements Span span = ContextManager.createSpan("Jedis/" + interceptorContext.methodName()); Tags.COMPONENT.set(span, REDIS_COMPONENT); Tags.DB_TYPE.set(span, REDIS_COMPONENT); + Tags.SPAN_KIND.set(span, Tags.SPAN_KIND_CLIENT); tagPeer(span, context); Tags.SPAN_LAYER.asDB(span); if (StringUtil.isEmpty(context.get(KEY_OF_REDIS_HOST, String.class))) { From d6696ad285a9911f71600a473e725afd529398fb Mon Sep 17 00:00:00 2001 From: wusheng Date: Wed, 22 Mar 2017 11:22:46 +0800 Subject: [PATCH 2/8] Fix database plugin missing tag span.kind. --- .../com/a/eye/skywalking/api/conf/Config.java | 2 +- .../api/sampling/SamplingService.java | 17 ++++++++--------- .../api/sampling/SamplingServiceTest.java | 4 ++-- .../plugin/jdbc/CallableStatementTracing.java | 1 + .../plugin/jdbc/ConnectionTracing.java | 1 + .../plugin/jdbc/PreparedStatementTracing.java | 1 + .../plugin/jdbc/StatementTracing.java | 1 + 7 files changed, 15 insertions(+), 12 deletions(-) diff --git a/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/conf/Config.java b/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/conf/Config.java index 402b4be81..1c2cd1022 100644 --- a/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/conf/Config.java +++ b/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/conf/Config.java @@ -9,7 +9,7 @@ public class Config { public static String PATH = ""; - public static int SAMPLING_RATE = 10000; + public static int SAMPLING_CYCLE = 1; } public static class Collector{ diff --git a/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/sampling/SamplingService.java b/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/sampling/SamplingService.java index f1701dd37..a2bfa0a2d 100644 --- a/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/sampling/SamplingService.java +++ b/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/sampling/SamplingService.java @@ -12,7 +12,7 @@ import com.a.eye.skywalking.trace.TraceSegment; * have been traced, but, considering CPU cost of serialization/deserialization, and network bandwidth, the agent do NOT * send all of them to collector, if SAMPLING is on. * - * By default, SAMPLING is off, and {@link Config.Agent#SAMPLING_RATE} == 1000. + * By default, SAMPLING is off, and {@link Config.Agent#SAMPLING_CYCLE} == 1. * * @author wusheng */ @@ -20,26 +20,25 @@ public class SamplingService implements BootService { private static ILog logger = LogManager.getLogger(SamplingService.class); private volatile boolean on = false; - private volatile int rate = 0; private volatile int rollingSeed = 1; @Override public void bootUp() throws Throwable { - if (Config.Agent.SAMPLING_RATE == 10000) { + if (Config.Agent.SAMPLING_CYCLE == 1) { + this.on = false; return; } - if (Config.Agent.SAMPLING_RATE > 10000 || Config.Agent.SAMPLING_RATE < 1) { - throw new IllegalSamplingRateException("sampling rate should stay in (0, 10000]."); + if (Config.Agent.SAMPLING_CYCLE < 1) { + throw new IllegalSamplingRateException("sampling cycle must greater than 0."); } - rate = 10000 / Config.Agent.SAMPLING_RATE; - on = true; + this.on = true; - logger.debug("The trace sampling is on, and the sampling rate is: {}", rate); + logger.debug("The trace sampling is on, and the sampling cycle is: {}", Config.Agent.SAMPLING_CYCLE); } public void trySampling(TraceSegment segment) { if (on) { - if (rollingSeed % rate != 0) { + if (rollingSeed % Config.Agent.SAMPLING_CYCLE != 0) { segment.setSampled(false); } rollingSeed++; diff --git a/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/sampling/SamplingServiceTest.java b/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/sampling/SamplingServiceTest.java index 6fedcb121..d3d406cad 100644 --- a/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/sampling/SamplingServiceTest.java +++ b/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/sampling/SamplingServiceTest.java @@ -13,7 +13,7 @@ import org.junit.Test; public class SamplingServiceTest { @Test public void test50Percent(){ - Config.Agent.SAMPLING_RATE = 5000; + Config.Agent.SAMPLING_CYCLE = 2; ServiceManager.INSTANCE.boot(); TraceSegment segment = new TraceSegment(); @@ -30,7 +30,7 @@ public class SamplingServiceTest { @AfterClass public static void clear(){ - Config.Agent.SAMPLING_RATE = 10000; + Config.Agent.SAMPLING_CYCLE = 1; ServiceManager.INSTANCE.boot(); } } diff --git a/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/CallableStatementTracing.java b/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/CallableStatementTracing.java index 797908dcd..02975b3b2 100644 --- a/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/CallableStatementTracing.java +++ b/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/CallableStatementTracing.java @@ -24,6 +24,7 @@ public class CallableStatementTracing { try { Span span = ContextManager.createSpan(connectInfo.getDBType() + "/JDBI/CallableStatement/" + method); Tags.DB_TYPE.set(span, "sql"); + Tags.SPAN_KIND.set(span, Tags.SPAN_KIND_CLIENT); Tags.DB_INSTANCE.set(span, connectInfo.getDatabaseName()); Tags.DB_STATEMENT.set(span, sql); Tags.SPAN_LAYER.asDB(span); diff --git a/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/ConnectionTracing.java b/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/ConnectionTracing.java index 1b20172ac..ebb089921 100755 --- a/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/ConnectionTracing.java +++ b/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/ConnectionTracing.java @@ -24,6 +24,7 @@ public class ConnectionTracing { try { Span span = ContextManager.createSpan(connectInfo.getDBType() + "/JDBI/Connection/" + method); Tags.DB_TYPE.set(span, "sql"); + Tags.SPAN_KIND.set(span, Tags.SPAN_KIND_CLIENT); Tags.DB_INSTANCE.set(span, connectInfo.getDatabaseName()); Tags.DB_STATEMENT.set(span, sql); Tags.COMPONENT.set(span, connectInfo.getDBType()); diff --git a/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/PreparedStatementTracing.java b/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/PreparedStatementTracing.java index 20f7fba3b..207bd91e7 100644 --- a/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/PreparedStatementTracing.java +++ b/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/PreparedStatementTracing.java @@ -23,6 +23,7 @@ public class PreparedStatementTracing { try { Span span = ContextManager.createSpan(connectInfo.getDBType() + "/JDBI/PreparedStatement/" + method); Tags.DB_TYPE.set(span, "sql"); + Tags.SPAN_KIND.set(span, Tags.SPAN_KIND_CLIENT); Tags.DB_INSTANCE.set(span, connectInfo.getDatabaseName()); Tags.DB_STATEMENT.set(span, sql); Tags.COMPONENT.set(span, connectInfo.getDBType()); diff --git a/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/StatementTracing.java b/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/StatementTracing.java index f421e0ad0..f27a5033e 100644 --- a/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/StatementTracing.java +++ b/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/StatementTracing.java @@ -23,6 +23,7 @@ public class StatementTracing { try { Span span = ContextManager.createSpan(connectInfo.getDBType() + "/JDBI/Statement/" + method); Tags.DB_TYPE.set(span, "sql"); + Tags.SPAN_KIND.set(span, Tags.SPAN_KIND_CLIENT); Tags.DB_INSTANCE.set(span, connectInfo.getDatabaseName()); Tags.DB_STATEMENT.set(span, sql); Tags.COMPONENT.set(span, connectInfo.getDBType()); From 680c2c2337df53a20829a8d42b9fed17bde03259 Mon Sep 17 00:00:00 2001 From: wusheng Date: Wed, 22 Mar 2017 14:19:21 +0800 Subject: [PATCH 3/8] Add host:port/peers to ContextCarrier. --- .../a/eye/skywalking/api/context/TracerContext.java | 11 +++++++++-- .../skywalking/api/context/TracerContextTestCase.java | 3 ++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/context/TracerContext.java b/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/context/TracerContext.java index a2a6c5b26..2485ee92d 100644 --- a/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/context/TracerContext.java +++ b/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/context/TracerContext.java @@ -125,9 +125,16 @@ public final class TracerContext { */ public void inject(ContextCarrier carrier) { carrier.setTraceSegmentId(this.segment.getTraceSegmentId()); - carrier.setSpanId(this.activeSpan().getSpanId()); + Span span = this.activeSpan(); + carrier.setSpanId(span.getSpanId()); carrier.setApplicationCode(Config.Agent.APPLICATION_CODE); - carrier.setPeerHost(Tags.PEER_HOST.get(activeSpan())); + String host = Tags.PEER_HOST.get(span); + if(host != null) { + Integer port = Tags.PEER_PORT.get(span); + carrier.setPeerHost(host + ":" + port); + }else{ + carrier.setPeerHost(Tags.PEERS.get(span)); + } carrier.setDistributedTraceIds(this.segment.getRelatedGlobalTraces()); carrier.setSampled(this.segment.isSampled()); } diff --git a/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/context/TracerContextTestCase.java b/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/context/TracerContextTestCase.java index 7fad516d8..3b62a2780 100644 --- a/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/context/TracerContextTestCase.java +++ b/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/context/TracerContextTestCase.java @@ -61,7 +61,8 @@ public class TracerContextTestCase { TracerContext context = new TracerContext(); Span serviceSpan = context.createSpan("/serviceA"); Span dbSpan = context.createSpan("db/preparedStatement/execute"); - Tags.PEER_HOST.set(dbSpan, "127.0.0.1:8080"); + Tags.PEER_HOST.set(dbSpan, "127.0.0.1"); + Tags.PEER_PORT.set(dbSpan, 8080); ContextCarrier carrier = new ContextCarrier(); context.inject(carrier); From fa81a0f6ba347a246f1e7b9cd590373fbb4dcd29 Mon Sep 17 00:00:00 2001 From: wusheng Date: Wed, 22 Mar 2017 16:51:56 +0800 Subject: [PATCH 4/8] Check sampling mechanism. --- .../com/a/eye/skywalking/api/sampling/SamplingService.java | 1 + .../a/eye/skywalking/api/context/TracerContextTestCase.java | 1 + .../a/eye/skywalking/api/sampling/SamplingServiceTest.java | 4 ++++ 3 files changed, 6 insertions(+) diff --git a/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/sampling/SamplingService.java b/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/sampling/SamplingService.java index a2bfa0a2d..dd6572f97 100644 --- a/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/sampling/SamplingService.java +++ b/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/sampling/SamplingService.java @@ -40,6 +40,7 @@ public class SamplingService implements BootService { if (on) { if (rollingSeed % Config.Agent.SAMPLING_CYCLE != 0) { segment.setSampled(false); + this.rollingSeed = 1; } rollingSeed++; } diff --git a/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/context/TracerContextTestCase.java b/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/context/TracerContextTestCase.java index 3b62a2780..308d72801 100644 --- a/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/context/TracerContextTestCase.java +++ b/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/context/TracerContextTestCase.java @@ -5,6 +5,7 @@ import com.a.eye.skywalking.trace.TraceId.DistributedTraceId; import com.a.eye.skywalking.trace.TraceId.PropagatedTraceId; import com.a.eye.skywalking.trace.TraceSegment; import com.a.eye.skywalking.trace.tag.Tags; +import java.awt.SystemTray; import java.util.LinkedList; import java.util.List; import org.junit.After; diff --git a/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/sampling/SamplingServiceTest.java b/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/sampling/SamplingServiceTest.java index d3d406cad..36bb9799c 100644 --- a/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/sampling/SamplingServiceTest.java +++ b/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/sampling/SamplingServiceTest.java @@ -26,6 +26,10 @@ public class SamplingServiceTest { segment = new TraceSegment(); service.trySampling(segment); Assert.assertTrue(segment.isSampled()); + + segment = new TraceSegment(); + service.trySampling(segment); + Assert.assertFalse(segment.isSampled()); } @AfterClass From 388d2481a092bc902bb2a325276d69799b0dbc1e Mon Sep 17 00:00:00 2001 From: wusheng Date: Thu, 23 Mar 2017 16:29:48 +0800 Subject: [PATCH 5/8] Fix typo, and remove unnecessary lock in NoConcurrencyAceessObject. Refact FileWriter and SnifferConfigInitializer. --- README.md | 3 +- .../api/util/ConfigInitializer.java | 15 +- .../eye/skywalking/agent/SkyWalkingAgent.java | 40 +---- .../com/a/eye/skywalking/api/conf/Config.java | 19 +-- .../a/eye/skywalking/api/conf/Constants.java | 10 +- .../api/conf/SnifferConfigInitializer.java | 120 ++++++++++++-- .../skywalking/api/logging/EasyLogger.java | 94 ++++++----- .../skywalking/api/logging/FileWriter.java | 156 ++++++++++++++++++ .../a/eye/skywalking/api/logging/IWriter.java | 2 - .../eye/skywalking/api/logging/LogLevel.java | 4 +- .../api/logging/LogMessageHolder.java | 19 +++ .../skywalking/api/logging/STDOutWriter.java | 15 -- .../api/logging/SyncFileWriter.java | 113 ------------- .../api/logging/SystemOutWriter.java | 10 ++ .../api/logging/ThrowableFormatter.java | 23 --- .../skywalking/api/logging/WriterFactory.java | 8 +- ...ct.java => NoConcurrencyAceessObject.java} | 19 +-- .../skywalking/api/conf/ConstantsTest.java | 14 -- .../conf/SnifferConfigInitializerTest.java | 21 +-- .../api/logging/EasyLoggerTest.java | 18 +- .../api/logging/FileWriterTest.java | 52 ++++++ ...iterTest.java => SystemOutWriterTest.java} | 19 +-- .../api/logging/ThrowableFormatterTest.java | 18 -- .../api/logging/WriterFactoryTest.java | 15 +- ...ava => NoConcurrencyAceessObjectTest.java} | 6 +- .../jedis/v2/JedisMethodInterceptor.java | 4 +- 26 files changed, 469 insertions(+), 368 deletions(-) create mode 100644 skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/logging/FileWriter.java create mode 100644 skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/logging/LogMessageHolder.java delete mode 100644 skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/logging/STDOutWriter.java delete mode 100644 skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/logging/SyncFileWriter.java create mode 100644 skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/logging/SystemOutWriter.java delete mode 100644 skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/logging/ThrowableFormatter.java rename skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/plugin/interceptor/assist/{NoCocurrencyAceessObject.java => NoConcurrencyAceessObject.java} (69%) delete mode 100644 skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/conf/ConstantsTest.java create mode 100644 skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/logging/FileWriterTest.java rename skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/logging/{STDOutWriterTest.java => SystemOutWriterTest.java} (59%) delete mode 100644 skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/logging/ThrowableFormatterTest.java rename skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/plugin/assist/{NoCocurrencyAceessObjectTest.java => NoConcurrencyAceessObjectTest.java} (86%) diff --git a/README.md b/README.md index f0d3abc5c..e1fde2118 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,8 @@ SkyWalking: Large-Scale Distributed Systems Tracing Infrastructure, also known D * Support popular rpc frameworks, such as [dubbo](https://github.com/alibaba/dubbo), [dubbox](https://github.com/dangdangdotcom/dubbox), [motan](https://github.com/weibocom/motan) etc., trigger email-alert when application occurs unexpected exception. * Auto-instrumentation mechenism, **no need to CHANGE any application source code**. * Easy to deploy, **even in product mode** (since 2.0) . No need of Hadoop, HBase, or Cassandra Cluster. -* Pure Java server implementation. provide gRPC (since 2.0) and HTTP (since 2.1) cross-platform spans collecting service. +* Pure Java server implementation. provide HTTP (since 2.1) cross-platform spans collecting service. +* High performance stream process. # Supported components diff --git a/skywalking-commons/skywalking-util/src/main/java/com/a/eye/skywalking/api/util/ConfigInitializer.java b/skywalking-commons/skywalking-util/src/main/java/com/a/eye/skywalking/api/util/ConfigInitializer.java index 7a079b81d..b7a14fb2c 100644 --- a/skywalking-commons/skywalking-util/src/main/java/com/a/eye/skywalking/api/util/ConfigInitializer.java +++ b/skywalking-commons/skywalking-util/src/main/java/com/a/eye/skywalking/api/util/ConfigInitializer.java @@ -19,20 +19,24 @@ public class ConfigInitializer { initNextLevel(properties, rootConfigType, new ConfigDesc()); } - private static void initNextLevel(Properties properties, Class recentConfigType, ConfigDesc parentDesc) throws IllegalArgumentException, IllegalAccessException { + private static void initNextLevel(Properties properties, Class recentConfigType, + ConfigDesc parentDesc) throws IllegalArgumentException, IllegalAccessException { for (Field field : recentConfigType.getFields()) { if (Modifier.isPublic(field.getModifiers()) && Modifier.isStatic(field.getModifiers())) { String configKey = (parentDesc + "." + field.getName()).toLowerCase(); String value = properties.getProperty(configKey); if (value != null) { - if (field.getType().equals(int.class)) + Class type = field.getType(); + if (type.equals(int.class)) field.set(null, Integer.valueOf(value)); - if (field.getType().equals(String.class)) + else if (type.equals(String.class)) field.set(null, value); - if (field.getType().equals(long.class)) + else if (type.equals(long.class)) field.set(null, Long.valueOf(value)); - if (field.getType().equals(boolean.class)) + else if (type.equals(boolean.class)) field.set(null, Boolean.valueOf(value)); + else if (type.isEnum()) + field.set(null, Enum.valueOf((Class)type, value.toUpperCase())); } } } @@ -44,7 +48,6 @@ public class ConfigInitializer { } } - class ConfigDesc { private LinkedList descs = new LinkedList(); diff --git a/skywalking-sniffer/skywalking-agent/src/main/java/com/a/eye/skywalking/agent/SkyWalkingAgent.java b/skywalking-sniffer/skywalking-agent/src/main/java/com/a/eye/skywalking/agent/SkyWalkingAgent.java index d2f2a659c..5d9508345 100644 --- a/skywalking-sniffer/skywalking-agent/src/main/java/com/a/eye/skywalking/agent/SkyWalkingAgent.java +++ b/skywalking-sniffer/skywalking-agent/src/main/java/com/a/eye/skywalking/agent/SkyWalkingAgent.java @@ -2,16 +2,15 @@ package com.a.eye.skywalking.agent; import com.a.eye.skywalking.agent.junction.SkyWalkingEnhanceMatcher; import com.a.eye.skywalking.api.boot.ServiceManager; -import com.a.eye.skywalking.api.conf.Config; import com.a.eye.skywalking.api.conf.SnifferConfigInitializer; import com.a.eye.skywalking.api.logging.EasyLogResolver; import com.a.eye.skywalking.api.plugin.AbstractClassEnhancePluginDefine; import com.a.eye.skywalking.api.plugin.PluginBootstrap; -import com.a.eye.skywalking.api.plugin.PluginFinder; import com.a.eye.skywalking.api.plugin.PluginException; - +import com.a.eye.skywalking.api.plugin.PluginFinder; import com.a.eye.skywalking.logging.ILog; import com.a.eye.skywalking.logging.LogManager; +import java.lang.instrument.Instrumentation; import net.bytebuddy.agent.builder.AgentBuilder; import net.bytebuddy.description.NamedElement; import net.bytebuddy.description.type.TypeDescription; @@ -19,10 +18,6 @@ import net.bytebuddy.dynamic.DynamicType; import net.bytebuddy.matcher.ElementMatcher; import net.bytebuddy.utility.JavaModule; -import java.io.File; -import java.lang.instrument.Instrumentation; -import java.net.URL; - import static net.bytebuddy.matcher.ElementMatchers.isInterface; import static net.bytebuddy.matcher.ElementMatchers.not; @@ -50,7 +45,7 @@ public class SkyWalkingAgent { public static void premain(String agentArgs, Instrumentation instrumentation) throws PluginException { logger = LogManager.getLogger(SkyWalkingAgent.class); - initConfig(); + SnifferConfigInitializer.initialize(); final PluginFinder pluginFinder = new PluginFinder(new PluginBootstrap().loadPlugins()); @@ -92,33 +87,4 @@ public class SkyWalkingAgent { private static ElementMatcher.Junction enhanceClassMatcher(PluginFinder pluginFinder) { return new SkyWalkingEnhanceMatcher(pluginFinder); } - - private static String generateLocationPath() { - return SkyWalkingAgent.class.getName().replaceAll("\\.", "/") + ".class"; - } - - - private static void initConfig() { - Config.Agent.IS_PREMAIN_MODE = true; - Config.Agent.PATH = initAgentBasePath(); - - SnifferConfigInitializer.initialize(); - } - - /** - * Try to allocate the skywalking-agent.jar - * Some config files or output resources are from this path. - * - * @return the path, where the skywalking-agent.jar is. - */ - private static String initAgentBasePath() { - try { - String urlString = SkyWalkingAgent.class.getClassLoader().getSystemClassLoader().getResource(generateLocationPath()).toString(); - urlString = urlString.substring(urlString.indexOf("file:"), urlString.indexOf('!')); - return new File(new URL(urlString).getFile()).getParentFile().getAbsolutePath(); - } catch (Exception e) { - logger.error("Failed to init config .", e); - return ""; - } - } } diff --git a/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/conf/Config.java b/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/conf/Config.java index 1c2cd1022..c71fc0336 100644 --- a/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/conf/Config.java +++ b/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/conf/Config.java @@ -1,18 +1,16 @@ package com.a.eye.skywalking.api.conf; +import com.a.eye.skywalking.api.logging.LogLevel; + public class Config { public static class Agent { public static String APPLICATION_CODE = ""; - public static boolean IS_PREMAIN_MODE = false; - - public static String PATH = ""; - public static int SAMPLING_CYCLE = 1; } - public static class Collector{ + public static class Collector { public static String SERVERS = ""; public static String SERVICE_NAME = "/segments"; @@ -24,15 +22,14 @@ public class Config { public static int SIZE = 512; } - public static class Logging { // log文件名 - public static String LOG_FILE_NAME = "skywalking-api.log"; + public static String FILE_NAME = "skywalking-api.log"; // log文件文件夹名字 - public static String LOG_DIR_NAME = "logs"; + public static String DIR = ""; // 最大文件大小 - public static int MAX_LOG_FILE_LENGTH = 300 * 1024 * 1024; - // skywalking 系统错误文件日志 - public static String SYSTEM_ERROR_LOG_FILE_NAME = "skywalking-api-error.log"; + public static int MAX_FILE_SIZE = 300 * 1024 * 1024; + + public static LogLevel LEVEL = LogLevel.DEBUG; } } diff --git a/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/conf/Constants.java b/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/conf/Constants.java index dbbe904d5..23fd19cc4 100644 --- a/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/conf/Constants.java +++ b/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/conf/Constants.java @@ -1,11 +1,7 @@ package com.a.eye.skywalking.api.conf; -import com.a.eye.skywalking.trace.GlobalIdGenerator; - public class Constants { - /** - * This is the version, which will be the first segment of traceid. - * Ref {@link GlobalIdGenerator#generate()} - */ - public final static String SDK_VERSION = "302017"; + public static String PATH_SEPARATOR = System.getProperty("file.separator", "/"); + + public static String LINE_SEPARATOR = System.getProperty("line.separator", "\n"); } diff --git a/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/conf/SnifferConfigInitializer.java b/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/conf/SnifferConfigInitializer.java index 9c9fd2f17..fc7c6512c 100644 --- a/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/conf/SnifferConfigInitializer.java +++ b/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/conf/SnifferConfigInitializer.java @@ -7,29 +7,59 @@ import com.a.eye.skywalking.api.util.StringUtil; import java.io.File; import java.io.FileInputStream; +import java.io.FileNotFoundException; import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; import java.util.Properties; +/** + * The SnifferConfigInitializer initializes all configs in several way. + * + * @author wusheng + * @see {@link #initialize()}, to learn more about how to initialzie. + */ public class SnifferConfigInitializer { private static ILog logger = LogManager.getLogger(SnifferConfigInitializer.class); + private static String CONFIG_FILE_NAME = "/sky-walking.config"; + /** + * Try to locate config file, named {@link #CONFIG_FILE_NAME}, in following order: + * 1. Path from SystemProperty. {@link #loadConfigBySystemProperty()} + * 2. class path. + * 3. Path, where agent is. {@link #loadConfigFromAgentFolder()} + * + * If no found in any path, agent is still going to run in default config, {@link Config}, + * but in initialization steps, these following configs must be set, by config file or system properties: + * + * 1. applicationCode. "-DapplicationCode=" or {@link Config.Agent#APPLICATION_CODE} + * 2. servers. "-Dservers=" or {@link Config.Collector#SERVERS} + */ public static void initialize() { InputStream configFileStream; - if (Config.Agent.IS_PREMAIN_MODE) { - configFileStream = fetchAuthFileInputStream(); - } else { - configFileStream = SnifferConfigInitializer.class.getResourceAsStream("/sky-walking.config"); + + configFileStream = loadConfigBySystemProperty(); + + if (configFileStream == null) { + configFileStream = SnifferConfigInitializer.class.getResourceAsStream(CONFIG_FILE_NAME); + + if (configFileStream == null) { + logger.info("No {} file found in class path.", CONFIG_FILE_NAME); + configFileStream = loadConfigFromAgentFolder(); + }else{ + logger.info("{} file found in class path.", CONFIG_FILE_NAME); + } } if (configFileStream == null) { - logger.info("Not provide sky-walking certification documents, sky-walking api run in default config."); + logger.info("No {} found, sky-walking is going to run in default config.", CONFIG_FILE_NAME); } else { try { Properties properties = new Properties(); properties.load(configFileStream); ConfigInitializer.initialize(properties, Config.class); } catch (Exception e) { - logger.error("Failed to read the config file, sky-walking api run in default config.", e); + logger.error("Failed to read the config file, sky-walking is going to run in default config.", e); } } @@ -38,7 +68,7 @@ public class SnifferConfigInitializer { Config.Agent.APPLICATION_CODE = applicationCode; } String servers = System.getProperty("servers"); - if(!StringUtil.isEmpty(servers)) { + if (!StringUtil.isEmpty(servers)) { Config.Collector.SERVERS = servers; } @@ -50,12 +80,78 @@ public class SnifferConfigInitializer { } } - private static InputStream fetchAuthFileInputStream() { - try { - return new FileInputStream(Config.Agent.PATH + File.separator + "sky-walking.config"); - } catch (Exception e) { - logger.warn("sky-walking.config is missing, use default config."); + /** + * Load the config file by the path, which is provided by system property, usually with a "-DconfigPath=" arg. + * + * @return the config file {@link InputStream}, or null if not exist. + */ + private static InputStream loadConfigBySystemProperty() { + String configPath = System.getProperty("configPath"); + if (StringUtil.isEmpty(configPath)) { return null; } + File configFile = new File(configPath, CONFIG_FILE_NAME); + if (configFile.exists() && configFile.isFile()) { + try { + logger.info("{} found in path {}, according system property.", CONFIG_FILE_NAME, configPath); + return new FileInputStream(configFile); + } catch (FileNotFoundException e) { + logger.error(e, "Fail to load {} in path {}, according system property.", CONFIG_FILE_NAME, configPath); + } + } + + logger.info("No {} found in path {}, according system property.", CONFIG_FILE_NAME, configPath); + return null; + } + + /** + * Load the config file, where the agent jar is. + * + * @return the config file {@link InputStream}, or null if not exist. + */ + private static InputStream loadConfigFromAgentFolder() { + String agentBasePath = initAgentBasePath(); + if (!StringUtil.isEmpty(agentBasePath)) { + File configFile = new File(agentBasePath, CONFIG_FILE_NAME); + if (configFile.exists() && configFile.isFile()) { + try { + logger.info("{} file found in agent folder.", CONFIG_FILE_NAME); + return new FileInputStream(configFile); + } catch (FileNotFoundException e) { + logger.error(e, "Fail to load {} in path {}, according auto-agent-folder mechanism.", CONFIG_FILE_NAME, agentBasePath); + } + } + } + + logger.info("No {} file found in agent folder.", CONFIG_FILE_NAME); + return null; + } + + /** + * Try to allocate the skywalking-agent.jar + * Some config files or output resources are from this path. + * + * @return he path, where the skywalking-agent.jar is + */ + private static String initAgentBasePath() { + String classResourcePath = SnifferConfigInitializer.class.getName().replaceAll("\\.", "/") + ".class"; + + URL resource = SnifferConfigInitializer.class.getClassLoader().getSystemClassLoader().getResource(classResourcePath); + if (resource != null) { + String urlString = resource.toString(); + urlString = urlString.substring(urlString.indexOf("file:"), urlString.indexOf('!')); + File agentJarFile = null; + try { + agentJarFile = new File(new URL(urlString).getFile()); + } catch (MalformedURLException e) { + logger.error(e, "Can not locate agent jar file by url:", urlString); + } + if (agentJarFile.exists()) { + return agentJarFile.getParentFile().getAbsolutePath(); + } + } + + logger.info("Can not locate agent jar file."); + return null; } } diff --git a/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/logging/EasyLogger.java b/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/logging/EasyLogger.java index 200c255e3..a519db621 100644 --- a/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/logging/EasyLogger.java +++ b/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/logging/EasyLogger.java @@ -1,46 +1,38 @@ package com.a.eye.skywalking.api.logging; - +import com.a.eye.skywalking.api.conf.Constants; +import com.a.eye.skywalking.api.util.StringUtil; import com.a.eye.skywalking.logging.ILog; +import java.io.ByteArrayOutputStream; +import java.io.IOException; import java.net.URLEncoder; import java.text.SimpleDateFormat; import java.util.Date; +import static com.a.eye.skywalking.api.conf.Config.Logging.LEVEL; import static com.a.eye.skywalking.api.logging.LogLevel.*; /** - * Created by xin on 16-6-23. + * The EasyLogger is a simple implementation of {@link ILog}. + * + * @author wusheng */ public class EasyLogger implements ILog { - private Class toBeLoggerClass; + private Class targetClass; - public EasyLogger(Class toBeLoggerClass) { - this.toBeLoggerClass = toBeLoggerClass; + public EasyLogger(Class targetClass) { + this.targetClass = targetClass; } - public void logger(LogLevel level, String message, Throwable e) { - Throwable dummyException = new Throwable(); - StackTraceElement locations[] = dummyException.getStackTrace(); - - if (locations != null && locations.length > 2) { - if (ERROR.equals(level) || WARN.equals(level)) { - WriterFactory.getLogWriter().writeError(formatMessage(level, message, locations[2])); - } else { - WriterFactory.getLogWriter().write(formatMessage(level, message, locations[2])); - } - } - - if (e != null) { - WriterFactory.getLogWriter().writeError(ThrowableFormatter.format(e)); - } + private void logger(LogLevel level, String message, Throwable e) { + WriterFactory.getLogWriter().write(format(level, message, e)); } - private String replaceParam(String message, Object... parameters) { int startSize = 0; int parametersIndex = 0; - int index = -1; + int index; String tmpMessage = message; while ((index = message.indexOf("{}", startSize)) != -1) { if (parametersIndex >= parameters.length) { @@ -53,69 +45,97 @@ public class EasyLogger implements ILog { return tmpMessage; } + String format(LogLevel level, String message, Throwable t) { + return StringUtil.join(' ', level.name(), + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()), + targetClass.getSimpleName(), + ": ", + message, + t == null ? "" : format(t) + ); + } - private String formatMessage(LogLevel level, String message, StackTraceElement caller) { - return level + " " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + " " - + caller.getClassName() + "." + caller.getMethodName() + "(" + caller.getFileName() + ":" + caller.getLineNumber() + ") " + message; + String format(Throwable t) { + ByteArrayOutputStream buf = new ByteArrayOutputStream(); + t.printStackTrace(new java.io.PrintWriter(buf, true)); + String expMessage = buf.toString(); + try { + buf.close(); + } catch (IOException e) { + e.printStackTrace(); + } + + return Constants.LINE_SEPARATOR + expMessage; } @Override public void info(String format) { - logger(INFO, format, null); + if (isInfoEnable()) + logger(INFO, format, null); } @Override public void info(String format, Object... arguments) { - logger(INFO, replaceParam(format, arguments), null); + if (isInfoEnable()) + logger(INFO, replaceParam(format, arguments), null); } @Override public void warn(String format, Object... arguments) { - logger(WARN, replaceParam(format, arguments), null); + if (isWarnEnable()) + logger(WARN, replaceParam(format, arguments), null); } @Override public void error(String format, Throwable e) { - logger(ERROR, format, e); + if (isErrorEnable()) + logger(ERROR, format, e); } @Override public void error(Throwable e, String format, Object... arguments) { - logger(ERROR, replaceParam(format, arguments), e); + if (isErrorEnable()) + logger(ERROR, replaceParam(format, arguments), e); } @Override public boolean isDebugEnable() { - return true; + return DEBUG.compareTo(LEVEL) >= 0; } @Override public boolean isInfoEnable() { - return true; + return INFO.compareTo(LEVEL) >= 0; } @Override public boolean isWarnEnable() { - return true; + return WARN.compareTo(LEVEL) >= 0; } @Override public boolean isErrorEnable() { - return true; + return ERROR.compareTo(LEVEL) >= 0; } @Override public void debug(String format) { - logger(DEBUG, format, null); + if (isDebugEnable()) { + logger(DEBUG, format, null); + } } @Override public void debug(String format, Object... arguments) { - logger(DEBUG, replaceParam(format, arguments), null); + if (isDebugEnable()) { + logger(DEBUG, replaceParam(format, arguments), null); + } } @Override public void error(String format) { - logger(ERROR, format, null); + if (isErrorEnable()) { + logger(ERROR, format, null); + } } } diff --git a/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/logging/FileWriter.java b/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/logging/FileWriter.java new file mode 100644 index 000000000..74f64698f --- /dev/null +++ b/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/logging/FileWriter.java @@ -0,0 +1,156 @@ +package com.a.eye.skywalking.api.logging; + +import com.a.eye.skywalking.api.conf.Config; +import com.a.eye.skywalking.api.conf.Constants; +import com.lmax.disruptor.EventFactory; +import com.lmax.disruptor.EventHandler; +import com.lmax.disruptor.RingBuffer; +import com.lmax.disruptor.dsl.Disruptor; +import com.lmax.disruptor.util.DaemonThreadFactory; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.concurrent.Callable; + +/** + * The FileWriter support async file output, by using a queue as buffer. + * + * @author wusheng + */ +public class FileWriter implements IWriter, EventHandler { + private static FileWriter instance; + private static Object createLock = new Object(); + private Disruptor disruptor; + private RingBuffer buffer; + private FileOutputStream fileOutputStream; + private volatile boolean started = false; + private volatile int fileSize; + private volatile int lineNum; + + public static FileWriter get() { + if (instance == null) { + synchronized (createLock) { + if (instance == null) { + instance = new FileWriter(); + } + } + } + return instance; + } + + private FileWriter() { + disruptor = new Disruptor(new EventFactory() { + @Override + public LogMessageHolder newInstance() { + return new LogMessageHolder(); + } + }, 1024, DaemonThreadFactory.INSTANCE); + disruptor.handleEventsWith(this); + buffer = disruptor.getRingBuffer(); + lineNum = 0; + disruptor.start(); + } + + @Override + public void onEvent(LogMessageHolder event, long sequence, boolean endOfBatch) throws Exception { + if (hasWriteStream()) { + try { + lineNum++; + write(event.getMessage() + Constants.LINE_SEPARATOR, endOfBatch); + } finally { + event.setMessage(null); + } + } + } + + private void write(String message, boolean forceFlush) { + try { + fileOutputStream.write(message.getBytes()); + fileSize += message.length(); + if (forceFlush || lineNum % 20 == 0) { + fileOutputStream.flush(); + } + } catch (IOException e) { + e.printStackTrace(); + } finally { + switchFile(); + } + } + + private void switchFile() { + if (fileSize > Config.Logging.MAX_FILE_SIZE) { + forceExecute(new Callable() { + @Override public Object call() throws Exception { + fileOutputStream.flush(); + return null; + } + }); + forceExecute(new Callable() { + @Override public Object call() throws Exception { + fileOutputStream.close(); + return null; + } + }); + forceExecute(new Callable() { + @Override public Object call() throws Exception { + new File(Config.Logging.DIR, Config.Logging.FILE_NAME) + .renameTo(new File(Config.Logging.DIR, + Config.Logging.FILE_NAME + new SimpleDateFormat(".yyyy_MM_dd_HH_mm_ss").format(new Date()))); + return null; + } + }); + forceExecute(new Callable() { + @Override public Object call() throws Exception { + fileOutputStream = null; + started = false; + return null; + } + }); + } + } + + private void forceExecute(Callable callable) { + try { + callable.call(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + private boolean hasWriteStream() { + if (fileOutputStream != null) { + return true; + } + if (!started) { + File logFilePath = new File(Config.Logging.DIR); + if (!logFilePath.exists()) { + logFilePath.mkdirs(); + } else if (!logFilePath.isDirectory()) { + System.err.println("Log dir(" + Config.Logging.DIR + ") is not a directory."); + } + try { + fileOutputStream = new FileOutputStream(new File(logFilePath, Config.Logging.FILE_NAME), true); + fileSize = Long.valueOf(new File(logFilePath, Config.Logging.FILE_NAME).length()).intValue(); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + started = true; + } + + return fileOutputStream != null; + } + + @Override + public void write(String message) { + long next = buffer.next(); + try { + LogMessageHolder messageHolder = buffer.get(next); + messageHolder.setMessage(message); + } finally { + buffer.publish(next); + } + } +} diff --git a/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/logging/IWriter.java b/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/logging/IWriter.java index 4bbf17116..3098c9f39 100644 --- a/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/logging/IWriter.java +++ b/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/logging/IWriter.java @@ -2,6 +2,4 @@ package com.a.eye.skywalking.api.logging; public interface IWriter { void write(String message); - - void writeError(String message); } diff --git a/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/logging/LogLevel.java b/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/logging/LogLevel.java index feb602e31..0579022b2 100644 --- a/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/logging/LogLevel.java +++ b/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/logging/LogLevel.java @@ -3,6 +3,6 @@ package com.a.eye.skywalking.api.logging; /** * Created by xin on 2016/12/7. */ -public enum LogLevel { - INFO, DEBUG, WARN, ERROR +public enum LogLevel{ + DEBUG, INFO, WARN, ERROR; } diff --git a/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/logging/LogMessageHolder.java b/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/logging/LogMessageHolder.java new file mode 100644 index 000000000..37d4e273e --- /dev/null +++ b/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/logging/LogMessageHolder.java @@ -0,0 +1,19 @@ +package com.a.eye.skywalking.api.logging; + +/** + * The LogMessageHolder is a {@link String} holder, + * in order to in-process propagation String across the disruptor queue. + * + * @author wusheng + */ +public class LogMessageHolder { + private String message; + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} diff --git a/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/logging/STDOutWriter.java b/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/logging/STDOutWriter.java deleted file mode 100644 index 58fbeaef0..000000000 --- a/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/logging/STDOutWriter.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.a.eye.skywalking.api.logging; - -public class STDOutWriter implements IWriter { - - - @Override - public void write(String message) { - System.out.println(message); - } - - @Override - public void writeError(String message) { - System.err.println(message); - } -} diff --git a/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/logging/SyncFileWriter.java b/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/logging/SyncFileWriter.java deleted file mode 100644 index 72b305f2b..000000000 --- a/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/logging/SyncFileWriter.java +++ /dev/null @@ -1,113 +0,0 @@ -package com.a.eye.skywalking.api.logging; - - - -import com.a.eye.skywalking.api.conf.Config; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.text.SimpleDateFormat; -import java.util.Date; - -public class SyncFileWriter implements IWriter { - - private static SyncFileWriter writer; - private FileOutputStream os; - private int bufferSize; - private static final Object lock = new Object(); - - private SyncFileWriter() { - try { - File logFilePath = new File(Config.Agent.PATH, Config.Logging.LOG_DIR_NAME); - if (!logFilePath.exists()) { - logFilePath.mkdirs(); - } - os = new FileOutputStream(new File(logFilePath, Config.Logging.LOG_FILE_NAME), true); - bufferSize = Long.valueOf(new File(logFilePath, Config.Logging.LOG_FILE_NAME).length()).intValue(); - } catch (IOException e) { - writeErrorLog(e); - } - } - - - public static IWriter instance() { - if (writer == null) { - writer = new SyncFileWriter(); - } - return writer; - } - - - public void write(String message) { - writeLogRecord(message); - switchLogFileIfNecessary(); - } - - @Override - public void writeError(String message) { - this.write(message); - } - - private void writeLogRecord(String message) { - try { - os.write(message.getBytes()); - os.write("\n".getBytes()); - bufferSize += message.length(); - } catch (IOException e) { - writeErrorLog(e); - } - } - - private void switchLogFileIfNecessary() { - if (bufferSize > Config.Logging.MAX_LOG_FILE_LENGTH) { - synchronized (lock) { - if (bufferSize > Config.Logging.MAX_LOG_FILE_LENGTH) { - try { - closeInputStream(); - renameLogFile(); - revertInputStream(); - } catch (IOException e) { - writeErrorLog(e); - } - bufferSize = 0; - } - } - } - } - - private void revertInputStream() throws FileNotFoundException { - os = new FileOutputStream(new File(Config.Logging.LOG_DIR_NAME, Config.Logging.LOG_FILE_NAME), true); - } - - private void renameLogFile() { - new File(Config.Logging.LOG_DIR_NAME, Config.Logging.LOG_FILE_NAME) - .renameTo(new File(Config.Logging.LOG_DIR_NAME, Config.Logging.LOG_FILE_NAME + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()))); - } - - private void closeInputStream() throws IOException { - this.os.flush(); - this.os.close(); - } - - - private void writeErrorLog(Throwable e) { - FileOutputStream fileOutputStream = null; - try { - File file = new File(Config.Logging.LOG_DIR_NAME, Config.Logging.SYSTEM_ERROR_LOG_FILE_NAME); - fileOutputStream = new FileOutputStream(file, true); - fileOutputStream.write(("Failed to init sync File Writer.\n" + ThrowableFormatter.format(e)).getBytes()); - } catch (Exception e1) { - System.err.print(ThrowableFormatter.format(e1)); - } finally { - if (fileOutputStream != null) { - try { - fileOutputStream.close(); - } catch (IOException e1) { - System.err.print(ThrowableFormatter.format(e1)); - } - } - } - } - -} diff --git a/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/logging/SystemOutWriter.java b/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/logging/SystemOutWriter.java new file mode 100644 index 000000000..c4b1458f1 --- /dev/null +++ b/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/logging/SystemOutWriter.java @@ -0,0 +1,10 @@ +package com.a.eye.skywalking.api.logging; + +public enum SystemOutWriter implements IWriter { + INSTANCE; + + @Override + public void write(String message) { + System.out.println(message); + } +} diff --git a/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/logging/ThrowableFormatter.java b/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/logging/ThrowableFormatter.java deleted file mode 100644 index 429e63d49..000000000 --- a/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/logging/ThrowableFormatter.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.a.eye.skywalking.api.logging; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; - -/** - * Created by xin on 16-6-24. - */ -public class ThrowableFormatter { - public static String format(Throwable e) { - ByteArrayOutputStream buf = new ByteArrayOutputStream(); - e.printStackTrace(new java.io.PrintWriter(buf, true)); - String expMessage = buf.toString(); - try { - buf.close(); - } catch (IOException e1) { - System.err.println("Failed to close throwable stack stream."); - e.printStackTrace(); - } - - return expMessage; - } -} diff --git a/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/logging/WriterFactory.java b/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/logging/WriterFactory.java index 6e5bd4230..ef6003d58 100644 --- a/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/logging/WriterFactory.java +++ b/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/logging/WriterFactory.java @@ -1,14 +1,14 @@ package com.a.eye.skywalking.api.logging; import com.a.eye.skywalking.api.conf.Config; +import com.a.eye.skywalking.api.util.StringUtil; public class WriterFactory { public static IWriter getLogWriter(){ - if (Config.Agent.IS_PREMAIN_MODE){ - return SyncFileWriter.instance(); + if (!StringUtil.isEmpty(Config.Logging.DIR)){ + return FileWriter.get(); }else{ - return new STDOutWriter(); + return SystemOutWriter.INSTANCE; } - } } diff --git a/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/plugin/interceptor/assist/NoCocurrencyAceessObject.java b/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/plugin/interceptor/assist/NoConcurrencyAceessObject.java similarity index 69% rename from skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/plugin/interceptor/assist/NoCocurrencyAceessObject.java rename to skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/plugin/interceptor/assist/NoConcurrencyAceessObject.java index 4f69939e2..ce326faef 100644 --- a/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/plugin/interceptor/assist/NoCocurrencyAceessObject.java +++ b/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/plugin/interceptor/assist/NoConcurrencyAceessObject.java @@ -2,10 +2,9 @@ package com.a.eye.skywalking.api.plugin.interceptor.assist; import com.a.eye.skywalking.api.plugin.interceptor.EnhancedClassInstanceContext; import com.a.eye.skywalking.api.plugin.interceptor.InterceptorException; -import com.a.eye.skywalking.api.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; /** - * {@link NoCocurrencyAceessObject} is method invocation counter, + * {@link NoConcurrencyAceessObject} is method invocation counter, * when {@link #whenEnter(EnhancedClassInstanceContext, Runnable)}, counter + 1; * and when {@link #whenExist(EnhancedClassInstanceContext, Runnable)}, counter -1; * @@ -13,22 +12,16 @@ import com.a.eye.skywalking.api.plugin.interceptor.enhance.InstanceMethodsAround * * @author wusheng */ -public class NoCocurrencyAceessObject { - protected String invokeCounterKey = "__$invokeCounterKey"; - - protected Object invokeCounterInstLock = new Object(); +public class NoConcurrencyAceessObject { + private static String invokeCounterKey = "__$invokeCounterKey"; public void whenEnter(EnhancedClassInstanceContext context, Runnable runnable) { if (!context.isContain(invokeCounterKey)) { - synchronized (invokeCounterInstLock) { - if (!context.isContain(invokeCounterKey)) { - context.set(invokeCounterKey, 0); - } - } + context.set(invokeCounterKey, 0); } int counter = context.get(invokeCounterKey, Integer.class); - if(++counter == 1){ + if (++counter == 1) { runnable.run(); } context.set(invokeCounterKey, counter); @@ -41,7 +34,7 @@ public class NoCocurrencyAceessObject { } int counter = context.get(invokeCounterKey, Integer.class); - if(--counter == 0){ + if (--counter == 0) { runnable.run(); } context.set(invokeCounterKey, counter); diff --git a/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/conf/ConstantsTest.java b/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/conf/ConstantsTest.java deleted file mode 100644 index 8f9f7f314..000000000 --- a/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/conf/ConstantsTest.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.a.eye.skywalking.api.conf; - -import org.junit.Assert; -import org.junit.Test; - -/** - * Created by wusheng on 2017/2/28. - */ -public class ConstantsTest { - @Test - public void testSDKVersion(){ - Assert.assertEquals("302017", Constants.SDK_VERSION); - } -} diff --git a/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/conf/SnifferConfigInitializerTest.java b/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/conf/SnifferConfigInitializerTest.java index befd85f85..8f1727cfe 100644 --- a/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/conf/SnifferConfigInitializerTest.java +++ b/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/conf/SnifferConfigInitializerTest.java @@ -1,6 +1,5 @@ package com.a.eye.skywalking.api.conf; -import org.junit.AfterClass; import org.junit.Assert; import org.junit.Test; @@ -11,27 +10,15 @@ public class SnifferConfigInitializerTest { @Test public void testInitialize(){ - Config.Agent.IS_PREMAIN_MODE = false; SnifferConfigInitializer.initialize(); Assert.assertEquals("crmApp", Config.Agent.APPLICATION_CODE); Assert.assertEquals("127.0.0.1:8080", Config.Collector.SERVERS); Assert.assertNotNull(Config.Buffer.SIZE); - Assert.assertNotNull(Config.Logging.LOG_DIR_NAME); - Assert.assertNotNull(Config.Logging.LOG_FILE_NAME); - Assert.assertNotNull(Config.Logging.MAX_LOG_FILE_LENGTH); - Assert.assertNotNull(Config.Logging.SYSTEM_ERROR_LOG_FILE_NAME); - } - - @Test(expected = ExceptionInInitializerError.class) - public void testErrorInitialize(){ - Config.Agent.IS_PREMAIN_MODE = true; - SnifferConfigInitializer.initialize(); - } - - @AfterClass - public static void reset(){ - Config.Agent.IS_PREMAIN_MODE = false; + Assert.assertNotNull(Config.Logging.DIR); + Assert.assertNotNull(Config.Logging.FILE_NAME); + Assert.assertNotNull(Config.Logging.MAX_FILE_SIZE); + Assert.assertNotNull(Config.Logging.FILE_NAME); } } diff --git a/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/logging/EasyLoggerTest.java b/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/logging/EasyLoggerTest.java index 854798abc..f65097292 100644 --- a/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/logging/EasyLoggerTest.java +++ b/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/logging/EasyLoggerTest.java @@ -1,6 +1,6 @@ package com.a.eye.skywalking.api.logging; -import com.a.eye.skywalking.api.conf.Config; +import com.a.eye.skywalking.api.conf.Constants; import java.io.PrintStream; import org.junit.AfterClass; import org.junit.Assert; @@ -26,8 +26,6 @@ public class EasyLoggerTest { @Test public void testLog(){ - Config.Agent.IS_PREMAIN_MODE = false; - PrintStream output = Mockito.mock(PrintStream.class); System.setOut(output); PrintStream err = Mockito.mock(PrintStream.class); @@ -50,12 +48,20 @@ public class EasyLoggerTest { logger.error("hello world", new NullPointerException()); logger.error(new NullPointerException(),"hello {}", "world"); - Mockito.verify(output,times(4)) - .println(anyString()); - Mockito.verify(err,times(7)) + Mockito.verify(output,times(9)) .println(anyString()); } + @Test + public void testFormat() { + NullPointerException exception = new NullPointerException(); + EasyLogger logger = new EasyLogger(EasyLoggerTest.class); + String formatLines = logger.format(exception); + String[] lines = formatLines.split(Constants.LINE_SEPARATOR); + Assert.assertEquals("java.lang.NullPointerException", lines[1]); + Assert.assertEquals("\tat com.a.eye.skywalking.api.logging.EasyLoggerTest.testFormat(EasyLoggerTest.java:57)", lines[2]); + } + @AfterClass public static void reset(){ System.setOut(outRef); diff --git a/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/logging/FileWriterTest.java b/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/logging/FileWriterTest.java new file mode 100644 index 000000000..af30a6abb --- /dev/null +++ b/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/logging/FileWriterTest.java @@ -0,0 +1,52 @@ +package com.a.eye.skywalking.api.logging; + +import com.a.eye.skywalking.api.conf.Config; +import com.a.eye.skywalking.api.conf.Constants; +import java.io.File; +import java.io.IOException; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +/** + * @author wusheng + */ +public class FileWriterTest { + + @BeforeClass + public static void beforeTestFile() throws IOException { + Config.Logging.MAX_FILE_SIZE = 10; + File directory = new File(""); + Config.Logging.DIR = directory.getCanonicalPath() + Constants.PATH_SEPARATOR + "/log-test/"; + } + + @Test + public void testWriteFile() throws InterruptedException { + FileWriter writer = FileWriter.get(); + for (int i = 0; i < 100; i++) { + writer.write("abcd"); + } + + Thread.sleep(10000L); + } + + @AfterClass + public static void clear() { + Config.Logging.MAX_FILE_SIZE = 300 * 1024 * 1024; + deleteDir(new File(Config.Logging.DIR)); + Config.Logging.DIR = ""; + } + + private static boolean deleteDir(File dir) { + if (dir.isDirectory()) { + String[] children = dir.list(); + for (int i = 0; i < children.length; i++) { + boolean success = deleteDir(new File(dir, children[i])); + if (!success) { + return false; + } + } + } + return dir.delete(); + } +} diff --git a/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/logging/STDOutWriterTest.java b/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/logging/SystemOutWriterTest.java similarity index 59% rename from skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/logging/STDOutWriterTest.java rename to skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/logging/SystemOutWriterTest.java index 31a5c2a54..c154ed3cb 100644 --- a/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/logging/STDOutWriterTest.java +++ b/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/logging/SystemOutWriterTest.java @@ -12,14 +12,12 @@ import static org.mockito.Mockito.times; /** * Created by wusheng on 2017/2/28. */ -public class STDOutWriterTest { +public class SystemOutWriterTest { private static PrintStream outRef; - private static PrintStream errRef; @BeforeClass public static void initAndHoldOut(){ outRef = System.out; - errRef = System.err; } @Test @@ -27,19 +25,7 @@ public class STDOutWriterTest { PrintStream mockStream = Mockito.mock(PrintStream.class); System.setOut(mockStream); - STDOutWriter writer = new STDOutWriter(); - writer.write("hello"); - - Mockito.verify(mockStream,times(1)).println(anyString()); - } - - @Test - public void testWriteError(){ - PrintStream mockStream = Mockito.mock(PrintStream.class); - System.setErr(mockStream); - - STDOutWriter writer = new STDOutWriter(); - writer.writeError("hello"); + SystemOutWriter.INSTANCE.write("hello"); Mockito.verify(mockStream,times(1)).println(anyString()); } @@ -47,6 +33,5 @@ public class STDOutWriterTest { @AfterClass public static void reset(){ System.setOut(outRef); - System.setErr(errRef); } } diff --git a/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/logging/ThrowableFormatterTest.java b/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/logging/ThrowableFormatterTest.java deleted file mode 100644 index f3c19f4bf..000000000 --- a/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/logging/ThrowableFormatterTest.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.a.eye.skywalking.api.logging; - -import org.junit.Assert; -import org.junit.Test; - -/** - * Created by wusheng on 2017/2/28. - */ -public class ThrowableFormatterTest { - @Test - public void testFormat() { - NullPointerException exception = new NullPointerException(); - String formatLines = ThrowableFormatter.format(exception); - String[] lines = formatLines.split(System.lineSeparator()); - Assert.assertEquals("java.lang.NullPointerException", lines[0]); - Assert.assertEquals("\tat com.a.eye.skywalking.api.logging.ThrowableFormatterTest.testFormat(ThrowableFormatterTest.java:12)", lines[1]); - } -} diff --git a/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/logging/WriterFactoryTest.java b/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/logging/WriterFactoryTest.java index d7adefd40..ea23a0cfd 100644 --- a/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/logging/WriterFactoryTest.java +++ b/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/logging/WriterFactoryTest.java @@ -15,7 +15,7 @@ public class WriterFactoryTest { private static PrintStream errRef; @BeforeClass - public static void initAndHoldOut(){ + public static void initAndHoldOut() { errRef = System.err; } @@ -24,19 +24,18 @@ public class WriterFactoryTest { * reset {@link System#out} to a Mock object, for avoid a console system.error. */ @Test - public void testGetLogWriter(){ - Config.Agent.IS_PREMAIN_MODE = true; + public void testGetLogWriter() { PrintStream mockStream = Mockito.mock(PrintStream.class); System.setErr(mockStream); - Assert.assertEquals(SyncFileWriter.instance(), WriterFactory.getLogWriter()); + Assert.assertEquals(SystemOutWriter.INSTANCE, WriterFactory.getLogWriter()); - Config.Agent.IS_PREMAIN_MODE = false; - Assert.assertTrue(WriterFactory.getLogWriter() instanceof STDOutWriter); + Config.Logging.DIR = "/only/test/folder"; + Assert.assertTrue(WriterFactory.getLogWriter() instanceof FileWriter); } @AfterClass - public static void reset(){ - Config.Agent.IS_PREMAIN_MODE = false; + public static void reset() { + Config.Logging.DIR = ""; System.setErr(errRef); } } diff --git a/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/plugin/assist/NoCocurrencyAceessObjectTest.java b/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/plugin/assist/NoConcurrencyAceessObjectTest.java similarity index 86% rename from skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/plugin/assist/NoCocurrencyAceessObjectTest.java rename to skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/plugin/assist/NoConcurrencyAceessObjectTest.java index bcf2304a8..c4eecd9d5 100644 --- a/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/plugin/assist/NoCocurrencyAceessObjectTest.java +++ b/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/plugin/assist/NoConcurrencyAceessObjectTest.java @@ -1,17 +1,17 @@ package com.a.eye.skywalking.api.plugin.assist; import com.a.eye.skywalking.api.plugin.interceptor.EnhancedClassInstanceContext; -import com.a.eye.skywalking.api.plugin.interceptor.assist.NoCocurrencyAceessObject; +import com.a.eye.skywalking.api.plugin.interceptor.assist.NoConcurrencyAceessObject; import org.junit.Assert; import org.junit.Test; /** * @author wusheng */ -public class NoCocurrencyAceessObjectTest { +public class NoConcurrencyAceessObjectTest { @Test public void testEntraExitCounter(){ - NoCocurrencyAceessObject object = new NoCocurrencyAceessObject(); + NoConcurrencyAceessObject object = new NoConcurrencyAceessObject(); final EnhancedClassInstanceContext context = new EnhancedClassInstanceContext(); object.whenEnter(context, new Runnable() { @Override diff --git a/skywalking-sniffer/skywalking-sdk-plugin/jedis-2.x-plugin/src/main/java/com/a/eye/skywalking/plugin/jedis/v2/JedisMethodInterceptor.java b/skywalking-sniffer/skywalking-sdk-plugin/jedis-2.x-plugin/src/main/java/com/a/eye/skywalking/plugin/jedis/v2/JedisMethodInterceptor.java index 914823ccf..2dc671c0f 100644 --- a/skywalking-sniffer/skywalking-sdk-plugin/jedis-2.x-plugin/src/main/java/com/a/eye/skywalking/plugin/jedis/v2/JedisMethodInterceptor.java +++ b/skywalking-sniffer/skywalking-sdk-plugin/jedis-2.x-plugin/src/main/java/com/a/eye/skywalking/plugin/jedis/v2/JedisMethodInterceptor.java @@ -2,7 +2,7 @@ package com.a.eye.skywalking.plugin.jedis.v2; import com.a.eye.skywalking.api.context.ContextManager; import com.a.eye.skywalking.api.plugin.interceptor.EnhancedClassInstanceContext; -import com.a.eye.skywalking.api.plugin.interceptor.assist.NoCocurrencyAceessObject; +import com.a.eye.skywalking.api.plugin.interceptor.assist.NoConcurrencyAceessObject; 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; @@ -17,7 +17,7 @@ import com.a.eye.skywalking.trace.tag.Tags; * * @author zhangxin */ -public class JedisMethodInterceptor extends NoCocurrencyAceessObject implements InstanceMethodsAroundInterceptor { +public class JedisMethodInterceptor extends NoConcurrencyAceessObject implements InstanceMethodsAroundInterceptor { /** * The key name that redis connection information in {@link EnhancedClassInstanceContext#context}. */ From f8b624c3cef78074eaf89779b89c55ba72252b30 Mon Sep 17 00:00:00 2001 From: wusheng Date: Thu, 23 Mar 2017 16:39:01 +0800 Subject: [PATCH 6/8] Add test case about enum config init. --- .../eye/skywalking/api/conf/SnifferConfigInitializerTest.java | 3 +++ .../skywalking-api/src/test/resources/sky-walking.config | 1 + 2 files changed, 4 insertions(+) diff --git a/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/conf/SnifferConfigInitializerTest.java b/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/conf/SnifferConfigInitializerTest.java index 8f1727cfe..da1bc5e01 100644 --- a/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/conf/SnifferConfigInitializerTest.java +++ b/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/conf/SnifferConfigInitializerTest.java @@ -3,6 +3,8 @@ package com.a.eye.skywalking.api.conf; import org.junit.Assert; import org.junit.Test; +import static com.a.eye.skywalking.api.logging.LogLevel.INFO; + /** * @author wusheng */ @@ -20,5 +22,6 @@ public class SnifferConfigInitializerTest { Assert.assertNotNull(Config.Logging.FILE_NAME); Assert.assertNotNull(Config.Logging.MAX_FILE_SIZE); Assert.assertNotNull(Config.Logging.FILE_NAME); + Assert.assertEquals(INFO, Config.Logging.LEVEL); } } diff --git a/skywalking-sniffer/skywalking-api/src/test/resources/sky-walking.config b/skywalking-sniffer/skywalking-api/src/test/resources/sky-walking.config index b563dfb11..5e9506e02 100644 --- a/skywalking-sniffer/skywalking-api/src/test/resources/sky-walking.config +++ b/skywalking-sniffer/skywalking-api/src/test/resources/sky-walking.config @@ -1,2 +1,3 @@ agent.application_code = crmApp collector.servers = 127.0.0.1:8080 +logging.level=info From dab1de8d22fbd47cc183aecb86ff722a8f1d2cd6 Mon Sep 17 00:00:00 2001 From: wusheng Date: Thu, 23 Mar 2017 16:57:22 +0800 Subject: [PATCH 7/8] Fix ci fail. --- .../skywalking/api/conf/SnifferConfigInitializerTest.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/conf/SnifferConfigInitializerTest.java b/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/conf/SnifferConfigInitializerTest.java index da1bc5e01..64ae18e7d 100644 --- a/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/conf/SnifferConfigInitializerTest.java +++ b/skywalking-sniffer/skywalking-api/src/test/java/com/a/eye/skywalking/api/conf/SnifferConfigInitializerTest.java @@ -1,9 +1,10 @@ package com.a.eye.skywalking.api.conf; +import org.junit.AfterClass; import org.junit.Assert; import org.junit.Test; -import static com.a.eye.skywalking.api.logging.LogLevel.INFO; +import static com.a.eye.skywalking.api.logging.LogLevel.*; /** * @author wusheng @@ -24,4 +25,9 @@ public class SnifferConfigInitializerTest { Assert.assertNotNull(Config.Logging.FILE_NAME); Assert.assertEquals(INFO, Config.Logging.LEVEL); } + + @AfterClass + public static void clear(){ + Config.Logging.LEVEL = DEBUG; + } } From c15706b46c402b4983f7ecca58d034f2c8de6487 Mon Sep 17 00:00:00 2001 From: wusheng Date: Thu, 23 Mar 2017 19:44:35 +0800 Subject: [PATCH 8/8] Add comments for sniffer Config. --- .../com/a/eye/skywalking/api/conf/Config.java | 55 ++++++++++++++++++- 1 file changed, 52 insertions(+), 3 deletions(-) diff --git a/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/conf/Config.java b/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/conf/Config.java index c71fc0336..96aaafa13 100644 --- a/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/conf/Config.java +++ b/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/api/conf/Config.java @@ -1,35 +1,84 @@ package com.a.eye.skywalking.api.conf; import com.a.eye.skywalking.api.logging.LogLevel; +import com.a.eye.skywalking.api.logging.WriterFactory; +/** + * This is the core config in sniffer agent. + * + * @author wusheng + */ public class Config { public static class Agent { + /** + * Application code is showed in sky-walking-ui. + * Suggestion: set a unique name for each application, one application's nodes share the same code. + */ public static String APPLICATION_CODE = ""; + /** + * One, means sampling OFF. + * Greater than one, select one trace in every N traces. + * Zero and negative number are illegal. + */ public static int SAMPLING_CYCLE = 1; } public static class Collector { + /** + * Collector REST-Service address. + * e.g. + * SERVERS="127.0.0.1:8080" for single collector node. + * SERVERS="10.2.45.126:8080,10.2.45.127:7600" for multi collector nodes. + */ public static String SERVERS = ""; + /** + * Collector receive segments REST-Service name. + */ public static String SERVICE_NAME = "/segments"; + /** + * The max size to send traces per rest-service call. + */ public static int BATCH_SIZE = 50; } public static class Buffer { + /** + * The in-memory buffer size. Based on Disruptor, this value must be 2^n. + * + * @see {https://github.com/LMAX-Exchange/disruptor} + */ public static int SIZE = 512; } public static class Logging { - // log文件名 + /** + * Log file name. + */ public static String FILE_NAME = "skywalking-api.log"; - // log文件文件夹名字 + + /** + * Log files directory. + * Default is blank string, means, use "system.out" to output logs. + * + * @see {@link WriterFactory#getLogWriter()} + */ public static String DIR = ""; - // 最大文件大小 + + /** + * The max size of log file. + * If the size is bigger than this, archive the current file, and write into a new file. + */ public static int MAX_FILE_SIZE = 300 * 1024 * 1024; + /** + * The log level. Default is debug. + * + * @see {@link LogLevel} + */ public static LogLevel LEVEL = LogLevel.DEBUG; } }