Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set default log level to INFO of JDK logging and improve log info and comment in SpiLoader #1365

Merged
merged 5 commits into from
Apr 3, 2020
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,9 @@ protected Handler makeLoggingHandler(String logName, Logger heliumRecordLog) {
if (handler != null) {
disableOtherHandlers(heliumRecordLog, handler);
}
heliumRecordLog.setLevel(Level.ALL);

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import com.alibaba.csp.sentinel.slotchain.ProcessorSlot;
import com.alibaba.csp.sentinel.slotchain.ProcessorSlotChain;
import com.alibaba.csp.sentinel.slotchain.SlotChainBuilder;
import com.alibaba.csp.sentinel.spi.SpiOrder;
import com.alibaba.csp.sentinel.util.SpiLoader;

import java.util.List;
Expand All @@ -33,12 +34,27 @@
*/
public class DefaultSlotChainBuilder implements SlotChainBuilder {

static {
List<ProcessorSlot> sortedSlotList = SpiLoader.loadPrototypeInstanceListSorted(ProcessorSlot.class);
for (ProcessorSlot slot : sortedSlotList) {
String slotClassCanonicalName = slot.getClass().getCanonicalName();
int order;
if (slot.getClass().isAnnotationPresent(SpiOrder.class)) {
SpiOrder spiOrder = slot.getClass().getAnnotation(SpiOrder.class);
order = spiOrder.value();
} else {
order = SpiOrder.LOWEST_PRECEDENCE;
}
RecordLog.info("[DefaultSlotChainBuilder]Found ProcessorSlot {} with order {}", slotClassCanonicalName, order);
}
}

@Override
public ProcessorSlotChain build() {
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");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -52,7 +60,7 @@ public static <T> T loadFirstInstance(Class<T> clazz) {
return null;
}
} catch (Throwable t) {
RecordLog.warn("[SpiLoader] ERROR: loadFirstInstance failed", t);
RecordLog.error("[SpiLoader] ERROR: loadFirstInstance failed", t);
t.printStackTrace();
return null;
}
Expand Down Expand Up @@ -87,7 +95,7 @@ public static <T> T loadFirstInstanceOrDefault(Class<T> clazz, Class<? extends T
}
return defaultClass.newInstance();
} catch (Throwable t) {
RecordLog.warn("[SpiLoader] ERROR: loadFirstInstanceOrDefault failed", t);
RecordLog.error("[SpiLoader] ERROR: loadFirstInstanceOrDefault failed", t);
t.printStackTrace();
return null;
}
Expand All @@ -96,6 +104,8 @@ public static <T> T loadFirstInstanceOrDefault(Class<T> clazz, Class<? extends T
/**
* 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
Expand All @@ -114,15 +124,15 @@ public static <T> T loadHighestPriorityInstance(Class<T> clazz) {
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;
}
Expand All @@ -132,6 +142,8 @@ public static <T> T loadHighestPriorityInstance(Class<T> clazz) {
* 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
Expand All @@ -149,11 +161,13 @@ public static <T> List<T> loadInstanceList(Class<T> clazz) {

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<>();
}
Expand All @@ -162,7 +176,7 @@ public static <T> List<T> loadInstanceList(Class<T> clazz) {
/**
* 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
Expand All @@ -184,32 +198,32 @@ public static <T> List<T> loadInstanceListSorted(Class<T> clazz) {
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);
Expand All @@ -219,16 +233,16 @@ public static <T> List<T> loadDifferentInstanceListSorted(Class<T> clazz) {
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<>();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,17 @@ public void testLoadFirstInstance() {
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
Expand All @@ -56,6 +64,10 @@ public void testLoadHighestPriorityInstance() {

// NodeSelectorSlot is highest order with @SpiOrder(-9000), 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
Expand All @@ -66,14 +78,15 @@ public void testLoadInstanceList() {
// 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
Expand All @@ -100,18 +113,22 @@ public void testLoadInstanceListSorted() {
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());
for (int i = 0; i < sortedSlots.size(); i++) {
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);

Expand All @@ -129,8 +146,8 @@ public void testLoadDifferentInstanceListSorted() {
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++) {
Expand Down