1

I need to allow deployers to specify the path for our Tomcat webapp log4j2 RollingFileLogger. I'd like to use JNDI but can use a plain -D param if I had to. This apache page seems to explain things pretty well.

Only problem is it doesn't work. I will admit to not being particularly experienced in JNDI, but I can't even get a simple JVM param to work. Reading about Property Substitution I got the impression I cannot just put the $${jndi:xxxx} in the filename attribute and that I should use a ${xxx} Property substitution instead. Unfortunately while that property substituion works fine no lookup jndi or env ever resolves.

log4j2.xml:

    <Properties>
       <Property name="filename">$${jndi:logPath/directory}/ief.log</Property>
    </Properties>
    ....
    <RollingFile name="RollingFileLogger" fileName="${filename}" immediateFlush="false" append="true"

Result:

2014-09-16 14:44:46,284 ERROR Unable to create file ${jndi:logPath/directory}/ief.log java.io.IOException: The filename, directory name, or volume label syntax is incorrect

As you can see the property is substituted but the lookup is not done. I am unsure what the context.xml entry should look like. But my best guess is:

<Resource name="logPath"
    auth="Container"
    directory="/tmp" />

I am using log4j version 2.0 but am fairly certain this is my misunderstanding not a bug. Any help clearing up what I'm doing wrong would be greatly appreciated.

Terry
  • 911
  • 10
  • 26

2 Answers2

1

I never found a JNDI browser that would work in Tomcat 7. But it did turn out to be a stupid problem. I defined this as a RESOURCE instead of an ENVIRONMENT. Just for the record the context.xml should look like:

<Environment name="logPath"
    auth="Container"
    type="java.lang.String"
    value="/tmp" />

And log4j2 lookup is then:

<Property name="logName">$${jndi:logPath}/iefrest.log</Property>
    <Property name="patternName">$${jndi:logPath}/iefrest</Property>
...
<RollingFile name="RollingFileLogger" fileName="${logName}" immediateFlush="false" append="true"
            filePattern="${patternName}-%d{yyyyMMdd-HH}.log.gz">

It is worth noting that the "java:comp/env" (which is clearly documented but misleading to people that don't have a deep knowledge of JNDI - like me) actually maps to the Environment XML element and does not imply a prefix to the name attribute.

From a Log4J2 prespective it is also interesting that the filename attribute is taken EXACTLY as provided. Specifically you cannot say filename="${logName}.log". This will not parse into the desired results. However expected concatenation DOES take place on the filepattern attribute. Inconsistent but not unmanageable.

Terry
  • 911
  • 10
  • 26
0

If you specify $${jndi:logPath/directory}, the lookup will add the prefix java:comp/env/, so the full value that it will look up is java:comp/env/logPath/directory. (This prefix is not added if your jndi lookup key already contains a ':' character.) Perhaps you can use a JNDI browser to see if this gives you the expected value.

Any errors that occur during this lookup will be logged to the status logger at WARN level. Status logs appear in the console. You can enable status logs by specifying <Configuration status="trace" ... in your log4j2.xml configuration file.

Remko Popma
  • 35,130
  • 11
  • 92
  • 114