How are logger names defined in Log4j v1 properties configuration? - log4j

I'm attempting to convert Log4j v1 properties configuration into some form of Log4j v2 config, but the problem is that I don't know what I'm reading when I look at the v1 properties file. Very little documentation is available for Log4j v1 configuration. In particular, I've managed to infer over six months of work that standard (non-Root) loggers must have defined names. These names appear to be defined implicitly, but the documentation is utterly worthless, and I can't find any clear statement from the developers about how that implicit process works.
Of the following examples I've been able to pull from the Internet, which lines define the names of individual loggers, and which define other properties? Of the lines that define names, what are those names?
log4j.logger.org.apache.axis.utils=ERROR
log4j.logger.strike=DEBUG
log4j.logger.strike.textfiles=DEBUG
log4j.logger.org.krake.strike.trace=INFO
log4j.logger.org.medusa.orm.armadillo.Loader=DEBUG
log4j.logger.org.medusa.orm.armadillo.functions.ProcessBulkErrors=WARN
log4j.logger.org.medusa.orm.engine.Armadillo=INFO
log4j.logger.org.medusa.orm.armadillo.lib=INFO
log4j.logger.org.medusa.orm.armadillo.ORM2ExecutionContext=DEBUG
log4j.logger.org.medusa.orm.armadillo.lib.GetFieldValue=DEBUG
log4j.logger.org.medusa.orm.toolkit.ORMt2ORMx=DEBUG
log4j.logger.org.krake.box.abstraction.slidr.service.job.manager.Cpu=DEBUG
log4j.logger.org.krake.box.abstraction.slidr.service.job.manager.Block=DEBUG
log4j.logger.org.krake.box.abstraction.slidr.service.job.manager.SimpleCloudWorkerManager=INFO
log4j.logger.org.krake.box.abstraction.impl.scheduler.common.AbstractExecutor=DEBUG
log4j.logger.org.krake.box.abstraction.impl.scheduler.pbs.PBSExecutor=DEBUG
log4j.logger.org.krake.box.armadillo.workflow.events.WorkerSweeper=WARN
log4j.logger.org.krake.box.armadillo.workflow.nodes.FlowNode=WARN
log4j.logger.org.krake.box.armadillo.scheduler.WeightedHostScoreScheduler=INFO
log4j.logger.org.krake.box.abstraction.impl.common.task.TaskImpl=INFO
log4j.logger.org.krake.box.abstraction.slidr.rlog=INFO
log4j.logger.com.senatus.impl.execution.ec2=DEBUG
log4j.logger.com.endeca=INFO
log4j.logger.com.endeca.itl.web.metrics=INFO
In short, what is the actual algorithm for defining logger names in Log4j v1's properties-based configuration?

In older software like Log4j 1.2 the best documentation is the javadoc. In the PropertyConfigurator javadoc you can find out that all properties of the form:
log4j.logger.logger_name=[level|INHERITED|NULL], appenderName, appenderName, ...
configure loggers and the logger name is the part of the key after the log4j.logger. prefix.
Other logger configuration options are only described in the source code. For example to configure the logger additivity you need to use this form:
log4j.additivity.logger_name=[true|false]

Related

log4j "bridge" and the RootLogger class

