Mule not honouring log4j2.component.properties or log4j2.system.properties - log4j

I've a mule application which needs to load log4j2.xml from different locations as per the environment shown below.
app1
dev --> /etc/dev/app1/log4j2.xml
sit --> /etc/sit/app1/log4j2.xml
. . .
prod --> /etc/prod/app1/log4j2.xml
I don't want to use spring bean loading as by the time this bean is loaded, Mule would have already initiated log context for this app1 with default configuration and writes few logs to it.
Within log4j functionality, there are log4j2.system.properties and log4j2.component.properties files. When either of them is added to classpath (src/main/resources) with log4j.configurationFile property in it, it is supposed to pick up this file during application startup itself.
Reference: Log4j System Properties
log4j.configurationFile=${config.path}/app1/log4j2.xml
config.path is defined in wrapper as system property and available to app1 holding the env path ("/etc/dev" if dev or "/etc/sit" if sit etc..)
However, both of these files are not picking up by Mule and resolving to default configuration.
Can someone please assist in making any of these files pick up by Mule during application startup itself?

After long research, we have to update mule_artifact.json with "logConfig" key to define the location of external log4j2.xml file in server relative to mule_home path.
The same path may not work in local but you can create "mklink" to resemble server path in local.
I've tested successfully both.

Related

How to enable /disable the RequestLogger in console?

Want to print API request in log with the help of RequestLogger. We have log4j properties file ,log4j dependency entry is there in pom and also POM is referring the log4j properties file too.
We have log4j properties under resources and also added dependency in POM file . And tried to dd
RequestLogger requestLogger = new RequestLogger(NullPrintStream.NULL_PRINT_STREAM);
TestBaseProvider.instance().get().getContext().setProperty("rest.client.requestlogger", requestLogger);
the above lines in OnStart listener method. But nothing works fine, Can anyone please guide how we can print api requests in log.
Looking at the source code of RequestLogger, it can operate in two ways: by sending messages to Jakarta Commons Logging or to a PrintStream, depending on the constructor you use:
by calling new RequestLogger(NullPrintStream.NULL_PRINT_STREAM) you send everything to a PrintStream, which:
Writes all data to the famous /dev/null.
This print stream has no destination (file/socket etc.) and all bytes written to it are ignored and lost.
by calling new RequestLogger(), you send everything to JCL, which is a logging API with a configurable backend. If you use Log4j2 and have log4j-jcl on the classpath, JCL will choose Log4j2. If you use the (EOL-ed) Log4j 1.2 and have no other JCL binding on the classpath, JCL will choose this one.

When IBM WAS starts it gives log4j : WARN Please initialize the log4j system properly

I am using IBM WAS as my server for my application.I have given log4j.properties in classpath of IBM WAS.It works fine.I want to change the name of log4j.properties to something like abclog4j.properties.My application is Eclipse based.
If I change it and start my server it gives me log4j : WARN Please initialize the log4j system properly error
How can I change it's name?
According to this page: http://logging.apache.org/log4j/1.2/manual.html
The preferred way to specify the default initialization file is through the log4j.configuration system property. In case the system property log4j.configuration is not defined, then set the string variable resource to its default value "log4j.properties".
So if you set the log4j.configuration system property before log4j is dynamically loaded (i.e., referenced in any object), then log4j will use that value for the name of the config file.
System.setProperty("log4j.configuration","abclog4j.properties");
You could do this in a static block at the beginning of some base class so that it is set before any log4j references are encountered.

Cannot read properties file with web app (Maven web app with JSF)

I have a properties file: hibernate.properties inside default package. I am trying to read it from a class inside another package: com.somepackage.SomeClass.
In a normal desktop application, the following input stream is working:
InputStream is = getClass().getResourceAsStream("/hibernate.properties");
But with my web app (A maven web application created using Netbeans with JSF 2.2 as dependency)
I tried these alternatives:
Using class:
getClass().getResourceAsStream("/hibernate.properties");
Using external context:
FacesContext.getCurrentInstance().getExternalContext().getResourceAsStream("/hibernate.properties");
Using context class loader:
Thread.currentThread().getContextClassLoader().getResourceAsStream("/hibernate.properties");
Each of these return null. How do I read the properties file inside the default package?
I assume you are looking on the wrong location for the file. hibernate.properties is usually not saved in the root of the deployment. Open your .war file and look up the location of hibernate.properties. If you have your application deployed to localhost:8080/app1 you need to call /app1/ to access the contents of your deployment.

