diff --git a/truffle/src/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/polyglot/LoggingTest.java b/truffle/src/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/polyglot/LoggingTest.java index ace401a82112..b8c8eda57ef1 100644 --- a/truffle/src/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/polyglot/LoggingTest.java +++ b/truffle/src/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/polyglot/LoggingTest.java @@ -580,10 +580,7 @@ public void testDecreaseLogLevelSingleContext() { Map setLevelsMap = new HashMap<>(); setLevelsMap.put("a", Level.FINEST); setLevelsMap.put("a.a", Level.INFO); - Context.Builder builder = newContextBuilder(); - for (Map.Entry levelsMapEntry : setLevelsMap.entrySet()) { - builder.options(createLoggingOptions(LoggingLanguageFirst.ID, levelsMapEntry.getKey(), levelsMapEntry.getValue().toString())); - } + Context.Builder builder = configureLogLevels(newContextBuilder(), setLevelsMap); TestHandler handler = new TestHandler(); try (Context ctx = builder.logHandler(handler).build()) { ctx.eval(LoggingLanguageFirst.ID, ""); @@ -599,10 +596,7 @@ public void testDecreaseLogLevelMultipleContexts() { Map setLevelsMap = new HashMap<>(); setLevelsMap.put("a", Level.FINEST); setLevelsMap.put("a.a", Level.INFO); - Context.Builder builder = newContextBuilder(); - for (Map.Entry levelsMapEntry : setLevelsMap.entrySet()) { - builder.options(createLoggingOptions(LoggingLanguageFirst.ID, levelsMapEntry.getKey(), levelsMapEntry.getValue().toString())); - } + Context.Builder builder = configureLogLevels(newContextBuilder(), setLevelsMap); TestHandler handler = new TestHandler(); try (Context ctx = builder.logHandler(handler).build()) { TestHandler handler2 = new TestHandler(); @@ -626,11 +620,26 @@ public void testDecreaseIncreaseLogLevelSingleContext() { setLevelsMap.put("a", Level.INFO); setLevelsMap.put("a.a", Level.FINE); TestHandler handler = new TestHandler(); - Context.Builder builder = newContextBuilder(); - for (Map.Entry levelsMapEntry : setLevelsMap.entrySet()) { - builder.options(createLoggingOptions(LoggingLanguageFirst.ID, levelsMapEntry.getKey(), levelsMapEntry.getValue().toString())); + Context.Builder builder = configureLogLevels(newContextBuilder(), setLevelsMap); + try (Context ctx = builder.logHandler(handler).build()) { + ctx.eval(LoggingLanguageFirst.ID, ""); + List> expected = new ArrayList<>(); + expected.addAll(createExpectedLog(LoggingLanguageFirst.ID, setLevelsMap.remove(null), setLevelsMap)); + Assert.assertEquals(expected, handler.getLog()); } + } + + @Test + public void testDecreaseIncreaseLogLevelSingleContextInterfering() { + Map setLevelsMap = new HashMap<>(); + setLevelsMap.put(null, Level.FINEST); // level on language root level + setLevelsMap.put("a", Level.INFO); + setLevelsMap.put("a.a", Level.FINE); + TestHandler handler = new TestHandler(); + Context.Builder builder = configureLogLevels(newContextBuilder(), setLevelsMap); + Context interferingContext = configureLogLevels(newContextBuilder(), Map.of("b", Level.FINE)).build(); try (Context ctx = builder.logHandler(handler).build()) { + interferingContext.close(); ctx.eval(LoggingLanguageFirst.ID, ""); List> expected = new ArrayList<>(); expected.addAll(createExpectedLog(LoggingLanguageFirst.ID, setLevelsMap.remove(null), setLevelsMap)); @@ -645,10 +654,7 @@ public void testDecreaseIncreaseLogLevelMultipleContexts() { setLevelsMap.put(null, Level.FINEST); // level on language root level setLevelsMap.put("a", Level.INFO); setLevelsMap.put("a.a", Level.FINE); - Context.Builder builder = newContextBuilder(); - for (Map.Entry levelsMapEntry : setLevelsMap.entrySet()) { - builder.options(createLoggingOptions(LoggingLanguageFirst.ID, levelsMapEntry.getKey(), levelsMapEntry.getValue().toString())); - } + Context.Builder builder = configureLogLevels(newContextBuilder(), setLevelsMap); TestHandler handler = new TestHandler(); try (Context ctx = builder.logHandler(handler).build()) { TestHandler handler2 = new TestHandler(); @@ -670,10 +676,7 @@ public void testDisableLoggersSingleContext() { Map setLevelsMap = new HashMap<>(); setLevelsMap.put(null, Level.FINEST); // level on language root level setLevelsMap.put("a", Level.OFF); - Context.Builder builder = newContextBuilder(); - for (Map.Entry levelsMapEntry : setLevelsMap.entrySet()) { - builder.options(createLoggingOptions(LoggingLanguageFirst.ID, levelsMapEntry.getKey(), levelsMapEntry.getValue().toString())); - } + Context.Builder builder = configureLogLevels(newContextBuilder(), setLevelsMap); TestHandler handler = new TestHandler(); try (Context ctx = builder.logHandler(handler).build()) { ctx.eval(LoggingLanguageFirst.ID, ""); @@ -683,16 +686,20 @@ public void testDisableLoggersSingleContext() { } } + private static Context.Builder configureLogLevels(Context.Builder builder, Map levels) { + for (Map.Entry e : levels.entrySet()) { + builder.options(createLoggingOptions(LoggingLanguageFirst.ID, e.getKey(), e.getValue().toString())); + } + return builder; + } + @Test public void testDisableLoggersMultipleContexts() { Level defaultLevel = Level.INFO; Map setLevelsMap = new HashMap<>(); setLevelsMap.put(null, Level.FINEST); // level on language root level setLevelsMap.put("a", Level.OFF); - Context.Builder builder = newContextBuilder(); - for (Map.Entry levelsMapEntry : setLevelsMap.entrySet()) { - builder.options(createLoggingOptions(LoggingLanguageFirst.ID, levelsMapEntry.getKey(), levelsMapEntry.getValue().toString())); - } + Context.Builder builder = configureLogLevels(newContextBuilder(), setLevelsMap); TestHandler handler = new TestHandler(); try (Context ctx = builder.logHandler(handler).build()) { TestHandler handler2 = new TestHandler(); @@ -709,6 +716,45 @@ public void testDisableLoggersMultipleContexts() { } } + @Test + public void testGR52530Interfering() { + Map setLevelsMap = new HashMap<>(); + setLevelsMap.put(null, Level.FINEST); // level on language root level + setLevelsMap.put("a", Level.OFF); + Context.Builder builder = configureLogLevels(newContextBuilder(), setLevelsMap); + TestHandler handler = new TestHandler(); + Context interferingContext = configureLogLevels(newContextBuilder(), Map.of("a", Level.FINE)).build(); + try (Context ctx = builder.logHandler(handler).build()) { + interferingContext.close(); + ctx.eval(LoggingLanguageFirst.ID, ""); + List> expected = new ArrayList<>(); + expected.addAll(createExpectedLog(LoggingLanguageFirst.ID, setLevelsMap.remove(null), setLevelsMap)); + Assert.assertEquals(expected, handler.getLog()); + } + } + + @Test + public void testGR52530Enclosing() { + Map setLevelsMap = new HashMap<>(); + setLevelsMap.put(null, Level.FINEST); // level on language root level + setLevelsMap.put("a", Level.OFF); + Context.Builder builder = configureLogLevels(newContextBuilder(), setLevelsMap); + TestHandler outerHandler = new TestHandler(); + try (Context outerContext = configureLogLevels(newContextBuilder().logHandler(outerHandler), Map.of("a", Level.FINE)).build()) { + TestHandler handler = new TestHandler(); + try (Context ctx = builder.logHandler(handler).build()) { + outerContext.eval(LoggingLanguageFirst.ID, ""); + ctx.eval(LoggingLanguageFirst.ID, ""); + List> expected = new ArrayList<>(); + expected.addAll(createExpectedLog(LoggingLanguageFirst.ID, setLevelsMap.remove(null), setLevelsMap)); + Assert.assertEquals(expected, handler.getLog()); + } + List> expected = new ArrayList<>(); + expected.addAll(createExpectedLog(LoggingLanguageFirst.ID, Level.INFO, Map.of("a", Level.FINE))); + Assert.assertEquals(expected, outerHandler.getLog()); + } + } + @Test public void testDefaultLevelMultipleContexts() { String parentLoggerName = "testDefaultLevelMultipleContexts"; @@ -716,10 +762,7 @@ public void testDefaultLevelMultipleContexts() { Map setLevelsMap = new HashMap<>(); setLevelsMap.put(parentLoggerName, Level.FINE); setLevelsMap.put(childLoggerName, Level.SEVERE); - Context.Builder builder = newContextBuilder(); - for (Map.Entry levelsMapEntry : setLevelsMap.entrySet()) { - builder.options(createLoggingOptions(LoggingLanguageFirst.ID, levelsMapEntry.getKey(), levelsMapEntry.getValue().toString())); - } + Context.Builder builder = configureLogLevels(newContextBuilder(), setLevelsMap); TestHandler handler = new TestHandler(); TruffleLogger parentLogger = TruffleLogger.getLogger(LoggingLanguageFirst.ID, parentLoggerName); TruffleLogger childLogger = TruffleLogger.getLogger(LoggingLanguageFirst.ID, childLoggerName); diff --git a/truffle/src/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleLogger.java b/truffle/src/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleLogger.java index 4861c7479ce0..6515235ab672 100644 --- a/truffle/src/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleLogger.java +++ b/truffle/src/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleLogger.java @@ -1155,14 +1155,18 @@ private void reconfigure(final Map addedLevels, final Set assert !addedLevels.isEmpty() || !toRemove.isEmpty(); final Collection loggersWithRemovedLevels = new HashSet<>(); final Collection loggersWithChangedLevels = new HashSet<>(); + boolean singleContext = activeContexts.size() <= 1; effectiveLevels = computeEffectiveLevels( effectiveLevels, toRemove, addedLevels, activeContexts, + singleContext, loggersWithRemovedLevels, loggersWithChangedLevels); - boolean singleContext = activeContexts.size() <= 1; + if (singleContext && !loggersWithRemovedLevels.isEmpty()) { + loggersWithChangedLevels.addAll(effectiveLevels.keySet()); + } for (String loggerName : loggersWithRemovedLevels) { final TruffleLogger logger = getLogger(loggerName); if (logger != null) { @@ -1232,12 +1236,13 @@ static LoggerCache getInstance() { } private static Map computeEffectiveLevels( - final Map currentEffectiveLevels, - final Set removed, - final Map added, - final Collection contexts, - final Collection removedLevels, - final Collection changedLevels) { + Map currentEffectiveLevels, + Set removed, + Map added, + Collection contexts, + boolean singleContext, + Collection removedLevels, + Collection changedLevels) { final Map newEffectiveLevels = new HashMap<>(currentEffectiveLevels); for (String loggerName : removed) { final Level level = findMinLevel(loggerName, contexts); @@ -1252,13 +1257,16 @@ private static Map computeEffectiveLevels( } } } - // In a multi context scenario there can be a logger with higher effective log level - // than a default one. When the newly configured context does not specify log level - // explicitly the effective log level of such a logger needs to be set to the default - // level. Map addedWithDefaults = new HashMap<>(added); - for (String loggerName : newEffectiveLevels.keySet()) { - addedWithDefaults.putIfAbsent(loggerName, Level.INFO); + if (!singleContext) { + // In a multi context scenario there can be a logger with higher effective log level + // than a default one. When the newly configured context does not specify log level + // explicitly the effective log level of such a logger needs to be set to the + // default + // level. + for (String loggerName : newEffectiveLevels.keySet()) { + addedWithDefaults.putIfAbsent(loggerName, Level.INFO); + } } for (Map.Entry addedLevel : addedWithDefaults.entrySet()) { final String loggerName = addedLevel.getKey();