Skip to content

Commit

Permalink
Merge pull request quarkusio#14326 from galderz/t_inherit_14154_v4
Browse files Browse the repository at this point in the history
Handle 'inherit' logging min-level settings
  • Loading branch information
gsmet authored Jan 18, 2021
2 parents 03bb925 + 96f8e9b commit 5018a9f
Show file tree
Hide file tree
Showing 7 changed files with 108 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.function.BiFunction;
import java.util.function.Consumer;
Expand Down Expand Up @@ -45,6 +46,7 @@
import io.quarkus.gizmo.ResultHandle;
import io.quarkus.runtime.RuntimeValue;
import io.quarkus.runtime.logging.CategoryBuildTimeConfig;
import io.quarkus.runtime.logging.InheritableLevel;
import io.quarkus.runtime.logging.LogBuildTimeConfig;
import io.quarkus.runtime.logging.LogConfig;
import io.quarkus.runtime.logging.LogMetricsHandlerRecorder;
Expand Down Expand Up @@ -189,9 +191,9 @@ private static void generateDefaultLoggers(Level minLevel, ClassOutput output) {
generateLogManagerLogger(output, LoggingResourceProcessor.generateMinLevelDefault(minLevel.getName()));
}

private static void generateCategoryMinLevelLoggers(Map<String, CategoryBuildTimeConfig> categories, Level minLevel,
private static void generateCategoryMinLevelLoggers(Map<String, CategoryBuildTimeConfig> categories, Level rootMinLevel,
ClassOutput output) {
generateMinLevelCompute(categories, minLevel.toString(), output);
generateMinLevelCompute(categories, rootMinLevel, output);
generateDefaultLoggerNode(output);
generateLogManagerLogger(output, LoggingResourceProcessor::generateMinLevelCheckCategory);
}
Expand All @@ -202,7 +204,7 @@ private static BranchResult generateMinLevelCheckCategory(MethodCreator method,
return method.ifTrue(method.invokeStaticMethod(IS_MIN_LEVEL_ENABLED, levelIntValue, nameAlias));
}

private static void generateMinLevelCompute(Map<String, CategoryBuildTimeConfig> categories, String defaultMinLevelName,
private static void generateMinLevelCompute(Map<String, CategoryBuildTimeConfig> categories, Level rootMinLevel,
ClassOutput output) {
try (ClassCreator cc = ClassCreator.builder().setFinal(true)
.className(MIN_LEVEL_COMPUTE_CLASS_NAME)
Expand All @@ -217,7 +219,8 @@ private static void generateMinLevelCompute(Map<String, CategoryBuildTimeConfig>
BytecodeCreator current = mc;
for (Map.Entry<String, CategoryBuildTimeConfig> entry : categories.entrySet()) {
final String category = entry.getKey();
final int categoryLevelIntValue = entry.getValue().minLevel.getLevel().intValue();
final int categoryLevelIntValue = getLogMinLevel(entry.getKey(), entry.getValue(), categories, rootMinLevel)
.intValue();

ResultHandle equalsResult = current.invokeVirtualMethod(
MethodDescriptor.ofMethod(Object.class, "equals", boolean.class, Object.class),
Expand All @@ -227,7 +230,7 @@ private static void generateMinLevelCompute(Map<String, CategoryBuildTimeConfig>
try (BytecodeCreator false1 = equalsBranch.falseBranch()) {
ResultHandle startsWithResult = false1.invokeVirtualMethod(
MethodDescriptor.ofMethod(String.class, "startsWith", boolean.class, String.class),
name, false1.load(category));
name, false1.load(category + "."));

BranchResult startsWithBranch = false1.ifTrue(startsWithResult);

Expand All @@ -243,14 +246,32 @@ private static void generateMinLevelCompute(Map<String, CategoryBuildTimeConfig>
equalsBranch.trueBranch().returnValue(equalsBranch.trueBranch().load(true));
}

final ResultHandle infoLevelIntValue = getLogManagerLevelIntValue(defaultMinLevelName, current);
final ResultHandle infoLevelIntValue = getLogManagerLevelIntValue(rootMinLevel.toString(), current);
final BranchResult isInfoOrHigherBranch = current.ifIntegerGreaterEqual(level, infoLevelIntValue);
isInfoOrHigherBranch.trueBranch().returnValue(isInfoOrHigherBranch.trueBranch().load(true));
isInfoOrHigherBranch.falseBranch().returnValue(isInfoOrHigherBranch.falseBranch().load(false));
}
}
}

private static Level getLogMinLevel(String categoryName, CategoryBuildTimeConfig categoryConfig,
Map<String, CategoryBuildTimeConfig> categories,
Level rootMinLevel) {
if (Objects.isNull(categoryConfig))
return rootMinLevel;

final InheritableLevel inheritableLevel = categoryConfig.minLevel;
if (!inheritableLevel.isInherited())
return inheritableLevel.getLevel();

int lastDotIndex = categoryName.lastIndexOf('.');
if (lastDotIndex == -1)
return rootMinLevel;

String parent = categoryName.substring(0, lastDotIndex);
return getLogMinLevel(parent, categories.get(parent), categories, rootMinLevel);
}

private static void generateDefaultLoggerNode(ClassOutput output) {
try (ClassCreator cc = ClassCreator.builder().setFinal(true)
.className(LOGGER_NODE_CLASS_NAME)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Supplier;
import java.util.logging.ErrorManager;
Expand Down Expand Up @@ -137,7 +138,7 @@ public void initializeLogging(LogConfig config, LogBuildTimeConfig buildConfig,

for (Map.Entry<String, CategoryConfig> entry : categories.entrySet()) {
final CategoryBuildTimeConfig buildCategory = isSubsetOf(entry.getKey(), buildConfig.categories);
final Level logLevel = entry.getValue().level.getLevel();
final Level logLevel = getLogLevel(entry.getKey(), entry.getValue(), categories, buildConfig.minLevel);
final Level minLogLevel = buildCategory == null
? buildConfig.minLevel
: buildCategory.minLevel.getLevel();
Expand Down Expand Up @@ -177,6 +178,23 @@ public void initializeLogging(LogConfig config, LogBuildTimeConfig buildConfig,
InitialConfigurator.DELAYED_HANDLER.setHandlers(handlers.toArray(EmbeddedConfigurator.NO_HANDLERS));
}

private Level getLogLevel(String categoryName, CategoryConfig categoryConfig, Map<String, CategoryConfig> categories,
Level rootMinLevel) {
if (Objects.isNull(categoryConfig))
return rootMinLevel;

final InheritableLevel inheritableLevel = categoryConfig.level;
if (!inheritableLevel.isInherited())
return inheritableLevel.getLevel();

int lastDotIndex = categoryName.lastIndexOf('.');
if (lastDotIndex == -1)
return rootMinLevel;

String parent = categoryName.substring(0, lastDotIndex);
return getLogLevel(parent, categories.get(parent), categories, rootMinLevel);
}

private CategoryBuildTimeConfig isSubsetOf(String categoryName, Map<String, CategoryBuildTimeConfig> categories) {
return categories.entrySet().stream()
.filter(buildCategoryEntry -> categoryName.startsWith(buildCategoryEntry.getKey()))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package io.quarkus.it.logging.minlevel.set.below.child;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import org.jboss.logging.Logger;

import io.quarkus.it.logging.minlevel.set.LoggingWitness;

@Path("/log/below/child")
public class LoggingMinLevelBelowChild {

static final Logger LOG = Logger.getLogger(LoggingMinLevelBelowChild.class);

@GET
@Path("/trace")
@Produces(MediaType.TEXT_PLAIN)
public boolean isTrace() {
return LOG.isTraceEnabled() && LoggingWitness.loggedTrace("trace-message", LOG);
}

}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
quarkus.log.min-level=DEBUG
quarkus.log.category."io.quarkus.it.logging.minlevel.set.above".min-level=INFO
quarkus.log.category."io.quarkus.it.logging.minlevel.set.below".min-level=TRACE
quarkus.log.category."io.quarkus.it.logging.minlevel.set.below.child".min-level=inherit
quarkus.log.category."io.quarkus.it.logging.minlevel.set.promote".min-level=ERROR
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package io.quarkus.it.logging.minlevel.set;

import static io.restassured.RestAssured.given;
import static org.hamcrest.CoreMatchers.is;

import org.junit.jupiter.api.Test;

import io.quarkus.test.common.QuarkusTestResource;
import io.quarkus.test.junit.QuarkusTest;

/**
* Test verifies that a min-level override that goes below the default min-level is applied correctly.
*/
@QuarkusTest
@QuarkusTestResource(SetRuntimeLogLevels.class)
public class LoggingMinLevelBelowChildTest {

@Test
public void testTrace() {
given()
.when().get("/log/below/child/trace")
.then()
.statusCode(200)
.body(is("true"));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package io.quarkus.it.logging.minlevel.set;

import io.quarkus.test.junit.NativeImageTest;

@NativeImageTest
public class NativeLoggingMinLevelBelowChildIT extends LoggingMinLevelBelowChildTest {

// Execute the same tests but in native mode.
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public Map<String, String> start() {
systemProperties.put("quarkus.log.category.\"io.quarkus.it.logging.minlevel.set.bydefault\".level", "DEBUG");
systemProperties.put("quarkus.log.category.\"io.quarkus.it.logging.minlevel.set.above\".level", "WARN");
systemProperties.put("quarkus.log.category.\"io.quarkus.it.logging.minlevel.set.below\".level", "TRACE");
systemProperties.put("quarkus.log.category.\"io.quarkus.it.logging.minlevel.set.below.child\".level", "inherit");
systemProperties.put("quarkus.log.category.\"io.quarkus.it.logging.minlevel.set.promote\".level", "INFO");
return systemProperties;
}
Expand Down

0 comments on commit 5018a9f

Please sign in to comment.