log4j2 lookup default value with empty contextPath - log4j2

Trying to create a log4j2 configuration using the ${web:contextPath} lookup worked fine, until I tried to use that with an empty contextPath.
Is there a way to specify a default value if the lookup returns an empty string?
If the contextPath is empty, I would like to specify a default value somehow.

You can define a fallback value within the configuration like so:
${web:contextPath:-default-value}
("default-value" being the fallback value). Note the hyphen in front of the fallback.

Try to define it as a property in the config.
For an xml config
<Properties>
<Property name="contextPath">default value</Property>
</Properties>
Assuming that the web lookup process works the same as a system property lookup then it should fall back to the value defined in the properties section if the web lookup fails.

Related

Dropwizard configuration with list of strings in environment variable with default fallback?

Dropwizard takes .yml configurations which of course allow lists. It also has the ${FOO:-bar} syntax which allows reading environment variables with default fallback.
Is there a way to read lists of strings from an env variable and parse automatically with Dropwizard or do I have to do it manually? What is the syntax to have a default fallback list if this exists? I could not find this in their documentation.
Thic can be achived by using a json format in the default parameter:
supported_locales: ${SUPPORTED_LOCALES:-[en,da_DK,pt_BR,es]}
This will make a config parameter called supported_locales which takes a SUPPORTED_LOCALES env variable (json array of strings format), and defaults to the array provided after the - character in this case [en,da_DK,pt_BR,es]

How to fall back to log4j2.xml when custom configurationFile is missing

My environment : JBoss EAP 7 with a "log4j2.xml" in classpath (historic behavior).
I would like to introduce a way to have a (non mandatory) custom log4j2 configuration file (per EAR application) but still use (fall back) to (existing) "log4j2.xml" if the custom configuration file is missing.
To me, the only way to accomplish this was to use composite configuration by using "log4j2.configurationFile" property (within log4j2.component.properties) and set both the "log4j2.xml" and the custom configuration filename (separated by a comma).
But if the custom file is missing, even the generic "log4j2.xml" is ignored.
When looking at log4j2 (v2.12.1) code (https://github.com/apache/logging-log4j2/blob/log4j-2.12.1/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ConfigurationFactory.java#L380) I can see that indeed if one config file is missing, none config file (of the list) is used (-> "return null")
Is there a way to accomplish the behavior I want?
Thanks

ANT Reading property from property files, using an ANT property

simple question for you..
I have a property file with a value like this
CommercialManager=MOT
CommercialUser=AT
CommercialAdmin=POT
I'm calling an Ant Script from Jenkins, passing some variables..
some of these variables are used to get a dynamic property from the property file..
I'm saying that if i select into the jenkins job the CommercialAdmin variable from a select list i want to get the property with that name.
The value selected into the Jenkins JOB is set inside a variable ROLE, that is passed to my ANT script..
Below my code:
<property file="Profiles.properties" prefix="profiles"/>
<echo>${profiles.CommercialManager}</echo>
Doing like this everything works fine, it prints out
MOT
But as you can see the value is not dynamic, is not the one taken from jenkins job..
So i should do something like this:
<echo>${ROLE}</echo>
But if I do something like this, the print returns the value of the property ROLE that is:
profiles.CommercialManager
and not the value taken from the properties file..
How can i manage this? I think its easy but, its late, and i swimming into a sea of confusion..
Thanks a lot!
There are a number of ways to dynamically get a property value from a variable described in other threads:
In Ant, how can I dynamically build a property that references a property file?
Dynamic property names in ant
Personally, I would use javascript:
<property file="Profiles.properties" prefix="profiles"/>
<script language="javascript"><![CDATA[
project.setProperty("CommercialManager", project.getProperty("${Role}"))
]]>
</script>
<echo>${CommercialManager}</echo>

Parameter substitution in log4j2

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.
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.
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.

Grails g:link - include app name in resulting anchor href attribute

This GSP:
<g:link controller="book" action="show" id="5">Example</g:link>
results in this HTML:
Example
This is relative to the HTTP host. If your site is running at http://localhost:8080 that's fine.
During development, an app will more commonly be running at http://localhost:8080/appName.
In such cases, the above link will not work - it will result in an absolute URL of http://localhost:8080/book/show/5 instead of the required http://localhost:8080/appName/book/show/5
What changes are required of the above GSP for the app name to be present in the resulting anchor's href?
The configuration setting grails.app.context should be equal to the context where you want your application deployed. If it's not set, as in the default configuration, it defaults to your application name, like http://localhost:8080/appName. If you want to deploy your app in the root context (e.g. http://locahost:8080/), add this to your Config.groovy:
grails.app.context = "/"
If the context is properly set, the URLs generated by g:link tags will include the context before the controller name.
I found that the meta tag is very useful for getting information in GSP files.
For example, if you want your application name, you can get it like this:
<g:meta name="app.name"/>
You can get any property in your application.properties file like that.
And if you, like me, need to concatenate it to another value, here is my example. Remember that any tag can be used as a method without the g: namespace. For example:
<g:set var="help" value="http://localhost:8080/${meta(name:"app.name")}/help" />
Grails documentation about this is a little poor, but it is here.
For me the single best reason to use <g:link> is that it adds the context if there is one, or omits it if you're running at http://localhost:8080 or in prod at http://mycoolsite.com - it's trivial to just concatenate the parts together yourself otherwise.
The same goes for using g:resource with css, javascript, etc. - it lets you have one GSP that works regardless of what the context is (e.g. 'appName'), since it's resolved at runtime.
I think that is what grails.serverURL is for. You defined this config variable in the Config.groovy, check the configuration documentation for Grails for more details.
Hope this helps!
createLink tag includes your appname / context parameter automatically in the link.
Here is reference doc for it.

Resources