InfoCollector.java 7.72 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  org.apache.felix.inventory.Format
 *  org.apache.felix.inventory.InventoryPrinter
 *  org.apache.felix.inventory.ZipAttachmentProvider
 *  org.apache.felix.scr.annotations.Activate
 *  org.apache.felix.scr.annotations.Component
 *  org.apache.felix.scr.annotations.Properties
 *  org.apache.felix.scr.annotations.Property
 *  org.apache.felix.scr.annotations.Reference
 *  org.apache.felix.scr.annotations.Service
 *  org.apache.sling.commons.osgi.OsgiUtil
 *  org.apache.sling.settings.SlingSettingsService
 *  org.osgi.service.component.ComponentContext
 *  org.slf4j.Logger
 *  org.slf4j.LoggerFactory
 */
package com.adobe.granite.infocollector.impl;

import com.adobe.granite.infocollector.impl.FilesHandler;
import com.adobe.granite.infocollector.impl.FilesIndexHandler;
import com.adobe.granite.infocollector.impl.FilesTraversal;
import com.adobe.granite.infocollector.impl.FilteredListFilesHandler;
import com.adobe.granite.infocollector.impl.ZipFilesHandler;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.management.ManagementFactory;
import java.lang.reflect.Method;
import java.util.Dictionary;
import java.util.List;
import java.util.zip.ZipOutputStream;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import org.apache.felix.inventory.Format;
import org.apache.felix.inventory.InventoryPrinter;
import org.apache.felix.inventory.ZipAttachmentProvider;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.commons.osgi.OsgiUtil;
import org.apache.sling.settings.SlingSettingsService;
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Component(metatype=1, name="com.adobe.granite.infocollector.InfoCollector", label="Granite System Information Collector", description="Collects in a Zipped stream all the system informations")
@Service(value={InventoryPrinter.class, ZipAttachmentProvider.class})
@Properties(value={@Property(name="felix.inventory.printer.name", value={"info-collector"}, propertyPrivate=1), @Property(name="felix.inventory.printer.title", value={"Info Collector"}, propertyPrivate=1)})
public final class InfoCollector
implements InventoryPrinter,
ZipAttachmentProvider {
    private static final boolean DEFAULT_INCLUDE_THREAD_DUMPS = true;
    private static final boolean DEFAULT_INCLUDE_HEAP_DUMP = false;
    private static final String XML_FILE_EXTENSION = ".xml";
    @Property(label="Include Thread Dumps", description="Include thread dump files", boolValue={1})
    public static String INCLUDE_THREAD_DUMPS = "granite.infocollector.includeThreadDumps";
    @Property(label="Include Heap Dump", description="Include heap dump file", boolValue={0})
    public static String INCLUDE_HEAP_DUMP = "granite.infocollector.includeHeapDump";
    @Reference
    private SlingSettingsService settingsService;
    private final Logger logger;
    private FilesTraversal filesTraversal;
    private boolean includeThreadDumps;
    private boolean includeHeapDump;

    public InfoCollector() {
        this.logger = LoggerFactory.getLogger(this.getClass());
    }

    @Activate
    protected void activate(ComponentContext context) {
        this.filesTraversal = new FilesTraversal(this.settingsService.getSlingHomePath());
        Dictionary contextProperties = context.getProperties();
        this.includeThreadDumps = OsgiUtil.toBoolean(contextProperties.get(INCLUDE_THREAD_DUMPS), (boolean)true);
        this.includeHeapDump = OsgiUtil.toBoolean(contextProperties.get(INCLUDE_HEAP_DUMP), (boolean)false);
    }

    public void print(PrintWriter printWriter, Format format, boolean isZip) {
        printWriter.println("     Length       Date        Time     rwx    Name");
        printWriter.println("    --------   ----------   --------   ---   ------");
        try {
            this.filesTraversal.traverse(new FilesIndexHandler(this.filesTraversal, printWriter));
        }
        catch (IOException e) {
            this.logger.error("Impossible to produce the file listing due to file system tarversal error", (Throwable)e);
        }
    }

    /*
     * WARNING - Removed try catching itself - possible behaviour change.
     */
    public void addAttachments(ZipOutputStream target, String namePrefix) throws IOException {
        ZipFilesHandler zipFilesHandler = new ZipFilesHandler(this.filesTraversal, target, namePrefix);
        this.logger.info("Creating the System Information collection...");
        try {
            FilteredListFilesHandler filteredListFilesHandler = new FilteredListFilesHandler(".xml");
            for (String xmlDir : new String[]{"server/etc", "server/runtime/0/_crx/WEB-INF"}) {
                this.filesTraversal.traverse(xmlDir, (FilesHandler)filteredListFilesHandler);
            }
            for (File xmlConfiguration : filteredListFilesHandler.getFilteredFiles()) {
                zipFilesHandler.onFile(xmlConfiguration);
            }
            if (this.includeThreadDumps) {
                this.logger.info("Including Thread Dump files...");
                this.filesTraversal.traverse("threaddumps", (FilesHandler)zipFilesHandler);
                this.logger.info("Thread Dump files included.");
            }
            if (this.includeHeapDump) {
                this.logger.info("Including Heap Dump file...");
                String name = String.format("heap.%s.hprof", System.currentTimeMillis());
                File dumpFile = new File(this.filesTraversal.getHome(), name);
                if (!this.dumpSunMBean(dumpFile)) {
                    this.dumpIbmDump(dumpFile);
                }
                zipFilesHandler.onFile(dumpFile);
                dumpFile.delete();
                this.logger.info("Heap Dump file included.");
            }
        }
        finally {
            this.logger.info("System Information collection creation is over.");
        }
    }

    private boolean dumpSunMBean(File dumpFile) throws IOException {
        MBeanServer server = ManagementFactory.getPlatformMBeanServer();
        try {
            server.invoke(new ObjectName("com.sun.management:type=HotSpotDiagnostic"), "dumpHeap", new Object[]{dumpFile.getAbsolutePath(), false}, new String[]{String.class.getName(), Boolean.TYPE.getName()});
            return true;
        }
        catch (Throwable ignore) {
            return false;
        }
    }

    private boolean dumpIbmDump(File dumpFile) {
        try {
            long minFileTime = System.currentTimeMillis();
            Class c = ClassLoader.getSystemClassLoader().loadClass("com.ibm.jvm.Dump");
            Method m = c.getDeclaredMethod("HeapDump", null);
            m.invoke(null, null);
            File dir = new File("").getAbsoluteFile();
            File[] files = dir.listFiles();
            if (files != null) {
                for (File file : files) {
                    if (!file.isFile() || file.lastModified() <= minFileTime) continue;
                    file.renameTo(dumpFile);
                    return true;
                }
            }
        }
        catch (Throwable ignore) {
            // empty catch block
        }
        return false;
    }

    protected void bindSettingsService(SlingSettingsService slingSettingsService) {
        this.settingsService = slingSettingsService;
    }

    protected void unbindSettingsService(SlingSettingsService slingSettingsService) {
        if (this.settingsService == slingSettingsService) {
            this.settingsService = null;
        }
    }
}