Change configuration in runtime by changing environment variables using the module node-config

I'm trying to use the node-config module to change some parameters of my configuration (basically logging level) during runtime.
In the official documentation says:
Environment variables can be used to override file configurations. Any environment variable that starts with $CONFIG_ is set into the CONFIG object.
I've checked that this is true when the server starts but it does not seem to work once it's up. (The handler of the watch function is never called when an environment variable is changed unlike a change in the runtime.json file or directly changing a config variable).
I'm currently watching the whole CONFIG object like this:
var CONFIG = require('config');
CONFIG.watch( CONFIG , null , function(object, propertyName, priorValue, newValue){
console.log("Configuration change detected");
});
Does anyone know if this is possible?
The environment is available during startup of a process.
If the process is running, you won't be able to change the environment anymore, the process is in.
The only option is to restart the process or use other mechanisms to communicate with it.
Say for example having a rest or tcp listener inside, where you can transfer your variable inside.
Best regards
Robert
As you must knowing, React is a single page application which is eventually when it is complied is a static page app that means all the files of the react application is complied into vanilla JS and CSS file bundle in a Tarball. Now that Tarball is eventually deployed on a web server. It could be Apache web server, nginx web server or anything which you are using it but an important point is the static app is running in someone else browser and someone access to website CSS and JS are downloaded in a browser and it is running in the browser runtime environment so technically you cannot have a runtime environment variable for someone else browser but may be there would be a way to access them during runtime.
SOLUTION
I have achieved this goal with the package called runtime-cra.
follow the steps on this official documentation: https://blog.risingstack.com/create-react-app-runtime-env-cra/

ClassLoader - Loading and saving data

Hopefully someone can help me with this.
It is my understanding that using a ClassLoader is the most reliable way to load in content.
public class Pipeline{
public static URL getResource(String filename) {
return ClassLoader.getSystemResource(filename);
}
public static InputStream getResourceAsStream(String filename) {
return ClassLoader.getSystemResourceAsStream(filename);
}
}
If you had a file at "[jar bundle]/resources/abc.png" ..You would load it by:
URL url = Pipeline.getResource("resources/abc.png");
Loading is simple.
Saving is what's getting me.
I have a program that collects data while running, saves that data on exit, and then loads the data back in next time and keeps adding to it.
Easiest solution I think would be to save back into the jar bundle so that ClassLoader can get at them. Is this even possible? Or recommended?
I don't mind having my resources outside of the jar, just as long as I don't have to resort to 'File' to get at them and save to them. (Unless it can be done cleanly)
folder/application.jar
folder/resources/abc.png
If you could ../ back one from where the ClassLoader is looking it would be easy to cleanly get data from the directory that actually contains the jar file
Pipeline.getResource("../resources/abc.png");
Any ideas?
This isn't really what class loaders are meant for. Loading resources from the class loader is meant so that you can bundle up your application as one package and components can read each other without worrying about how the system you're deploying to is setup.
If the file in the JAR is meant to be changed by the app, then it isn't part of the app and thus probably shouldn't be in the JAR.
I don't have a lot of context on your app, but hopefully my suggestion will be valid for your situation.
I recommend setting a requirement in your app that it has a work area to which it is allowed to read and write and accept a configuration setting that specifies where this directory is. Typical ways to do this in Java are with environment variables, system properties or JNDI settings (for container deployments).
Examples:
Tomcat's startup scripts figure out where it is installed and sets a system property called catalina.home and allows you to over-ride it with an environment variable called CATALINA_HOME.
JBoss looks for JBOSS_HOME
Java application servers typically look for JAVA_HOME to find the JDK.

Resources