Updated Branches: refs/heads/develop 74c2c7df4 -> 5a6e37abd
started working on MARMOTTA-390 (configurable logging) Project: http://git-wip-us.apache.org/repos/asf/marmotta/repo Commit: http://git-wip-us.apache.org/repos/asf/marmotta/commit/c7301a7a Tree: http://git-wip-us.apache.org/repos/asf/marmotta/tree/c7301a7a Diff: http://git-wip-us.apache.org/repos/asf/marmotta/diff/c7301a7a Branch: refs/heads/develop Commit: c7301a7ac14fd209cfd50f12ed0a892746b8a42e Parents: 46c6872 Author: Sebastian Schaffert <[email protected]> Authored: Wed Nov 27 18:15:18 2013 +0100 Committer: Sebastian Schaffert <[email protected]> Committed: Wed Nov 27 18:15:18 2013 +0100 ---------------------------------------------------------------------- .../core/api/config/ConfigurationService.java | 12 ++ .../core/api/logging/LoggingModule.java | 74 +++++++++ .../core/api/logging/LoggingService.java | 62 ++++++- .../core/logging/BaseLoggingModule.java | 38 +++++ .../logging/ConfigurationLoggingModule.java | 64 ++++++++ .../core/logging/SystemLoggingModule.java | 70 ++++++++ .../core/model/logging/ConsoleOutput.java | 39 +++++ .../core/model/logging/LogFileOutput.java | 50 ++++++ .../core/model/logging/LoggingOutput.java | 67 ++++++++ .../core/model/logging/SyslogOutput.java | 43 +++++ .../config/ConfigurationServiceImpl.java | 50 +++++- .../services/logging/LoggingServiceImpl.java | 162 +++++++++++++++++++ .../main/resources/config-defaults.properties | 28 +++- 13 files changed, 744 insertions(+), 15 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/marmotta/blob/c7301a7a/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/api/config/ConfigurationService.java ---------------------------------------------------------------------- diff --git a/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/api/config/ConfigurationService.java b/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/api/config/ConfigurationService.java index 6a00235..4f8c5f1 100644 --- a/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/api/config/ConfigurationService.java +++ b/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/api/config/ConfigurationService.java @@ -23,6 +23,8 @@ import javax.servlet.ServletContext; import java.util.List; import java.util.Map; import java.util.Properties; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * Manage the system configuration. @@ -113,6 +115,16 @@ public interface ConfigurationService { */ List<String> listConfigurationKeys(String prefix); + + /** + * List all configuration keys matching a certain regular expression pattern. Returns a matcher object for all + * matching keys that can be used to access capturing groups + * + * @param pattern + * @return + */ + List<Matcher> listConfigurationKeys(Pattern pattern); + /** * Check whether a certain configuration property is set. * @param key http://git-wip-us.apache.org/repos/asf/marmotta/blob/c7301a7a/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/api/logging/LoggingModule.java ---------------------------------------------------------------------- diff --git a/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/api/logging/LoggingModule.java b/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/api/logging/LoggingModule.java new file mode 100644 index 0000000..2e5beb7 --- /dev/null +++ b/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/api/logging/LoggingModule.java @@ -0,0 +1,74 @@ +package org.apache.marmotta.platform.core.api.logging; + +import ch.qos.logback.classic.Level; + +import java.util.Collection; + +/** + * An implementation of a LoggingModule provides information about a component for which to provide logging + * facilities. It is an abstraction from the "logging by package" concept used by lower-level logging frameworks. + * A user can select to change the logging configuration for a module, resulting in all packages managed by this + * module to be logged according to the new configuration. This allows to group packages together that conceptually + * belong together. + * <p/> + * LoggingModule providers are injected by the LoggingService using CDI injection. As such they should be proper CDI + * bearns and probably live in application scope. + * + * @author Sebastian Schaffert ([email protected]) + */ +public interface LoggingModule { + + + /** + * Return a unique identifier for this logging module. This identifier will e.g. be used in the configuration file + * to store the configuration for this module. For this reason it should only consist of alpha-numeric characters + * plus _ and _. + * + * @return a unique identifier for the module, suitable for use in the configuration file + */ + public String getId(); + + + /** + * Return a human-readable name for this logging module. This name is used for displaying information about the + * module to the user, e.g. in a configuration interface. + * + * @return a human-readable name for the module, suitable for displaying in a user interface + */ + public String getName(); + + + /** + * Return a collection of packages covered by this logging module. This method should be used to group together + * those packages that conceptually make up the functionality described by the logging module (e.g. "SPARQL"). + * + * @return a collection of package names + */ + public Collection<String> getPackages(); + + + /** + * Return the default (logback) level used by this logging module. Should in most cases be INFO or WARN. + * + * @return + */ + public Level getDefaultLevel(); + + + /** + * Return the currently configured (logback) level used by this logging module. This field is read from the + * configuration file and defaults to getDefaultLevel() + * + * @return + */ + public Level getCurrentLevel(); + + + /** + * Update the currently active (logback) level used by this logging module. This method directly updates the + * configuration file. + * + * @param level + */ + public void setCurrentLevel(Level level); +} http://git-wip-us.apache.org/repos/asf/marmotta/blob/c7301a7a/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/api/logging/LoggingService.java ---------------------------------------------------------------------- diff --git a/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/api/logging/LoggingService.java b/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/api/logging/LoggingService.java index 1f82b60..7ab5d0e 100644 --- a/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/api/logging/LoggingService.java +++ b/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/api/logging/LoggingService.java @@ -17,9 +17,14 @@ */ package org.apache.marmotta.platform.core.api.logging; +import org.apache.marmotta.platform.core.model.logging.ConsoleOutput; +import org.apache.marmotta.platform.core.model.logging.LogFileOutput; +import org.apache.marmotta.platform.core.model.logging.LoggingOutput; +import org.apache.marmotta.platform.core.model.logging.SyslogOutput; import org.slf4j.Logger; import javax.enterprise.inject.spi.InjectionPoint; +import java.util.List; /** * LoggingService - a service for providing a SLF4J logger to other components in the @@ -37,5 +42,60 @@ public interface LoggingService { * @return */ public Logger createLogger(InjectionPoint injectionPoint); - + + + /** + * Return a list of all output configurations, reading directly from the configuration service. + * + * @return + */ + public List<LoggingOutput> listOutputConfigurations(); + + + /** + * Return the output configuration with the given ID. + * @param id + * @return + */ + public LoggingOutput getOutputConfiguration(String id); + + + /** + * Return the console output configuration used by Marmotta. There is only a single console output for any + * Marmotta instance. + * + * @return + */ + public ConsoleOutput getConsoleOutput(); + + /** + * Create a new syslog output configuration using the given parameters; further options can be set on the object + * itself. If not set, the default hostname is "localhost" and the default facility is "LOCAL0". + * + * @param id unique identifier for the log output configuration + * @param name human-readable name for configuration (displayed in UI) + * @return + */ + public SyslogOutput createSyslogOutput(String id, String name); + + /** + * Create a new logfile output configuration using the given parameters; further options can be set on the object + * itself. + * + * @param id unique identifier for the log output configuration + * @param name human-readable name for configuration (displayed in UI) + * @param file filename under MARMOTTA_HOME/log + * @return + */ + public LogFileOutput createLogFileOutput(String id, String name, String file); + + + /** + * Return a list of all modules found on the classpath. This list is assembled via CDI injection. Since modules are + * managed beans, calling setters on the LoggingModule implementations will directly change the configuration. + * + * @return + */ + public List<LoggingModule> listModules(); + } http://git-wip-us.apache.org/repos/asf/marmotta/blob/c7301a7a/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/logging/BaseLoggingModule.java ---------------------------------------------------------------------- diff --git a/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/logging/BaseLoggingModule.java b/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/logging/BaseLoggingModule.java new file mode 100644 index 0000000..f11048c --- /dev/null +++ b/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/logging/BaseLoggingModule.java @@ -0,0 +1,38 @@ +package org.apache.marmotta.platform.core.logging; + +import ch.qos.logback.classic.Level; +import org.apache.marmotta.platform.core.api.config.ConfigurationService; +import org.apache.marmotta.platform.core.api.logging.LoggingModule; + +/** + * Add file description here! + * + * @author Sebastian Schaffert ([email protected]) + */ +public abstract class BaseLoggingModule implements LoggingModule { + + private ConfigurationService configurationService; + + + /** + * Update the currently active (logback) level used by this logging module. This method directly updates the + * configuration file. + * + * @param level + */ + @Override + public void setCurrentLevel(Level level) { + configurationService.setConfiguration(String.format("logging.module.%s.level", getId()), level.toString()); + } + + /** + * Return the currently configured (logback) level used by this logging module. This field is read from the + * configuration file and defaults to getDefaultLevel() + * + * @return + */ + @Override + public Level getCurrentLevel() { + return Level.toLevel(configurationService.getStringConfiguration(String.format("logging.module.%s.level", getId())), getDefaultLevel()); + } +} http://git-wip-us.apache.org/repos/asf/marmotta/blob/c7301a7a/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/logging/ConfigurationLoggingModule.java ---------------------------------------------------------------------- diff --git a/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/logging/ConfigurationLoggingModule.java b/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/logging/ConfigurationLoggingModule.java new file mode 100644 index 0000000..ccb78f4 --- /dev/null +++ b/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/logging/ConfigurationLoggingModule.java @@ -0,0 +1,64 @@ +package org.apache.marmotta.platform.core.logging; + +import ch.qos.logback.classic.Level; +import com.google.common.collect.ImmutableSet; +import org.apache.marmotta.platform.core.api.logging.LoggingModule; + +import javax.enterprise.context.ApplicationScoped; +import java.util.Collection; + +/** + * Logging module for configuration-related logging information. + * + * @author Sebastian Schaffert ([email protected]) + */ +@ApplicationScoped +public class ConfigurationLoggingModule extends BaseLoggingModule implements LoggingModule { + + /** + * Return the default (logback) level used by this logging module. Should in most cases be INFO or WARN. + * + * @return + */ + @Override + public Level getDefaultLevel() { + return Level.INFO; + } + + /** + * Return a unique identifier for this logging module. This identifier will e.g. be used in the configuration file + * to store the configuration for this module. For this reason it should only consist of alpha-numeric characters + * plus _ and _. + * + * @return a unique identifier for the module, suitable for use in the configuration file + */ + @Override + public String getId() { + return "configuration"; + } + + /** + * Return a human-readable name for this logging module. This name is used for displaying information about the + * module to the user, e.g. in a configuration interface. + * + * @return a human-readable name for the module, suitable for displaying in a user interface + */ + @Override + public String getName() { + return "Configuration Changes"; + } + + /** + * Return a collection of packages covered by this logging module. This method should be used to group together + * those packages that conceptually make up the functionality described by the logging module (e.g. "SPARQL"). + * + * @return a collection of package names + */ + @Override + public Collection<String> getPackages() { + return ImmutableSet.of( + "org.apache.marmotta.platform.core.services.config", + "org.apache.marmotta.platform.core.webservices.config" + ); + } +} http://git-wip-us.apache.org/repos/asf/marmotta/blob/c7301a7a/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/logging/SystemLoggingModule.java ---------------------------------------------------------------------- diff --git a/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/logging/SystemLoggingModule.java b/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/logging/SystemLoggingModule.java new file mode 100644 index 0000000..052c898 --- /dev/null +++ b/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/logging/SystemLoggingModule.java @@ -0,0 +1,70 @@ +package org.apache.marmotta.platform.core.logging; + +import ch.qos.logback.classic.Level; +import com.google.common.collect.ImmutableSet; +import org.apache.marmotta.platform.core.api.logging.LoggingModule; + +import javax.enterprise.context.ApplicationScoped; +import java.util.Collection; + +/** + * Logging module for system-related information (startup, shutdown, ...). + * + * @author Sebastian Schaffert ([email protected]) + */ +@ApplicationScoped +public class SystemLoggingModule extends BaseLoggingModule implements LoggingModule { + + /** + * Return the default (logback) level used by this logging module. Should in most cases be INFO or WARN. + * + * @return + */ + @Override + public Level getDefaultLevel() { + return Level.INFO; + } + + /** + * Return a unique identifier for this logging module. This identifier will e.g. be used in the configuration file + * to store the configuration for this module. For this reason it should only consist of alpha-numeric characters + * plus _ and _. + * + * @return a unique identifier for the module, suitable for use in the configuration file + */ + @Override + public String getId() { + return "system"; + } + + /** + * Return a human-readable name for this logging module. This name is used for displaying information about the + * module to the user, e.g. in a configuration interface. + * + * @return a human-readable name for the module, suitable for displaying in a user interface + */ + @Override + public String getName() { + return "System"; + } + + /** + * Return a collection of packages covered by this logging module. This method should be used to group together + * those packages that conceptually make up the functionality described by the logging module (e.g. "SPARQL"). + * + * @return a collection of package names + */ + @Override + public Collection<String> getPackages() { + return ImmutableSet.of( + "org.apache.marmotta.platform.core.filters", + "org.apache.marmotta.platform.core.startup", + "org.apache.marmotta.platform.core.servlet", + "org.apache.marmotta.platform.core.services.modules", + "org.apache.marmotta.platform.core.webservices.system", + "org.apache.marmotta.platform.core.jndi", + "org.apache.marmotta.platform.core.jaxrs", + "org.apache.marmotta.platform.core.util" + ); + } +} http://git-wip-us.apache.org/repos/asf/marmotta/blob/c7301a7a/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/model/logging/ConsoleOutput.java ---------------------------------------------------------------------- diff --git a/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/model/logging/ConsoleOutput.java b/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/model/logging/ConsoleOutput.java new file mode 100644 index 0000000..25f92a1 --- /dev/null +++ b/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/model/logging/ConsoleOutput.java @@ -0,0 +1,39 @@ +package org.apache.marmotta.platform.core.model.logging; + +import org.apache.marmotta.platform.core.api.config.ConfigurationService; + +/** + * Add file description here! + * + * @author Sebastian Schaffert ([email protected]) + */ +public class ConsoleOutput extends LoggingOutput { + + + public ConsoleOutput(ConfigurationService configurationService) { + super("console", configurationService); + } + + /** + * Get the type identifier for this kind of logging output (e.g. "file", "console", "syslog"). Used for + * properly resolving the configuration keys. + * + * @return + */ + @Override + protected String getTypeIdentifier() { + return "console"; + } + + /** + * Internal method: return the configuration key for this logging output and the given key suffix. + * + * @param key + * @return + */ + @Override + protected String getConfigKey(String key) { + return String.format("logging.console.%s", key); + } +} + http://git-wip-us.apache.org/repos/asf/marmotta/blob/c7301a7a/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/model/logging/LogFileOutput.java ---------------------------------------------------------------------- diff --git a/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/model/logging/LogFileOutput.java b/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/model/logging/LogFileOutput.java new file mode 100644 index 0000000..428229f --- /dev/null +++ b/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/model/logging/LogFileOutput.java @@ -0,0 +1,50 @@ +package org.apache.marmotta.platform.core.model.logging; + +import org.apache.marmotta.platform.core.api.config.ConfigurationService; + +/** + * Representation of the configuration of a Marmotta logfile. Mapped to a Logback RollingFileAppender configuration by + * the LoggingService. + * + * @author Sebastian Schaffert ([email protected]) + */ +public class LogFileOutput extends LoggingOutput { + + + public LogFileOutput(String id, ConfigurationService configurationService) { + super(id, configurationService); + } + + /** + * Return the filename for logging; all logfiles will be created beneath MARMOTTA_HOME/log. + * @return + */ + public String getFileName() { + return configurationService.getStringConfiguration(getConfigKey("file")); + } + + public void setFileName(String fileName) { + configurationService.setConfiguration(getConfigKey("file"), fileName); + } + + public int getKeepDays() { + return configurationService.getIntConfiguration(getConfigKey("keep"),30); + } + + public void setKeepDays(int keepDays) { + configurationService.setIntConfiguration(getConfigKey("keep"), keepDays); + } + + /** + * Get the type identifier for this kind of logging output (e.g. "file", "console", "syslog"). Used for + * properly resolving the configuration keys. + * + * @return + */ + @Override + protected String getTypeIdentifier() { + return "file"; + } + + +} http://git-wip-us.apache.org/repos/asf/marmotta/blob/c7301a7a/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/model/logging/LoggingOutput.java ---------------------------------------------------------------------- diff --git a/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/model/logging/LoggingOutput.java b/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/model/logging/LoggingOutput.java new file mode 100644 index 0000000..e723897 --- /dev/null +++ b/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/model/logging/LoggingOutput.java @@ -0,0 +1,67 @@ +package org.apache.marmotta.platform.core.model.logging; + +import org.apache.marmotta.platform.core.api.config.ConfigurationService; + +/** + * Add file description here! + * + * @author Sebastian Schaffert ([email protected]) + */ +public abstract class LoggingOutput { + protected String id; + + + protected ConfigurationService configurationService; + + protected static String DEFAULT_PATTERN = "%d{HH:mm:ss.SSS} %-5level %logger{36} - %msg%n"; + + protected static String CONFIG_PATTERN = "logging.%s.%s.%s"; + + + public LoggingOutput(String id, ConfigurationService configurationService) { + this.id = id; + this.configurationService = configurationService; + } + + public String getName() { + return configurationService.getStringConfiguration(getConfigKey("name")); + } + + public void setName(String name) { + configurationService.setConfiguration(getConfigKey("name"), name); + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getPattern() { + return configurationService.getStringConfiguration(getConfigKey("pattern"), DEFAULT_PATTERN); + } + + public void setPattern(String pattern) { + configurationService.setConfiguration(getConfigKey("pattern"), pattern); + } + + + /** + * Internal method: return the configuration key for this logging output and the given key suffix. + * @param key + * @return + */ + protected String getConfigKey(String key) { + return String.format(CONFIG_PATTERN, getTypeIdentifier(), getId(), key); + } + + /** + * Get the type identifier for this kind of logging output (e.g. "file", "console", "syslog"). Used for + * properly resolving the configuration keys. + * + * @return + */ + protected abstract String getTypeIdentifier(); +} http://git-wip-us.apache.org/repos/asf/marmotta/blob/c7301a7a/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/model/logging/SyslogOutput.java ---------------------------------------------------------------------- diff --git a/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/model/logging/SyslogOutput.java b/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/model/logging/SyslogOutput.java new file mode 100644 index 0000000..f4a549e --- /dev/null +++ b/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/model/logging/SyslogOutput.java @@ -0,0 +1,43 @@ +package org.apache.marmotta.platform.core.model.logging; + +import org.apache.marmotta.platform.core.api.config.ConfigurationService; + +/** + * Add file description here! + * + * @author Sebastian Schaffert ([email protected]) + */ +public class SyslogOutput extends LoggingOutput { + + + public SyslogOutput(String id, ConfigurationService configurationService) { + super(id, configurationService); + } + + public String getFacility() { + return configurationService.getStringConfiguration(getConfigKey("facility"), "LOCAL0"); + } + + public void setFacility(String facility) { + configurationService.setConfiguration(getConfigKey("facility"), facility); + } + + public String getHostName() { + return configurationService.getStringConfiguration(getConfigKey("host"),"localhost"); + } + + public void setHostName(String hostName) { + configurationService.setConfiguration(getConfigKey("host"), hostName); + } + + /** + * Get the type identifier for this kind of logging output (e.g. "file", "console", "syslog"). Used for + * properly resolving the configuration keys. + * + * @return + */ + @Override + protected String getTypeIdentifier() { + return "syslog"; + } +} http://git-wip-us.apache.org/repos/asf/marmotta/blob/c7301a7a/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/services/config/ConfigurationServiceImpl.java ---------------------------------------------------------------------- diff --git a/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/services/config/ConfigurationServiceImpl.java b/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/services/config/ConfigurationServiceImpl.java index 6b9e567..7c2b44f 100644 --- a/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/services/config/ConfigurationServiceImpl.java +++ b/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/services/config/ConfigurationServiceImpl.java @@ -26,7 +26,12 @@ import com.google.common.base.Preconditions; import com.google.common.collect.Lists; import com.google.common.io.Files; import com.google.common.io.Resources; -import org.apache.commons.configuration.*; +import org.apache.commons.configuration.AbstractConfiguration; +import org.apache.commons.configuration.CompositeConfiguration; +import org.apache.commons.configuration.Configuration; +import org.apache.commons.configuration.ConfigurationException; +import org.apache.commons.configuration.MapConfiguration; +import org.apache.commons.configuration.PropertiesConfiguration; import org.apache.commons.lang3.ObjectUtils; import org.apache.marmotta.platform.core.api.config.ConfigurationService; import org.apache.marmotta.platform.core.events.ConfigurationChangedEvent; @@ -49,9 +54,18 @@ import java.io.IOException; import java.lang.reflect.Array; import java.net.URL; import java.net.UnknownHostException; -import java.util.*; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Properties; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * This service offers access to the system configuration of the LMF and takes care of initialising the system @@ -491,12 +505,36 @@ public class ConfigurationServiceImpl implements ConfigurationService { } } - /* - * (non-Javadoc) - * - * @see kiwi.api.config.ConfigurationService#isConfigurationSet(java.lang.String) + /** + * List all configuration keys matching a certain regular expression pattern. Returns a matcher object for all + * matching keys that can be used to access capturing groups + * + * @param pattern + * @return */ @Override + public List<Matcher> listConfigurationKeys(Pattern pattern) { + lock.readLock().lock(); + try { + List<Matcher> keys = new LinkedList<Matcher>(); + for (Iterator<String> it = config.getKeys(); it.hasNext();) { + Matcher m = pattern.matcher(it.next()); + if(m.matches()) { + keys.add(m); + } + } + return keys; + } finally { + lock.readLock().unlock(); + } + } + + /* + * (non-Javadoc) + * + * @see kiwi.api.config.ConfigurationService#isConfigurationSet(java.lang.String) + */ + @Override public boolean isConfigurationSet(String key) { lock.readLock().lock(); try { http://git-wip-us.apache.org/repos/asf/marmotta/blob/c7301a7a/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/services/logging/LoggingServiceImpl.java ---------------------------------------------------------------------- diff --git a/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/services/logging/LoggingServiceImpl.java b/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/services/logging/LoggingServiceImpl.java index 4a5cb23..db3206a 100644 --- a/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/services/logging/LoggingServiceImpl.java +++ b/platform/marmotta-core/src/main/java/org/apache/marmotta/platform/core/services/logging/LoggingServiceImpl.java @@ -22,9 +22,20 @@ import ch.qos.logback.classic.LoggerContext; import ch.qos.logback.classic.joran.JoranConfigurator; import ch.qos.logback.core.joran.spi.JoranException; import ch.qos.logback.core.util.StatusPrinter; +import com.google.common.base.Function; +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; +import com.google.common.collect.Lists; import org.apache.marmotta.platform.core.api.config.ConfigurationService; +import org.apache.marmotta.platform.core.api.logging.LoggingModule; import org.apache.marmotta.platform.core.api.logging.LoggingService; import org.apache.marmotta.platform.core.events.ConfigurationChangedEvent; +import org.apache.marmotta.platform.core.exception.MarmottaConfigurationException; +import org.apache.marmotta.platform.core.model.logging.ConsoleOutput; +import org.apache.marmotta.platform.core.model.logging.LogFileOutput; +import org.apache.marmotta.platform.core.model.logging.LoggingOutput; +import org.apache.marmotta.platform.core.model.logging.SyslogOutput; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -35,6 +46,12 @@ import javax.enterprise.inject.Produces; import javax.enterprise.inject.spi.InjectionPoint; import javax.inject.Inject; import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * LoggingServiceImpl @@ -49,6 +66,12 @@ public class LoggingServiceImpl implements LoggingService { @Inject private ConfigurationService configurationService; + + private LoadingCache<String,LogFileOutput> logfileCache; + private LoadingCache<String,SyslogOutput> syslogCache; + + private ConsoleOutput consoleOutput; + @PostConstruct public void initialize() { log.info("Apache Marmotta Logging Service starting up ..."); @@ -57,6 +80,35 @@ public class LoggingServiceImpl implements LoggingService { String loggerName = key.substring("logging.".length()); setConfiguredLevel(loggerName); } + + logfileCache = CacheBuilder.newBuilder().maximumSize(10).expireAfterAccess(10, TimeUnit.MINUTES).build( + new CacheLoader<String, LogFileOutput>() { + @Override + public LogFileOutput load(String key) throws Exception { + + if(configurationService.isConfigurationSet("logging.file."+key+".name")) { + return new LogFileOutput(key, configurationService); + } else { + throw new MarmottaConfigurationException("logfile configuration "+key+" not found"); + } + } + } + ); + + syslogCache = CacheBuilder.newBuilder().maximumSize(5).expireAfterAccess(10, TimeUnit.MINUTES).build( + new CacheLoader<String, SyslogOutput>() { + @Override + public SyslogOutput load(String key) throws Exception { + if(configurationService.isConfigurationSet("logging.syslog."+key+".name")) { + return new SyslogOutput(key, configurationService); + } else { + throw new MarmottaConfigurationException("syslog configuration "+key+" not found"); + } + } + } + ); + + consoleOutput = new ConsoleOutput(configurationService); } public void configurationChangedEvent(@Observes ConfigurationChangedEvent event) { @@ -137,4 +189,114 @@ public class LoggingServiceImpl implements LoggingService { return LoggerFactory.getLogger(injectionPoint.getMember().getDeclaringClass()); } + + /** + * Create a new logfile output configuration using the given parameters; further options can be set on the object + * itself. + * + * @param id unique identifier for the log output configuration + * @param name human-readable name for configuration (displayed in UI) + * @param file filename under MARMOTTA_HOME/log + * @return + */ + @Override + public LogFileOutput createLogFileOutput(String id, String name, String file) { + try { + return logfileCache.get(id); + } catch (ExecutionException e) { + LogFileOutput r = new LogFileOutput(id, configurationService); + r.setFileName(file); + r.setName(name); + return r; + } + } + + /** + * Return a list of all output configurations, reading directly from the configuration service. + * + * @return + */ + @Override + public List<LoggingOutput> listOutputConfigurations() { + List<LoggingOutput> logs = new ArrayList<>(); + + logs.addAll( + Lists.transform(configurationService.listConfigurationKeys(Pattern.compile("logging\\.(file|syslog)\\.([^\\.]+)\\.name")), new Function<Matcher, LoggingOutput>() { + @Override + public LoggingOutput apply(java.util.regex.Matcher input) { + return getOutputConfiguration(input.group(2)); + } + } + )); + + logs.add(consoleOutput); + + return logs; + } + + /** + * Return the output configuration with the given ID. + * + * @param id + * @return + */ + @Override + public LoggingOutput getOutputConfiguration(String id) { + if("console".equals(id)) { + return consoleOutput; + } + + try { + return logfileCache.get(id); + } catch (ExecutionException e) { + } + + try { + return syslogCache.get(id); + } catch (ExecutionException e) { + } + + return null; + } + + /** + * Create a new syslog output configuration using the given parameters; further options can be set on the object + * itself. If not set, the default hostname is "localhost" and the default facility is "LOCAL0". + * + * @param id unique identifier for the log output configuration + * @param name human-readable name for configuration (displayed in UI) + * @return + */ + @Override + public SyslogOutput createSyslogOutput(String id, String name) { + try { + return syslogCache.get(id); + } catch (ExecutionException e) { + SyslogOutput r = new SyslogOutput(id,configurationService); + r.setName(name); + return r; + } + } + + /** + * Return the console output configuration used by Marmotta. There is only a single console output for any + * Marmotta instance. + * + * @return + */ + @Override + public ConsoleOutput getConsoleOutput() { + return consoleOutput; + } + + /** + * Return a list of all modules found on the classpath. This list is assembled via CDI injection. Since modules are + * managed beans, calling setters on the LoggingModule implementations will directly change the configuration. + * + * @return + */ + @Override + public List<LoggingModule> listModules() { + return null; //To change body of implemented methods use File | Settings | File Templates. + } } http://git-wip-us.apache.org/repos/asf/marmotta/blob/c7301a7a/platform/marmotta-core/src/main/resources/config-defaults.properties ---------------------------------------------------------------------- diff --git a/platform/marmotta-core/src/main/resources/config-defaults.properties b/platform/marmotta-core/src/main/resources/config-defaults.properties index bb0390a..366adaa 100644 --- a/platform/marmotta-core/src/main/resources/config-defaults.properties +++ b/platform/marmotta-core/src/main/resources/config-defaults.properties @@ -89,14 +89,26 @@ templating.cache.enabled = true ############################################################################### # configure logging for the core system; valid values: DEBUG, INFO, WARN, ERROR -logging.kiwi.core = INFO - -# configure logging for the security system; valid values: DEBUG, INFO, WARN, ERROR -logging.kiwi.core.services.security = DEBUG - - -# configure logging for the reasoner; valid values: DEBUG, INFO, WARN, ERROR -logging.kiwi.reasoner = INFO +logging.console.name = Marmotta Console +logging.console.level = WARN +logging.console.pattern = %d{HH:mm:ss.SSS} %-5level - %msg%n + +logging.syslog.local0.name = Syslog (LOCAL0) +logging.syslog.local0.level = INFO +logging.syslog.local0.pattern = %logger{36} %msg +logging.syslog.local0.facility = LEVEL0 + +logging.file.main.name = Marmotta Main Log +logging.file.main.level = INFO +logging.file.main.pattern = %d{HH:mm:ss.SSS} %-5level %logger{36} - %msg%n +logging.file.main.file = marmotta-main.log +logging.file.main.keep = 30 + +logging.file.debug.name = Marmotta Debug Log +logging.file.debug.level = DEBUG +logging.file.debug.pattern = %d{HH:mm:ss.SSS} %-5level %logger{36} - %msg%n +logging.file.debug.file = marmotta-debug.log +logging.file.debug.keep = 30 ###############################################################################
