From 3bd8dc9175a3bf118792aa5dc01a73455a0136b4 Mon Sep 17 00:00:00 2001 From: Yongkoo Kang Date: Mon, 5 Feb 2024 17:32:13 -0800 Subject: [PATCH 1/4] Augment instrumentation stack trace functionality and surface it --- .../ConcurrentCompositeConfiguration.java | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/archaius-core/src/main/java/com/netflix/config/ConcurrentCompositeConfiguration.java b/archaius-core/src/main/java/com/netflix/config/ConcurrentCompositeConfiguration.java index 7b792202..a060e32d 100644 --- a/archaius-core/src/main/java/com/netflix/config/ConcurrentCompositeConfiguration.java +++ b/archaius-core/src/main/java/com/netflix/config/ConcurrentCompositeConfiguration.java @@ -20,6 +20,7 @@ import java.util.Collection; import java.util.Collections; import java.util.ConcurrentModificationException; +import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.LinkedList; @@ -106,15 +107,26 @@ public class ConcurrentCompositeConfiguration extends ConcurrentMapConfiguration implements AggregatedConfiguration, ConfigurationListener, Cloneable { public static final String ENABLE_STACK_TRACE = "archaius_enable_stack_trace"; + public static final String STACK_TRACE_ENABLED_PROPERTIES = "archaius_stack_trace_enabled_properties"; public static final String ENABLE_INSTRUMENTATION = "archaius_enable_instrumentation"; private final boolean enableStackTrace = Boolean.parseBoolean(System.getProperty(ENABLE_STACK_TRACE)); private final boolean enableInstrumentation = Boolean.parseBoolean(System.getProperty(ENABLE_INSTRUMENTATION)); + private final Set stackTraceEnabledProperties = convertStringFlag(System.getProperty(STACK_TRACE_ENABLED_PROPERTIES)); private Map namedConfigurations = new ConcurrentHashMap<>(); private final Map stackTraces = new ConcurrentHashMap<>(); private final AtomicReference> usedPropertiesRef = new AtomicReference<>(ConcurrentHashMap.newKeySet()); + private Set convertStringFlag(String properties) { + if (properties == null) { + return Collections.emptySet(); + } + Set ret = new HashSet<>(); + Collections.addAll(ret, properties.split(",")); + return ret; + } + public Set getUsedProperties() { return Collections.unmodifiableSet(new HashSet<>(usedPropertiesRef.get())); } @@ -124,6 +136,10 @@ public Set getAndClearUsedProperties() { return Collections.unmodifiableSet(ret); } + public Map getInstrumentationStackTraces() { + return Collections.unmodifiableMap(new HashMap<>(stackTraces)); + } + private List configList = new CopyOnWriteArrayList(); private static final Logger logger = LoggerFactory.getLogger(ConcurrentCompositeConfiguration.class); @@ -589,7 +605,8 @@ private Object getProperty(String key, boolean instrument) public void recordUsage(String key) { if (enableInstrumentation) { usedPropertiesRef.get().add(key); - if (enableStackTrace) { + if (enableStackTrace + || (!stackTraceEnabledProperties.isEmpty() && stackTraceEnabledProperties.contains(key))) { String trace = Arrays.toString(Thread.currentThread().getStackTrace()); stackTraces.merge(trace, 1, (v1, v2) -> v1 + 1); } From 5e5023773a033b9a767062e52ada243cf30ee0b4 Mon Sep 17 00:00:00 2001 From: Yongkoo Kang Date: Mon, 5 Feb 2024 17:46:40 -0800 Subject: [PATCH 2/4] Track all used properties per stack trace, in case we are tracking several --- .../ConcurrentCompositeConfiguration.java | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/archaius-core/src/main/java/com/netflix/config/ConcurrentCompositeConfiguration.java b/archaius-core/src/main/java/com/netflix/config/ConcurrentCompositeConfiguration.java index a060e32d..8a1bdd9d 100644 --- a/archaius-core/src/main/java/com/netflix/config/ConcurrentCompositeConfiguration.java +++ b/archaius-core/src/main/java/com/netflix/config/ConcurrentCompositeConfiguration.java @@ -116,6 +116,7 @@ public class ConcurrentCompositeConfiguration extends ConcurrentMapConfiguration private Map namedConfigurations = new ConcurrentHashMap<>(); private final Map stackTraces = new ConcurrentHashMap<>(); + private final Map> stackTracesAndProperties = new ConcurrentHashMap<>(); private final AtomicReference> usedPropertiesRef = new AtomicReference<>(ConcurrentHashMap.newKeySet()); private Set convertStringFlag(String properties) { @@ -140,6 +141,11 @@ public Map getInstrumentationStackTraces() { return Collections.unmodifiableMap(new HashMap<>(stackTraces)); } + public Map> getInstrumentationStackTracesAndProperties() { + // Shallow copy + return Collections.unmodifiableMap(new HashMap<>(stackTracesAndProperties)); + } + private List configList = new CopyOnWriteArrayList(); private static final Logger logger = LoggerFactory.getLogger(ConcurrentCompositeConfiguration.class); @@ -608,11 +614,27 @@ public void recordUsage(String key) { if (enableStackTrace || (!stackTraceEnabledProperties.isEmpty() && stackTraceEnabledProperties.contains(key))) { String trace = Arrays.toString(Thread.currentThread().getStackTrace()); - stackTraces.merge(trace, 1, (v1, v2) -> v1 + 1); + if (enableStackTrace) { + stackTraces.merge(trace, 1, (v1, v2) -> v1 + 1); + } + if (!stackTraceEnabledProperties.isEmpty() && stackTraceEnabledProperties.contains(key)) { + stackTracesAndProperties.merge(trace, createSet(key), this::union); + } } } } + private Set union(Set s1, Set s2) { + s1.addAll(s2); + return s1; + } + + private Set createSet(String s) { + Set ret = new HashSet<>(); + ret.add(s); + return ret; + } + /** * Get all the keys contained by sub configurations. * From 877d31c89b974a10fa19d22d0260d7210af522ba Mon Sep 17 00:00:00 2001 From: Yongkoo Kang Date: Mon, 5 Feb 2024 17:52:29 -0800 Subject: [PATCH 3/4] Small fixes --- .../netflix/config/ConcurrentCompositeConfiguration.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/archaius-core/src/main/java/com/netflix/config/ConcurrentCompositeConfiguration.java b/archaius-core/src/main/java/com/netflix/config/ConcurrentCompositeConfiguration.java index 8a1bdd9d..0a0c8d9e 100644 --- a/archaius-core/src/main/java/com/netflix/config/ConcurrentCompositeConfiguration.java +++ b/archaius-core/src/main/java/com/netflix/config/ConcurrentCompositeConfiguration.java @@ -107,8 +107,8 @@ public class ConcurrentCompositeConfiguration extends ConcurrentMapConfiguration implements AggregatedConfiguration, ConfigurationListener, Cloneable { public static final String ENABLE_STACK_TRACE = "archaius_enable_stack_trace"; - public static final String STACK_TRACE_ENABLED_PROPERTIES = "archaius_stack_trace_enabled_properties"; public static final String ENABLE_INSTRUMENTATION = "archaius_enable_instrumentation"; + public static final String STACK_TRACE_ENABLED_PROPERTIES = "archaius_stack_trace_enabled_properties"; private final boolean enableStackTrace = Boolean.parseBoolean(System.getProperty(ENABLE_STACK_TRACE)); private final boolean enableInstrumentation = Boolean.parseBoolean(System.getProperty(ENABLE_INSTRUMENTATION)); private final Set stackTraceEnabledProperties = convertStringFlag(System.getProperty(STACK_TRACE_ENABLED_PROPERTIES)); @@ -611,13 +611,13 @@ private Object getProperty(String key, boolean instrument) public void recordUsage(String key) { if (enableInstrumentation) { usedPropertiesRef.get().add(key); - if (enableStackTrace - || (!stackTraceEnabledProperties.isEmpty() && stackTraceEnabledProperties.contains(key))) { + boolean isTrackedProperty = !stackTraceEnabledProperties.isEmpty() && stackTraceEnabledProperties.contains(key); + if (enableStackTrace || isTrackedProperty) { String trace = Arrays.toString(Thread.currentThread().getStackTrace()); if (enableStackTrace) { stackTraces.merge(trace, 1, (v1, v2) -> v1 + 1); } - if (!stackTraceEnabledProperties.isEmpty() && stackTraceEnabledProperties.contains(key)) { + if (isTrackedProperty) { stackTracesAndProperties.merge(trace, createSet(key), this::union); } } From 5bf66d76608820fcb0e5a618207659d902a340df Mon Sep 17 00:00:00 2001 From: Yongkoo Kang Date: Tue, 6 Feb 2024 10:56:33 -0800 Subject: [PATCH 4/4] Update set handling --- .../netflix/config/ConcurrentCompositeConfiguration.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/archaius-core/src/main/java/com/netflix/config/ConcurrentCompositeConfiguration.java b/archaius-core/src/main/java/com/netflix/config/ConcurrentCompositeConfiguration.java index 0a0c8d9e..d7aa61a3 100644 --- a/archaius-core/src/main/java/com/netflix/config/ConcurrentCompositeConfiguration.java +++ b/archaius-core/src/main/java/com/netflix/config/ConcurrentCompositeConfiguration.java @@ -33,6 +33,8 @@ import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.atomic.AtomicReference; +import com.google.common.base.Splitter; +import com.google.common.collect.ImmutableSet; import org.apache.commons.configuration.AbstractConfiguration; import org.apache.commons.configuration.Configuration; import org.apache.commons.configuration.ConfigurationRuntimeException; @@ -123,9 +125,8 @@ private Set convertStringFlag(String properties) { if (properties == null) { return Collections.emptySet(); } - Set ret = new HashSet<>(); - Collections.addAll(ret, properties.split(",")); - return ret; + + return ImmutableSet.copyOf(Splitter.on(',').trimResults().omitEmptyStrings().split(properties)); } public Set getUsedProperties() { @@ -611,7 +612,7 @@ private Object getProperty(String key, boolean instrument) public void recordUsage(String key) { if (enableInstrumentation) { usedPropertiesRef.get().add(key); - boolean isTrackedProperty = !stackTraceEnabledProperties.isEmpty() && stackTraceEnabledProperties.contains(key); + boolean isTrackedProperty = stackTraceEnabledProperties.contains(key); if (enableStackTrace || isTrackedProperty) { String trace = Arrays.toString(Thread.currentThread().getStackTrace()); if (enableStackTrace) {