*
The moose likes JBoss/WildFly and the fly likes Help? - Reloading log4j.xml config without jboss restart Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of OCM Java EE 6 Enterprise Architect Exam Guide this week in the OCMJEA forum!
JavaRanch » Java Forums » Products » JBoss/WildFly
Bookmark "Help? - Reloading log4j.xml config without jboss restart" Watch "Help? - Reloading log4j.xml config without jboss restart" New topic
Author

Help? - Reloading log4j.xml config without jboss restart

Sean Stephens
Ranch Hand

Joined: Oct 25, 2004
Posts: 40
Hey folks. I'm pretty deep into trying to get log4j to reconfig without a restart. I'm using a servlet to cause this code snippet to run:

DOMConfigurator conf = new DOMConfigurator();
conf.doConfigure(doc.getDocumentElement(), hierarchy);

the document that I've read in is the correct one, and doConfigure seems to be doing its work.

However, the change does not take.

The code path appears to be the same as the one followed when using the configureAndWatch() method on the configurator which sets up a watchdog on the xml file. All the watchdog does is rerun doConfigure on the file.

configureAndWatch however does not work in my case as we've had to hack the normal loader to allow a different log4j config per webapp as defined in each ones log4j.xml file.

Any idea why the reconfig isn't taking?

Code follows.

Thanks all for the help. Its a real stumper at this point and I've probably been looking at it too long.

Thanks,
Sean
Sean Stephens
Ranch Hand

Joined: Oct 25, 2004
Posts: 40
log4j xml specifics
=====================
<appender name="gem_logfile" class="org.jboss.logging.appender.DailyRollingFileAppender">
<errorHandler class="org.jboss.logging.util.OnlyOnceErrorHandler"/>
<param name="File" value="${jboss.server.home.dir}/log/gem.log"/>
<param name="Append" value="false"/>
<param name="Threshold" value="DEBUG"/>

<!-- Rollover at midnight each day -->
<param name="DatePattern" value="'.'yyyy-MM-dd"/>

<layout class="org.apache.log4j.PatternLayout">
<!-- The default pattern: Date Priority [Category] Message\n
<param name="ConversionPattern" value="%d{ABSOLUTE} %-5p [%c{1}] %m%n"/> -->
<param name="ConversionPattern" value="%-5p %d{dd-MM HH:mm:ss,SSS} (%F:%M:%L) -%m%n"/>

<!-- The full pattern: Date MS Priority [Category] (Thread:NDC) Message\n
<param name="ConversionPattern" value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
-->
</layout>
</appender>
<!-- ======================= -->
<!-- Set app-specific levels -->
<!-- ======================= -->

<logger name="com.blah" additivity="false">
<level value="error"/>
<appender-ref ref="gem_logfile"/>
<appender-ref ref="gem_console"/>
</logger>
<logger name="com.blah.common.RDException" additivity="false">
<level value="error"/>
<appender-ref ref="rd_exceptions"/>
<appender-ref ref="gem_console"/>
</logger>

<!-- ======================= -->
<!-- Set pkg specific levels -->
<!-- ======================= -->

<!-- === com.blah.common pkg === -->

<logger name="com.blah.common" additivity="false">
<level value="error"/>
<appender-ref ref="gem_logfile"/>
</logger>

<!-- === com.renewdata.gem pkg === -->

<logger name="com.blah.gem" additivity="false">
<level value="error"/>
<appender-ref ref="gem_logfile"/>
</logger>

</log4j:configuration>
Sean Stephens
Ranch Hand

Joined: Oct 25, 2004
Posts: 40
public class Log4jInit extends HttpServlet {

public Log4jInit() {
}

public void init(ServletConfig config) throws ServletException {

super.init(config);
RDRepositorySelector.init(config);
Log initLogger = LogFactory.getLog(Log4jInit.class);
initLogger.info("config logger initialized.");

}

public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException {
doPost(req,res);
}

public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException {
ServletContext ctx = req.getSession().getServletContext();
RDRepositorySelector.loadLog4j(ctx);
Log initLogger = LogFactory.getLog(Log4jInit.class);
initLogger.info("config logger initialized.");
try {
res.getWriter().println(new Date(System.currentTimeMillis()).toString());
res.getWriter().println("config logger initialized.");
} catch (IOException e) {
throw new ServletException("Error writing message to page on log4j init load servlet.",e);
}
}

}
Sean Stephens
Ranch Hand

Joined: Oct 25, 2004
Posts: 40
Above was the reconfig servlet...
==================================

Below is the RepositorySelector subclass that makes it possible to use different log4j configs for each web app

==================================

