Skip to content

Commit

Permalink
Fixed problem with lost event handling of logging.properties
Browse files Browse the repository at this point in the history
- Some editors save the file so they delete and create it. But when GF noticed
  that the file was deleted, it disabled the mechanism used to refresh
  the configuration.
- Now it prints the warning, but then creates a special thread waiting until
  the file is backa again, then configuring the mechanism again.

Signed-off-by: David Matějček <david.matejcek@omnifish.ee>
  • Loading branch information
dmatej committed Jan 14, 2024
1 parent fe2e65d commit d0996d9
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 11 deletions.
@@ -1,4 +1,5 @@
/*
* Copyright (c) 2024 Contributors to the Eclipse Foundation
* Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
Expand Down Expand Up @@ -56,9 +57,17 @@ public class LogFacade {
@LogMessageInfo(message = "Updated logger levels successfully.", level="INFO")
public static final String UPDATED_LOG_LEVELS = "NCLS-LOGGING-00003";

@LogMessageInfo(message = "The logging configuration file {0} has been deleted.", level="WARNING")
@LogMessageInfo(
message = "The logging configuration file {0} has been deleted."
+ " The server will wait until the file reappears.",
cause="The file was deleted.",
action="Create the file again using the Admin Console or asadmin command.",
level="SEVERE")
public static final String CONF_FILE_DELETED = "NCLS-LOGGING-00004";

@LogMessageInfo(message = "The logging configuration file {0} has reappeared.", level="INFO")
public static final String CONF_FILE_REAPPEARED = "NCLS-LOGGING-00004-1";

@LogMessageInfo(message = "Error executing query to fetch log records.", level="SEVERE",
cause="There was an exception thrown while executing log query.",
action="Take appropriate action based on the exception message.")
Expand Down
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022, 2023 Contributors to the Eclipse Foundation
* Copyright (c) 2022, 2024 Contributors to the Eclipse Foundation
* Copyright (c) 2009, 2018 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
Expand Down Expand Up @@ -45,6 +45,7 @@

import org.glassfish.api.VersionInfo;
import org.glassfish.api.admin.FileMonitoring;
import org.glassfish.api.admin.FileMonitoring.FileChangeListener;
import org.glassfish.common.util.Constants;
import org.glassfish.config.support.TranslatedConfigView;
import org.glassfish.hk2.api.Rank;
Expand Down Expand Up @@ -121,9 +122,7 @@ public void postConstruct() {

final File loggingPropertiesFile = getOrCreateLoggingProperties();
reconfigure(loggingPropertiesFile);
LOG.config("Configuring change detection of the configuration file ...");
fileMonitoring.monitors(loggingPropertiesFile, new LoggingCfgFileChangeListener(this::reconfigure));

configureFileMonitoring(loggingPropertiesFile);
LOG.config("LogManagerService completed successfuly ...");
LOG.log(Level.INFO, LogFacade.GF_VERSION_INFO, Version.getProductIdInfo());
}
Expand Down Expand Up @@ -349,6 +348,13 @@ private void reconfigure(final File configFile) {
}


private void configureFileMonitoring(File loggingPropertiesFile) {
LOG.config("Configuring change detection of the configuration file ...");
fileMonitoring.monitors(loggingPropertiesFile,
new LoggingCfgFileChangeListener(this::reconfigure, this::configureFileMonitoring));
}


private void reconfigureGlassFishLogHandler() {
final GlassFishLogHandler handler = JULHelperFactory.getHelper().findGlassFishLogHandler();
if (handler == null) {
Expand Down Expand Up @@ -433,26 +439,52 @@ private boolean isKnownHandlerClass(final String name) {
}


private static final class LoggingCfgFileChangeListener implements FileMonitoring.FileChangeListener {
private static final class LoggingCfgFileChangeListener implements FileChangeListener {

private final Consumer<File> action;
private final Consumer<File> reconfiguration;
private final Consumer<File> fileMonitoring;


LoggingCfgFileChangeListener(final Consumer<File> action) {
this.action = action;
LoggingCfgFileChangeListener(final Consumer<File> reconfiguration, final Consumer<File> fileMonitoring) {
this.reconfiguration = reconfiguration;
this.fileMonitoring = fileMonitoring;
}


@Override
public void changed(File changedFile) {
LOG.info(() -> "Detected change of file: " + changedFile);
action.accept(changedFile);
reconfiguration.accept(changedFile);
}


@Override
public void deleted(File deletedFile) {
LOG.log(Level.WARNING, LogFacade.CONF_FILE_DELETED, deletedFile.getAbsolutePath());
LOG.log(Level.SEVERE, LogFacade.CONF_FILE_DELETED, deletedFile.getAbsolutePath());
final Runnable waitingJob = () -> this.waitUntilFileReappears(deletedFile);
final Thread thread = new Thread(waitingJob, "Wait-to-reappear-" + deletedFile.getName());
thread.setDaemon(true);
thread.start();
}


/**
* Ie. the Vim editor can quickly remove and create the file on saving changes.
* Sometimes GF monitoring notices that the file vanished, then stops
* the monitoring and notifies this listener.
* <p>
* If the file is back again, we do the reconfiguration and we also reset
* the monitoring again.
* <p>
* If the file is really lost, we have a serious problem.
*/
private void waitUntilFileReappears(File deletedFile) {
while (!deletedFile.exists()) {
Thread.onSpinWait();
}
LOG.log(Level.INFO, LogFacade.CONF_FILE_REAPPEARED, deletedFile.getAbsolutePath());
reconfiguration.accept(deletedFile);
fileMonitoring.accept(deletedFile);
}
}
}

0 comments on commit d0996d9

Please sign in to comment.