diff --git a/.gitignore b/.gitignore index ecf4036..4d292ea 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,12 @@ +.* +!.github +!.gitignore +!.mvn +*.bak +*.log +*.diff +*.patch +*.iml target -.project -.classpath -.settings -release.properties \ No newline at end of file +release.properties + diff --git a/pom.xml b/pom.xml index 8592b6b..2461ad5 100644 --- a/pom.xml +++ b/pom.xml @@ -47,14 +47,14 @@ org.apache.maven.plugins maven-compiler-plugin - 1.6 - 1.6 + 1.8 + 1.8 - + io.tesla.maven.plugins tesla-license-plugin - + org.sonatype.plugins sisu-maven-plugin diff --git a/src/main/java/io/tesla/lifecycle/profiler/AbstractProfile.java b/src/main/java/io/tesla/lifecycle/profiler/AbstractProfile.java new file mode 100644 index 0000000..c3275cd --- /dev/null +++ b/src/main/java/io/tesla/lifecycle/profiler/AbstractProfile.java @@ -0,0 +1,38 @@ +/** + * Copyright (c) 2012 to original author or authors + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package io.tesla.lifecycle.profiler; + +public abstract class AbstractProfile implements Profile { + + protected long elapsedTime; + + protected AbstractProfile() { + super(); + } + + /** + * @param elapsedTime the new value of {@link #getElapsedTime()}. + */ + public void setElapsedTime(long elapsedTime) { + this.elapsedTime = elapsedTime; + } + + /** + * @param millis the milliseconds to add to {@link #getElapsedTime() elapsed time}. + */ + public void addElapsedTime(long millis) { + + this.elapsedTime += millis; + } + + @Override + public long getElapsedTime() { + return elapsedTime; + } + +} diff --git a/src/main/java/io/tesla/lifecycle/profiler/AbstractTimerProfile.java b/src/main/java/io/tesla/lifecycle/profiler/AbstractTimerProfile.java new file mode 100644 index 0000000..e3ae431 --- /dev/null +++ b/src/main/java/io/tesla/lifecycle/profiler/AbstractTimerProfile.java @@ -0,0 +1,32 @@ +/** + * Copyright (c) 2012 to original author or authors + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package io.tesla.lifecycle.profiler; + +import io.tesla.lifecycle.profiler.internal.DefaultTimer; + +public abstract class AbstractTimerProfile extends AbstractProfile { + + protected final Timer timer; + + protected AbstractTimerProfile() { + this.timer = new DefaultTimer(); + } + + public void stop() { + timer.stop(); + } + + @Override + public long getElapsedTime() { + if(elapsedTime != 0) { + return elapsedTime; + } + return timer.getElapsedTime(); + } + +} diff --git a/src/main/java/io/tesla/lifecycle/profiler/AggregationProfile.java b/src/main/java/io/tesla/lifecycle/profiler/AggregationProfile.java new file mode 100644 index 0000000..48d1bd6 --- /dev/null +++ b/src/main/java/io/tesla/lifecycle/profiler/AggregationProfile.java @@ -0,0 +1,75 @@ +/** + * Copyright (c) 2012 to original author or authors + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package io.tesla.lifecycle.profiler; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class AggregationProfile extends AbstractProfile { + + private final String name; + + private final Map childMap; + + private final List children; + + public AggregationProfile() { + this("all"); + } + + public AggregationProfile(String name) { + super(); + this.name = name; + this.childMap = new HashMap<>(); + this.children = new ArrayList<>(); + } + + @Override + public String getName() { + + return this.name; + } + + @Override + public long getElapsedTime() { + + long millis = this.elapsedTime; + if (millis == 0) { + for (AggregationProfile child : this.children) { + millis += child.getElapsedTime(); + } + } + return millis; + } + + public AggregationProfile getChild(String name) { + + return this.childMap.get(name); + } + + public AggregationProfile getOrCreateChild(String name) { + + return this.childMap.computeIfAbsent(name, this::newAggregationProfile); + } + + private AggregationProfile newAggregationProfile(String name) { + + AggregationProfile profile = new AggregationProfile(name); + this.children.add(profile); + return profile; + } + + @Override + public Collection getChildren() { + + return this.children; + } +} diff --git a/src/main/java/io/tesla/lifecycle/profiler/LifecycleProfiler.java b/src/main/java/io/tesla/lifecycle/profiler/LifecycleProfiler.java index 7c23095..7eac884 100644 --- a/src/main/java/io/tesla/lifecycle/profiler/LifecycleProfiler.java +++ b/src/main/java/io/tesla/lifecycle/profiler/LifecycleProfiler.java @@ -26,12 +26,11 @@ @Singleton public class LifecycleProfiler extends AbstractEventSpy { - private final static String TESLA_PROFILE = "maven.profile"; - - // - // Components - // - private SessionProfileRenderer renderer; + private final static String MAVEN_PROFILE = "maven.profile"; + + private final SessionProfileRenderer renderer; + + private final boolean disabled; // // Profile data @@ -43,7 +42,9 @@ public class LifecycleProfiler extends AbstractEventSpy { @Inject public LifecycleProfiler(SessionProfileRenderer sessionProfileRenderer) { + super(); this.renderer = sessionProfileRenderer; + this.disabled = (System.getProperty(MAVEN_PROFILE) == null); } @Override @@ -52,30 +53,38 @@ public void init(Context context) throws Exception { @Override public void onEvent(Object event) throws Exception { + if (this.disabled) { + return; + } if (event instanceof ExecutionEvent) { ExecutionEvent executionEvent = (ExecutionEvent) event; if (executionEvent.getType() == ExecutionEvent.Type.SessionStarted) { // // // - sessionProfile = new SessionProfile(); + StringBuilder command = new StringBuilder("mvn"); + for (String goal : executionEvent.getSession().getGoals()) { + command.append(' '); + command.append(goal); + } + sessionProfile = new SessionProfile(command.toString()); } else if (executionEvent.getType() == ExecutionEvent.Type.SessionEnded) { // // // sessionProfile.stop(); - if (System.getProperty(TESLA_PROFILE) != null) { - renderer.render(sessionProfile); - } + renderer.render(sessionProfile); } else if (executionEvent.getType() == ExecutionEvent.Type.ProjectStarted) { // // We need to collect the mojoExecutions within each project // projectProfile = new ProjectProfile(executionEvent.getProject()); } else if (executionEvent.getType() == ExecutionEvent.Type.ProjectSucceeded || executionEvent.getType() == ExecutionEvent.Type.ProjectFailed) { - // - // - // + if (phaseProfile != null) { + phaseProfile.stop(); + projectProfile.addPhaseProfile(phaseProfile); + phaseProfile = null; + } projectProfile.stop(); sessionProfile.addProjectProfile(projectProfile); } else if (executionEvent.getType() == ExecutionEvent.Type.MojoStarted) { diff --git a/src/main/java/io/tesla/lifecycle/profiler/MojoProfile.java b/src/main/java/io/tesla/lifecycle/profiler/MojoProfile.java index 0324d8a..dbebe7a 100644 --- a/src/main/java/io/tesla/lifecycle/profiler/MojoProfile.java +++ b/src/main/java/io/tesla/lifecycle/profiler/MojoProfile.java @@ -7,21 +7,34 @@ */ package io.tesla.lifecycle.profiler; -import io.tesla.lifecycle.profiler.internal.DefaultTimer; +import java.util.Collections; +import java.util.List; import org.apache.maven.plugin.MojoExecution; -public class MojoProfile extends Profile { +public class MojoProfile extends AbstractTimerProfile { private MojoExecution mojoExecution; - + protected MojoProfile(MojoExecution mojoExecution) { - super(new DefaultTimer()); + super(); this.mojoExecution = mojoExecution; } - + public String getId() { - return mojoExecution.getGroupId() + ":" + mojoExecution.getArtifactId() + ":" + mojoExecution.getVersion() + " (" + mojoExecution.getExecutionId() + ") "; + return mojoExecution.getGroupId() + ":" + mojoExecution.getArtifactId() + ":" + mojoExecution.getVersion() + " (" + mojoExecution.getExecutionId() + ")"; + } + + @Override + public String getName() { + + return getId(); + } + + @Override + public List getChildren() { + + return Collections.emptyList(); } } diff --git a/src/main/java/io/tesla/lifecycle/profiler/PhaseProfile.java b/src/main/java/io/tesla/lifecycle/profiler/PhaseProfile.java index d887b9e..0716df9 100644 --- a/src/main/java/io/tesla/lifecycle/profiler/PhaseProfile.java +++ b/src/main/java/io/tesla/lifecycle/profiler/PhaseProfile.java @@ -7,22 +7,20 @@ */ package io.tesla.lifecycle.profiler; -import io.tesla.lifecycle.profiler.internal.DefaultTimer; - import java.util.ArrayList; import java.util.List; -public class PhaseProfile extends Profile { +public class PhaseProfile extends AbstractTimerProfile { private String phase; private List mojoProfiles; - + public PhaseProfile(String phase) { - super(new DefaultTimer()); + super(); this.phase = phase; this.mojoProfiles = new ArrayList(); } - + public void addMojoProfile(MojoProfile mojoProfile) { mojoProfiles.add(mojoProfile); } @@ -34,4 +32,16 @@ public String getPhase() { public List getMojoProfiles() { return mojoProfiles; } + + @Override + public String getName() { + + return phase; + } + + @Override + public List getChildren() { + + return getMojoProfiles(); + } } diff --git a/src/main/java/io/tesla/lifecycle/profiler/Profile.java b/src/main/java/io/tesla/lifecycle/profiler/Profile.java index 58b3bd0..00b490e 100644 --- a/src/main/java/io/tesla/lifecycle/profiler/Profile.java +++ b/src/main/java/io/tesla/lifecycle/profiler/Profile.java @@ -7,29 +7,25 @@ */ package io.tesla.lifecycle.profiler; -import io.tesla.lifecycle.profiler.internal.DefaultTimer; +import java.util.Collection; +import java.util.List; + +/** + * Interface for a profile of the profiling. The root profile is {@link SessionProfile} representing the recording of the + * entire session. Each {@link Profile} can have {@link #getChildren() children} representing a partition of the whole + * into smaller steps to give more details and granularity to trace down leaks and find spots worth to optimize. + */ +public interface Profile extends Timing { + + /** + * @return the name of this profile (name of e.g. maven project, phase, plugin). + */ + String getName(); + + /** + * @return the {@link List} of child {@link Profile}s contained in this {@link Profile}. Will be an empty list if this + * profile has not children. + */ + Collection getChildren(); -public class Profile { - - protected long elapsedTime; - protected Timer timer; - - protected Profile(DefaultTimer timer) { - this.timer = timer; - } - - public void stop() { - timer.stop(); - } - - void setElapsedTime(long elapsedTime) { - this.elapsedTime = elapsedTime; - } - - public long getElapsedTime() { - if(elapsedTime != 0) { - return elapsedTime; - } - return timer.getTime(); - } } diff --git a/src/main/java/io/tesla/lifecycle/profiler/ProjectProfile.java b/src/main/java/io/tesla/lifecycle/profiler/ProjectProfile.java index 2afcf32..2b696f5 100644 --- a/src/main/java/io/tesla/lifecycle/profiler/ProjectProfile.java +++ b/src/main/java/io/tesla/lifecycle/profiler/ProjectProfile.java @@ -7,24 +7,22 @@ */ package io.tesla.lifecycle.profiler; -import io.tesla.lifecycle.profiler.internal.DefaultTimer; - import java.util.ArrayList; import java.util.List; import org.apache.maven.project.MavenProject; -public class ProjectProfile extends Profile { +public class ProjectProfile extends AbstractTimerProfile { private MavenProject project; private List phaseProfiles; - + public ProjectProfile(MavenProject project) { - super(new DefaultTimer()); + super(); this.project = project; this.phaseProfiles = new ArrayList(); } - + public void addPhaseProfile(PhaseProfile phaseProfile) { phaseProfiles.add(phaseProfile); } @@ -36,4 +34,16 @@ public String getProjectName() { public List getPhaseProfile() { return phaseProfiles; } + + @Override + public String getName() { + + return getProjectName(); + } + + @Override + public List getChildren() { + + return getPhaseProfile(); + } } diff --git a/src/main/java/io/tesla/lifecycle/profiler/SessionProfile.java b/src/main/java/io/tesla/lifecycle/profiler/SessionProfile.java index cce073f..9460d0f 100644 --- a/src/main/java/io/tesla/lifecycle/profiler/SessionProfile.java +++ b/src/main/java/io/tesla/lifecycle/profiler/SessionProfile.java @@ -7,20 +7,21 @@ */ package io.tesla.lifecycle.profiler; -import io.tesla.lifecycle.profiler.internal.DefaultTimer; - import java.util.ArrayList; import java.util.List; -public class SessionProfile extends Profile { +public class SessionProfile extends AbstractTimerProfile { + + private final String name; private List projectProfiles; - - public SessionProfile() { - super(new DefaultTimer()); - this.projectProfiles = new ArrayList(); + + public SessionProfile(String name) { + super(); + this.name = name; + this.projectProfiles = new ArrayList<>(); } - + public void addProjectProfile(ProjectProfile projectProfile) { projectProfiles.add(projectProfile); } @@ -28,4 +29,16 @@ public void addProjectProfile(ProjectProfile projectProfile) { public List getProjectProfiles() { return projectProfiles; } + + @Override + public String getName() { + + return this.name; + } + + @Override + public List getChildren() { + + return getProjectProfiles(); + } } diff --git a/src/main/java/io/tesla/lifecycle/profiler/Timer.java b/src/main/java/io/tesla/lifecycle/profiler/Timer.java index 8783f45..a68da07 100644 --- a/src/main/java/io/tesla/lifecycle/profiler/Timer.java +++ b/src/main/java/io/tesla/lifecycle/profiler/Timer.java @@ -7,9 +7,20 @@ */ package io.tesla.lifecycle.profiler; -public interface Timer { +/** + * Interface for a simple timer that is like a stop-watch. Once created, it starts ticking until you {@link #stop() stop} it. + * Then you can use {@link #getElapsedTime()} to retrieve the elapsed duration. + */ +public interface Timer extends Timing { + /** + * Stops this timer. Should only be called once. + */ void stop(); - long getTime(); - String format(long elapsedTime); + +// default Duration getDuration() { +// +// return Duration.of(getTime(), ChronoUnit.MILLIS); +// } + } diff --git a/src/main/java/io/tesla/lifecycle/profiler/Timing.java b/src/main/java/io/tesla/lifecycle/profiler/Timing.java new file mode 100644 index 0000000..ea9e2a1 --- /dev/null +++ b/src/main/java/io/tesla/lifecycle/profiler/Timing.java @@ -0,0 +1,26 @@ +/** + * Copyright (c) 2012 to original author or authors + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package io.tesla.lifecycle.profiler; + +/** + * Interface for an object that records the timing and therefore has an {@link #getElapsedTime() elapsed time}. + */ +public interface Timing { + + /** + * @return the duration in milliseconds of this timing. Typically the duration from the instantiation a {@link Timer} + * until it has been {@link Timer#stop() stop}ed. + */ + long getElapsedTime(); + +// default Duration getDuration() { +// +// return Duration.of(getTime(), ChronoUnit.MILLIS); +// } + +} diff --git a/src/main/java/io/tesla/lifecycle/profiler/internal/AbstractSessionProfileRenderer.java b/src/main/java/io/tesla/lifecycle/profiler/internal/AbstractSessionProfileRenderer.java new file mode 100644 index 0000000..d40efdc --- /dev/null +++ b/src/main/java/io/tesla/lifecycle/profiler/internal/AbstractSessionProfileRenderer.java @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2012 to original author or authors + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package io.tesla.lifecycle.profiler.internal; + +import java.util.Locale; + +import io.tesla.lifecycle.profiler.SessionProfileRenderer; + +/** + * Abstract base implementation of {@link SessionProfileRenderer}. + */ +public abstract class AbstractSessionProfileRenderer implements SessionProfileRenderer { + + /** Determines if the profiling report shall be logged at the end of the build */ + protected final boolean logProfileData; + + /** + * The constructor. + */ + public AbstractSessionProfileRenderer() { + + super(); + this.logProfileData = getBooleanProperty("maven.profile.log.output", true); + } + + /** + * @param name the name of the {@link System#getProperty(String) system property}. + * @param defaultValue the default value if the {@link System#getProperty(String) system property} is undefined or invalid. + * @return the configured boolean value. + */ + protected static boolean getBooleanProperty(String name, boolean defaultValue) { + + boolean result = defaultValue; + String valueAsString = System.getProperty(name); + if (valueAsString != null) { + valueAsString = valueAsString.toLowerCase(Locale.ROOT); + if ("true".equals(valueAsString) || "yes".equals(valueAsString)) { + result = true; + } else if ("false".equals(valueAsString) || "no".equals(valueAsString)) { + result = true; + } + } + return result; + } + +} diff --git a/src/main/java/io/tesla/lifecycle/profiler/internal/AdvancedSessionProfileRenderer.java b/src/main/java/io/tesla/lifecycle/profiler/internal/AdvancedSessionProfileRenderer.java new file mode 100644 index 0000000..a2f8134 --- /dev/null +++ b/src/main/java/io/tesla/lifecycle/profiler/internal/AdvancedSessionProfileRenderer.java @@ -0,0 +1,184 @@ +/** + * Copyright (c) 2012 to original author or authors + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package io.tesla.lifecycle.profiler.internal; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.nio.charset.StandardCharsets; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatterBuilder; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import javax.inject.Named; +import javax.inject.Singleton; + +import io.tesla.lifecycle.profiler.AggregationProfile; +import io.tesla.lifecycle.profiler.Profile; +import io.tesla.lifecycle.profiler.SessionProfile; + +/** + * Advanced implementation of {@link AbstractSessionProfileRenderer} that can write both CSV and/or log human readable profiling summary. + */ +@Named +@Singleton +public class AdvancedSessionProfileRenderer extends AbstractSessionProfileRenderer { + + private final static String WRITE_CSV = "maven.profile.write.csv"; + + private static final char CSV_SEPARATOR = ';'; + + private final List aggregations; + + private Writer csvWriter; + + public AdvancedSessionProfileRenderer() { + + super(); + this.aggregations = new ArrayList<>(); + this.aggregations.add(new AggregationProfile("Aggregation by project")); + this.aggregations.add(new AggregationProfile("Aggregation by phase")); + this.aggregations.add(new AggregationProfile("Aggregation by mojo")); + } + + public void render(SessionProfile sessionProfile) { + + boolean writeCsv = getBooleanProperty(WRITE_CSV, true); + OutputStream out = null; + if (writeCsv) { + String timestamp = new DateTimeFormatterBuilder().appendPattern("YYYY-MM-dd_HH-mm-ss").toFormatter() + .format(LocalDateTime.now()); + String filename = ".maven.profiling." + timestamp + ".csv"; + try { + out = new FileOutputStream(filename); + this.csvWriter = new OutputStreamWriter(out, StandardCharsets.UTF_8); + try { + this.csvWriter.write("Depth"); + this.csvWriter.write(CSV_SEPARATOR); + this.csvWriter.write("Name"); + this.csvWriter.write(CSV_SEPARATOR); + this.csvWriter.write("Duration (ms)"); + this.csvWriter.write(CSV_SEPARATOR); + this.csvWriter.write("Fraction"); + this.csvWriter.write("\n"); + } catch (IOException e) { + throw new IllegalStateException("Failed to write CSV data!", e); + } + } catch (IOException e) { + throw new IllegalStateException("Failed to open file '" + filename + "' for writing!", e); + } + } + try { + renderProfile(sessionProfile, true); + for (AggregationProfile aggregation : this.aggregations) { + aggregation.setElapsedTime(sessionProfile.getElapsedTime()); + renderProfile(aggregation, false); + } + } finally { + if (writeCsv) { + close(this.csvWriter); + this.csvWriter = null; + close(out); + } + } + } + + private void renderProfile(Profile sessionProfile, boolean aggregate) { + + renderProfile(0, sessionProfile, 0, ""); + renderProfileRecursive(sessionProfile, 0, "", aggregate); + } + + private void close(AutoCloseable out) { + + if (out != null) { + try { + out.close(); + } catch (Exception e) { + // ignore + } + } + } + + private void renderProfileRecursive(Profile profile, int depth, String prefix, boolean aggregate) { + + Collection children = profile.getChildren(); + AggregationProfile aggregation = null; + if (aggregate && (depth < aggregations.size())) { + aggregation = this.aggregations.get(depth); + } + int childDepth = depth + 1; + long duration = profile.getElapsedTime(); + String childPrefix = prefix + " "; + for (Profile child : children) { + renderProfile(childDepth, child, duration, childPrefix); + if (aggregation != null) { + aggregation.getOrCreateChild(child.getName()).addElapsedTime(child.getElapsedTime()); + } + renderProfileRecursive(child, childDepth, childPrefix, aggregate); + } + } + + private void renderProfile(int depth, Profile profile, long total, String prefix) { + + String fraction = "1"; + String percentage = "100%"; + if (total > 0) { + long duration = profile.getElapsedTime(); + if (duration < total) { + long fract = (duration * 1000) / total; + percentage = (fract / 10) + "%"; + fraction = Long.toString(fract); + int zeros = 3 - fraction.length(); + while (zeros > 0) { + fraction = "0" + fraction; + zeros--; + } + fraction = "0." + fraction; + } else if (duration > total) { + // invalid, should never happen + fraction = ""; + percentage = ""; + } + } + renderProfileAsCsv(depth, profile, fraction); + if (this.logProfileData) { + String message = prefix + profile.getName() + " " + DefaultTimer.formatMilliseconds(profile.getElapsedTime()) + + "(" + percentage + ")"; + render(message); + } + } + + private void renderProfileAsCsv(int depth, Profile profile, String fraction) { + + if (this.csvWriter == null) { + return; + } + try { + this.csvWriter.write(Integer.toString(depth)); + this.csvWriter.write(CSV_SEPARATOR); + this.csvWriter.write(profile.getName()); + this.csvWriter.write(CSV_SEPARATOR); + this.csvWriter.write(Long.toString(profile.getElapsedTime())); + this.csvWriter.write(CSV_SEPARATOR); + this.csvWriter.write(fraction); + this.csvWriter.write("\n"); + } catch (IOException e) { + throw new IllegalStateException("Failed to write CSV data!", e); + } + } + + private void render(String s) { + + System.out.println(s); + } +} diff --git a/src/main/java/io/tesla/lifecycle/profiler/internal/DefaultSessionProfileRenderer.java b/src/main/java/io/tesla/lifecycle/profiler/internal/DefaultSessionProfileRenderer.java index c499fe0..770bfa3 100644 --- a/src/main/java/io/tesla/lifecycle/profiler/internal/DefaultSessionProfileRenderer.java +++ b/src/main/java/io/tesla/lifecycle/profiler/internal/DefaultSessionProfileRenderer.java @@ -11,40 +11,35 @@ import io.tesla.lifecycle.profiler.PhaseProfile; import io.tesla.lifecycle.profiler.ProjectProfile; import io.tesla.lifecycle.profiler.SessionProfile; -import io.tesla.lifecycle.profiler.SessionProfileRenderer; -import io.tesla.lifecycle.profiler.Timer; -import javax.inject.Inject; -import javax.inject.Named; -import javax.inject.Singleton; +// old implementation that has been replaced by AdvancedSessionProfileRenderer. Could actually be removed. +//@Named +//@Singleton +public class DefaultSessionProfileRenderer extends AbstractSessionProfileRenderer { -@Named -@Singleton -public class DefaultSessionProfileRenderer implements SessionProfileRenderer { - - private Timer timer; - - @Inject - public DefaultSessionProfileRenderer(Timer timer) { - this.timer = timer; + public DefaultSessionProfileRenderer() { + super(); } - + public void render(SessionProfile sessionProfile) { - + + if (!this.logProfileData) { + return; + } for(ProjectProfile pp : sessionProfile.getProjectProfiles()) { render(""); render(pp.getProjectName()); render(""); for(PhaseProfile phaseProfile : pp.getPhaseProfile()) { - render(" " + phaseProfile.getPhase() + " " + timer.format(phaseProfile.getElapsedTime())); + render(" " + phaseProfile.getPhase() + " " + DefaultTimer.formatMilliseconds(phaseProfile.getElapsedTime())); for(MojoProfile mp : phaseProfile.getMojoProfiles()) { - render(" " + mp.getId() + timer.format(mp.getElapsedTime())); + render(" " + mp.getId() + DefaultTimer.formatMilliseconds(mp.getElapsedTime())); } render(""); } } } - + private void render(String s) { System.out.println(s); } diff --git a/src/main/java/io/tesla/lifecycle/profiler/internal/DefaultTimer.java b/src/main/java/io/tesla/lifecycle/profiler/internal/DefaultTimer.java index 18dfe22..cca5dc7 100644 --- a/src/main/java/io/tesla/lifecycle/profiler/internal/DefaultTimer.java +++ b/src/main/java/io/tesla/lifecycle/profiler/internal/DefaultTimer.java @@ -7,17 +7,17 @@ */ package io.tesla.lifecycle.profiler.internal; -import io.tesla.lifecycle.profiler.Timer; - import javax.inject.Named; import javax.inject.Singleton; +import io.tesla.lifecycle.profiler.Timer; + @Named @Singleton public class DefaultTimer implements Timer { - - public static final int MS_PER_SEC = 1000; - public static final int SEC_PER_MIN = 60; + static final int MS_PER_SEC = 1000; + static final int SEC_PER_MIN = 60; + private long start; private long time; @@ -25,11 +25,13 @@ public DefaultTimer() { start = System.currentTimeMillis(); } + @Override public void stop() { time = elapsedTime(); } - public long getTime() { + @Override + public long getElapsedTime() { return time; } @@ -37,11 +39,12 @@ private long elapsedTime() { return System.currentTimeMillis() - start; } - public String format(long ms) { - long secs = ms / MS_PER_SEC; + protected static String formatMilliseconds(long durationInMillis) { + + long secs = durationInMillis / MS_PER_SEC; long mins = secs / SEC_PER_MIN; secs = secs % SEC_PER_MIN; - long fractionOfASecond = ms - (secs * 1000); + long fractionOfASecond = durationInMillis - (secs * 1000); StringBuilder msg = new StringBuilder(); if (mins > 0) { @@ -62,4 +65,5 @@ public String format(long ms) { return msg.toString(); } + } diff --git a/src/test/java/io/tesla/lifecycle/profiler/LifecycleProfilerTest.java b/src/test/java/io/tesla/lifecycle/profiler/LifecycleProfilerTest.java index 558587c..6335483 100644 --- a/src/test/java/io/tesla/lifecycle/profiler/LifecycleProfilerTest.java +++ b/src/test/java/io/tesla/lifecycle/profiler/LifecycleProfilerTest.java @@ -21,7 +21,7 @@ public class LifecycleProfilerTest extends InjectedTestCase { public void testSessionProfile() { - SessionProfile s = new SessionProfile(); + SessionProfile s = new SessionProfile("mvn"); ProjectProfile p0 = new ProjectProfile(project("g0", "a0", "v0")); PhaseProfile ph0 = new PhaseProfile("phase0"); diff --git a/src/test/java/io/tesla/lifecycle/profiler/TimerTest.java b/src/test/java/io/tesla/lifecycle/profiler/internal/TimerTest.java similarity index 57% rename from src/test/java/io/tesla/lifecycle/profiler/TimerTest.java rename to src/test/java/io/tesla/lifecycle/profiler/internal/TimerTest.java index e5fa9f5..2889762 100755 --- a/src/test/java/io/tesla/lifecycle/profiler/TimerTest.java +++ b/src/test/java/io/tesla/lifecycle/profiler/internal/TimerTest.java @@ -5,15 +5,13 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ -package io.tesla.lifecycle.profiler; +package io.tesla.lifecycle.profiler.internal; -import io.tesla.lifecycle.profiler.internal.DefaultTimer; +import static io.tesla.lifecycle.profiler.internal.DefaultTimer.MS_PER_SEC; import org.junit.Assert; import org.junit.Test; -import static io.tesla.lifecycle.profiler.internal.DefaultTimer.MS_PER_SEC; - /** * @author Kristian Rosenvold */ @@ -22,15 +20,13 @@ public class TimerTest { @Test public void testTimeFormats() throws Exception { - Timer timer = new DefaultTimer(); - Assert.assertEquals("1ms", timer.format(1)); - Assert.assertEquals("1s 1ms", timer.format(1001)); - Assert.assertEquals("1m 1s", timer.format(61 * MS_PER_SEC)); + Assert.assertEquals("1ms", DefaultTimer.formatMilliseconds(1)); + Assert.assertEquals("1s 1ms", DefaultTimer.formatMilliseconds(1001)); + Assert.assertEquals("1m 1s", DefaultTimer.formatMilliseconds(61 * MS_PER_SEC)); } @Test public void assertDetailLoss() { - Timer timer = new DefaultTimer(); - Assert.assertEquals("1m 1s", timer.format(61 * MS_PER_SEC + 1)); + Assert.assertEquals("1m 1s", DefaultTimer.formatMilliseconds(61 * MS_PER_SEC + 1)); } }