I am using SLF4J in my application which is deployed on websphere liberty profile. I want to configure it so that 1- logging configuration (such as log4j properties if I use log4j with slf4j) resides outside the application war file, 2 - The logging configuration applies only to my application and not to other applications deployed on the same profile.
(1) can be achieved by using slf4j with java.util.logging since websphere liberty is integrated with that, however the logging configuration applies to the entire profile
However, what would be the best way to get both (1) and (2) ?
I ended up using the org.apache.log4j.PropertyConfigurator for this along with the java.nio.file.WatchService.
The watchservice will watch a log4j.properties file at a predefined location for changes. If the file is changed it will call this method
/**
* Update configuration.
*/
public void updateConfiguration() {
Path path = configPath.resolve(LOG_FILE_NAME);
if (Files.exists(path)){
System.out.println(MessageFormat.format("Reloading logging configuration from {0}", path.toAbsolutePath()));
PropertyConfigurator.configure(path.toAbsolutePath().toString());
} else {
System.err.println(MessageFormat.format("log4j.properties file was expected at {0} but was not present. Please create this file and configure it for logging to work.", path.toAbsolutePath()));
}
}
This will allow for a log configuration file outside the application which will also be updateable at runtime.
Related
My Dev machine has JBoss while production server is running tomcat8 on AWS.
How do I setup Log (java.util.loggin) to log into default log file in the default directory, for instance following are the default paths for log files for each server. (no 3rd party loggers please)
/log/tomcat8/catalina
jboss-4.0.4/server/some_server_conf/log/
In some code examples I've seen, a FileHandler("file.log") is provided but then this log exists locally within the project folder and is not accessible from outside in a production environment. I want the application to be part of the root logging system that appends the log info into default directories and into default files.
Lateral Thinking: Please advise if there's a totally different strategy for production servers.
Part of the reason is that it's easier to see the log files right from AWS by requesting last 100 lines and I'd like to append some additional meaningful information there regarding my application as it runs.
public class Service {
private static Logger logger = Logger.getLogger("myproject");
public Service() {
logger.log(Level.INFO, "abc");
}
}
The easiest solution would be to simply install a java.util.logging.ConsoleHandler on the root logger of your myproject. That would direct all of your project output to the tomcat8-stderr.YYYY-MM-DD.log.
Otherwise you can create a ServletContextListener and install a custom handler on the root logger of your project which formats and logs to the ServletContext.log methods.
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).
Our Spring Boot application uses log4j2 for logging, but the admins of the server we are going to deploy it to require that:
the logging be fully configurable on their end, i.e., there must be a log4j2.xml file that they can edit to adjust logging formats, files, levels etc., and
The configuration must not be lost or overridden when a new version of the app is deployed (the upload war -> stop tomcat -> delete webapp folder -> start Tomcat) process will be automated.
Ideally, the path to log4j2.xml should be set in the webapps context .xml file — since that's where the DB connection config is. But I can't seem to find a way to make this work. All search results talk about using META-INF/web.xml or application.properties files (not an option, since they get overwritten on deploy), and the only SO question I could find (Spring application without web.xml log4j configuration) did not work for me ("No Configuration was provided") exception on startup.
Set the environment variable logging.config to be the location of your log4j2.xml file.
It's also recommended that you call it log4j2-spring.xml
See https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-logging.html
section "Custom log configuration"
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/
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.