From a572112bd0d36505c856a0c3d5e1fefcbb94ed57 Mon Sep 17 00:00:00 2001 From: Pierre Mauduit Date: Fri, 9 Jul 2021 15:08:20 +0200 Subject: [PATCH] services - being able to externalize the logging configurations With the suggested modifications, we can define a bean as a string in any XML configuration files, e.g.: ``` ``` Then having a `/etc/geonetwork/log4j/` directory with some log4j configurations like the default ones from the WEB-INF/classes subdirectory, we can externalize from the webapp the logging configuration. Not having the previous bean defined will fall back onto the current behaviour (e.g. using the files from the classpath). the main advantage of this approach is that we can customize the logging configuration without having to recompile GeoNetwork. We can even add new configurations without atering the webapp content. --- .../org/fao/geonet/api/site/LogUtils.java | 24 ++++++++++++++++++- .../org/fao/geonet/api/site/LoggingApi.java | 13 +++++++--- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/services/src/main/java/org/fao/geonet/api/site/LogUtils.java b/services/src/main/java/org/fao/geonet/api/site/LogUtils.java index eddcd35fb35..32a39a6990f 100644 --- a/services/src/main/java/org/fao/geonet/api/site/LogUtils.java +++ b/services/src/main/java/org/fao/geonet/api/site/LogUtils.java @@ -29,8 +29,11 @@ import org.fao.geonet.exceptions.OperationAbortedEx; import org.fao.geonet.kernel.setting.Settings; import org.fao.geonet.repository.SettingRepository; +import org.springframework.beans.BeansException; +import java.net.MalformedURLException; import java.net.URL; +import java.nio.file.Paths; import java.util.Optional; /** @@ -41,6 +44,7 @@ public class LogUtils { public static final String DEFAULT_LOG_FILE = "log4j.xml"; + /** * Refresh logger configuration. If settings is not set in database, using default log4j.xml * file. If requested file does not exist, using default log4j.xml file. @@ -55,9 +59,27 @@ public static void refreshLogConfiguration() { setting = settingOpt.get(); } + + String loggingConfigurationPath; + try { + loggingConfigurationPath = (String) ApplicationContextHolder.get().getBean("loggingConfigurationPath"); + } catch (BeansException e) { + loggingConfigurationPath = null; + } // get log config from db settings String log4jProp = setting != null ? setting.getValue() : DEFAULT_LOG_FILE; - URL url = LogUtils.class.getResource("/" + log4jProp); + URL url ; + + if (loggingConfigurationPath != null) { + try { + url = Paths.get(loggingConfigurationPath, log4jProp).toUri().toURL(); + } catch (MalformedURLException e) { + url = LogUtils.class.getResource("/" + log4jProp); + } + } else { + url = LogUtils.class.getResource("/" + log4jProp); + } + if (url != null) { // refresh configuration DOMConfigurator.configure(url); diff --git a/services/src/main/java/org/fao/geonet/api/site/LoggingApi.java b/services/src/main/java/org/fao/geonet/api/site/LoggingApi.java index d33692e2619..7b3a9a017af 100644 --- a/services/src/main/java/org/fao/geonet/api/site/LoggingApi.java +++ b/services/src/main/java/org/fao/geonet/api/site/LoggingApi.java @@ -28,7 +28,7 @@ import org.apache.commons.io.IOUtils; import org.apache.log4j.FileAppender; import org.apache.log4j.Logger; -import org.fao.geonet.api.API; +import org.fao.geonet.ApplicationContextHolder; import org.fao.geonet.api.site.model.ListLogFilesResponse; import org.fao.geonet.constants.Geonet; import org.fao.geonet.kernel.GeonetworkDataDirectory; @@ -91,8 +91,15 @@ public List getLogFiles( ) throws Exception { java.util.List logFileList = new ArrayList<>(); - String classesFolder = dataDirectory.getWebappDir() + "/WEB-INF/classes"; - File folder = new File(classesFolder); + String loggingConfigurationFolder = dataDirectory.getWebappDir() + "/WEB-INF/classes"; + // overrides if a "loggingConfigurationPath" bean is available + try { + loggingConfigurationFolder = (String) ApplicationContextHolder.get().getBean("loggingConfigurationPath"); + } catch (Exception e) { + // stick with the folder in the classpath. + } + + File folder = new File(loggingConfigurationFolder); if (folder != null && folder.isDirectory()) { Pattern pattern = Pattern.compile(regexp, Pattern.CASE_INSENSITIVE);