Log4j2's FailoverAppender Error: appender Failover has no parameter that matches element Failovers

泄露秘密 提交于 2019-12-04 06:53:34

What I have seen while debugging is the PluginBuilder#verifyNodeChildrenUsed() method is called to, you would expect, verify that the child elements of the Node are correct. As I describe below, this method name does not match the behaviour.

In the case of a Failover appender, the plugin type is: (btw, the extra "==" at "isDeferChildren" is just in the toString() implementation and does not affect the test.)

PluginType [pluginClass=class org.apache.logging.log4j.core.appender.FailoversPlugin, key=failovers, elementName=failovers, isObjectPrintable=false, isDeferChildren==false, category=core]

The implementation of this method:

private void verifyNodeChildrenUsed() {
    final List<Node> children = node.getChildren();
    if (!(pluginType.isDeferChildren() || children.isEmpty())) {
        for (final Node child : children) {
            final String nodeType = node.getType().getElementName();
            final String start = nodeType.equals(node.getName()) ? node.getName() : nodeType + ' ' + node.getName();
            LOGGER.error("{} has no parameter that matches element {}", start, child.getName());
        }
   }
}

When the nodeType is the FailoversPlugin class (see above), the node type is "appender" but the name is "Failovers". So the test of equality produces the string "appender Failovers".

What I haven't dug into fully is WHY this method is called such that if the node is not empty and the property of deferring is false, the error message MUST be displayed. It seems to me that the logic here is dependent on something up-the-stack and tracing through this is cumbersome.

What I'd really like to do is ask the developer responsible what's the intention, because it's not clear to me that the behaviour is correct. Well, obviously that's true in this case. :S

This is a bug in log4j. I've pointed out the error in the issue linked to by @Deses. For the time-being, here's a workaround:

/**
 * Avoids a bug in log4j, whereby plugins that produce an array (e.g. {@linkplain FailoversPlugin})
 * cause an error to be logged.
 * <p>
 * To use, instead of this:
 * <pre>
 * &lt;Failover name="MyAppender" primary="xxx">
 *   &lt;Failovers>
 *     &lt;AppenderRef ref="fallback1"/>
 *     &lt;AppenderRef ref="fallback2"/>
 *   &lt;/Failovers>
 * &lt;/Failover>
 * </pre>
 * do this:
 * <pre>
 * &lt;Failover name="MyAppender" primary="xxx">
 *   &lt;Fallback ref="fallback1"/>
 *   &lt;Fallback ref="fallback2"/>
 * &lt;/Failover>
 * </pre>
 */
@Plugin(name="Fallback", category=Node.CATEGORY, elementType="Failovers")
public class Fallback {

    private Fallback(){}

    @PluginFactory
    public static String createFallbackRef(@PluginAttribute("ref") @Required String ref) {
        return ref;
    }

}

Just stick this on your compile and runtime classpaths, and make sure annotation processing is enabled.

For anyone that runs into this problem, it's a bug in log4j2.

I ran into this JIRA issue and found this commentary in its xml config file:

<!-- set status below to FATAL to suppress a bug in log4j2: "ERROR appender Failover has no parameter that matches element Failovers" -->
<!--  other working value for status is "warn" -  -->

Not much else to do.

I had a similar issue and i had commented the failover tags in Log4j xml and all my logs are getting created now

in my case, you should add ignoreExceptions filed on both primary and failovers.

`<Console name="Console-Appender" target="SYSTEM_OUT" ignoreExceptions="false">
            <PatternLayout>
                <pattern>${log-pattern}</pattern>
            </PatternLayout>
</Console>`
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!