Author: jm Date: 2012-10-24 14:31:13 -0700 (Wed, 24 Oct 2012) New Revision: 30703
Added: core3/gui-distribution/trunk/diagnostics/ core3/gui-distribution/trunk/diagnostics/pom.xml core3/gui-distribution/trunk/diagnostics/src/ core3/gui-distribution/trunk/diagnostics/src/main/ core3/gui-distribution/trunk/diagnostics/src/main/java/ core3/gui-distribution/trunk/diagnostics/src/main/java/org/ core3/gui-distribution/trunk/diagnostics/src/main/java/org/cytoscape/ core3/gui-distribution/trunk/diagnostics/src/main/java/org/cytoscape/diagnostics/ core3/gui-distribution/trunk/diagnostics/src/main/java/org/cytoscape/diagnostics/PerformanceDetails.java core3/gui-distribution/trunk/diagnostics/src/main/java/org/cytoscape/diagnostics/internal/ core3/gui-distribution/trunk/diagnostics/src/main/java/org/cytoscape/diagnostics/internal/Activator.java core3/gui-distribution/trunk/diagnostics/src/main/java/org/cytoscape/diagnostics/internal/PerformanceDetailsBuilder.java core3/gui-distribution/trunk/diagnostics/src/main/java/org/cytoscape/diagnostics/internal/PerformanceTracker.java Modified: core3/gui-distribution/trunk/features/src/main/resources/features.xml core3/gui-distribution/trunk/launcher/src/main/java/org/cytoscape/launcher/internal/Launcher.java core3/gui-distribution/trunk/pom.xml core3/support/trunk/splash-updater-impl/src/main/java/org/cytoscape/splash/internal/SplashManipulator.java Log: References #1529, #1494: Added internal OSGi service for tracking start up performance. Moved start-level hack into new diagnostics-impl bundle. Added: core3/gui-distribution/trunk/diagnostics/pom.xml =================================================================== --- core3/gui-distribution/trunk/diagnostics/pom.xml (rev 0) +++ core3/gui-distribution/trunk/diagnostics/pom.xml 2012-10-24 21:31:13 UTC (rev 30703) @@ -0,0 +1,58 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + + <parent> + <groupId>org.cytoscape.distribution</groupId> + <artifactId>parent</artifactId> + <version>3.0.0-beta2-SNAPSHOT</version> + <relativePath>..</relativePath> + </parent> + + <modelVersion>4.0.0</modelVersion> + <artifactId>diagnostics-impl</artifactId> + + <name>Cytoscape Diagnostics</name> + + <properties> + <bundle.symbolicName>org.cytoscape.diagnostics-impl</bundle.symbolicName> + <bundle.namespace>org.cytoscape.diagnostics</bundle.namespace> + </properties> + + <packaging>bundle</packaging> + + <dependencies> + <dependency> + <groupId>org.osgi</groupId> + <artifactId>org.osgi.core</artifactId> + <version>${osgi.api.version}</version> + </dependency> + + <dependency> + <groupId>org.cytoscape.distribution</groupId> + <artifactId>karaf-launcher</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <version>${maven-bundle-plugin.version}</version> + <extensions>true</extensions> + <configuration> + <instructions> + <Bundle-Activator>${bundle.namespace}.internal.Activator</Bundle-Activator> + <Bundle-SymbolicName>${bundle.symbolicName}</Bundle-SymbolicName> + <Bundle-Version>${project.version}</Bundle-Version> + <Export-Package>!${bundle.namespace}.internal.*,*</Export-Package> + <Private-Package>${bundle.namespace}.internal.*</Private-Package> + <_include>-osgi.bnd</_include> + </instructions> + </configuration> + </plugin> + </plugins> + </build> +</project> Added: core3/gui-distribution/trunk/diagnostics/src/main/java/org/cytoscape/diagnostics/PerformanceDetails.java =================================================================== --- core3/gui-distribution/trunk/diagnostics/src/main/java/org/cytoscape/diagnostics/PerformanceDetails.java (rev 0) +++ core3/gui-distribution/trunk/diagnostics/src/main/java/org/cytoscape/diagnostics/PerformanceDetails.java 2012-10-24 21:31:13 UTC (rev 30703) @@ -0,0 +1,15 @@ +package org.cytoscape.diagnostics; + +import java.util.Map; +import java.util.Set; + +public interface PerformanceDetails { + long getFrameworkLaunchDuration(); + long getTotalLaunchDuration(); + + Set<Long> getObservedBundleIds(); + long getBundleLaunchDuration(long bundleId); + long getBundleLaunchLatency(long bundleId); + String getBundleDescription(long bundleId); + Map<String, Long> getAllBundleLaunchDurations(); +} Added: core3/gui-distribution/trunk/diagnostics/src/main/java/org/cytoscape/diagnostics/internal/Activator.java =================================================================== --- core3/gui-distribution/trunk/diagnostics/src/main/java/org/cytoscape/diagnostics/internal/Activator.java (rev 0) +++ core3/gui-distribution/trunk/diagnostics/src/main/java/org/cytoscape/diagnostics/internal/Activator.java 2012-10-24 21:31:13 UTC (rev 30703) @@ -0,0 +1,39 @@ +package org.cytoscape.diagnostics.internal; + +import java.util.Properties; + +import org.cytoscape.diagnostics.PerformanceDetails; +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceReference; +import org.osgi.service.startlevel.StartLevel; + +public class Activator implements BundleActivator { + + static final int INITIAL_START_LEVEL = 200; + + @Override + public void start(BundleContext context) throws Exception { + applyStartLevelHack(context); + + PerformanceDetailsBuilder details = new PerformanceDetailsBuilder(); + context.registerService(PerformanceDetails.class.getName(), details, new Properties()); + + PerformanceTracker performanceTracker = new PerformanceTracker(context, details); + context.addFrameworkListener(performanceTracker); + context.addBundleListener(performanceTracker); + } + + private void applyStartLevelHack(BundleContext context) { + // See ticket #1494. This hack needs to remain in place until Karaf + // is patched. + ServiceReference reference = context.getServiceReference(StartLevel.class.getName()); + StartLevel level = (StartLevel) context.getService(reference); + level.setStartLevel(INITIAL_START_LEVEL); + context.ungetService(reference); + } + + @Override + public void stop(BundleContext context) throws Exception { + } +} Added: core3/gui-distribution/trunk/diagnostics/src/main/java/org/cytoscape/diagnostics/internal/PerformanceDetailsBuilder.java =================================================================== --- core3/gui-distribution/trunk/diagnostics/src/main/java/org/cytoscape/diagnostics/internal/PerformanceDetailsBuilder.java (rev 0) +++ core3/gui-distribution/trunk/diagnostics/src/main/java/org/cytoscape/diagnostics/internal/PerformanceDetailsBuilder.java 2012-10-24 21:31:13 UTC (rev 30703) @@ -0,0 +1,124 @@ +package org.cytoscape.diagnostics.internal; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import org.cytoscape.diagnostics.PerformanceDetails; +import org.osgi.framework.Bundle; + +public class PerformanceDetailsBuilder implements PerformanceDetails { + + private long systemLaunchStartTime; + private long systemLaunchEndTime; + private long frameworkLaunchEndTime; + + private Map<Long, String> bundleNames; + private Map<Long, Long> bundleActivationStartTimes; + private Map<Long, Long> bundleActivationEndTimes; + + public PerformanceDetailsBuilder() { + bundleNames = new HashMap<Long, String>(); + bundleActivationStartTimes = new HashMap<Long, Long>(); + bundleActivationEndTimes = new HashMap<Long, Long>(); + } + + @Override + public long getFrameworkLaunchDuration() { + return frameworkLaunchEndTime - systemLaunchStartTime; + } + + @Override + public long getTotalLaunchDuration() { + return systemLaunchEndTime - systemLaunchStartTime; + } + + @Override + public long getBundleLaunchDuration(long bundleId) { + Long startTime = bundleActivationStartTimes.get(bundleId); + Long endTime = bundleActivationEndTimes.get(bundleId); + if (startTime == null || endTime == null) { + return -1; + } + return endTime - startTime; + } + + @Override + public Set<Long> getObservedBundleIds() { + Set<Long> bundleIds = new HashSet<Long>(bundleActivationStartTimes.keySet()); + bundleIds.addAll(bundleActivationEndTimes.keySet()); + return bundleIds; + } + + @Override + public Map<String, Long> getAllBundleLaunchDurations() { + Map<String, Long> durations = new HashMap<String, Long>(); + for (Entry<Long, Long> entry : bundleActivationStartTimes.entrySet()) { + Long bundleId = entry.getKey(); + Long endTime = bundleActivationEndTimes.get(bundleId); + if (endTime == null) { + continue; + } + durations.put(bundleNames.get(bundleId), endTime - entry.getValue()); + } + return durations; + } + + @Override + public long getBundleLaunchLatency(long bundleId) { + Long startTime = bundleActivationStartTimes.get(bundleId); + if (startTime == null) { + return -1; + } + return startTime - systemLaunchStartTime; + } + + @Override + public String getBundleDescription(long bundleId) { + return bundleNames.get(bundleId); + } + + void setSystemLaunchStartTime(long time) { + systemLaunchStartTime = time; + } + + void setSystemLaunchEndTime(long time) { + systemLaunchEndTime = time; + } + + void setFrameworkLaunchEndTime(long time) { + frameworkLaunchEndTime = time; + } + + void logBundleStarting(Bundle bundle) { + logBundleName(bundle); + + // Only log the first activation + Long startTime = bundleActivationStartTimes.get(bundle.getBundleId()); + if (startTime != null) { + return; + } + bundleActivationStartTimes.put(bundle.getBundleId(), System.currentTimeMillis()); + } + + private void logBundleName(Bundle bundle) { + String name = bundleNames.get(bundle.getBundleId()); + if (name == null) { + name = String.format("%s (%s)", bundle.getSymbolicName(), bundle.getVersion().toString()); + bundleNames.put(bundle.getBundleId(), name); + } + } + + void logBundleStarted(Bundle bundle) { + logBundleName(bundle); + + // Only log the first activation + Long endTime = bundleActivationEndTimes.get(bundle.getBundleId()); + if (endTime != null) { + return; + } + bundleActivationEndTimes.put(bundle.getBundleId(), System.currentTimeMillis()); + } +} Added: core3/gui-distribution/trunk/diagnostics/src/main/java/org/cytoscape/diagnostics/internal/PerformanceTracker.java =================================================================== --- core3/gui-distribution/trunk/diagnostics/src/main/java/org/cytoscape/diagnostics/internal/PerformanceTracker.java (rev 0) +++ core3/gui-distribution/trunk/diagnostics/src/main/java/org/cytoscape/diagnostics/internal/PerformanceTracker.java 2012-10-24 21:31:13 UTC (rev 30703) @@ -0,0 +1,59 @@ +package org.cytoscape.diagnostics.internal; + +import org.cytoscape.launcher.internal.Launcher; +import org.osgi.framework.BundleContext; +import org.osgi.framework.BundleEvent; +import org.osgi.framework.FrameworkEvent; +import org.osgi.framework.FrameworkListener; +import org.osgi.framework.ServiceReference; +import org.osgi.framework.SynchronousBundleListener; +import org.osgi.service.startlevel.StartLevel; + +public class PerformanceTracker implements FrameworkListener, SynchronousBundleListener { + private BundleContext context; + private PerformanceDetailsBuilder performanceDetails; + private boolean finishedStarting; + + public PerformanceTracker(BundleContext context, PerformanceDetailsBuilder performanceDetails) { + this.context = context; + this.performanceDetails = performanceDetails; + + performanceDetails.setSystemLaunchStartTime(Launcher.getStartTime()); + performanceDetails.setFrameworkLaunchEndTime(System.currentTimeMillis()); + } + + @Override + public void frameworkEvent(FrameworkEvent event) { + if (event.getType() == FrameworkEvent.STARTLEVEL_CHANGED && !finishedStarting) { + ServiceReference reference = context.getServiceReference(StartLevel.class.getName()); + StartLevel level = (StartLevel) context.getService(reference); + if ( level.getStartLevel() == Activator.INITIAL_START_LEVEL ) { + performanceDetails.setSystemLaunchEndTime(System.currentTimeMillis()); + dump(); + finishedStarting = true; + } + context.ungetService(reference); + } + } + + private void dump() { + for (Long id : performanceDetails.getObservedBundleIds()) { + String description = performanceDetails.getBundleDescription(id); + long latency = performanceDetails.getBundleLaunchLatency(id); + long duration = performanceDetails.getBundleLaunchDuration(id); + System.out.printf("%s\t%d\t%d\n", description, latency, duration); + } + } + + @Override + public void bundleChanged(BundleEvent event) { + switch (event.getType()) { + case BundleEvent.STARTING: + performanceDetails.logBundleStarting(event.getBundle()); + break; + case BundleEvent.STARTED: + performanceDetails.logBundleStarted(event.getBundle()); + break; + } + } +} Modified: core3/gui-distribution/trunk/features/src/main/resources/features.xml =================================================================== --- core3/gui-distribution/trunk/features/src/main/resources/features.xml 2012-10-24 12:07:24 UTC (rev 30702) +++ core3/gui-distribution/trunk/features/src/main/resources/features.xml 2012-10-24 21:31:13 UTC (rev 30703) @@ -1,6 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <features> <feature name="cytoscape-gui" version="${project.version}"> + <bundle start-level="1">mvn:org.cytoscape.distribution/diagnostics-impl/${project.version}</bundle> <bundle start-level="100">mvn:org.cytoscape/splash-updater-impl/${cytoscape.support.version}</bundle> Modified: core3/gui-distribution/trunk/launcher/src/main/java/org/cytoscape/launcher/internal/Launcher.java =================================================================== --- core3/gui-distribution/trunk/launcher/src/main/java/org/cytoscape/launcher/internal/Launcher.java 2012-10-24 12:07:24 UTC (rev 30702) +++ core3/gui-distribution/trunk/launcher/src/main/java/org/cytoscape/launcher/internal/Launcher.java 2012-10-24 21:31:13 UTC (rev 30703) @@ -6,8 +6,10 @@ public class Launcher { private static String[] startupArguments; + private static long startTime; public static void main(String[] args) throws Exception { + startTime = System.currentTimeMillis(); startupArguments = args; setDefaultSystemProperties(); createConfigurationDirectory(); @@ -46,4 +48,8 @@ System.arraycopy(startupArguments, 0, result, 0, startupArguments.length); return result; } + + public static long getStartTime() { + return startTime; + } } Modified: core3/gui-distribution/trunk/pom.xml =================================================================== --- core3/gui-distribution/trunk/pom.xml 2012-10-24 12:07:24 UTC (rev 30702) +++ core3/gui-distribution/trunk/pom.xml 2012-10-24 21:31:13 UTC (rev 30703) @@ -71,6 +71,7 @@ <module>splash-launcher</module> <module>launcher</module> <module>cmdline-impl</module> + <module>diagnostics</module> <module>branding</module> <module>features</module> <module>assembly</module> @@ -86,6 +87,7 @@ <module>splash-launcher</module> <module>launcher</module> <module>cmdline-impl</module> + <module>diagnostics</module> <module>branding</module> <module>features</module> <module>assembly</module> Modified: core3/support/trunk/splash-updater-impl/src/main/java/org/cytoscape/splash/internal/SplashManipulator.java =================================================================== --- core3/support/trunk/splash-updater-impl/src/main/java/org/cytoscape/splash/internal/SplashManipulator.java 2012-10-24 12:07:24 UTC (rev 30702) +++ core3/support/trunk/splash-updater-impl/src/main/java/org/cytoscape/splash/internal/SplashManipulator.java 2012-10-24 21:31:13 UTC (rev 30703) @@ -13,8 +13,6 @@ import org.osgi.framework.BundleListener; import org.osgi.framework.FrameworkEvent; import org.osgi.framework.FrameworkListener; -import org.osgi.framework.ServiceReference; -import org.osgi.service.startlevel.StartLevel; public class SplashManipulator implements BundleListener, @@ -32,8 +30,6 @@ resolved = new HashSet<Long>(); started = new HashSet<Long>(); - applyStartLevelHack(); - for (Bundle bundle : context.getBundles()) { long id = bundle.getBundleId(); resolved.add(id); @@ -50,15 +46,6 @@ font = new Font(Font.MONOSPACED,Font.PLAIN,12); } - private void applyStartLevelHack() { - // See ticket #1494. This hack needs to remain in place until Karaf - // is patched. - ServiceReference reference = context.getServiceReference(StartLevel.class.getName()); - StartLevel level = (StartLevel) context.getService(reference); - level.setStartLevel(200); - context.ungetService(reference); - } - public void bundleChanged(BundleEvent event) { if ( event.getType() == BundleEvent.RESOLVED ) resolved.add(event.getBundle().getBundleId()); -- You received this message because you are subscribed to the Google Groups "cytoscape-cvs" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/cytoscape-cvs?hl=en.