public class RDRepositorySelector implements RepositorySelector
{
private static boolean initialized = false;
private static Object guard = new Object();

private static Map repositories = new HashMap();
private static LoggerRepository defaultRepository;

/**
* Register your web-app with this repository selector.
*/
public static synchronized void init(ServletConfig config)
throws ServletException {

loadLog4j(config.getServletContext());
}

public static void loadLog4j (ServletContext ctx) throws ServletException {
if( !initialized ) // set the global RepositorySelector
{
defaultRepository = LogManager.getLoggerRepository();
RepositorySelector theSelector = new RDRepositorySelector();
LogManager.setRepositorySelector(theSelector, guard);
initialized = true;
}
Hierarchy hierarchy = new Hierarchy(new RootCategory(Level.DEBUG));
loadLog4JConfig(ctx, hierarchy);
ClassLoader loader = Thread.currentThread().getContextClassLoader();
repositories.put(loader, hierarchy);
}

// load log4j.xml from WEB-INF
private static void loadLog4JConfig(ServletContext ctx,
Hierarchy hierarchy)
throws ServletException {
try {
String log4jFile = "/WEB-INF/log4j.xml";

// Original method of getting stream as ByteArrayInputStream
// InputStream log4JConfig =
// ctx.getResourceAsStream(log4jFile);

// Getting InputStream from file directly instead of thru resource loader.
String log4jPath = ctx.getRealPath(log4jFile);
InputStream log4JConfig =
new FileInputStream(log4jPath);

Document doc = DocumentBuilderFactory.newInstance()
.newDocumentBuilder()
.parse(log4JConfig);
DOMConfigurator conf = new DOMConfigurator();
conf.doConfigure(doc.getDocumentElement(), hierarchy);
} catch (Exception e) {
throw new ServletException(e);
}
}

private RDRepositorySelector() {
}

public LoggerRepository getLoggerRepository() {
ClassLoader loader = Thread.currentThread().getContextClassLoader();

// get repository from hashmap
LoggerRepository repository = (LoggerRepository)repositories.get(loader);

if (repository == null) {
return defaultRepository;
} else {
return repository;
}
}
Sean Stephens
Ranch Hand

Joined: Oct 25, 2004
Posts: 40
What I'm trying to do is change from error level to debug level without having to restart the server. I have more than one webapp running on the appserver and need to have different logging configs for each one, and as far as I could find, subclassing the RepositorySelector in this manner is the only way to manage it.

As I said, when I reconfig by hitting the servlet and reading the changed log4j xml, the new information makes it to and is used by the Configurator. However, the log levels aren't changed in the webapp.

We are using jboss 3.2.6 and log4j 1.2.8

Thanks for any and all help.
Sean Stephens
Ranch Hand

Joined: Oct 25, 2004
Posts: 40
Wow. Could it be true? No one here has any idea? Come on... at least one of you has to have at least a suggestion for where I could look further?

Thanks!
Carol Enderlin
drifter
Ranch Hand

Joined: Oct 10, 2000
Posts: 1364
If you can modify the log4j code I figure you should be able to find suitable log4j resources, ... sorry, but one of my pet peeves is posts like "could it be true? no one here has any idea?" At least you didn't use the banging head graemlin.

You could search one of the log4j mailing list archive or subscribe to the log4j-user mailing list and ask there.

The JBoss or Other Open Source Projects (description: "Jakarta Projects (like Log4j etc.)...") forums here at javaranch seem like better forums for your questions, since you seem to have some JBoss specific log4j issues and are trying to solve them by extending log4j.
Sean Stephens
Ranch Hand

Joined: Oct 25, 2004
Posts: 40
Its not a log4j issue... Its a jboss one. Wherever the log4j config is stored in the jboss structure, its not getting replaced.

And yes, of course I'm polling other resources My comment was more related to the fact that this is the first time the Ranch hadn't posted some sort of response within 1 day to a well-formed question from me. Sorry to have offended your sensibilities.
Carol Enderlin
drifter
Ranch Hand

Joined: Oct 10, 2000
Posts: 1364
Well, we're all volunteers here and it might take more than one work day (plus 2 weekend days) for someone to digest your 5-post question.

Hey, can a friendly bartender or sheriff move this over to the JBoss forum since Sean says its a JBoss issue?
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Originally posted by Carol Enderlin:

Hey, can a friendly bartender or sheriff move this over to the JBoss forum since Sean says its a JBoss issue?


Yes, I can, and will...


The soul is dyed the color of its thoughts. Think only on those things that are in line with your principles and can bear the light of day. The content of your character is your choice. Day by day, what you do is who you become. Your integrity is your destiny - it is the light that guides your way. - Heraclitus
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Help? - Reloading log4j.xml config without jboss restart