package org.simantics.logging; 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.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.eclipse.core.runtime.Platform; import org.osgi.framework.InvalidSyntaxException; import org.osgi.framework.ServiceReference; import org.simantics.logging.internal.Activator; import org.simantics.utils.FileUtils; 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; } private static String currentLocalDateTimeStamp() { return LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd_HHmm")); } public static String archiveFileName() { StringBuilder fileName = new StringBuilder(); String productName = Platform.getProduct().getName(); if (productName != null) fileName.append(productName.replaceAll(" ", "_")).append("-"); fileName.append("logs-").append(currentLocalDateTimeStamp()); String result = fileName.toString(); if (LOGGER.isDebugEnabled()) LOGGER.debug("Resolved log files name {}", result); return result; } public static void archiveLogs(String destination) throws IOException { archiveLogs(Paths.get(destination)); } private static void archiveLogs(Path destination) throws IOException { Path tempDir = Files.createTempDirectory(destination.getFileName().toString()); try { 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.toAbsolutePath().toString()); } finally { FileUtils.delete(tempDir); } } }