From: jsimomaa Date: Fri, 2 Mar 2018 10:28:34 +0000 (+0200) Subject: Logging configuration via SCL and UI & saving to ZIP-archive X-Git-Tag: v1.43.0~136^2~565 X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=commitdiff_plain;h=7d5a5691780ed8373e77641b4a08f18cba0b9fab;ds=sidebyside Logging configuration via SCL and UI & saving to ZIP-archive refs #7795 Change-Id: Ib8867aff85634d6a1ed6d2fe65da4e43818b83fc --- diff --git a/bundles/org.simantics.logging.ui/.classpath b/bundles/org.simantics.logging.ui/.classpath new file mode 100644 index 000000000..eca7bdba8 --- /dev/null +++ b/bundles/org.simantics.logging.ui/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/bundles/org.simantics.logging.ui/.project b/bundles/org.simantics.logging.ui/.project new file mode 100644 index 000000000..e5853c591 --- /dev/null +++ b/bundles/org.simantics.logging.ui/.project @@ -0,0 +1,28 @@ + + + org.simantics.logging.ui + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/bundles/org.simantics.logging.ui/.settings/org.eclipse.jdt.core.prefs b/bundles/org.simantics.logging.ui/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..0c68a61dc --- /dev/null +++ b/bundles/org.simantics.logging.ui/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,7 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/bundles/org.simantics.logging.ui/META-INF/MANIFEST.MF b/bundles/org.simantics.logging.ui/META-INF/MANIFEST.MF new file mode 100644 index 000000000..3f910c8e4 --- /dev/null +++ b/bundles/org.simantics.logging.ui/META-INF/MANIFEST.MF @@ -0,0 +1,20 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Ui +Bundle-SymbolicName: org.simantics.logging.ui;singleton:=true +Bundle-Version: 1.0.0.qualifier +Bundle-Activator: org.simantics.logging.ui.Activator +Require-Bundle: javax.inject, + org.eclipse.osgi, + org.eclipse.jface, + org.eclipse.e4.ui.services, + org.eclipse.e4.core.di.annotations, + org.eclipse.core.runtime, + org.eclipse.ui.ide, + org.slf4j.api, + org.simantics.logging, + org.simantics.utils, + org.simantics.utils.ui +Bundle-RequiredExecutionEnvironment: JavaSE-1.8 +Import-Package: javax.annotation;version="1.2.0" +Bundle-ActivationPolicy: lazy diff --git a/bundles/org.simantics.logging.ui/build.properties b/bundles/org.simantics.logging.ui/build.properties new file mode 100644 index 000000000..7af290f32 --- /dev/null +++ b/bundles/org.simantics.logging.ui/build.properties @@ -0,0 +1,7 @@ +source.. = src/ +output.. = bin/ +bin.includes = plugin.xml,\ + META-INF/,\ + .,\ + icons/,\ + fragment.e4xmi diff --git a/bundles/org.simantics.logging.ui/fragment.e4xmi b/bundles/org.simantics.logging.ui/fragment.e4xmi new file mode 100644 index 000000000..cc14bb5f8 --- /dev/null +++ b/bundles/org.simantics.logging.ui/fragment.e4xmi @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bundles/org.simantics.logging.ui/icons/bug.png b/bundles/org.simantics.logging.ui/icons/bug.png new file mode 100644 index 000000000..2d5fb90ec Binary files /dev/null and b/bundles/org.simantics.logging.ui/icons/bug.png differ diff --git a/bundles/org.simantics.logging.ui/icons/error.png b/bundles/org.simantics.logging.ui/icons/error.png new file mode 100644 index 000000000..c37bd062e Binary files /dev/null and b/bundles/org.simantics.logging.ui/icons/error.png differ diff --git a/bundles/org.simantics.logging.ui/icons/information.png b/bundles/org.simantics.logging.ui/icons/information.png new file mode 100644 index 000000000..12cd1aef9 Binary files /dev/null and b/bundles/org.simantics.logging.ui/icons/information.png differ diff --git a/bundles/org.simantics.logging.ui/icons/page.png b/bundles/org.simantics.logging.ui/icons/page.png new file mode 100644 index 000000000..03ddd799f Binary files /dev/null and b/bundles/org.simantics.logging.ui/icons/page.png differ diff --git a/bundles/org.simantics.logging.ui/icons/page_white_compressed.png b/bundles/org.simantics.logging.ui/icons/page_white_compressed.png new file mode 100644 index 000000000..2b6b1007f Binary files /dev/null and b/bundles/org.simantics.logging.ui/icons/page_white_compressed.png differ diff --git a/bundles/org.simantics.logging.ui/icons/page_white_edit.png b/bundles/org.simantics.logging.ui/icons/page_white_edit.png new file mode 100644 index 000000000..b93e77600 Binary files /dev/null and b/bundles/org.simantics.logging.ui/icons/page_white_edit.png differ diff --git a/bundles/org.simantics.logging.ui/icons/text_align_left.png b/bundles/org.simantics.logging.ui/icons/text_align_left.png new file mode 100644 index 000000000..6c8fcc116 Binary files /dev/null and b/bundles/org.simantics.logging.ui/icons/text_align_left.png differ diff --git a/bundles/org.simantics.logging.ui/icons/warning.png b/bundles/org.simantics.logging.ui/icons/warning.png new file mode 100644 index 000000000..628cf2dae Binary files /dev/null and b/bundles/org.simantics.logging.ui/icons/warning.png differ diff --git a/bundles/org.simantics.logging.ui/plugin.xml b/bundles/org.simantics.logging.ui/plugin.xml new file mode 100644 index 000000000..f57c8897e --- /dev/null +++ b/bundles/org.simantics.logging.ui/plugin.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/bundles/org.simantics.logging.ui/src/org/simantics/logging/ui/Activator.java b/bundles/org.simantics.logging.ui/src/org/simantics/logging/ui/Activator.java new file mode 100644 index 000000000..942a88ba2 --- /dev/null +++ b/bundles/org.simantics.logging.ui/src/org/simantics/logging/ui/Activator.java @@ -0,0 +1,30 @@ +package org.simantics.logging.ui; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; + +public class Activator implements BundleActivator { + + private static BundleContext context; + + static BundleContext getContext() { + return context; + } + + /* + * (non-Javadoc) + * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext) + */ + public void start(BundleContext bundleContext) throws Exception { + Activator.context = bundleContext; + } + + /* + * (non-Javadoc) + * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) + */ + public void stop(BundleContext bundleContext) throws Exception { + Activator.context = null; + } + +} diff --git a/bundles/org.simantics.logging.ui/src/org/simantics/logging/ui/handlers/SaveLogFilesHandler.java b/bundles/org.simantics.logging.ui/src/org/simantics/logging/ui/handlers/SaveLogFilesHandler.java new file mode 100644 index 000000000..7d7983f59 --- /dev/null +++ b/bundles/org.simantics.logging.ui/src/org/simantics/logging/ui/handlers/SaveLogFilesHandler.java @@ -0,0 +1,93 @@ +package org.simantics.logging.ui.handlers; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import javax.inject.Named; + +import org.eclipse.core.runtime.Platform; +import org.eclipse.e4.core.di.annotations.Execute; +import org.eclipse.e4.ui.services.IServiceConstants; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Shell; +import org.simantics.logging.LogCollector; +import org.simantics.utils.FileUtils; +import org.simantics.utils.ui.ExceptionUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SaveLogFilesHandler { + + private static final Logger LOGGER = LoggerFactory.getLogger(SaveLogFilesHandler.class); + + private static final String[] FILTER_NAMES = { "ZIP-archive", "AllFiles (*:*)" }; + private static final String[] FILTER_EXTENSIONS = { "*.zip", "*.*" }; + private static final String USER_HOME = System.getProperty("user.home"); + + @Execute + public void execute(@Named(IServiceConstants.ACTIVE_SHELL) Shell shell) { + + FileDialog dialog = new FileDialog(shell, SWT.SAVE); + dialog.setFilterNames(FILTER_NAMES); + dialog.setFilterExtensions(FILTER_EXTENSIONS); + if (USER_HOME != null) { + if (Files.exists(Paths.get(USER_HOME))) { + dialog.setFilterPath(USER_HOME); + } + } + StringBuilder fileName = new StringBuilder(); + String productName = Platform.getProduct().getName(); + if (productName != null) + fileName.append(productName.replaceAll(" ", "_")).append("-"); + + fileName.append("logs-").append(currentLocalDateTimeStamp()); + String actualFileName = fileName.toString(); + if (LOGGER.isDebugEnabled()) + LOGGER.debug("Resolved log files name {}", actualFileName); + dialog.setFileName(actualFileName); + + String destination = dialog.open(); + if (destination != null) { + if (LOGGER.isDebugEnabled()) + LOGGER.debug("Destination for saving log files is {}", destination); + + try { + Path tempDir = Files.createTempDirectory(actualFileName); + Map> allLogs = LogCollector.allLogs(); + for (Entry> logEntry : allLogs.entrySet()) { + Path subFolder = tempDir.resolve(logEntry.getKey()); + Files.createDirectory(subFolder); + for (Path p : logEntry.getValue()) { + try { + Files.copy(p, subFolder.resolve(p.getFileName())); + } catch (IOException e) { + LOGGER.error("Could not copy {}", p.toAbsolutePath(), e); + } + } + } + FileUtils.compressZip(tempDir.toAbsolutePath().toString(), destination); + FileUtils.delete(tempDir); + } catch (Throwable t) { + LOGGER.error("Could not save log files to ZIP", t); + ExceptionUtils.logAndShowError("Could not save log files to ZIP", t); + } + } else { + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("No destination selected for saving logs"); + } + } + } + + private static String currentLocalDateTimeStamp() { + return LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd_HHmm")); + } + +} diff --git a/bundles/org.simantics.logging.ui/src/org/simantics/logging/ui/handlers/SelectLoggingLevelHandler.java b/bundles/org.simantics.logging.ui/src/org/simantics/logging/ui/handlers/SelectLoggingLevelHandler.java new file mode 100644 index 000000000..27473f182 --- /dev/null +++ b/bundles/org.simantics.logging.ui/src/org/simantics/logging/ui/handlers/SelectLoggingLevelHandler.java @@ -0,0 +1,21 @@ +package org.simantics.logging.ui.handlers; + +import javax.inject.Named; + +import org.eclipse.e4.core.di.annotations.Execute; +import org.simantics.logging.LogConfigurator; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SelectLoggingLevelHandler { + + private static final Logger LOGGER = LoggerFactory.getLogger(SelectLoggingLevelHandler.class); + + @Execute + public void execute(@Named("org.simantics.logging.ui.commandparameter.selectLoggingLevel") String level) { + if (LOGGER.isDebugEnabled()) + LOGGER.debug("Setting logging level to {}", level); + LogConfigurator.setLoggingLevel(level); + } + +} diff --git a/bundles/org.simantics.logging/.classpath b/bundles/org.simantics.logging/.classpath new file mode 100644 index 000000000..eca7bdba8 --- /dev/null +++ b/bundles/org.simantics.logging/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/bundles/org.simantics.logging/.project b/bundles/org.simantics.logging/.project new file mode 100644 index 000000000..9f60062cf --- /dev/null +++ b/bundles/org.simantics.logging/.project @@ -0,0 +1,33 @@ + + + org.simantics.logging + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + org.eclipse.pde.ds.core.builder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/bundles/org.simantics.logging/.settings/org.eclipse.jdt.core.prefs b/bundles/org.simantics.logging/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..0c68a61dc --- /dev/null +++ b/bundles/org.simantics.logging/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,7 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/bundles/org.simantics.logging/META-INF/MANIFEST.MF b/bundles/org.simantics.logging/META-INF/MANIFEST.MF new file mode 100644 index 000000000..115019a65 --- /dev/null +++ b/bundles/org.simantics.logging/META-INF/MANIFEST.MF @@ -0,0 +1,16 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Simantics Logging Core +Bundle-SymbolicName: org.simantics.logging +Bundle-Version: 1.0.0.qualifier +Bundle-Activator: org.simantics.logging.internal.Activator +Bundle-Vendor: Semantum Oy +Require-Bundle: org.eclipse.core.runtime, + org.slf4j.api, + ch.qos.logback.classic, + ch.qos.logback.core +Bundle-RequiredExecutionEnvironment: JavaSE-1.8 +Bundle-ActivationPolicy: lazy +Service-Component: logbackLogProvider.xml, + dbAndMetadataLogProvider.xml +Export-Package: org.simantics.logging diff --git a/bundles/org.simantics.logging/build.properties b/bundles/org.simantics.logging/build.properties new file mode 100644 index 000000000..c5cc5f8a3 --- /dev/null +++ b/bundles/org.simantics.logging/build.properties @@ -0,0 +1,7 @@ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + scl/,\ + logbackLogProvider.xml,\ + dbAndMetadataLogProvider.xml +source.. = src/ diff --git a/bundles/org.simantics.logging/dbAndMetadataLogProvider.xml b/bundles/org.simantics.logging/dbAndMetadataLogProvider.xml new file mode 100644 index 000000000..aa4678fe7 --- /dev/null +++ b/bundles/org.simantics.logging/dbAndMetadataLogProvider.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/bundles/org.simantics.logging/logbackLogProvider.xml b/bundles/org.simantics.logging/logbackLogProvider.xml new file mode 100644 index 000000000..9e9e6db1a --- /dev/null +++ b/bundles/org.simantics.logging/logbackLogProvider.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/bundles/org.simantics.logging/scl/LoggingUtils.scl b/bundles/org.simantics.logging/scl/LoggingUtils.scl new file mode 100644 index 000000000..500ba1b83 --- /dev/null +++ b/bundles/org.simantics.logging/scl/LoggingUtils.scl @@ -0,0 +1,9 @@ +import "Files" +import "Map" as Map + +importJava "org.simantics.logging.LogConfigurator" where + setLoggingLevel :: String -> () + setLoggingLevelForLogger :: String -> String -> () + +importJava "org.simantics.logging.LogCollector" where + allLogs :: Map.T String [Path] \ No newline at end of file diff --git a/bundles/org.simantics.logging/src/org/simantics/logging/DBAndMetadataLogProvider.java b/bundles/org.simantics.logging/src/org/simantics/logging/DBAndMetadataLogProvider.java new file mode 100644 index 000000000..79e10dbef --- /dev/null +++ b/bundles/org.simantics.logging/src/org/simantics/logging/DBAndMetadataLogProvider.java @@ -0,0 +1,60 @@ +package org.simantics.logging; + +import java.lang.reflect.Field; +import java.net.URL; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.runtime.Platform; +import org.osgi.framework.Bundle; +import org.slf4j.LoggerFactory; + +public class DBAndMetadataLogProvider implements LogProvider { + + private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(DBAndMetadataLogProvider.class); + + @Override + public List get() { + List logs = new ArrayList<>(); + Path dbClientLog = getDBClientLogLocation(); + if (dbClientLog != null) + logs.add(dbClientLog); + Path metadataLogLocation = getMetadataLogLocation(); + if (metadataLogLocation != null) + logs.add(metadataLogLocation); + return logs; + } + + private static Path getDBClientLogLocation() { + Bundle bundle = Platform.getBundle("org.simantics.db.common"); + try { + Class forName = bundle.loadClass("org.simantics.db.common.internal.config.InternalClientConfig"); + Field field = forName.getField("DB_CLIENT_LOG_FILE"); + String value = (String) field.get(null); + return Paths.get(value); + } catch (ClassNotFoundException | NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) { + LOGGER.error("Could not read db-client.log location", e); + } + return null; + } + + private static Path getMetadataLogLocation() { + String prop = System.getProperty("osgi.instance.area", null); + if (prop != null) { + try { + URL url = new URL(prop); + if ("file".equals(url .getProtocol())) { + Path path = Paths.get(url.toURI()); + return path.resolve(".metadata").resolve(".log"); + } else { + LOGGER.warn("Unsupported protocol {}", url); + } + } catch (Throwable t) { + LOGGER.error("Could not get .metadata/.log", t); + } + } + return null; + } +} diff --git a/bundles/org.simantics.logging/src/org/simantics/logging/LogCollector.java b/bundles/org.simantics.logging/src/org/simantics/logging/LogCollector.java new file mode 100644 index 000000000..4d98e2767 --- /dev/null +++ b/bundles/org.simantics.logging/src/org/simantics/logging/LogCollector.java @@ -0,0 +1,65 @@ +package org.simantics.logging; + +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.osgi.framework.InvalidSyntaxException; +import org.osgi.framework.ServiceReference; +import org.simantics.logging.internal.Activator; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public final class LogCollector { + + private static final Logger LOGGER = LoggerFactory.getLogger(LogCollector.class); + + public static Map> allLogs() { + Map> results = new HashMap<>(); + if (LOGGER.isDebugEnabled()) + LOGGER.debug("Collecting all logs from declarative services"); + + Collection logProviders = getLogProviders(); + for (LogProvider logProvider : logProviders) { + List logs = logProvider.get(); + String key = logProvider.getClass().getSimpleName(); + Collection existing = results.get(key); + if (existing != null) { + LOGGER.info("Duplicate log providers with name {} exist, merging logs", key); + logs.addAll(existing); + } + results.put(key, logs); + } + if (LOGGER.isDebugEnabled()) + LOGGER.debug("Found logs from {} providers", results.keySet()); + return results; + } + + private static List getLogProviders() { + ServiceReference[] serviceReferences = new ServiceReference[0]; + String key = LogProvider.class.getName(); + try { + serviceReferences = Activator.getContext().getAllServiceReferences(key, null); + } catch (InvalidSyntaxException e) { + LOGGER.error("Could not get service references for {}!", key, e); + } + if (serviceReferences.length == 0) { + if (LOGGER.isDebugEnabled()) + LOGGER.debug("No service references found for {}", key); + return Collections.emptyList(); + } + + List logProviders = new ArrayList<>(serviceReferences.length); + for (ServiceReference reference : serviceReferences) { + LogProvider logProvider = (LogProvider) Activator.getContext().getService(reference); + logProviders.add(logProvider); + } + if (LOGGER.isDebugEnabled()) + LOGGER.debug("Found {} log providers", logProviders); + return logProviders; + } +} diff --git a/bundles/org.simantics.logging/src/org/simantics/logging/LogConfigurator.java b/bundles/org.simantics.logging/src/org/simantics/logging/LogConfigurator.java new file mode 100644 index 000000000..047bac8b6 --- /dev/null +++ b/bundles/org.simantics.logging/src/org/simantics/logging/LogConfigurator.java @@ -0,0 +1,54 @@ +package org.simantics.logging; + +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import ch.qos.logback.classic.Level; +import ch.qos.logback.classic.LoggerContext; + +/** + * Class for modifying the active logging configuration + * + * @author Jani Simomaa + * + */ +public final class LogConfigurator { + + private static final Logger LOGGER = LoggerFactory.getLogger(LogConfigurator.class); + + private LogConfigurator() { + } + + /** + * Sets logging level to represent the given argument + * + * @param level ERROR WARN INFO DEBUG TRACE + */ + public static void setLoggingLevel(String level) { + if (LOGGER.isInfoEnabled()) + LOGGER.info("Setting logger level to {}", level); + LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory(); + Level ll = getLoggerLevel(level); + List loggerList = context.getLoggerList(); + loggerList.forEach(l -> l.setLevel(ll)); + if (LOGGER.isDebugEnabled()) + LOGGER.debug("Loggers installed {}", loggerList); + } + + public static void setLoggingLevelForLogger(String logger, String level) { + if (LOGGER.isInfoEnabled()) + LOGGER.info("Setting logger level to {} for loggers {}", level, logger); + LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory(); + Level ll = getLoggerLevel(level); + ch.qos.logback.classic.Logger loggerList = context.getLogger(logger); + loggerList.setLevel(ll); + if (LOGGER.isDebugEnabled()) + LOGGER.debug("Loggers installed {}", loggerList); + } + + private static Level getLoggerLevel(String level) { + return Level.valueOf(level); + } +} diff --git a/bundles/org.simantics.logging/src/org/simantics/logging/LogProvider.java b/bundles/org.simantics.logging/src/org/simantics/logging/LogProvider.java new file mode 100644 index 000000000..7f7a8278c --- /dev/null +++ b/bundles/org.simantics.logging/src/org/simantics/logging/LogProvider.java @@ -0,0 +1,9 @@ +package org.simantics.logging; + +import java.nio.file.Path; +import java.util.List; +import java.util.function.Supplier; + +public interface LogProvider extends Supplier> { + +} diff --git a/bundles/org.simantics.logging/src/org/simantics/logging/LogbackLogProvider.java b/bundles/org.simantics.logging/src/org/simantics/logging/LogbackLogProvider.java new file mode 100644 index 000000000..3c88cd542 --- /dev/null +++ b/bundles/org.simantics.logging/src/org/simantics/logging/LogbackLogProvider.java @@ -0,0 +1,83 @@ +package org.simantics.logging; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.stream.Collectors; + +import org.slf4j.LoggerFactory; + +import ch.qos.logback.classic.Logger; +import ch.qos.logback.classic.LoggerContext; +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.core.Appender; +import ch.qos.logback.core.FileAppender; +import ch.qos.logback.core.rolling.RollingFileAppender; +import ch.qos.logback.core.spi.AppenderAttachable; + +public class LogbackLogProvider implements LogProvider { + + private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(LogbackLogProvider.class); + + @Override + public List get() { + List logs = new ArrayList<>(); + try { + LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory(); + Logger logger = context.getLogger(Logger.ROOT_LOGGER_NAME); + Iterator> appenderIter = logger.iteratorForAppenders(); + while (appenderIter.hasNext()) { + FileAppender appender = findFileAppender(appenderIter.next()); + if (appender != null) { + String logFile = ((FileAppender)appender).getFile(); + Path log = Paths.get(logFile).toAbsolutePath(); + if (appender instanceof RollingFileAppender) { + // Collect all logs + Path parent = log.getParent(); + List newLogs = Files.walk(parent).collect(Collectors.toList()); + if (LOGGER.isDebugEnabled()) + LOGGER.debug("Found {} from {}", newLogs, appender); + logs.addAll(newLogs); + } else { + logs.add(log); + } + } else { + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("Appender is not {} but is {} instead", FileAppender.class.getName(), appender != null ? appender.getClass().getName() : "null"); + } + } + } + } catch (ClassCastException e) { + // Okay, we are not using logback here + if (LOGGER.isDebugEnabled()) + LOGGER.debug("Seems like we are not using logback but {} instead", LoggerFactory.getILoggerFactory(), e); + } catch (Throwable t) { + LOGGER.error("Could not collect logs", t); + } + if (LOGGER.isDebugEnabled()) + LOGGER.debug("Found {} log files : {}", logs.size(), logs); + return logs; + } + + private static FileAppender findFileAppender(Appender appender) { + if (appender instanceof AppenderAttachable) { + // Ok, has child appender + Iterator> children = ((AppenderAttachable) appender).iteratorForAppenders(); + while (children.hasNext()) { + FileAppender app = findFileAppender(children.next()); + // TODO: returns only first FileAppender that it founds but not a collection + if (app != null) + return app; + } + return null; + } else if (appender instanceof FileAppender) { + return (FileAppender) appender; + } else { + return null; + } + } + +} diff --git a/bundles/org.simantics.logging/src/org/simantics/logging/internal/Activator.java b/bundles/org.simantics.logging/src/org/simantics/logging/internal/Activator.java new file mode 100644 index 000000000..abedac6ea --- /dev/null +++ b/bundles/org.simantics.logging/src/org/simantics/logging/internal/Activator.java @@ -0,0 +1,30 @@ +package org.simantics.logging.internal; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; + +public class Activator implements BundleActivator { + + private static BundleContext context; + + public static BundleContext getContext() { + return context; + } + + /* + * (non-Javadoc) + * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext) + */ + public void start(BundleContext bundleContext) throws Exception { + Activator.context = bundleContext; + } + + /* + * (non-Javadoc) + * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) + */ + public void stop(BundleContext bundleContext) throws Exception { + Activator.context = null; + } + +} diff --git a/bundles/pom.xml b/bundles/pom.xml index 7ac841ad1..6bcbd6657 100644 --- a/bundles/pom.xml +++ b/bundles/pom.xml @@ -156,6 +156,8 @@ org.simantics.layer0.utils org.simantics.layer0x.ontology org.simantics.logback.configuration + org.simantics.logging + org.simantics.logging.ui org.simantics.ltk org.simantics.ltk.antlr org.simantics.lz4 diff --git a/features/org.simantics.logging.feature/.project b/features/org.simantics.logging.feature/.project new file mode 100644 index 000000000..3ba00777a --- /dev/null +++ b/features/org.simantics.logging.feature/.project @@ -0,0 +1,17 @@ + + + org.simantics.logging.feature + + + + + + org.eclipse.pde.FeatureBuilder + + + + + + org.eclipse.pde.FeatureNature + + diff --git a/features/org.simantics.logging.feature/build.properties b/features/org.simantics.logging.feature/build.properties new file mode 100644 index 000000000..64f93a9f0 --- /dev/null +++ b/features/org.simantics.logging.feature/build.properties @@ -0,0 +1 @@ +bin.includes = feature.xml diff --git a/features/org.simantics.logging.feature/feature.xml b/features/org.simantics.logging.feature/feature.xml new file mode 100644 index 000000000..3f4e57318 --- /dev/null +++ b/features/org.simantics.logging.feature/feature.xml @@ -0,0 +1,27 @@ + + + + + [Enter Feature Description here.] + + + + [Enter Copyright Description here.] + + + + [Enter License Description here.] + + + + + diff --git a/features/org.simantics.logging.ui.feature/.project b/features/org.simantics.logging.ui.feature/.project new file mode 100644 index 000000000..e4640469e --- /dev/null +++ b/features/org.simantics.logging.ui.feature/.project @@ -0,0 +1,17 @@ + + + org.simantics.logging.ui.feature + + + + + + org.eclipse.pde.FeatureBuilder + + + + + + org.eclipse.pde.FeatureNature + + diff --git a/features/org.simantics.logging.ui.feature/build.properties b/features/org.simantics.logging.ui.feature/build.properties new file mode 100644 index 000000000..64f93a9f0 --- /dev/null +++ b/features/org.simantics.logging.ui.feature/build.properties @@ -0,0 +1 @@ +bin.includes = feature.xml diff --git a/features/org.simantics.logging.ui.feature/feature.xml b/features/org.simantics.logging.ui.feature/feature.xml new file mode 100644 index 000000000..6f94a0ef0 --- /dev/null +++ b/features/org.simantics.logging.ui.feature/feature.xml @@ -0,0 +1,31 @@ + + + + + [Enter Feature Description here.] + + + + [Enter Copyright Description here.] + + + + [Enter License Description here.] + + + + + + + diff --git a/features/org.simantics.sdk.feature/feature.xml b/features/org.simantics.sdk.feature/feature.xml index 0fc787e69..b7dc9adee 100644 --- a/features/org.simantics.sdk.feature/feature.xml +++ b/features/org.simantics.sdk.feature/feature.xml @@ -216,6 +216,14 @@ id="hdf.hdf5" version="0.0.0"/> + + + + org.simantics.issues.feature org.simantics.issues.ui.feature org.simantics.layer0.feature + org.simantics.logging.feature + org.simantics.logging.ui.feature org.simantics.message.feature org.simantics.migration.feature org.simantics.modeling.feature