We're trying to force an old vendor-provided Java-program (a JAR) to use log4j2, with the help of the log4j "bridge".
To do this, I:
Deleted all entries starting with org/apache/log4j/* from the vendor's JAR
Added the log4j-1.2-api-2.17.1.jar and the regular log4j-*-2.17.1.jar files to CLASSPATH
The program dies unable to find the org/apache/log4j/spi/RootLogger. Listing the contents of the bridge JAR, I find several classes under the org/apache/log4j/spi/, but the RootLogger is, indeed, missing.
How do I deal with this?
The newest version 2.17.2 of Log4j2 contains a couple of dozen of fixes to the Log4j 1.x bridge (cf. changelog).
Among them the org.apache.log4j.RootLogger class has been added to provide binary compatibility with Log4j 1.x.
Warning: many of the added classes are no-ops and just prevent ClassNotFoundExceptions as the one in your question.

Environment Variables in Hybris local.properties

I'm wondering if, in a Hybris properties file, there is a way to reference environment variables.
For example, in local.properties:
my.property = ${MY_ENVIRONMENT_VARIABLE}
My searching has concluded that this is possible in Spring, but doesn't appear to work in Hybris.
Any thoughts would be appreciated.
It's possible to access to environment variables within hybris. A partner of my company found out this deep down in hybris documentation:
Platform allows you to specify properties also as environment variables
# security: make the platform *abort startup* if no one overrides the settings below
db.url=<CHANGE_ME>
db.username=<CHANGE_ME>
db.password=<CHANGE_ME>
# security: end
The special property value has been introduced exactly for such use cases where administrators want to ensure that: a) files do not contain sensible settings, and b) the system doesn't start up if those settings haven't been overridden.
On the server, those settings are to be exposed as environment variables just before starting Platform:
foo$ export y_db_url=jdbc:mysql://my.secret-db-host.com/AlfavaMetraxis?useConfigs=maxPerformance&characterEncoding=utf8
foo$ export y_db_username=Amy
foo$ export y_db_password=Rory
foo$ ./hybrisserver.sh start
...
As you can see, settings need to be prefixed and escaped in order to work as environment variable.
https://help.sap.com/viewer/a74589c3a81a4a95bf51d87258c0ab15/1905/en-US/8b8e13c9866910149d40b151a9196543.html?q=CHANGE_ME
Hope this is useful for you.
I found this related to your question on Hybris Experts. Hope it helps.
It is not possible to access shell environment variables inside local.properties file. As a workaround you can do echo "my.property = $MY_ENVIRONMENT_VARIABLE" >> local.properties before starting platform.
No it's not possible.
Actually hybris use org.apache.commons.configuration package. In the documentation you'll find that it's possible to use environment variable.
user.file = ${sys:user.home}/settings.xml
action.key = ${const:java.awt.event.KeyEvent.VK_CANCEL}
java.home = ${env:JAVA_HOME}
Unfortunately hybris has done something I can't explain, they have overidded the default implementation and removed all interpolation features.
If we analyze the issue further, the configuration class used is called HybrisConfiguration. This class extends AbstractConfiguration from Apache Commons Configuration. The getProperty method use an other interface called ConfigIntf. The implementation is found in the class AbstractConfig. There every getString getInteger, etc... methods are overrided.
For example, for String, the method does not call the interpolate method but instead you'll find a really simple...
StringUtils.isEmpty(value) ? def : value;
So if you want to use all features of Apache API, then try to replace hybris implementation... However I think that it won't be so easy to do that without modifying the platform since I don't see any beans there that could be injected.

Groovy - extensions structure

I'd like to extend String's asType method to handle LocalDateTime. I know how to override this method, however I've no idea where should I put it in project structure to work globally - for all strings in my project. Is it enough to put such extension wherever in the classpath? I know that there's a special convention for extensions (META-INF/services), how does it work for method overriding?
All documentation regarding this topic can be found here. And here exactly the relevant part can be found.
Module extension and module descriptor
For Groovy to be able to load your extension methods, you must declare
your extension helper classes. You must create a file named
org.codehaus.groovy.runtime.ExtensionModule into the META-INF/services
directory:
org.codehaus.groovy.runtime.ExtensionModule moduleName=Test module for
specifications moduleVersion=1.0-test
extensionClasses=support.MaxRetriesExtension
staticExtensionClasses=support.StaticStringExtension The module
descriptor requires 4 keys:
moduleName : the name of your module
moduleVersion: the version of your module. Note that version number is
only used to check that you don’t load the same module in two
different versions.
extensionClasses: the list of extension helper classes for instance
methods. You can provide several classes, given that they are comma
separated.
staticExtensionClasses: the list of extension helper classes for
static methods. You can provide several classes, given that they are
comma separated.
Note that it is not required for a module to define both static
helpers and instance helpers, and that you may add several classes to
a single module. You can also extend different classes in a single
module without problem. It is even possible to use different classes
in a single extension class, but it is recommended to group extension
methods into classes by feature set.
Module extension and classpath
It’s worth noting that you can’t use an extension which is compiled at
the same time as code using it. That means that to use an extension,
it has to be available on classpath, as compiled classes, before the
code using it gets compiled. Usually, this means that you can’t have
the test classes in the same source unit as the extension class
itself. Since in general, test sources are separated from normal
sources and executed in another step of the build, this is not an
issue.

Inherit XSD namespace prefix

I have a lot XSD which access each other.
Since I'm changing to JAXB I'm currently looking for a straightforward way to add namespaces to the xsds according to their folder structure.
My main issue at the moment is to add the namespace to the XSD itself, to the import in the accessing file and also to the prefix definition in the accessing file.
Here a small example (not quite real live)
User.xsd - targetNamespace="common.user"
Message.xsd - targetNamespace="common.message"
Email.xsd - targetNamespace="email" xmlns:user="common.user" xmlns:message="common.message"
import namespace="common.user" schemaLocation="./common/user.xsd"
import namespace="common.message" schemaLocation="./common/message.xsd"
When I now have a new Message.xsd schema I have to duplicate 90% of my xsd header.
I was creating a Namespace.xsd xmlns:user="common.user" xmlns:message="common.message" which is then included by Email.xsd. But accessing e.g. user:name did not work.
Is there a way to save the namespace-prefix definition in a central XSD-file so I do not have to define them in every single xsd?
Also, is there a way to not need to set the namespace in the import when it is already defines in the imported xsd as targetNamespace?
I think (not 100% sure though) that including into the schema A a schema B which imports another schema C will give you access to C in A.
However you will still need to declare the namespace prefix (like xmlns:user="common.user").
ps. Just a warning - never ever do chameleon schemas. It does not seem that you plan to, but i still wanted to warn.

groovy typesafe configurations with ConfigObject and ConfigSlurper

I am using a groovy configuration file and parse it with ConfigSlurper resulting in a ConfigObject that I use for accessing my configuration. The disadvantage is that I have no help from eclipse regarding if properties exist - every configuration property is underlined as groovy/eclipse do not know which properties the (dynamic) ConfigObject has. Refactoring is also not possible - for example if I rename a property in the config, groovy/eclipse does not recognise its usages in the sourcecode and does not rename it there.
Are there ways to fix or workaround these two issues?
Groovy-eclipse DSL Descriptors come to mind:
Also, #TypeChecked extensions may be used if you want type safety in your DSL.

Resources