Log4jConfigurator.java

1
package com.reallifedeveloper.common.infrastructure.jmx;
2
3
import java.util.List;
4
import java.util.Optional;
5
import java.util.stream.Stream;
6
7
import org.apache.logging.log4j.Level;
8
import org.apache.logging.log4j.core.Logger;
9
import org.apache.logging.log4j.core.LoggerContext;
10
import org.springframework.jmx.export.annotation.ManagedAttribute;
11
import org.springframework.jmx.export.annotation.ManagedOperation;
12
import org.springframework.jmx.export.annotation.ManagedOperationParameter;
13
import org.springframework.jmx.export.annotation.ManagedOperationParameters;
14
import org.springframework.jmx.export.annotation.ManagedResource;
15
16
import com.reallifedeveloper.common.domain.ErrorHandling;
17
18
/**
19
 * An implementation of the JMX {@link LogConfiguratorMXBean} interface using Log4j.
20
 *
21
 * @author RealLifeDeveloper
22
 */
23
@ManagedResource(description = "Log4j Configuration")
24
public class Log4jConfigurator implements LogConfiguratorMXBean {
25
26
    @Override
27
    @ManagedAttribute(description = "The available loggers")
28
    public List<String> getLoggers() {
29
        List<String> configLoggers = getContext().getConfiguration().getLoggers().entrySet().stream()
30
                .map(entry -> entry.getKey() + "=" + entry.getValue().getLevel()).toList();
31
        List<String> contextLoggers = getContext().getLoggers().stream().map(l -> l.getName() + "=" + l.getLevel()).toList();
32 1 1. getLoggers : replaced return value with Collections.emptyList for com/reallifedeveloper/common/infrastructure/jmx/Log4jConfigurator::getLoggers → KILLED
        return Stream.concat(configLoggers.stream(), contextLoggers.stream()).distinct().toList();
33
    }
34
35
    @Override
36
    @ManagedOperation(description = "Gives the log level for a logger")
37
    @ManagedOperationParameters({ @ManagedOperationParameter(name = "logger", description = "The name of the logger") })
38
    public String getLogLevel(String loggerName) {
39
        return getLoggerIfExists(loggerName).map(l -> l.getLevel().name()).orElse("unavailable");
40
    }
41
42
    @Override
43
    @ManagedOperation(description = "Sets the log level for a logger")
44
    @ManagedOperationParameters({ @ManagedOperationParameter(name = "logger", description = "The name of the logger"),
45
            @ManagedOperationParameter(name = "level", description = "The new log level") })
46
    public void setLogLevel(String loggerName, String level) {
47 2 1. setLogLevel : negated conditional → KILLED
2. setLogLevel : negated conditional → KILLED
        if (isNotBlank(loggerName) && isNotBlank(level)) {
48
            Level logLevel = Level.getLevel(level);
49 1 1. setLogLevel : negated conditional → KILLED
            if (logLevel != null) {
50
                Logger logger = getOrCreateLogger(loggerName);
51
                logger.setLevel(logLevel);
52
            }
53
        }
54
    }
55
56
    @SuppressWarnings("PMD.CloseResource") // Closing the LoggerContext shuts down logging.
57
    private static Optional<Logger> getLoggerIfExists(String loggerName) {
58 1 1. getLoggerIfExists : removed call to com/reallifedeveloper/common/domain/ErrorHandling::checkNull → KILLED
        ErrorHandling.checkNull("loggerName must not be null", loggerName);
59
        LoggerContext context = getContext();
60
        if (context.hasLogger(loggerName) || context.getConfiguration().getLoggers().containsKey(loggerName)) {
61
            return Optional.of(context.getLogger(loggerName));
62
        } else {
63
            return Optional.empty();
64
        }
65
    }
66
67
    private static Logger getOrCreateLogger(String loggerName) {
68
        return getContext().getLogger(loggerName);
69
    }
70
71
    private static LoggerContext getContext() {
72
        return LoggerContext.getContext();
73
    }
74
75
    private static boolean isNotBlank(String s) {
76 3 1. isNotBlank : replaced boolean return with true for com/reallifedeveloper/common/infrastructure/jmx/Log4jConfigurator::isNotBlank → KILLED
2. isNotBlank : negated conditional → KILLED
3. isNotBlank : negated conditional → KILLED
        return s != null && !s.isBlank();
77
    }
78
}

Mutations

32

1.1
Location : getLoggers
Killed by : com.reallifedeveloper.common.infrastructure.jmx.Log4jConfiguratorTest.[engine:junit-jupiter]/[class:com.reallifedeveloper.common.infrastructure.jmx.Log4jConfiguratorTest]/[method:getLoggers()]
replaced return value with Collections.emptyList for com/reallifedeveloper/common/infrastructure/jmx/Log4jConfigurator::getLoggers → KILLED

47

1.1
Location : setLogLevel
Killed by : com.reallifedeveloper.common.infrastructure.jmx.Log4jConfiguratorTest.[engine:junit-jupiter]/[class:com.reallifedeveloper.common.infrastructure.jmx.Log4jConfiguratorTest]/[method:setLogLevelNullLevel()]
negated conditional → KILLED

2.2
Location : setLogLevel
Killed by : com.reallifedeveloper.common.infrastructure.jmx.Log4jConfiguratorTest.[engine:junit-jupiter]/[class:com.reallifedeveloper.common.infrastructure.jmx.Log4jConfiguratorTest]/[method:setLogLevelNullLoggerName()]
negated conditional → KILLED

49

1.1
Location : setLogLevel
Killed by : com.reallifedeveloper.common.infrastructure.jmx.Log4jConfiguratorTest.[engine:junit-jupiter]/[class:com.reallifedeveloper.common.infrastructure.jmx.Log4jConfiguratorTest]/[method:setLogLevelIncorrectLevel()]
negated conditional → KILLED

58

1.1
Location : getLoggerIfExists
Killed by : com.reallifedeveloper.common.infrastructure.jmx.Log4jConfiguratorTest.[engine:junit-jupiter]/[class:com.reallifedeveloper.common.infrastructure.jmx.Log4jConfiguratorTest]/[method:setLogLevelNonExistingLoggerName()]
removed call to com/reallifedeveloper/common/domain/ErrorHandling::checkNull → KILLED

76

1.1
Location : isNotBlank
Killed by : com.reallifedeveloper.common.infrastructure.jmx.Log4jConfiguratorTest.[engine:junit-jupiter]/[class:com.reallifedeveloper.common.infrastructure.jmx.Log4jConfiguratorTest]/[method:setLogLevelNullLevel()]
replaced boolean return with true for com/reallifedeveloper/common/infrastructure/jmx/Log4jConfigurator::isNotBlank → KILLED

2.2
Location : isNotBlank
Killed by : com.reallifedeveloper.common.infrastructure.jmx.Log4jConfiguratorTest.[engine:junit-jupiter]/[class:com.reallifedeveloper.common.infrastructure.jmx.Log4jConfiguratorTest]/[method:setLogLevelNonExistingLoggerName()]
negated conditional → KILLED

3.3
Location : isNotBlank
Killed by : com.reallifedeveloper.common.infrastructure.jmx.Log4jConfiguratorTest.[engine:junit-jupiter]/[class:com.reallifedeveloper.common.infrastructure.jmx.Log4jConfiguratorTest]/[method:setLogLevelNullLoggerName()]
negated conditional → KILLED

Active mutators

Tests examined


Report generated by PIT 1.20.0