[ 
https://issues.apache.org/jira/browse/LOG4J2-589?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14147080#comment-14147080
 ] 

Remko Popma commented on LOG4J2-589:
------------------------------------

I'm assuming that users want to write code like this:
{code}
public class Driver {
    public static void main(String[] args) throws Exception {
        final Logger logger = LogManager.getLogger("LOG4J2-589");
        logger.error("an error message");
        logger.info("an info message");
        logger.log(Level.getLevel("DIAG"), "a DIAG message"); // either use 
Level.getLevel
        logger.log(Level.forName("NOTICE", 450), "a NOTICE message"); // or 
Level.forName should work too
    }
}
{code}

I'm also assuming that users want to use custom levels in configuration (the 
goal of this Jira):
{code}
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="trace">
  <CustomLevel name="DIAG" intLevel="350" />
  <CustomLevel name="NOTICE" intLevel="450" />
  <CustomLevel name="VERBOSE" intLevel="550" />

  <Appenders>
    <Console name="errorAppender" target="SYSTEM_OUT">
      <PatternLayout pattern="%d %-5p ERRORAPPENDER - %m%n" />
    </Console>
    <Console name="diagAppender" target="SYSTEM_OUT">
      <PatternLayout pattern="%d %-5p DIAGAPPENDER - %m%n" />
    </Console>
    <Console name="infoAppender" target="SYSTEM_OUT">
      <PatternLayout pattern="%d %-5p INFOAPPENDER - %m%n" />
    </Console>
  </Appenders>
  <Loggers>
    <Root level="trace">
      <AppenderRef ref="errorAppender" level="error" />
      <AppenderRef ref="diagAppender" level="diag" />
      <AppenderRef ref="infoAppender" level="debug" />
    </Root>
  </Loggers>
</Configuration>
{code}

Currently the configuration process ignores the {{<CustomLevel>}} elements and 
chokes on the unknown level in {{<AppenderRef ref="diagAppender" level="diag" 
/>}}:
{noformat}
2014-09-25 08:09:12,317 WARN Error while converting string [diag] to type 
[class org.apache.logging.log4j.Level]. Using default value [null]. 
java.lang.IllegalArgumentException: Unknown level constant [DIAG].
        at org.apache.logging.log4j.Level.valueOf(Level.java:283)
        at 
org.apache.logging.log4j.core.config.plugins.convert.TypeConverters$LevelConverter.convert(TypeConverters.java:230)
        at 
org.apache.logging.log4j.core.config.plugins.convert.TypeConverters$LevelConverter.convert(TypeConverters.java:226)
        at 
org.apache.logging.log4j.core.config.plugins.convert.TypeConverters.convert(TypeConverters.java:336)
        at 
org.apache.logging.log4j.core.config.plugins.visitors.AbstractPluginVisitor.convert(AbstractPluginVisitor.java:130)
        at 
org.apache.logging.log4j.core.config.plugins.visitors.PluginAttributeVisitor.visit(PluginAttributeVisitor.java:44)
        at 
org.apache.logging.log4j.core.config.plugins.util.PluginBuilder.generateParameters(PluginBuilder.java:246)
        at 
org.apache.logging.log4j.core.config.plugins.util.PluginBuilder.build(PluginBuilder.java:135)
        at 
org.apache.logging.log4j.core.config.AbstractConfiguration.createPluginObject(AbstractConfiguration.java:756)
        at 
org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:691)
        at 
org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:683)
        at 
org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:683)
        at 
org.apache.logging.log4j.core.config.AbstractConfiguration.doConfigure(AbstractConfiguration.java:358)
        at 
org.apache.logging.log4j.core.config.AbstractConfiguration.start(AbstractConfiguration.java:159)
        at 
org.apache.logging.log4j.core.LoggerContext.setConfiguration(LoggerContext.java:385)
        at 
org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:444)
        at 
org.apache.logging.log4j.core.LoggerContext.start(LoggerContext.java:151)
        at 
org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:85)
        at 
org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:37)
        at org.apache.logging.log4j.LogManager.getContext(LogManager.java:176)
        at org.apache.logging.log4j.LogManager.getLogger(LogManager.java:427)
        at log4j2_589_levelconfig.Driver.main(Driver.java:33)
{noformat}

A solution would be to have this plugin in core:
{code}
@Plugin(name = "CustomLevel", category = "Core")
public final class CustomLevelPlugin {
    private CustomLevelPlugin() {
    }
    @PluginFactory
    public static Level createLevel(
            @PluginAttribute("name") final String levelName,
            @PluginAttribute("intLevel") final int intLevel) {
        Level result = Level.forName(levelName, intLevel);
        return result;
    }
}
{code}
So the level does not only exist in configuration: the plugin ensures the Level 
object with the correct name/intLevel is instantiated. After that this Level 
can be used by components that are part of the configuration process, as well 
as by the user application.

If the level is not defined in the configuration, then
* the configuration process will choke if other config elements refer to this 
level, like  {{<AppenderRef ref="diagAppender" level="diag" />}}
* user code that uses Level.forName will work, but user code that uses 
Level.getName will fail with a NPE in 
Logger$PrivateConfig.filter(Logger.java:314)

> Allow the use of custom levels in configuration
> -----------------------------------------------
>
>                 Key: LOG4J2-589
>                 URL: https://issues.apache.org/jira/browse/LOG4J2-589
>             Project: Log4j 2
>          Issue Type: Improvement
>          Components: Configurators
>    Affects Versions: 2.0-rc1
>            Reporter: James Hutton
>              Labels: configuration, custom, level
>             Fix For: 2.2
>
>
> Previous title: Use forName instead of getLevel and valueOf for configuration
> Without this one cannot use custom log levels in configuration without 
> forking a large amount of code.  Either the forName method needs to be 
> removed and custom log levels should be explicitly forbidden, or support 
> should be consistent.
> Classes that would need to be modified:
> BaseConfiguration, NullConfiguration, and DefaultConfiguration.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org

Reply via email to