Change Log4J Configuration for Apache Storm Topology - java

I'm currently submitting Storm topologies programatically via my Java application by using the following command:
Nimbus.Client client = NimbusClient.getConfiguredClient(stormConfigProvider.getStormConfig()).getClient();
client.submitTopology(
this.topologyID.toString(),
stormJarManager.getRemoteJarLocation(),
JSONValue.toJSONString(stormConfigProvider.getStormConfig()),
topology
);
In my scenario, I have two kinds of topologies. Testing topologies and production topologies. For both kind of topologies, I require different types of logging. While the testing topologies run with TRACE level, the production topologies will run with INFO level. In addition, I require that the production topologies have a SPLUNK Log4J2 appender configured, to centralize the logging of my production application.
For that, I included a log4j.xml file into my topology JAR which configures the SPLUNK appender. However, the log4j.xml file is not honored by the Server. Instead, the Storm Server seems to use its own configuration.
How can I change my log4j configuration for different topologies? (I don't want to modify the log4j.xml on each worker).

You can use https://storm.apache.org/releases/current/dynamic-log-level-settings.html to set log levels for each topology.
I'm not sure how you'd add/remove the splunk appender based on the loaded topology. You might be able to configure log4j programatically https://logging.apache.org/log4j/2.x/manual/customconfig.html and set the log4j2.configurationFactory system property on your workers to point to your configuration factory (you can do this by adding it to the topology.worker.childopts property in your topology config).
Just for context, here's where Storm sets the system property that causes Log4j to load the worker log4j configuration https://github.com/apache/storm/blob/4137328b75c06771f84414c3c2113e2d1c757c08/storm-server/src/main/java/org/apache/storm/daemon/supervisor/BasicContainer.java#L560. If you wanted to load a log4j2.xml included in your topology jar, maybe it would be possible to conditionally exclude that setting from the system properties set for workers. I think it would require a code change though, so you'd need to raise an issue on https://issues.apache.org/jira

Related

Logging.properties in WAR file ignored by Liberty server

I have a Maven java project, my logging.properties is placed under resources folder. I have configured to print FINE level messages using console logger.
The WAR file generated has the properties file under WEB-INF/classes but, the application when deployed and executed, I can see only INFO level logs.
Should i initialize any LogConfiguration apart from having my logging.properties in the correct path ?
As describe here, you configure loggers in Liberty by something like this in the server.xml:
<logging traceSpecification="*=audit:com.myco.mypackage.*=debug"/>
and see the logging metatype doc to configure other aspects like log file size, number of logs to keep, etc.
Or, as the article mentions, you can use the bootstrap.properties
entries to do the same, e.g. com.ibm.ws.logging.trace.specification.
Though WebSphere also supports java.util.logging APIs, its full infrastructure isn't necessarily configured the same way as say Tomcat, which your app may be patterned after.
If you want to configure different logging behavior for different applications you can have the application Java code use a different Logger name for each, and then configure them differently through the single server.xml config (or also potentially separate the apps out onto different servers).
Dynamically changing the trace settings on a running server can be done simply by editing the server.xml config (as can dynamically configuring almost any aspect of Liberty).

JBoss Logging for Java Unit Test?

I've inherited some java code that uses the JBoss Logging implementation explicitly. I know that this is normally configured as a JBoss Subsytem, and I'm able to observe various log tuning operations just fine when running on the server. However, I'm not getting any log message output for unit tests. I've dropped several configuration files on the test classpath to include:
logging.properties
log4j.xml
log4j2.xml
but have not seen any results. Has anyone been able to configure the JBoss Logging system such that they're visible outside of the container in unit tests? Is this even possible? The logging configuration guide didn't speak to how to do this.
You can make log4j.xml work, but you need to make sure that you have a compatible vanilla log4j version on the test classpath, e.g. 1.2.17, and that you don't have the modified version, log4j-jboss-logmanager, on the the classpath, which doesn't read log4j.xml.
Details.
See https://stackoverflow.com/a/18323126/1341535.
I take this:
I would recommend you configure the log manager using the logging
subsystem provided with the application server. This is the only way
to configure the server logging.
to imply that it's basically impossible to configure the JBoss Log Manager in tests, because there is no server subsystem configuration and nothing to parse it. Maybe you could configure it programmatically, but that's too inconvenient.
So this leaves us using the JBoss Logging facade with log4j for the log manager, which can be easily configured with log4j.xml.
Now, that I think of it, there is a logging.properties file in Wildfly, that configures logging before the logging subsystem is initialized. That means you can configure the JBoss Log Manager with logging.properties, you just need to put the relevant jars on the test classpath, probably jboss-logmanager and log4j-jboss-logmanager.
I will try to test the code using Arquillian Test Cases, it features the possibility to deploy parts of your code only to test it in a "real environment".
It is reccomended in a lot of RH JBoss documentation.
You can try reusing your junit code, and modify them using this guide: http://arquillian.org/guides/getting_started/
I'm not a guru of that technology. I hope it would help you.

Is it possible to get the root log level of Jboss Server, if custom loggers are used instead of logging service provided by the Server?

Following are the requirements,
multiple modules deployed on JBoss AS 7 with individual logging configuration using logback.xml.
all of them request exclusion of default logging-service provided by the Server, using jboss-deployment-structure.xml.
Following are observation,
log.debug statements get printed as INFO on Server log(server.log)
it's because root level of custom-logger(logback.xml) is set to DEBUG
Now questions,
How can I make, DEBUG statements generated by custom logging statement gets printed with appropriate log level?
Conversely, is it possible to get log level of Server without using it's logging service?
In other words, is it possible to achieve uniform log-level configuration across multiple modules that use custom-loggers?

Grails log configuration is hijacking the external log configuration, how to stop it?

I have a web application consisting of severals modules. All the modules are packaged together in one single ear.
One of them is a brand new groovy app, while others are more old school. This new grails app is not under my responsibility.
Notice that grails is not using any log4j.[properties|xml] file, but it as its own DSL which interact directly with log4j at runtime. This configuration is located inside a config.groovy script, packaged with the application.
Log4j is configured using an external file and the -Dlog4j.configuration option for the JVM.
The problem is the grail configuration is containing a very liberal config:
- set the root level to info
- add a console appender
The result is that the external configuration is hijacked by grails:
now there are two console appender (logging twice the same info) and lots of useless info data are logged.
Is there another solution than a programmatic approach, to tell grails to stop being rude ?
You could just turn off the grails logging so it uses the external logger
http://blog.saddey.net/2010/02/07/grails-how-to-use-native-server-logging-configuration-eg-tomcat-glassfish-jboss/

log4j configuration with Java Web Start

Our Java WebStart application does not include a log4j configuration file; it simply sets up some hardcoded loggers and appenders.
I would like individual clients to be able to drop a log4j.properties file in somewhere and set up their own custom logging in troubleshooting situations. I could bundle a log4j.properties file into one of the jars of our application somewhere and that would allow configuration, but then the configuration would be the same for each client instead of only affecting the client that I want to troubleshoot. Plus, I wouldn't be able to change settings on the fly.
Is there a way I can hijack the log4j initialization procedure to use a per-client configuration file?
The basic problem here, is that Java Web Start severely restricts the access to the machine.
You should be able to do this, if you are running a signed application AND the user allows you full access to the machine. If not, you cannot do this with log4j with the default mechanism.
You may want to write your own configurator which reads from the file system using the Java WebStart API an then feeds that to log4j, but it will require some elbow grease.
You could use the PersistenceService to store the log4j configuration on the local user's machine (works without signing), or at least store a flag on whether to load a special config or not at startup of your web start application.
There is also a FileOpenService with which the end-user could open a local log4j.xml file to re-configure the logging facility on the fly. That way, the user has the control over the configuration and he has the control when and where to apply it.
Your app code which uses the FileOpenService to get the stream to the log4j configuration file can then use the DOMConfigurator.configure(InputStream) to reconfigure log4j.

Categories

Resources