Browse Source

Set default log level of JDK logging to INFO and polish code of SpiLoader (#1365)

* Improve log info in SpiLoader, improve comment and test case
* Use error level in catch block, init ArrayList with capacity and improve add item to list
master
cdfive GitHub 4 years ago
parent
commit
e1435974c6
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 61 additions and 28 deletions
  1. +3
    -1
      sentinel-core/src/main/java/com/alibaba/csp/sentinel/log/jul/BaseJulLogger.java
  2. +1
    -1
      sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/DefaultSlotChainBuilder.java
  3. +34
    -20
      sentinel-core/src/main/java/com/alibaba/csp/sentinel/util/SpiLoader.java
  4. +23
    -6
      sentinel-core/src/test/java/com/alibaba/csp/sentinel/util/SpiLoaderTest.java

+ 3
- 1
sentinel-core/src/main/java/com/alibaba/csp/sentinel/log/jul/BaseJulLogger.java View File

@@ -90,7 +90,9 @@ public class BaseJulLogger {
if (handler != null) {
disableOtherHandlers(heliumRecordLog, handler);
}
heliumRecordLog.setLevel(Level.ALL);

// Set log level to INFO by default
heliumRecordLog.setLevel(Level.INFO);
return handler;
}



+ 1
- 1
sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/DefaultSlotChainBuilder.java View File

@@ -38,7 +38,7 @@ public class DefaultSlotChainBuilder implements SlotChainBuilder {
ProcessorSlotChain chain = new DefaultProcessorSlotChain();

// Note: the instances of ProcessorSlot should be different, since they are not stateless.
List<ProcessorSlot> sortedSlotList = SpiLoader.loadDifferentInstanceListSorted(ProcessorSlot.class);
List<ProcessorSlot> sortedSlotList = SpiLoader.loadPrototypeInstanceListSorted(ProcessorSlot.class);
for (ProcessorSlot slot : sortedSlotList) {
if (!(slot instanceof AbstractLinkedProcessorSlot)) {
RecordLog.warn("The ProcessorSlot(" + slot.getClass().getCanonicalName() + ") is not an instance of AbstractLinkedProcessorSlot, can't be added into ProcessorSlotChain");


+ 34
- 20
sentinel-core/src/main/java/com/alibaba/csp/sentinel/util/SpiLoader.java View File

@@ -34,6 +34,14 @@ public final class SpiLoader {

private static final Map<String, ServiceLoader> SERVICE_LOADER_MAP = new ConcurrentHashMap<String, ServiceLoader>();

/**
* Load the first-found specific SPI instance
*
* @param clazz class of the SPI interface
* @param <T> SPI type
* @return the first specific SPI instance if exists, or else return null
* @since 1.7.0
*/
public static <T> T loadFirstInstance(Class<T> clazz) {
AssertUtil.notNull(clazz, "SPI class cannot be null");
try {
@@ -52,7 +60,7 @@ public final class SpiLoader {
return null;
}
} catch (Throwable t) {
RecordLog.warn("[SpiLoader] ERROR: loadFirstInstance failed", t);
RecordLog.error("[SpiLoader] ERROR: loadFirstInstance failed", t);
t.printStackTrace();
return null;
}
@@ -87,7 +95,7 @@ public final class SpiLoader {
}
return defaultClass.newInstance();
} catch (Throwable t) {
RecordLog.warn("[SpiLoader] ERROR: loadFirstInstanceOrDefault failed", t);
RecordLog.error("[SpiLoader] ERROR: loadFirstInstanceOrDefault failed", t);
t.printStackTrace();
return null;
}
@@ -96,6 +104,8 @@ public final class SpiLoader {
/**
* Load the SPI instance with highest priority.
*
* Note: each call return same instances.
*
* @param clazz class of the SPI
* @param <T> SPI type
* @return the SPI instance with highest priority if exists, or else false
@@ -114,15 +124,15 @@ public final class SpiLoader {
SpiOrderWrapper<T> w = null;
for (T spi : serviceLoader) {
int order = SpiOrderResolver.resolveOrder(spi);
RecordLog.info("[SpiLoader] Found {} SPI: {} with order " + order, clazz.getSimpleName(),
spi.getClass().getCanonicalName());
RecordLog.info("[SpiLoader] Found {} SPI: {} with order {}", clazz.getSimpleName(),
spi.getClass().getCanonicalName(), order);
if (w == null || order < w.order) {
w = new SpiOrderWrapper<>(order, spi);
}
}
return w == null ? null : w.spi;
} catch (Throwable t) {
RecordLog.warn("[SpiLoader] ERROR: loadHighestPriorityInstance failed", t);
RecordLog.error("[SpiLoader] ERROR: loadHighestPriorityInstance failed", t);
t.printStackTrace();
return null;
}
@@ -132,6 +142,8 @@ public final class SpiLoader {
* Load and sorted SPI instance list.
* Load the SPI instance list for provided SPI interface.
*
* Note: each call return same instances.
*
* @param clazz class of the SPI
* @param <T> SPI type
* @return sorted SPI instance list
@@ -149,11 +161,13 @@ public final class SpiLoader {

List<T> list = new ArrayList<>();
for (T spi : serviceLoader) {
RecordLog.info("[SpiLoader] Found {} SPI: {}", clazz.getSimpleName(),
spi.getClass().getCanonicalName());
list.add(spi);
}
return list;
} catch (Throwable t) {
RecordLog.warn("[SpiLoader] ERROR: loadInstanceListSorted failed", t);
RecordLog.error("[SpiLoader] ERROR: loadInstanceList failed", t);
t.printStackTrace();
return new ArrayList<>();
}
@@ -162,7 +176,7 @@ public final class SpiLoader {
/**
* Load the sorted SPI instance list for provided SPI interface.
*
* Note: each call return new instances.
* Note: each call return same instances.
*
* @param clazz class of the SPI
* @param <T> SPI type
@@ -184,32 +198,32 @@ public final class SpiLoader {
int order = SpiOrderResolver.resolveOrder(spi);
// Since SPI is lazy initialized in ServiceLoader, we use online sort algorithm here.
SpiOrderResolver.insertSorted(orderWrappers, spi, order);
RecordLog.info("[SpiLoader] Found {} SPI: {} with order " + order, clazz.getSimpleName(),
spi.getClass().getCanonicalName());
RecordLog.info("[SpiLoader] Found {} SPI: {} with order {}", clazz.getSimpleName(),
spi.getClass().getCanonicalName(), order);
}
List<T> list = new ArrayList<>();
List<T> list = new ArrayList<>(orderWrappers.size());
for (int i = 0; i < orderWrappers.size(); i++) {
list.add(i, orderWrappers.get(i).spi);
list.add(orderWrappers.get(i).spi);
}
return list;
} catch (Throwable t) {
RecordLog.warn("[SpiLoader] ERROR: loadInstanceListSorted failed", t);
RecordLog.error("[SpiLoader] ERROR: loadInstanceListSorted failed", t);
t.printStackTrace();
return new ArrayList<>();
}
}

/**
* Load the sorted and different SPI instance list for provided SPI interface.
* Load the sorted and prototype SPI instance list for provided SPI interface.
*
* Note: each call return new instances.
* Note: each call return different instances, i.e. prototype instance, not singleton instance.
*
* @param clazz class of the SPI
* @param <T> SPI type
* @return sorted and different SPI instance list
* @since 1.7.2
*/
public static <T> List<T> loadDifferentInstanceListSorted(Class<T> clazz) {
public static <T> List<T> loadPrototypeInstanceListSorted(Class<T> clazz) {
try {
// Not use SERVICE_LOADER_MAP, to make sure the instances loaded are different.
ServiceLoader<T> serviceLoader = ServiceLoaderUtil.getServiceLoader(clazz);
@@ -219,16 +233,16 @@ public final class SpiLoader {
int order = SpiOrderResolver.resolveOrder(spi);
// Since SPI is lazy initialized in ServiceLoader, we use online sort algorithm here.
SpiOrderResolver.insertSorted(orderWrappers, spi, order);
RecordLog.info("[SpiLoader] Found {0} SPI: {1} with order " + order, clazz.getSimpleName(),
spi.getClass().getCanonicalName());
RecordLog.debug("[SpiLoader] Found {} SPI: {} with order {}", clazz.getSimpleName(),
spi.getClass().getCanonicalName(), order);
}
List<T> list = new ArrayList<>();
List<T> list = new ArrayList<>(orderWrappers.size());
for (int i = 0; i < orderWrappers.size(); i++) {
list.add(i, orderWrappers.get(i).spi);
list.add(orderWrappers.get(i).spi);
}
return list;
} catch (Throwable t) {
RecordLog.warn("[SpiLoader] ERROR: loadDifferentInstanceListSorted failed", t);
RecordLog.error("[SpiLoader] ERROR: loadPrototypeInstanceListSorted failed", t);
t.printStackTrace();
return new ArrayList<>();
}


+ 23
- 6
sentinel-core/src/test/java/com/alibaba/csp/sentinel/util/SpiLoaderTest.java View File

@@ -44,9 +44,17 @@ public class SpiLoaderTest {
ProcessorSlot processorSlot = SpiLoader.loadFirstInstance(ProcessorSlot.class);
assertNotNull(processorSlot);

ProcessorSlot processorSlot2 = SpiLoader.loadFirstInstance(ProcessorSlot.class);
// As SERVICE_LOADER_MAP in SpiLoader cached the instance, so they're same instances
assertSame(processorSlot, processorSlot2);

SlotChainBuilder slotChainBuilder = SpiLoader.loadFirstInstance(SlotChainBuilder.class);
assertNotNull(slotChainBuilder);
assertTrue(slotChainBuilder instanceof DefaultSlotChainBuilder);

SlotChainBuilder slotChainBuilder2 = SpiLoader.loadFirstInstance(SlotChainBuilder.class);
// As SERVICE_LOADER_MAP in SpiLoader cached the instance, so they're same instances
assertSame(slotChainBuilder, slotChainBuilder2);
}

@Test
@@ -54,8 +62,12 @@ public class SpiLoaderTest {
ProcessorSlot processorSlot = SpiLoader.loadHighestPriorityInstance(ProcessorSlot.class);
assertNotNull(processorSlot);

// NodeSelectorSlot is highest order with @SpiOrder(-9000), among all slots
// NodeSelectorSlot is highest order with @SpiOrder(-10000), among all slots
assertTrue(processorSlot instanceof NodeSelectorSlot);

ProcessorSlot processorSlot2 = SpiLoader.loadHighestPriorityInstance(ProcessorSlot.class);
// As SERVICE_LOADER_MAP in SpiLoader cached the instance, so they're same instances
assertSame(processorSlot, processorSlot2);
}

@Test
@@ -66,14 +78,15 @@ public class SpiLoaderTest {
// Total 8 default slot in sentinel-core
assertEquals(8, slots.size());

// Store the first slot of slots
// Get the first slot of slots
ProcessorSlot firstSlot = slots.get(0);

// Call loadInstanceList again
List<ProcessorSlot> slots2 = SpiLoader.loadInstanceList(ProcessorSlot.class);
// Note: the return list are different, and the item instances in list are same
assertNotSame(slots, slots2);

// Store the first slot of slots
// Get the first slot of slots2
ProcessorSlot firstSlot2 = slots2.get(0);

// As SERVICE_LOADER_MAP in SpiLoader cached the instance, so they're same instances
@@ -100,6 +113,7 @@ public class SpiLoaderTest {
assertTrue(sortedSlots.get(index++) instanceof DegradeSlot);

// Verify each call return different instances
// Note: the return list are different, and the item instances in list are same
List<ProcessorSlot> sortedSlots2 = SpiLoader.loadInstanceListSorted(ProcessorSlot.class);
assertNotSame(sortedSlots, sortedSlots2);
assertEquals(sortedSlots.size(), sortedSlots2.size());
@@ -107,11 +121,14 @@ public class SpiLoaderTest {
ProcessorSlot slot = sortedSlots.get(i);
ProcessorSlot slot2 = sortedSlots2.get(i);
assertEquals(slot.getClass(), slot2.getClass());

// As SERVICE_LOADER_MAP in SpiLoader cached the instance, so they're same instances
assertSame(slot, slot2);
}
}

@Test
public void testLoadDifferentInstanceListSorted() {
public void testLoadPrototypeInstanceListSorted() {
List<ProcessorSlot> sortedSlots = SpiLoader.loadInstanceListSorted(ProcessorSlot.class);
assertNotNull(sortedSlots);

@@ -129,8 +146,8 @@ public class SpiLoaderTest {
assertTrue(sortedSlots.get(index++) instanceof FlowSlot);
assertTrue(sortedSlots.get(index++) instanceof DegradeSlot);

// Verify each call return different instances
List<ProcessorSlot> sortedSlots2 = SpiLoader.loadDifferentInstanceListSorted(ProcessorSlot.class);
// Verify each call return new instances
List<ProcessorSlot> sortedSlots2 = SpiLoader.loadPrototypeInstanceListSorted(ProcessorSlot.class);
assertNotSame(sortedSlots, sortedSlots2);
assertEquals(sortedSlots.size(), sortedSlots2.size());
for (int i = 0; i < sortedSlots.size(); i++) {


Loading…
Cancel
Save