[slf4j-dev] svn commit: r1069 - in slf4j/trunk: . slf4j-ext slf4j-ext/src slf4j-ext/src/main slf4j-ext/src/main/java slf4j-ext/src/main/java/org slf4j-ext/src/main/java/org/slf4j slf4j-ext/src/main/java/org/slf4j/profiler slf4j-ext/src/test slf4j-ext/src/test/java slf4j-ext/src/test/java/org slf4j-ext/src/test/java/org/slf4j slf4j-ext/src/test/java/org/slf4j/profiler
ceki at slf4j.org
ceki at slf4j.org
Mon Jul 21 16:28:30 CEST 2008
Author: ceki
Date: Mon Jul 21 16:28:29 2008
New Revision: 1069
Added:
slf4j/trunk/slf4j-ext/
slf4j/trunk/slf4j-ext/pom.xml
slf4j/trunk/slf4j-ext/src/
slf4j/trunk/slf4j-ext/src/main/
slf4j/trunk/slf4j-ext/src/main/java/
slf4j/trunk/slf4j-ext/src/main/java/org/
slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/
slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/profiler/
slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/profiler/DurationUnit.java
slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/profiler/Profiler.java
slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/profiler/ProfilerRegistry.java
slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/profiler/SpacePadder.java
slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/profiler/StopWatch.java
slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/profiler/Util.java
slf4j/trunk/slf4j-ext/src/test/
slf4j/trunk/slf4j-ext/src/test/java/
slf4j/trunk/slf4j-ext/src/test/java/org/
slf4j/trunk/slf4j-ext/src/test/java/org/slf4j/
slf4j/trunk/slf4j-ext/src/test/java/org/slf4j/profiler/
slf4j/trunk/slf4j-ext/src/test/java/org/slf4j/profiler/PackageTest.java
slf4j/trunk/slf4j-ext/src/test/java/org/slf4j/profiler/ProfilerTest.java
slf4j/trunk/slf4j-ext/src/test/java/org/slf4j/profiler/StopWatchTest.java
Modified:
slf4j/trunk/pom.xml
Log:
Related to bug 68. See also [1]
- As suggested by Ralph Goers on comment #5, migrating code from the
logback project, in particular the ch.qos.logback.classic.stopwatch
package to SLF4J. Since 99.9% of the code is logging system
independent, it makes sense to migrate this code to SLF4J, more
precisely into the newly created slf4j-ext module.
The profiler code has been extremely useful in measuring the
performance of a real-world project.
Documentation to follow.
[1] http://bugzilla.slf4j.org/show_bug.cgi?id=86
Modified: slf4j/trunk/pom.xml
==============================================================================
--- slf4j/trunk/pom.xml (original)
+++ slf4j/trunk/pom.xml Mon Jul 21 16:28:29 2008
@@ -30,6 +30,7 @@
<module>slf4j-jdk14</module>
<module>slf4j-log4j12</module>
<module>slf4j-jcl</module>
+ <module>slf4j-ext</module>
<module>jcl-over-slf4j</module>
<module>jcl104-over-slf4j</module>
<module>log4j-over-slf4j</module>
Added: slf4j/trunk/slf4j-ext/pom.xml
==============================================================================
--- (empty file)
+++ slf4j/trunk/slf4j-ext/pom.xml Mon Jul 21 16:28:29 2008
@@ -0,0 +1,95 @@
+<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.slf4j</groupId>
+ <artifactId>slf4j-parent</artifactId>
+ <version>1.5.3-SNAPSHOT</version>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-ext</artifactId>
+ <packaging>jar</packaging>
+ <name>SLF4J Extensions Module</name>
+
+ <url>http://www.slf4j.org</url>
+ <description>Extensions to the SLF4J API</description>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ </dependencies>
+
+
+ <build>
+ <plugins>
+
+
+ </plugins>
+ </build>
+
+
+ <build>
+
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>1.5</source>
+ <target>1.5</target>
+ </configuration>
+ </plugin>
+
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <forkMode>once</forkMode>
+ <reportFormat>plain</reportFormat>
+ <trimStackTrace>false</trimStackTrace>
+ <excludes>
+ <exclude>**/AllTest.java</exclude>
+ <exclude>**/PackageTest.java</exclude>
+ </excludes>
+ </configuration>
+ </plugin>
+
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <configuration>
+ <archive>
+ <manifestEntries>
+ <Bundle-Version>${project.version}</Bundle-Version>
+ <Bundle-Description>${project.description}</Bundle-Description>
+ <Implementation-Version>${project.version}</Implementation-Version>
+ </manifestEntries>
+ <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
+ </archive>
+ </configuration>
+ </plugin>
+ </plugins>
+
+ </build>
+
+ <reporting>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>clirr-maven-plugin</artifactId>
+ <configuration>
+ <comparisonVersion>1.5.0</comparisonVersion>
+ </configuration>
+ </plugin>
+ </plugins>
+ </reporting>
+
+</project>
\ No newline at end of file
Added: slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/profiler/DurationUnit.java
==============================================================================
--- (empty file)
+++ slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/profiler/DurationUnit.java Mon Jul 21 16:28:29 2008
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2004-2008 QOS.ch
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+package org.slf4j.profiler;
+
+public enum DurationUnit {
+ NANOSECOND, MICROSECOND, MILLISSECOND, SECOND;
+}
\ No newline at end of file
Added: slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/profiler/Profiler.java
==============================================================================
--- (empty file)
+++ slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/profiler/Profiler.java Mon Jul 21 16:28:29 2008
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 2004-2008 QOS.ch
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+package org.slf4j.profiler;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+// + Profiler [BAS]
+// |-- elapsed time [doX] 0 milliseconds.
+// |-- elapsed time [doYYYYY] 56 milliseconds.
+// |--+ Profiler Y
+// |-- elapsed time [doZ] 21 milliseconds.
+// |-- elapsed time [doZ] 21 milliseconds.
+// |-- Total elapsed time [Y] 78 milliseconds.
+// |-- elapsed time [doZ] 21 milliseconds.
+// |-- Total elapsed time [BAS] 78 milliseconds.
+
+// + Profiler [TOP]
+// |--+ Profiler [IIII]
+// |-- elapsed time [A] 0.006 milliseconds.
+// |-- elapsed time [B] 75.777 milliseconds.
+// |-- elapsed time [VVVVVV] 161.589 milliseconds.
+// |-- Total elapsed time [IIII] 240.580 milliseconds.
+// |--+ Profiler [RRRRRRRRR]
+// |-- elapsed time [R0] 9.390 milliseconds.
+// |-- elapsed time [R1] 6.555 milliseconds.
+// |-- elapsed time [R2] 5.995 milliseconds.
+// |-- elapsed time [R3] 115.502 milliseconds.
+// |-- elapsed time [R4] 0.064 milliseconds.
+// |-- Total elapsed time [R] 138.340 milliseconds.
+// |--+ Profiler [S]
+// |-- Total elapsed time [S0] 3.091 milliseconds.
+// |--+ Profiler [P]
+// |-- elapsed time [P0] 87.550 milliseconds.
+// |-- Total elapsed time [P] 87.559 milliseconds.
+// |-- Total elapsed time [TOP] 467.548 milliseconds.
+
+public class Profiler {
+
+ final static int MIN_SW_NAME_LENGTH = 24;
+ final static int MIN_SW_ELAPSED_TIME_NUMBER_LENGTH = 9;
+
+ final String name;
+ final StopWatch globalStopWatch;
+
+ List<StopWatch> stopwatchList = new ArrayList<StopWatch>();
+ List<Object> childList = new ArrayList<Object>();
+
+ ProfilerRegistry profilerRegistry;
+
+ public Profiler(String name) {
+ this.name = name;
+ this.globalStopWatch = new StopWatch(name);
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public ProfilerRegistry getProfilerRegistry() {
+ return profilerRegistry;
+ }
+
+ public void setProfilerRegistry(ProfilerRegistry profilerRegistry) {
+ if(profilerRegistry == null) {
+ return;
+ }
+ this.profilerRegistry = profilerRegistry;
+ profilerRegistry.put(this);
+ }
+
+ public void start(String name) {
+ stopLastStopWatch();
+ StopWatch childSW = new StopWatch(name);
+ stopwatchList.add(childSW);
+ childList.add(childSW);
+ }
+
+ public Profiler startNested(String name) {
+ Profiler nestedProfiler = new Profiler(name);
+ nestedProfiler.setProfilerRegistry(profilerRegistry);
+ childList.add(nestedProfiler);
+ return nestedProfiler;
+ }
+
+ StopWatch getLastStopWatch() {
+ if (stopwatchList.size() > 0) {
+ return stopwatchList.get(stopwatchList.size() - 1);
+ } else {
+ return null;
+ }
+ }
+
+ void stopLastStopWatch() {
+ StopWatch last = getLastStopWatch();
+ if (last != null) {
+ last.stop();
+ }
+ }
+
+ void stopNestedProfilers() {
+ for (Object child : childList) {
+ if (child instanceof Profiler)
+ ((Profiler) child).stop();
+ }
+ }
+
+ public Profiler stop() {
+ stopLastStopWatch();
+ stopNestedProfilers();
+ globalStopWatch.stop();
+ return this;
+ }
+
+ public void print() {
+ DurationUnit du = Util.selectDurationUnitForDisplay(globalStopWatch);
+ String r = buildString(du, "+", "");
+ System.out.println(r);
+ }
+
+ private String buildString(DurationUnit du, String prefix, String indentation) {
+ StringBuffer buf = new StringBuffer();
+
+
+ buf.append(prefix);
+ buf.append(" Profiler [");
+ buf.append(name);
+ buf.append("]");
+ buf.append(SpacePadder.LINE_SEP);
+ for (Object child : childList) {
+ if(child instanceof StopWatch) {
+ buildStringForChildStopWatch(buf, indentation, (StopWatch) child, du);
+ } else if(child instanceof Profiler) {
+ Profiler profiler = (Profiler) child;
+ profiler.stop();
+ String subString = profiler.buildString(du, "|--+", indentation + " ");
+ buf.append(subString);
+ }
+ }
+ buildStringForGlobalStopWatch(buf, indentation, globalStopWatch, du);
+ return buf.toString();
+ }
+
+ private static void buildStringForChildStopWatch(StringBuffer buf,
+ String indentation, StopWatch sw, DurationUnit du) {
+
+ buf.append(indentation);
+ buf.append("|--");
+ buf.append(" elapsed time ");
+ SpacePadder.leftPad(buf, "[" + sw.getName() + "]", MIN_SW_NAME_LENGTH);
+ buf.append(" ");
+ String timeStr = Util.durationInDunrationUnitsAsStr(sw.getResultInNanos(),
+ du);
+ SpacePadder.leftPad(buf, timeStr, MIN_SW_ELAPSED_TIME_NUMBER_LENGTH);
+ buf.append(" ");
+ Util.appendDurationUnitAsStr(buf, du);
+ buf.append(SpacePadder.LINE_SEP);
+ }
+
+ private static void buildStringForGlobalStopWatch(StringBuffer buf,
+ String indentation, StopWatch sw, DurationUnit du) {
+ buf.append(indentation);
+ buf.append("|--");
+ buf.append(" Total elapsed time ");
+ SpacePadder.leftPad(buf, "[" + sw.getName() + "]", MIN_SW_NAME_LENGTH);
+ buf.append(" ");
+ String timeStr = Util.durationInDunrationUnitsAsStr(sw.getResultInNanos(),
+ du);
+ SpacePadder.leftPad(buf, timeStr, MIN_SW_ELAPSED_TIME_NUMBER_LENGTH);
+ buf.append(" ");
+ Util.appendDurationUnitAsStr(buf, du);
+ buf.append(SpacePadder.LINE_SEP);
+ }
+
+}
Added: slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/profiler/ProfilerRegistry.java
==============================================================================
--- (empty file)
+++ slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/profiler/ProfilerRegistry.java Mon Jul 21 16:28:29 2008
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2004-2008 QOS.ch
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+package org.slf4j.profiler;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * A miniminalistic registry of profilers.
+ *
+ * @author Ceki
+ */
+public class ProfilerRegistry {
+
+ private static final InheritableThreadLocal<ProfilerRegistry> inheritableThreadLocal = new InheritableThreadLocal<ProfilerRegistry>();
+
+
+ Map<String, Profiler> profilerMap = new HashMap<String, Profiler>();
+
+ public void put(Profiler profiler) {
+ put(profiler.getName(), profiler);
+ }
+
+ public void put(String name, Profiler profiler) {
+ profilerMap.put(name, profiler);
+ }
+
+
+ public static ProfilerRegistry getThreadContextInstance() {
+ ProfilerRegistry pr = inheritableThreadLocal.get();
+ if(pr == null) {
+ pr = new ProfilerRegistry();
+ inheritableThreadLocal.set(pr);
+ }
+ return pr;
+ }
+
+ public Profiler get(String name) {
+ return profilerMap.get(name);
+ }
+
+ public void clear() {
+ profilerMap.clear();
+ }
+}
Added: slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/profiler/SpacePadder.java
==============================================================================
--- (empty file)
+++ slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/profiler/SpacePadder.java Mon Jul 21 16:28:29 2008
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2004-2008 QOS.ch
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+package org.slf4j.profiler;
+
+public class SpacePadder {
+ public static final String LINE_SEP = System.getProperty("line.separator");
+
+ final static String[] SPACES = { " ", " ", " ", " ", // 1,2,4,8
+ // spaces
+ " ", // 16 spaces
+ " " }; // 32 spaces
+
+ final static public void leftPad(StringBuffer buf, String s, int desiredLength) {
+ int actualLen = 0;
+ if (s != null) {
+ actualLen = s.length();
+ }
+ if (actualLen < desiredLength) {
+ spacePad(buf, desiredLength - actualLen);
+ }
+ if (s != null) {
+ buf.append(s);
+ }
+ }
+
+ final static public void rightPad(StringBuffer buf, String s, int desiredLength) {
+ int actualLen = 0;
+ if (s != null) {
+ actualLen = s.length();
+ }
+ if (s != null) {
+ buf.append(s);
+ }
+ if (actualLen < desiredLength) {
+ spacePad(buf, desiredLength - actualLen);
+ }
+ }
+
+ /**
+ * Fast space padding method.
+ */
+ final static public void spacePad(StringBuffer sbuf, int length) {
+ while (length >= 32) {
+ sbuf.append(SPACES[5]);
+ length -= 32;
+ }
+
+ for (int i = 4; i >= 0; i--) {
+ if ((length & (1 << i)) != 0) {
+ sbuf.append(SPACES[i]);
+ }
+ }
+ }
+}
Added: slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/profiler/StopWatch.java
==============================================================================
--- (empty file)
+++ slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/profiler/StopWatch.java Mon Jul 21 16:28:29 2008
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2004-2008 QOS.ch
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+package org.slf4j.profiler;
+
+
+public class StopWatch {
+
+
+ enum Status {
+ STARTED, STOPPED;
+ }
+
+ final String name;
+ final long startTime;
+ long stopTime;
+ Status status;
+
+ public StopWatch(String name) {
+ this.name = name;
+ this.startTime = System.nanoTime();
+ this.status = Status.STARTED;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public StopWatch stop() {
+ if(status == Status.STOPPED) {
+ return this;
+ }
+ return stop(System.nanoTime());
+ }
+
+ public StopWatch stop(long stopTime) {
+ this.status = Status.STOPPED;
+ this.stopTime = stopTime;
+ return this;
+ }
+
+ @Override
+ public String toString() {
+ StringBuffer buf = new StringBuffer();
+ buf.append("StopWatch [");
+ buf.append(name);
+ buf.append("] ");
+
+ switch (status) {
+ case STARTED:
+ buf.append("STARTED");
+ break;
+ case STOPPED:
+ buf.append("elapsed time: ");
+ buf.append(Util.durationInDunrationUnitsAsStr(getResultInNanos(), DurationUnit.MICROSECOND));
+ break;
+ default:
+ new IllegalStateException("Status " + status + " is not expected");
+ }
+ return buf.toString();
+ }
+
+ public final long getResultInNanos() {
+ if (status == Status.STARTED) {
+ return 0;
+ } else {
+ return stopTime - startTime;
+ }
+ }
+
+}
Added: slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/profiler/Util.java
==============================================================================
--- (empty file)
+++ slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/profiler/Util.java Mon Jul 21 16:28:29 2008
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2004-2008 QOS.ch
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+package org.slf4j.profiler;
+
+import java.text.DecimalFormat;
+
+class Util {
+
+ static final long NANOS_IN_ONE_MICROSECOND = 1000;
+ static final long NANOS_IN_ONE_MILLISECOND = NANOS_IN_ONE_MICROSECOND * 1000;
+ static final long NANOS_IN_ONE_SECOND =NANOS_IN_ONE_MILLISECOND * 1000;
+ private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("0.000");
+
+ static DurationUnit selectDurationUnitForDisplay(StopWatch sw) {
+ return selectDurationUnitForDisplay(sw.getResultInNanos());
+ }
+
+ static DurationUnit selectDurationUnitForDisplay(long durationInNanos) {
+ if (durationInNanos < 10*NANOS_IN_ONE_MICROSECOND) {
+ return DurationUnit.NANOSECOND;
+ } else if (durationInNanos < 10*NANOS_IN_ONE_MILLISECOND) {
+ return DurationUnit.MICROSECOND;
+ } else if (durationInNanos < 10*NANOS_IN_ONE_SECOND) {
+ return DurationUnit.MILLISSECOND;
+ } else {
+ return DurationUnit.SECOND;
+ }
+ }
+
+ static public double convertToMicros(long nanos) {
+ return (double) nanos / NANOS_IN_ONE_MICROSECOND;
+ }
+
+ static public double convertToMillis(long nanos) {
+ return (double) nanos / NANOS_IN_ONE_MILLISECOND;
+ }
+
+ static public double convertToSeconds(long nanos) {
+ return ((double) nanos / NANOS_IN_ONE_SECOND);
+ }
+
+ static String durationInDunrationUnitsAsStr(StringBuffer buf, StopWatch sw) {
+ DurationUnit du = selectDurationUnitForDisplay(sw);
+ return durationInDunrationUnitsAsStr(sw.getResultInNanos(), du);
+ }
+
+ static String durationInDunrationUnitsAsStr(long nanos, DurationUnit durationUnit) {
+ StringBuffer buf = new StringBuffer();
+ switch (durationUnit) {
+ case NANOSECOND:
+ buf.append(nanos);
+ break;
+ case MICROSECOND:
+ double micros = convertToMicros(nanos);
+ buf.append(DECIMAL_FORMAT.format(micros));
+ break;
+ case MILLISSECOND:
+ double millis = convertToMillis(nanos);
+ buf.append(DECIMAL_FORMAT.format(millis));
+ break;
+ case SECOND:
+ double seconds = convertToSeconds(nanos);
+ buf.append(DECIMAL_FORMAT.format(seconds));
+ break;
+ }
+ return buf.toString();
+ }
+
+ static void appendDurationUnitAsStr(StringBuffer buf, DurationUnit durationUnit) {
+ switch (durationUnit) {
+ case NANOSECOND:
+ buf.append("nanoseconds.");
+ break;
+ case MICROSECOND:
+ buf.append("microseconds.");
+ break;
+ case MILLISSECOND:
+ buf.append("milliseconds.");
+ break;
+ case SECOND:
+ buf.append(" seconds.");
+ break;
+ }
+ }
+}
Added: slf4j/trunk/slf4j-ext/src/test/java/org/slf4j/profiler/PackageTest.java
==============================================================================
--- (empty file)
+++ slf4j/trunk/slf4j-ext/src/test/java/org/slf4j/profiler/PackageTest.java Mon Jul 21 16:28:29 2008
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2004-2008 QOS.ch
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+package org.slf4j.profiler;
+
+
+import junit.framework.*;
+
+public class PackageTest extends TestCase {
+
+ public static Test suite() {
+ TestSuite suite = new TestSuite();
+ suite.addTestSuite(StopWatchTest.class);
+ suite.addTestSuite(ProfilerTest.class);
+ return suite;
+ }
+}
\ No newline at end of file
Added: slf4j/trunk/slf4j-ext/src/test/java/org/slf4j/profiler/ProfilerTest.java
==============================================================================
--- (empty file)
+++ slf4j/trunk/slf4j-ext/src/test/java/org/slf4j/profiler/ProfilerTest.java Mon Jul 21 16:28:29 2008
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2004-2008 QOS.ch
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+package org.slf4j.profiler;
+
+import junit.framework.TestCase;
+
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ProfilerTest extends TestCase{
+
+ Logger logger = LoggerFactory.getLogger(ProfilerTest.class);
+
+ public void smoke() {
+ Profiler profiler = new Profiler("SMOKE");
+ System.out.println("Hello");
+ profiler.stop();
+ }
+
+ public void testBasicProfiling() {
+ Profiler profiler = new Profiler("BAS");
+
+ profiler.start("doX");
+ doX(1);
+
+ profiler.start("doYYYYY");
+ for (int i = 0; i < 5; i++) {
+ doY(i);
+ }
+ profiler.start("doZ");
+ doZ(2);
+ profiler.stop().print();
+ }
+
+ public void X() {
+ Profiler profiler = new Profiler("BASIC");
+
+
+ profiler.start("Subtask_1");
+ doX(1);
+
+ profiler.start("Subtask_1");
+ for (int i = 0; i < 5; i++) {
+ doX(i);
+ }
+ profiler.start("doOther");
+ doX(2);
+ profiler.stop().print();
+ }
+
+
+ public void testNestedProfiling() {
+ Profiler profiler = new Profiler("BAS");
+
+ profiler.start("doX");
+ doX(1);
+
+ profiler.start("doYYYYY");
+ for (int i = 0; i < 5; i++) {
+ doY(i);
+ }
+ Profiler nested = profiler.startNested("subtask");
+ doSubtask(nested);
+ profiler.start("doZ");
+ doZ(2);
+ profiler.stop().print();
+ }
+
+ void doX(int millis) {
+ delay(millis);
+ }
+
+ public void doSubtask(Profiler nested) {
+ nested.start("n1");
+ doX(1);
+
+ nested.start("n2");
+ doX(5);
+ nested.stop();
+ }
+
+ void doY(int millis) {
+ delay(millis);
+ }
+
+ void doZ(int millis) {
+ delay(millis);
+ }
+
+ void delay(int millis) {
+ try {
+ Thread.sleep(millis);
+ } catch (InterruptedException e) {
+ }
+ }
+}
Added: slf4j/trunk/slf4j-ext/src/test/java/org/slf4j/profiler/StopWatchTest.java
==============================================================================
--- (empty file)
+++ slf4j/trunk/slf4j-ext/src/test/java/org/slf4j/profiler/StopWatchTest.java Mon Jul 21 16:28:29 2008
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2004-2008 QOS.ch
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+package org.slf4j.profiler;
+
+import junit.framework.TestCase;
+
+public class StopWatchTest extends TestCase {
+
+ public StopWatchTest(String name) {
+ super(name);
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ public void testSelectDurationUnitForDisplay() throws InterruptedException {
+ assertEquals(DurationUnit.NANOSECOND, Util.selectDurationUnitForDisplay(10));
+ assertEquals(DurationUnit.NANOSECOND, Util.selectDurationUnitForDisplay(9*Util.NANOS_IN_ONE_MICROSECOND));
+ assertEquals(DurationUnit.MICROSECOND, Util.selectDurationUnitForDisplay(11*Util.NANOS_IN_ONE_MICROSECOND));
+ assertEquals(DurationUnit.MICROSECOND, Util.selectDurationUnitForDisplay(9*Util.NANOS_IN_ONE_MILLISECOND));
+ assertEquals(DurationUnit.MILLISSECOND, Util.selectDurationUnitForDisplay(11*Util.NANOS_IN_ONE_MILLISECOND));
+ assertEquals(DurationUnit.SECOND, Util.selectDurationUnitForDisplay(11*Util.NANOS_IN_ONE_SECOND));
+ }
+
+}
More information about the slf4j-dev
mailing list