@Override public FilterReply decide(Marker marker, Logger logger, Level level, String format, Object[] params, Throwable t) { if (!isStarted()) { return FilterReply.NEUTRAL; } // for performance reasons, skip change detection (MASK-1) times out of MASK. // Only once every MASK calls is change detection code executed // Note that MASK is a variable itself. if (((invocationCounter++) & mask) != mask) { return FilterReply.NEUTRAL; } long now = System.currentTimeMillis(); synchronized (configurationWatchList) { updateMaskIfNecessary(now); if (changeDetected(now)) { // Even though reconfiguration involves resetting the loggerContext, // which clears the list of turbo filters including this instance, it is // still possible for this instance to be subsequently invoked by another // thread if it was already executing when the context was reset. disableSubsequentReconfiguration(); detachReconfigurationToNewThread(); } } return FilterReply.NEUTRAL; }
private void fallbackConfiguration(LoggerContext lc, List<SaxEvent> eventList, URL mainURL) { JoranConfigurator joranConfigurator = new JoranConfigurator(); joranConfigurator.setContext(context); if (eventList != null) { addWarn("Falling back to previously registered safe configuration."); try { lc.reset(); JoranConfigurator.informContextOfURLUsedForConfiguration(context, mainURL); joranConfigurator.doConfigure(eventList); addInfo("Re-registering previous fallback configuration once more as a fallback configuration point"); joranConfigurator.registerSafeConfiguration(eventList); } catch (JoranException e) { addError("Unexpected exception thrown by a configuration considered safe.", e); } } else { addWarn("No previous configuration to fall back on."); } } }
@Override public void start() { configurationWatchList = ConfigurationWatchListUtil.getConfigurationWatchList(context); if (configurationWatchList != null) { mainConfigurationURL = configurationWatchList.getMainURL(); if (mainConfigurationURL == null) { addWarn("Due to missing top level configuration file, automatic reconfiguration is impossible."); return; } List<File> watchList = configurationWatchList.getCopyOfFileWatchList(); long inSeconds = refreshPeriod / 1000; addInfo("Will scan for changes in [" + watchList + "] every " + inSeconds + " seconds. "); synchronized (configurationWatchList) { updateNextCheck(System.currentTimeMillis()); } super.start(); } else { addWarn("Empty ConfigurationWatchList in context"); } }
@Override public FilterReply decide(Marker marker, Logger logger, Level level, String format, Object[] params, Throwable t) { if (!isStarted()) { return FilterReply.NEUTRAL; } // for performance reasons, check for changes every 16 invocations if (((invocationCounter++) & 0xF) != 0xF) { return FilterReply.NEUTRAL; } synchronized (lock) { boolean changed = changeDetected(); if (changed) { detachReconfigurationToNewThread(); } } return FilterReply.NEUTRAL; }
SMAwareReconfigureOnChangeFilter(ReconfigureOnChangeFilter reconfigureOnChangeFilter) { setRefreshPeriod(reconfigureOnChangeFilter.getRefreshPeriod()); setName(reconfigureOnChangeFilter.getName()); setContext(reconfigureOnChangeFilter.getContext()); if (reconfigureOnChangeFilter.isStarted()) { reconfigureOnChangeFilter.stop(); start(); } }
public void run() { if (mainConfigurationURL == null) { addInfo("Due to missing top level configuration file, skipping reconfiguration"); return; } LoggerContext lc = (LoggerContext) context; addInfo(CoreConstants.RESET_MSG_PREFIX + "named [" + context.getName() + "]"); if (mainConfigurationURL.toString().endsWith("xml")) { performXMLConfiguration(lc); } else if (mainConfigurationURL.toString().endsWith("groovy")) { if (EnvUtil.isGroovyAvailable()) { lc.reset(); // avoid directly referring to GafferConfigurator so as to avoid // loading groovy.lang.GroovyObject . See also http://jira.qos.ch/browse/LBCLASSIC-214 GafferUtil.runGafferConfiguratorOn(lc, this, mainConfigurationURL); } else { addError("Groovy classes are not available on the class path. ABORTING INITIALIZATION."); } } }
@Override public void start() { URL url = (URL) context .getObject(CoreConstants.URL_OF_LAST_CONFIGURATION_VIA_JORAN); if (url != null) { fileToScan = convertToFile(url); if (fileToScan != null) { synchronized (lock) { long inSeconds = refreshPeriod / 1000; addInfo("Will scan for changes in file [" + fileToScan + "] every " + inSeconds + " seconds. "); lastModified = fileToScan.lastModified(); updateNextCheck(System.currentTimeMillis()); } super.start(); } } else { addError("Could not find URL of file to scan."); } }
protected boolean changeDetected(long now) { if (now >= nextCheck) { updateNextCheck(now); return configurationWatchList.changeDetected(); } return false; }
void detachReconfigurationToNewThread() { addInfo("Detected change in [" + configurationWatchList.getCopyOfFileWatchList() + "]"); context.getExecutorService().submit(new ReconfiguringThread()); }
protected boolean changeDetected(long now) { if (isSecuredThread()) return false; return super.changeDetected(now); } }
@Test public void includeScanViaInputStreamSuppliedConfigFile() throws IOException, JoranException, InterruptedException { String configurationStr = "<configuration scan=\"true\" scanPeriod=\"50 millisecond\"><include resource=\"asResource/inner1.xml\"/></configuration>"; configure(new ByteArrayInputStream(configurationStr.getBytes("UTF-8"))); ConfigurationWatchList configurationWatchList = ConfigurationWatchListUtil.getConfigurationWatchList(loggerContext); assertNull(configurationWatchList.getMainURL()); ReconfigureOnChangeFilter reconfigureOnChangeFilter = (ReconfigureOnChangeFilter) getFirstTurboFilter(); // without a top level file, reconfigureOnChangeFilter should not start assertFalse(reconfigureOnChangeFilter.isStarted()); }
@SuppressWarnings("deprecation") File convertToFile(URL url) { String protocol = url.getProtocol(); if ("file".equals(protocol)) { File file = new File(URLDecoder.decode(url.getFile())); return file; } else { addError("URL [" + url + "] is not of type file"); return null; } }
private void rocfDetachReconfigurationToNewThreadAndAwaitTermination() throws InterruptedException { ReconfigureOnChangeFilter reconfigureOnChangeFilter = (ReconfigureOnChangeFilter) getFirstTurboFilter(); reconfigureOnChangeFilter.detachReconfigurationToNewThread(); executorService.shutdown(); executorService.awaitTermination(1000, TimeUnit.MILLISECONDS); }
private void detachReconfigurationToNewThread() { // Even though this method resets the loggerContext, which clears the // list of turbo filters including this instance, it is still possible // for this instance to be subsequently invoked by another thread if it // was already executing when the context was reset. disableSubsequentRecofiguration(); addInfo("Detected change in [" + fileToScan + "]"); addInfo("Resetting and reconfiguring context [" + context.getName() + "]"); new ReconfiguringThread().start(); }
SMAwareReconfigureOnChangeFilter(ReconfigureOnChangeFilter reconfigureOnChangeFilter) { setRefreshPeriod(reconfigureOnChangeFilter.getRefreshPeriod()); setName(reconfigureOnChangeFilter.getName()); setContext(reconfigureOnChangeFilter.getContext()); if (reconfigureOnChangeFilter.isStarted()) { reconfigureOnChangeFilter.stop(); start(); } }
public void run() { if (mainConfigurationURL == null) { addInfo("Due to missing top level configuration file, skipping reconfiguration"); return; } LoggerContext lc = (LoggerContext) context; addInfo(CoreConstants.RESET_MSG_PREFIX + "named [" + context.getName() + "]"); if (mainConfigurationURL.toString().endsWith("xml")) { performXMLConfiguration(lc); } else if (mainConfigurationURL.toString().endsWith("groovy")) { if (EnvUtil.isGroovyAvailable()) { lc.reset(); // avoid directly referring to GafferConfigurator so as to avoid // loading groovy.lang.GroovyObject . See also http://jira.qos.ch/browse/LBCLASSIC-214 GafferUtil.runGafferConfiguratorOn(lc, this, mainConfigurationURL); } else { addError("Groovy classes are not available on the class path. ABORTING INITIALIZATION."); } } }
protected boolean changeDetected(long now) { if (now >= nextCheck) { updateNextCheck(now); return configurationWatchList.changeDetected(); } return false; }
void detachReconfigurationToNewThread() { addInfo("Detected change in [" + configurationWatchList.getCopyOfFileWatchList() + "]"); context.getExecutorService().submit(new ReconfiguringThread()); }
protected boolean changeDetected(long now) { if (ThreadAwareSecurityManager.isSecuredThread()) return false; return super.changeDetected(now); } }
public void run() { JoranConfigurator jc = new JoranConfigurator(); jc.setContext(context); LoggerContext lc = (LoggerContext) context; lc.reset(); try { jc.doConfigure(fileToScan); } catch (JoranException e) { addError("Failure during reconfiguration", e); } lc.getStatusManager().add( new InfoStatus("done resetting the logging context", this)); } }