I'm having a problem to print the log files after updating the log4 jars. Here is my implementation below. for the old version of log4j we only use the "PropertyConfigurator" for our logf4.properties (this is an external file). Im not sure if I missed something to declare but upon testing logs still not printing. The log4j version that im currently using now is the 2.17.2
private LoggerConfig (){
try {
//PropertyConfigurator.configureAndWatch(Constants.LOG_CONFIG);
LoggerContext context = (LoggerContext) LogManager.getContext(false);
File file = new File(Constants.LOG_CONFIG);
ConfigurationSource source = new ConfigurationSource(new FileInputStream(Constants.LOG_CONFIG), new File(Constants.LOG_CONFIG));
Configurator.initialize(null, source);
LOGGER = LogManager.getLogger(this.getClass());
LoggerContext.getContext().setConfigLocation(file.toURI());
LOGGER.debug("Log4j Properties successfully loaded.");
} catch (Exception e) {
LOGGER.error("Unable to load application properties file: " + Constants.LOG_CONFIG);
}
LOGGER.debug("Connection pool successfully initialized.");
}
you are using mostly LOGGER.debug, the logging level is set to DEBUG or lower?
if is set to a higher level please consider setting it to a level lower to debug or trace to validate the logf4.properties is proper linked
Related
I have an application for which I want to have the logging level set to INFO unless Debug Mode is set in which case I want to set the level to FINEST.
If I set the level in the properties file it does not get overridden from the program using logger.setLevel(Level.FINEST) also, if I do not set anything for the .level field in the properties file, by default the INFO level is taken and again I cannot override to use FINEST if isDebugEnable().
How can I make this level configurable based on the condition ?
try(InputStream configFile = getClass().getClassLoader().getResourceAsStream("logging.properties")) {
LogManager.getLogManager().readConfiguration(configFile);
} catch (IOException e) {
throw new IllegalStateException("Unable to load default logging properties.", e);
}
if (isDebugEnabled()) {
logger.setLevel(Level.FINEST);
} else {
logger.setLevel(Level.INFO);
}
My config file is as follows:
handlers= java.util.logging.ConsoleHandler
.level= INFO
# default file output is in user's home directory.
java.util.logging.FileHandler.pattern = %h/java%u.log
java.util.logging.FileHandler.limit = 50000
java.util.logging.FileHandler.count = 1
java.util.logging.FileHandler.formatter = java.util.logging.XMLFormatter
# Enable console to set level to FINEST and above.
java.util.logging.ConsoleHandler.level = FINEST
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
I can do this using as follow, but would like to know if there is a better way to do this. (May be using properties file)
ConsoleHandler consoleHandler = new ConsoleHandler();
setLogLevel();
consoleHandler.setLevel(Level.FINEST);
logger.addHandler(new ConsoleHandler());
If you are setting a DEBUG option before startup of the JVM then just package a 2nd logging.properties file called debug.properties and change the java.util.logging.config.file to point to the debug.properties when you want debug options.
handlers= java.util.logging.ConsoleHandler
.level= FINEST
# default file output is in user's home directory.
java.util.logging.FileHandler.pattern = %h/java%u.log
java.util.logging.FileHandler.level = ALL
java.util.logging.FileHandler.limit = 50000
java.util.logging.FileHandler.count = 1
java.util.logging.FileHandler.formatter = java.util.logging.XMLFormatter
# Enable console to set level to show all levels.
java.util.logging.ConsoleHandler.level = ALL
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
If you have to set the levels at runtime you'll run in to problems with readConfiguration not resetting all everything after boot of the JVM. Under JDK 8 or older all you can do is call readConfiguration to populate the defaults and add more code to fix the broken behavior. Since you just need to set the level on handlers then just add that code.
try(InputStream configFile = getClass().getClassLoader().getResourceAsStream("logging.properties")) {
LogManager.getLogManager().readConfiguration(configFile);
} catch (IOException e) {
throw new IllegalStateException("Unable to load default logging properties.", e);
}
Level lvl;
if (isDebugEnabled()) {
lvl = Level.FINEST;
} else {
lvl = Level.INFO;
}
logger.setLevel(lvl);
for(Handler h : logger.getHandlers()) {
h.setLevel(lvl);
}
JDK 9 provides an updateConfiguration method that will work around the broken behavior of the readConfiguration method.
I have got installed two versions of solr on Tomcat 6, 1.3 and 4.7 each of them are accessible but in the tomcat configuration's tab Java -Dsolr.solr.home=C:\Solr\solr where this path is the path of 1.3 However, I have the 4.7 on E:\new-solr.
When I try to create new core it created well but it disappeared after restarting Tomcat. I belive that the missing of correct Solr home is the reason. So, is there a way to set multiple solr home in Java properties of Tomcat?
Edit: When I run Tomcat with -Dsolr.solr.home=C:\Solr\solr I have got errors about missing cores in Solr 4.7 version where those
cores works fine in Solr 1.3.
SolrCore Initialization Failures archive: org.apache.solr.common.SolrException:org.apache.solr.common.SolrException:
Could not load config file c:\solr\solr\archive\solrconfig.xml
Looks like you are passing in the value of solr home using JAVA_OPTS. You need to edit server.xml and add the appropriate Solr home to Context. The following example is from SolrTomcat page on the Solr wiki.
<Context docBase="/opt/solr/example/solr/solr.war" debug="0" crossContext="true">
<Environment name="solr/home" type="java.lang.String" value="/opt/solr/example/solr" override="true"/>
</Context>
Solr's SolrResourceLoader#locateSolrHome first tries JNDI and then system properties to find its settings. As -D system properties are shared between all applications in a single Tomcat instance, those cannot be used to configure multiple Solr instances.
If for some reason one cannot use JNDI (like <Environment name="solr/home" ...> in XML files), or a single instance with multiple cores, then one could wrap the Solr WAR into one's own application and use a servlet context listener to (temporarily) change the system properties while starting.
This surely is a hack, and relies on Tomcat not starting applications in parallel, and on Solr only reading the system properties on startup. I've tested this to work nicely, but still it's probably only suitable for testing purposes.
Again, this first of all needs one to wrap Solr into one's own application. Next, create a folder /some/config with a sub folder for each instance, matching its context name. In each sub folder create a custom.properties file:
# This file /some/config/[servlet-context-name]/custom.properties is used
# if Tomcat is started with:
# -Dcustom.config.dir=/some/config
# ...and then (temporarily) overwrites any system properties specified below:
solr.solr.home=/some/other/folder/conf
solr.data.dir=/some/other/folder/data
To merge system properties based on some key-values in a properties file:
/**
* Tries to find the given file and merges its properties into the existing
* system properties.
*
* #param configFile
* full path of a property file
* #return {#code true} if the file was found and merged; {#code false}
* otherwise
*/
private boolean mergeSystemProperties(final String configFile) {
try (final FileInputStream is = new FileInputStream(configFile)) {
final Properties custom = new Properties();
custom.load(is);
for (final Map.Entry<Object, Object> prop : custom.entrySet()) {
LOG.info("Setting {}={}", prop.getKey(), prop.getValue());
System.setProperty((String)prop.getKey(), (String)prop.getValue());
}
return true;
} catch (final FileNotFoundException e) {
LOG.info("Could not find custom properties: {}", configFile);
} catch (final IOException e) {
LOG.error("Failed to read custom properties: " + configFile, e);
}
return false;
}
This can be used in a listener:
public class TestConfigContextListener implements ServletContextListener {
private static final Logger LOG = ...
private static final String PROP_DIR = "custom.config.dir";
private static final String FILE_NAME = "custom.properties";
#Override
public void contextInitialized(final ServletContextEvent event) {
final String configDir = System.getProperty(PROP_DIR);
if (configDir == null) {
LOG.info("No value for -D{}; not reading custom config", PROP_DIR);
} else {
LOG.info("Custom config dir: -D{}={}", PROP_DIR, configDir);
final ServletContext context = event.getServletContext();
// Either "" for the root, or "/some-path" otherwise
final String contextPath = context.getContextPath();
if (!contextPath.isEmpty()) {
if (mergeSystemProperties(configDir + File.separator
+ contextPath.substring(1, contextPath.length())
+ File.separator + FILE_NAME)) {
// We found the configuration in a subfolder matching the
// specific contextPath; done.
return;
}
}
// Root context, or no configuration in a subfolder matching the
// specific contextPath; try to load from configDir itself:
mergeSystemProperties(configDir + File.separator + FILE_NAME);
}
}
...
}
...with in web.xml:
<!--
Tries to read a property file to set/override system properties just before
Solr is initialized, sort of allowing to run multiple instances with
different settings, IF THEY ARE NOT STARTED SIMULTANEOUSLY.
-->
<listener>
<listener-class>net.example.TestConfigContextListener</listener-class>
</listener>
Final notes: though one could use <env-entry> in web.xml for "fake" JNDI entries, using ServletContext#setInitParameter to change those in the context listener has no effect. Also, the JNDI context java:comp/env is read-only hence cannot be changed from code. So one really needs to fall back to (temporarily) setting the system properties.
I want to export the log of my app in a html file,until now the log is displayed on the console of eclipse.
in all my classes logs are defined by
private static Logger logger = Logger.getLogger (classname.class.getName ());
does anyone know how I can do this in java?
Re-configure a particular logger:
private static final Logger LOGGER
= Logger.getLogger(ClassName.class.getName());
static
{
try
{
LOGGER.addHandler(new FileHandler("mylog.xml"));
// if you don’t want additional console output:
LOGGER.setUseParentHandlers(false);
} catch(IOException ex)
{
throw new ExceptionInInitializerError(ex);
}
}
Or change the global configuration:
Create a properties file like this:
handlers=java.util.logging.FileHandler
java.util.logging.FileHandler.pattern=mylog2.xml
# add more options if you like
Run your application with -Djava.util.logging.config.file=<path to the file above>.
In either case:
Study http://docs.oracle.com/javase/7/docs/api/java/util/logging/LogManager.html and http://docs.oracle.com/javase/7/docs/technotes/guides/logging/overview.html
You may do that using Log4j or some library.
You can export as XML for example with http://logging.apache.org/chainsaw/
There must be something similar with HTML, have a look at http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/HTMLLayout.html
I am trying to create multiple logs in Log4j, but I am facing a weird problem. Here's the log4j.properties and the code implementing it.
# Define the root logger with appender file
log4j.rootLogger = DEBUG, FILEALL
# Define the file appender
log4j.appender.FILEALL=org.apache.log4j.FileAppender
log4j.appender.FILEALL.File=${logfile.name}
# Define the layout for file appender
log4j.appender.FILEALL.layout=org.apache.log4j.HTMLLayout
#log4j.appender.FILEMAIN=org.apache.log4j.FileAppender
#log4j.appender.FILEMAIN.File=${logfilemain.name}
#log4j.appender.FILEMAIN.layout=org.apache.log4j.HTMLLayout
I have added the statement when running both and removed the original one
log4j.rootLogger = DEBUG, FILEALL , FILEMAIN
And this is the java code:
System.setProperty("logfile.name", savePath1);
// System.setProperty("logfilemain.name", savePath1);
logger = Logger.getLogger(HarishLog.class.getName());
PropertyConfigurator.configure("log4j.properties");
The code works perfectly fine till I make one log, but as soon as I enable the setting for 2nd log in either the properties or the javafile, nothing happens.
Besides I am unable to put a different name at
log4j.appender.FILEALL.File=${logfile.name}
it only works for logfile.name and logfilea.name, It doesn't work for any other name if I change it both in the javacode and the properties folder. Why is this???
Thank you
This works for me:
log4j.rootLogger = DEBUG, FILEALL, FILEMAIN
log4j.appender.FILEALL=org.apache.log4j.FileAppender
log4j.appender.FILEALL.File=${logfile.name}
log4j.appender.FILEALL.layout=org.apache.log4j.HTMLLayout
log4j.appender.FILEMAIN=org.apache.log4j.FileAppender
log4j.appender.FILEMAIN.File=${logfilemain.name}
log4j.appender.FILEMAIN.layout=org.apache.log4j.HTMLLayout
import org.apache.log4j.Logger;
public class LogTest {
public static void main(final String... args) {
System.setProperty("logfile.name", "logall.txt");
System.setProperty("logfilemain.name", "logmain.txt");
Logger logger = Logger.getLogger(LogTest.class.getName());
logger.info("hello");
}
}
If you're still having problems, try adding:
log4j.debug = true
to the beginning of your log4j.properties, and check the output messages.
In weblogic I can configure in the console for the Serverlog to use log4j instead of default JDK logging.
However the serverlog is not using a log4j.properties file, but seems to use the configuration in config.xml
Even if the log4j.properties file is in the classpath and I set these properties:
set JAVA_OPTIONS=%JAVA_OPTIONS% -Dlog4j.configuration=file:<path>/log4j.properties
set JAVA_OPTIONS=%JAVA_OPTIONS% -Dorg.apache.commons.logging.Log=org.apache.commons.logging.impl.Log4JLogger
set JAVA_OPTIONS=%JAVA_OPTIONS% -Dweblogic.log.Log4jLoggingEnabled=true
Is it possible to use log4j.properties configuration for Weblogic Server Logging, or can I only change the log4j configuration with java code?
I don't know anything about WebLogic in particular, but adding -Dlog4j.debug will cause log4j to tell you where it's looking for its configuration. I've found that to be invaluable when tracking down logging issues in tomcat previously.
Check out the docs for PropertyConfigurator and DOMConfigurator for details on the log4j configuration process.
If you put the log4j.xml in your classpath, WebLogic will pick it up. I use Apache Commons logging with log4j in WebLogic, and it's an easy thing to do. No need for those Java options.
Where are you setting the above options? Try putting the -Dlog4j option in the Server Start options for each managed server that will use log4j
To specify logging to a Log4j Logger instead of the default Java Logging:
* When you start the Administration Server, include the following Java option in the weblogic.Server command:
-Dweblogic.log.Log4jLoggingEnabled=true
From: http://edocs.bea.com/wls/docs103/logging/config_logs.html#wp1014610
I never got this working as I intented.
What I eventually did was create some kind of work-around.
I register a Handler that listens to the Weblogic serverlog.
From this handler I do my own logging to log4j. That logging can be redirected to do anything I want.
create a custom logHandler:
public class CustomLogHandler extends Handler {
..
public CustomLogHandler () throws SecurityException, IOException,
NamingException {
String log4jConfig = LogFilterConfiguration.getLog4jDirectory();
classlogger.info("log4j configured for file"+ log4jConfig );
PropertyConfigurator.configure(log4jConfig);
logFilterConfiguration = new LogFilterConfiguration();
}
public void publish(LogRecord record) {
WLLogRecord rec = (WLLogRecord) record;
if (!isLoggable(rec))
return;
if (getLoggerName().. is something i want to log) {
// do my own log4j logging
}
then create an ApplicationLifecycleListener.
with a postStart method:
public void postStart(ApplicationLifecycleEvent evt) {
Logger logger = LoggingHelper.getServerLogger();
Handler oldHandler = null;
Handler[] currentHandlers = logger.getHandlers();
.. code to remove an old custom handler if exists...
with something like logger.removeHandler(oldHandler);
// add custom handler to serverlogger.
CustomLogHandler h = null;
try {
h = new CustomLogHandler ();
// If handler was removed we can add a new version.
if (!(unRemovedHandlerClasses.contains(h.getClass()))){
logger.addHandler(h);
registerMBean(h) ;
}
} catch (Exception nmex) {
classLogger.error("Error adding CustomLogHandler to serverlogger "
+ nmex.getMessage());
logger.removeHandler(h);
}
}