From bugzilla-daemon at pixie.qos.ch Fri Jul 4 10:12:09 2008
From: bugzilla-daemon at pixie.qos.ch (bugzilla-daemon at pixie.qos.ch)
Date: Fri, 4 Jul 2008 10:12:09 +0200 (CEST)
Subject: [slf4j-dev] [Bug 91] New: Typo in FAQ
Message-ID:
http://bugzilla.slf4j.org/show_bug.cgi?id=91
Summary: Typo in FAQ
Product: SLF4J
Version: unspecified
Platform: Other
URL: http://www.slf4j.org/faq.html#declared_static
OS/Version: All
Status: NEW
Severity: trivial
Priority: P5
Component: Core API
AssignedTo: dev at slf4j.org
ReportedBy: gwyn.evans at gmail.com
"happened to fist load" rather than "happened to first load" :-)
--
Configure bugmail: http://bugzilla.slf4j.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug, or are watching the assignee.
From bugzilla-daemon at pixie.qos.ch Sun Jul 20 09:53:46 2008
From: bugzilla-daemon at pixie.qos.ch (bugzilla-daemon at pixie.qos.ch)
Date: Sun, 20 Jul 2008 09:53:46 +0200 (CEST)
Subject: [slf4j-dev] [Bug 68] java.lang.NoSuchMethodError:
org.apache.log4j.Logger.isTraceEnabled()Z
In-Reply-To:
Message-ID: <20080720075346.DD98C1207E8@pixie.qos.ch>
http://bugzilla.slf4j.org/show_bug.cgi?id=68
michael_furman at hotmail.com changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|RESOLVED |REOPENED
Resolution|FIXED |
--
Configure bugmail: http://bugzilla.slf4j.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug, or are watching the assignee.
From bugzilla-daemon at pixie.qos.ch Sun Jul 20 09:57:29 2008
From: bugzilla-daemon at pixie.qos.ch (bugzilla-daemon at pixie.qos.ch)
Date: Sun, 20 Jul 2008 09:57:29 +0200 (CEST)
Subject: [slf4j-dev] [Bug 68] java.lang.NoSuchMethodError:
org.apache.log4j.Logger.isTraceEnabled()Z
In-Reply-To:
Message-ID: <20080720075729.88B4EC86A1@pixie.qos.ch>
http://bugzilla.slf4j.org/show_bug.cgi?id=68
------- Comment #4 from michael_furman at hotmail.com 2008-07-20 09:57 -------
Created an attachment (id=40)
--> (http://bugzilla.slf4j.org/attachment.cgi?id=40&action=view)
Source with fixed bug
Hi!
I have reproduced problem on JBoss 4.0.3 SP1.
Please find attached file with bug fix.
I will reaaly appreciate if you will check in file and will release a new
version .
Thanks and best regards,
Michael
--
Configure bugmail: http://bugzilla.slf4j.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug, or are watching the assignee.
From ceki at slf4j.org Mon Jul 21 14:21:13 2008
From: ceki at slf4j.org (ceki at slf4j.org)
Date: Mon, 21 Jul 2008 14:21:13 +0200 (CEST)
Subject: [slf4j-dev] svn commit: r1067 -
slf4j/trunk/slf4j-site/src/site/pages
Message-ID: <20080721122113.5E4D2A2E6B@pixie.qos.ch>
Author: ceki
Date: Mon Jul 21 14:21:12 2008
New Revision: 1067
Modified:
slf4j/trunk/slf4j-site/src/site/pages/index.html
Log:
apache archiva added to the list
Modified: slf4j/trunk/slf4j-site/src/site/pages/index.html
==============================================================================
--- slf4j/trunk/slf4j-site/src/site/pages/index.html (original)
+++ slf4j/trunk/slf4j-site/src/site/pages/index.html Mon Jul 21 14:21:12 2008
@@ -83,7 +83,7 @@
+ jLynx
+
JMesa
JODConverter
JTrac
From ceki at slf4j.org Mon Jul 21 15:46:38 2008
From: ceki at slf4j.org (ceki at slf4j.org)
Date: Mon, 21 Jul 2008 15:46:38 +0200 (CEST)
Subject: [slf4j-dev] svn commit: r1068 -
slf4j/trunk/slf4j-api/src/main/java/org/slf4j/helpers
Message-ID: <20080721134638.B19C017FE7E@pixie.qos.ch>
Author: ceki
Date: Mon Jul 21 15:46:38 2008
New Revision: 1068
Modified:
slf4j/trunk/slf4j-api/src/main/java/org/slf4j/helpers/MessageFormatter.java
Log:
typographical changes
Modified: slf4j/trunk/slf4j-api/src/main/java/org/slf4j/helpers/MessageFormatter.java
==============================================================================
--- slf4j/trunk/slf4j-api/src/main/java/org/slf4j/helpers/MessageFormatter.java (original)
+++ slf4j/trunk/slf4j-api/src/main/java/org/slf4j/helpers/MessageFormatter.java Mon Jul 21 15:46:38 2008
@@ -38,14 +38,14 @@
*
* In the rare case where you need to place the '{' or '}' in the message
* pattern itself but do not want them to be interpreted as a formatting
- * anchors, you can espace the '{' character with '\', that is the backslash
+ * anchors, you can escape the '{' character with '\', that is the backslash
* character. Only the '{' character should be escaped. There is no need to
* escape the '}' character. For example,
*
MessageFormatter.format("Set \\{1,2,3} is not equal to {}.", "1,2");
* will return the string "Set {1,2,3} is not equal to 1,2.".
*
*
- * The escaping behaviour just described can be overridden by
+ * The escaping behavior just described can be overridden by
* escaping the escape character '\'. Calling
*
MessageFormatter.format("File name is C:\\\\{}.", "file.zip");
* will return the string "File name is C:\file.zip".
From lizongbo at gmail.com Mon Jul 21 16:01:50 2008
From: lizongbo at gmail.com (lizongbo)
Date: Mon, 21 Jul 2008 22:01:50 +0800
Subject: [slf4j-dev] report bug for slf4 1.5.2 :MessageFormatter's method
"arrayFormat" had not check the parameter argArray's Array Type
Message-ID:
Sorry for my poor english :(
when i test logback0.9.9 and slf4j 1.5.2 ,I found this bug?
the test code is fllow:
log.debug("a:{},v:{},float:{},", new Object[] {"A", "C", new float[]
{1, 2, 3} });
Then I got the log message is :
2008-07-20 02:11:18,656 DEBUG main a:A,v:C,float:[F at 1b09468,
but I want to got :
2008-07-20 02:13:49,515 DEBUG main a:A,v:C,float:[1.0,2.0,3.0],
so I read the souce and found the bug in MessageFormatter.java.
then I change the code in MessageFormatter.java to fix the bug ..
I got the code from svn :
http://svn.slf4j.org/repos/slf4j/trunk/slf4j-api/src/main/java/
and use "svn diff MessageFormatter.java >MessageFormatter.java.patch" to
make a patch file.
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
-------------- next part --------------
A non-text attachment was scrubbed...
Name: MessageFormatter.java.patch
Type: application/octet-stream
Size: 7553 bytes
Desc: not available
URL:
From ceki at slf4j.org Mon Jul 21 16:28:30 2008
From: ceki at slf4j.org (ceki at slf4j.org)
Date: Mon, 21 Jul 2008 16:28:30 +0200 (CEST)
Subject: [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
Message-ID: <20080721142830.53C4C180216@pixie.qos.ch>
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 @@
slf4j-jdk14
slf4j-log4j12
slf4j-jcl
+ slf4j-ext
jcl-over-slf4j
jcl104-over-slf4j
log4j-over-slf4j
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 @@
+
+
+
+ org.slf4j
+ slf4j-parent
+ 1.5.3-SNAPSHOT
+
+
+ 4.0.0
+
+ org.slf4j
+ slf4j-ext
+ jar
+ SLF4J Extensions Module
+
+ http://www.slf4j.org
+ Extensions to the SLF4J API
+
+
+
+ org.slf4j
+ slf4j-api
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ 1.5
+ 1.5
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+ once
+ plain
+ false
+
+ **/AllTest.java
+ **/PackageTest.java
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+
+
+
+ ${project.version}
+ ${project.description}
+ ${project.version}
+
+ ${project.build.outputDirectory}/META-INF/MANIFEST.MF
+
+
+
+
+
+
+
+
+
+
+ org.codehaus.mojo
+ clirr-maven-plugin
+
+ 1.5.0
+
+
+
+
+
+
\ 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 stopwatchList = new ArrayList();
+ List childList = new ArrayList();
+
+ 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 inheritableThreadLocal = new InheritableThreadLocal();
+
+
+ Map profilerMap = new HashMap();
+
+ 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));
+ }
+
+}
From ceki at slf4j.org Mon Jul 21 16:43:40 2008
From: ceki at slf4j.org (ceki at slf4j.org)
Date: Mon, 21 Jul 2008 16:43:40 +0200 (CEST)
Subject: [slf4j-dev] svn commit: r1070 - slf4j/trunk/slf4j-ext
Message-ID: <20080721144340.16C9F180268@pixie.qos.ch>
Author: ceki
Date: Mon Jul 21 16:43:39 2008
New Revision: 1070
Modified:
slf4j/trunk/slf4j-ext/ (props changed)
slf4j/trunk/slf4j-ext/pom.xml
Log:
- fixing cruft in pom.xml
- adding files to .svn ignore list
Modified: slf4j/trunk/slf4j-ext/pom.xml
==============================================================================
--- slf4j/trunk/slf4j-ext/pom.xml (original)
+++ slf4j/trunk/slf4j-ext/pom.xml Mon Jul 21 16:43:39 2008
@@ -27,14 +27,6 @@
-
-
-
-
-
-
-
-
From ceki at slf4j.org Mon Jul 21 16:52:30 2008
From: ceki at slf4j.org (ceki at slf4j.org)
Date: Mon, 21 Jul 2008 16:52:30 +0200 (CEST)
Subject: [slf4j-dev] svn commit: r1071 - slf4j/trunk/slf4j-ext
Message-ID: <20080721145230.0C7BD1805AA@pixie.qos.ch>
Author: ceki
Date: Mon Jul 21 16:52:29 2008
New Revision: 1071
Modified:
slf4j/trunk/slf4j-ext/pom.xml
Log:
- we need an actual binding for tests to pass
Modified: slf4j/trunk/slf4j-ext/pom.xml
==============================================================================
--- slf4j/trunk/slf4j-ext/pom.xml (original)
+++ slf4j/trunk/slf4j-ext/pom.xml Mon Jul 21 16:52:29 2008
@@ -22,7 +22,13 @@
org.slf4j
slf4j-api
-
+
+
+ org.slf4j
+ slf4j-log4j12
+ ${project.version}
+ test
+
From ceki at slf4j.org Mon Jul 21 17:05:10 2008
From: ceki at slf4j.org (ceki at slf4j.org)
Date: Mon, 21 Jul 2008 17:05:10 +0200 (CEST)
Subject: [slf4j-dev] svn commit: r1072 - in slf4j/trunk/slf4j-ext/src:
main/java/org/slf4j/profiler main/java/resources
main/java/resources/META-INF test/java/org/slf4j/profiler
Message-ID: <20080721150510.714B01805AA@pixie.qos.ch>
Author: ceki
Date: Mon Jul 21 17:05:10 2008
New Revision: 1072
Added:
slf4j/trunk/slf4j-ext/src/main/java/resources/
slf4j/trunk/slf4j-ext/src/main/java/resources/META-INF/
slf4j/trunk/slf4j-ext/src/main/java/resources/META-INF/MANIFEST.MF
slf4j/trunk/slf4j-ext/src/test/java/org/slf4j/profiler/UtilTest.java
- copied, changed from r1069, /slf4j/trunk/slf4j-ext/src/test/java/org/slf4j/profiler/StopWatchTest.java
Removed:
slf4j/trunk/slf4j-ext/src/test/java/org/slf4j/profiler/StopWatchTest.java
Modified:
slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/profiler/Profiler.java
slf4j/trunk/slf4j-ext/src/test/java/org/slf4j/profiler/PackageTest.java
Log:
- profilers now know about loggers
- added MANIFEST.MF file
Modified: slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/profiler/Profiler.java
==============================================================================
--- slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/profiler/Profiler.java (original)
+++ slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/profiler/Profiler.java Mon Jul 21 17:05:10 2008
@@ -26,42 +26,47 @@
import java.util.ArrayList;
import java.util.List;
-
-// + Profiler [BAS]
-// |-- elapsed time [doX] 0 milliseconds.
-// |-- elapsed time [doYYYYY] 56 milliseconds.
+import org.slf4j.Logger;
+import org.slf4j.Marker;
+import org.slf4j.MarkerFactory;
+
+// + 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.
+// |-- 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.
+// |-- 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.
+// |-- 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.
+// |-- 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.
-
+// |-- 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 String PROFILER_MARKER_NAME = "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;
@@ -69,12 +74,13 @@
List childList = new ArrayList();
ProfilerRegistry profilerRegistry;
-
+ Logger logger;
+
public Profiler(String name) {
this.name = name;
this.globalStopWatch = new StopWatch(name);
}
-
+
public String getName() {
return name;
}
@@ -84,13 +90,21 @@
}
public void setProfilerRegistry(ProfilerRegistry profilerRegistry) {
- if(profilerRegistry == null) {
+ if (profilerRegistry == null) {
return;
}
this.profilerRegistry = profilerRegistry;
profilerRegistry.put(this);
}
+ public Logger getLogger() {
+ return logger;
+ }
+
+ public void setLogger(Logger logger) {
+ this.logger = logger;
+ }
+
public void start(String name) {
stopLastStopWatch();
StopWatch childSW = new StopWatch(name);
@@ -101,6 +115,7 @@
public Profiler startNested(String name) {
Profiler nestedProfiler = new Profiler(name);
nestedProfiler.setProfilerRegistry(profilerRegistry);
+ nestedProfiler.setLogger(logger);
childList.add(nestedProfiler);
return nestedProfiler;
}
@@ -140,22 +155,31 @@
System.out.println(r);
}
+ public void log() {
+ Marker profilerMarker = MarkerFactory.getMarker(PROFILER_MARKER_NAME);
+ if (logger.isDebugEnabled(profilerMarker)) {
+ DurationUnit du = Util.selectDurationUnitForDisplay(globalStopWatch);
+ String r = buildString(du, "+", "");
+ logger.debug(profilerMarker, 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) {
+ 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 + " ");
+ String subString = profiler
+ .buildString(du, "|--+", indentation + " ");
buf.append(subString);
}
}
Added: slf4j/trunk/slf4j-ext/src/main/java/resources/META-INF/MANIFEST.MF
==============================================================================
--- (empty file)
+++ slf4j/trunk/slf4j-ext/src/main/java/resources/META-INF/MANIFEST.MF Mon Jul 21 17:05:10 2008
@@ -0,0 +1,8 @@
+Implementation-Title: slf4j-ext
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: slf4j.ext
+Bundle-Name: slf4j-log4j12
+Bundle-Vendor: SLF4J.ORG
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Export-Package: org.slf4j.profiler;version=${project.version}
+Import-Package: org.slf4j;version=${project.version}, org.slf4j.spi;version=${project.version}, org.slf4j.helpers;version=${project.version}
Modified: slf4j/trunk/slf4j-ext/src/test/java/org/slf4j/profiler/PackageTest.java
==============================================================================
--- slf4j/trunk/slf4j-ext/src/test/java/org/slf4j/profiler/PackageTest.java (original)
+++ slf4j/trunk/slf4j-ext/src/test/java/org/slf4j/profiler/PackageTest.java Mon Jul 21 17:05:10 2008
@@ -31,7 +31,7 @@
public static Test suite() {
TestSuite suite = new TestSuite();
- suite.addTestSuite(StopWatchTest.class);
+ suite.addTestSuite(UtilTest.class);
suite.addTestSuite(ProfilerTest.class);
return suite;
}
Copied: slf4j/trunk/slf4j-ext/src/test/java/org/slf4j/profiler/UtilTest.java (from r1069, /slf4j/trunk/slf4j-ext/src/test/java/org/slf4j/profiler/StopWatchTest.java)
==============================================================================
--- /slf4j/trunk/slf4j-ext/src/test/java/org/slf4j/profiler/StopWatchTest.java (original)
+++ slf4j/trunk/slf4j-ext/src/test/java/org/slf4j/profiler/UtilTest.java Mon Jul 21 17:05:10 2008
@@ -26,9 +26,9 @@
import junit.framework.TestCase;
-public class StopWatchTest extends TestCase {
+public class UtilTest extends TestCase {
- public StopWatchTest(String name) {
+ public UtilTest(String name) {
super(name);
}
From ceki at slf4j.org Mon Jul 21 17:11:48 2008
From: ceki at slf4j.org (ceki at slf4j.org)
Date: Mon, 21 Jul 2008 17:11:48 +0200 (CEST)
Subject: [slf4j-dev] svn commit: r1073 -
slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/profiler
Message-ID: <20080721151148.63B9B180614@pixie.qos.ch>
Author: ceki
Date: Mon Jul 21 17:11:48 2008
New Revision: 1073
Modified:
slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/profiler/Profiler.java
Log:
indentation matters
Modified: slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/profiler/Profiler.java
==============================================================================
--- slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/profiler/Profiler.java (original)
+++ slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/profiler/Profiler.java Mon Jul 21 17:11:48 2008
@@ -30,35 +30,36 @@
import org.slf4j.Marker;
import org.slf4j.MarkerFactory;
-// + Profiler [BAS]
-// |-- elapsed time [doX] 0 milliseconds.
-// |-- elapsed time [doYYYYY] 56 milliseconds.
+
+// + 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.
+// |-- 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.
+// |-- 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.
+// |-- 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.
+// |-- 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.
+// |-- elapsed time [P0] 87.550 milliseconds.
+// |-- Total elapsed time [P] 87.559 milliseconds.
+// |-- Total elapsed time [TOP] 467.548 milliseconds.
public class Profiler {
From ceki at slf4j.org Mon Jul 21 17:14:11 2008
From: ceki at slf4j.org (ceki at slf4j.org)
Date: Mon, 21 Jul 2008 17:14:11 +0200 (CEST)
Subject: [slf4j-dev] svn commit: r1074 - in slf4j/trunk/slf4j-ext/src/main:
java/resources resources
Message-ID: <20080721151411.95D60180636@pixie.qos.ch>
Author: ceki
Date: Mon Jul 21 17:14:11 2008
New Revision: 1074
Added:
slf4j/trunk/slf4j-ext/src/main/resources/
- copied from r1072, /slf4j/trunk/slf4j-ext/src/main/java/resources/
Removed:
slf4j/trunk/slf4j-ext/src/main/java/resources/
Log:
slf4j-ext/src/main/resources directory was misplaced
From ceki at slf4j.org Wed Jul 23 22:34:12 2008
From: ceki at slf4j.org (ceki at slf4j.org)
Date: Wed, 23 Jul 2008 22:34:12 +0200 (CEST)
Subject: [slf4j-dev] svn commit: r1075 - in slf4j/trunk: .
slf4j-api/src/main/java/org/slf4j/impl slf4j-ext
slf4j-ext/src/main/java/org/slf4j/profiler
slf4j-ext/src/test/java/org/slf4j/profiler slf4j-site/src/site/pages
Message-ID: <20080723203412.CBA12A0BCE@pixie.qos.ch>
Author: ceki
Date: Wed Jul 23 22:34:11 2008
New Revision: 1075
Added:
slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/profiler/TimeInstrumentStatus.java
slf4j/trunk/slf4j-ext/src/test/java/org/slf4j/profiler/ProfilerDemo.java
slf4j/trunk/slf4j-ext/src/test/java/org/slf4j/profiler/RandomIntegerArrayGenerator.java
slf4j/trunk/slf4j-ext/src/test/java/org/slf4j/profiler/SortAndPruneComposites.java
slf4j/trunk/slf4j-site/src/site/pages/extensions.html
Modified:
slf4j/trunk/pom.xml
slf4j/trunk/slf4j-api/src/main/java/org/slf4j/impl/StaticLoggerBinder.java
slf4j/trunk/slf4j-ext/pom.xml
slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/profiler/Profiler.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/java/org/slf4j/profiler/ProfilerTest.java
slf4j/trunk/slf4j-site/src/site/pages/docs.html
Log:
- minor refactoring of the SLF4J profiler API
- documentation (of SLF4J profilers)
This is still ongoing work
Modified: slf4j/trunk/pom.xml
==============================================================================
--- slf4j/trunk/pom.xml (original)
+++ slf4j/trunk/pom.xml Wed Jul 23 22:34:11 2008
@@ -254,12 +254,22 @@
org.apache.maven.plugins
maven-jxr-plugin
+
+
+
+ jxr
+ test-jxr
+
+
+
true
target/site/api/
true
+
+
Modified: slf4j/trunk/slf4j-api/src/main/java/org/slf4j/impl/StaticLoggerBinder.java
==============================================================================
--- slf4j/trunk/slf4j-api/src/main/java/org/slf4j/impl/StaticLoggerBinder.java (original)
+++ slf4j/trunk/slf4j-api/src/main/java/org/slf4j/impl/StaticLoggerBinder.java Wed Jul 23 22:34:11 2008
@@ -44,7 +44,7 @@
public static final StaticLoggerBinder SINGLETON = new StaticLoggerBinder();
private StaticLoggerBinder() {
- throw new UnsupportedOperationException("This code should never make it into the jar");
+ throw new UnsupportedOperationException("This code should have never made it into the jar");
}
public ILoggerFactory getLoggerFactory() {
Modified: slf4j/trunk/slf4j-ext/pom.xml
==============================================================================
--- slf4j/trunk/slf4j-ext/pom.xml (original)
+++ slf4j/trunk/slf4j-ext/pom.xml Wed Jul 23 22:34:11 2008
@@ -80,13 +80,7 @@
-
- org.codehaus.mojo
- clirr-maven-plugin
-
- 1.5.0
-
-
+
Modified: slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/profiler/Profiler.java
==============================================================================
--- slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/profiler/Profiler.java (original)
+++ slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/profiler/Profiler.java Wed Jul 23 22:34:11 2008
@@ -41,27 +41,12 @@
// |-- 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 {
+/**
+ * A poor man's profiler to measure the time elapsed performing
+ * some lengthy task.
+ *
+ */
+public class Profiler implements TimeInstrument {
final static String PROFILER_MARKER_NAME = "PROFILER";
@@ -71,10 +56,12 @@
final String name;
final StopWatch globalStopWatch;
- List stopwatchList = new ArrayList();
- List childList = new ArrayList();
+ //List stopwatchList = new ArrayList();
+ List childTimeInstrumentList = new ArrayList();
+ // optional field
ProfilerRegistry profilerRegistry;
+//optional field
Logger logger;
public Profiler(String name) {
@@ -90,7 +77,7 @@
return profilerRegistry;
}
- public void setProfilerRegistry(ProfilerRegistry profilerRegistry) {
+ public void registerWith(ProfilerRegistry profilerRegistry) {
if (profilerRegistry == null) {
return;
}
@@ -106,97 +93,144 @@
this.logger = logger;
}
+ /**
+ * Starts a child stop watch and stops any previously started time instruments.
+ */
public void start(String name) {
- stopLastStopWatch();
+ stopLastTimeInstrument();
StopWatch childSW = new StopWatch(name);
- stopwatchList.add(childSW);
- childList.add(childSW);
+ childTimeInstrumentList.add(childSW);
}
public Profiler startNested(String name) {
+ stopLastTimeInstrument();
Profiler nestedProfiler = new Profiler(name);
- nestedProfiler.setProfilerRegistry(profilerRegistry);
+ nestedProfiler.registerWith(profilerRegistry);
nestedProfiler.setLogger(logger);
- childList.add(nestedProfiler);
+ childTimeInstrumentList.add(nestedProfiler);
return nestedProfiler;
}
- StopWatch getLastStopWatch() {
- if (stopwatchList.size() > 0) {
- return stopwatchList.get(stopwatchList.size() - 1);
+ TimeInstrument getLastTimeInstrument() {
+ if (childTimeInstrumentList.size() > 0) {
+ return childTimeInstrumentList.get(childTimeInstrumentList.size() - 1);
} else {
return null;
}
}
- void stopLastStopWatch() {
- StopWatch last = getLastStopWatch();
+ void stopLastTimeInstrument() {
+ TimeInstrument last = getLastTimeInstrument();
if (last != null) {
last.stop();
}
}
- void stopNestedProfilers() {
- for (Object child : childList) {
- if (child instanceof Profiler)
- ((Profiler) child).stop();
- }
- }
+// void stopNestedProfilers() {
+// for (Object child : childTimeInstrumentList) {
+// if (child instanceof Profiler)
+// ((Profiler) child).stop();
+// }
+// }
- public Profiler stop() {
- stopLastStopWatch();
- stopNestedProfilers();
+ public long elapsedTime() {
+ return globalStopWatch.elapsedTime();
+ }
+
+ public TimeInstrument stop() {
+ stopLastTimeInstrument();
globalStopWatch.stop();
return this;
}
+ public TimeInstrumentStatus getStatus() {
+ return globalStopWatch.status;
+ }
+
+ /**
+ * This mehtod is used in tests.
+ */
+ void sanityCheck() throws IllegalStateException {
+ if(getStatus() != TimeInstrumentStatus.STOPPED) {
+ throw new IllegalStateException("time instrument ["+getName()+" is not stopped");
+ }
+
+ long totalElapsed = globalStopWatch.elapsedTime();
+ long childTotal = 0;
+
+ for(TimeInstrument ti: childTimeInstrumentList) {
+ childTotal += ti.elapsedTime();
+ if(ti.getStatus() != TimeInstrumentStatus.STOPPED) {
+ throw new IllegalStateException("time instrument ["+ti.getName()+" is not stopped");
+ }
+ if(ti instanceof Profiler) {
+ Profiler nestedProfiler = (Profiler) ti;
+ nestedProfiler.sanityCheck();
+ }
+ }
+ if(totalElapsed < childTotal) {
+ throw new IllegalStateException("children have a higher accumulated elapsed time");
+ }
+ }
+
+ static String TOP_PROFILER_FIRST_PREFIX = "+";
+ static String NESTED_PROFILER_FIRST_PREFIX = "|---+";
+ static String TOTAL_ELAPSED = " Total ";
+ static String SUBTOTAL_ELAPSED = " Subtotal ";
+ static String ELAPSED_TIME = " elapsed time ";
+
+
public void print() {
+ System.out.println(toString());
+ }
+
+ @Override
+ public String toString() {
DurationUnit du = Util.selectDurationUnitForDisplay(globalStopWatch);
- String r = buildString(du, "+", "");
- System.out.println(r);
+ return buildProfilerString(du, TOP_PROFILER_FIRST_PREFIX, TOTAL_ELAPSED, "");
}
-
+
public void log() {
Marker profilerMarker = MarkerFactory.getMarker(PROFILER_MARKER_NAME);
if (logger.isDebugEnabled(profilerMarker)) {
DurationUnit du = Util.selectDurationUnitForDisplay(globalStopWatch);
- String r = buildString(du, "+", "");
- logger.debug(profilerMarker, r);
+ String r = buildProfilerString(du, TOP_PROFILER_FIRST_PREFIX, TOTAL_ELAPSED, "");
+ logger.debug(profilerMarker, SpacePadder.LINE_SEP+r);
}
}
-
- private String buildString(DurationUnit du, String prefix, String indentation) {
+
+ private String buildProfilerString(DurationUnit du, String firstPrefix, String label, String indentation) {
StringBuffer buf = new StringBuffer();
- buf.append(prefix);
+ buf.append(firstPrefix);
buf.append(" Profiler [");
buf.append(name);
buf.append("]");
buf.append(SpacePadder.LINE_SEP);
- for (Object child : childList) {
+ for (TimeInstrument child : childTimeInstrumentList) {
if (child instanceof StopWatch) {
- buildStringForChildStopWatch(buf, indentation, (StopWatch) child, du);
+ buildStopWatchString(buf, du, ELAPSED_TIME, indentation, (StopWatch) child);
} else if (child instanceof Profiler) {
Profiler profiler = (Profiler) child;
- profiler.stop();
String subString = profiler
- .buildString(du, "|--+", indentation + " ");
+ .buildProfilerString(du, NESTED_PROFILER_FIRST_PREFIX, SUBTOTAL_ELAPSED, indentation + " ");
buf.append(subString);
+ buildStopWatchString(buf, du, ELAPSED_TIME, indentation, profiler.globalStopWatch);
}
}
- buildStringForGlobalStopWatch(buf, indentation, globalStopWatch, du);
+ buildStopWatchString(buf, du, label, indentation, globalStopWatch);
return buf.toString();
}
- private static void buildStringForChildStopWatch(StringBuffer buf,
- String indentation, StopWatch sw, DurationUnit du) {
+ private static void buildStopWatchString(StringBuffer buf, DurationUnit du,
+ String prefix, String indentation, StopWatch sw) {
buf.append(indentation);
buf.append("|--");
- buf.append(" elapsed time ");
+ buf.append(prefix);
SpacePadder.leftPad(buf, "[" + sw.getName() + "]", MIN_SW_NAME_LENGTH);
buf.append(" ");
- String timeStr = Util.durationInDunrationUnitsAsStr(sw.getResultInNanos(),
+ String timeStr = Util.durationInDunrationUnitsAsStr(sw.elapsedTime(),
du);
SpacePadder.leftPad(buf, timeStr, MIN_SW_ELAPSED_TIME_NUMBER_LENGTH);
buf.append(" ");
@@ -204,14 +238,15 @@
buf.append(SpacePadder.LINE_SEP);
}
- private static void buildStringForGlobalStopWatch(StringBuffer buf,
+ static void XXXbuildStringForGlobalStopWatch(StringBuffer buf,
String indentation, StopWatch sw, DurationUnit du) {
buf.append(indentation);
buf.append("|--");
- buf.append(" Total elapsed time ");
+ //buf.append(prefix);
+ //buf.append(" Total elapsed time ");
SpacePadder.leftPad(buf, "[" + sw.getName() + "]", MIN_SW_NAME_LENGTH);
buf.append(" ");
- String timeStr = Util.durationInDunrationUnitsAsStr(sw.getResultInNanos(),
+ String timeStr = Util.durationInDunrationUnitsAsStr(sw.elapsedTime(),
du);
SpacePadder.leftPad(buf, timeStr, MIN_SW_ELAPSED_TIME_NUMBER_LENGTH);
buf.append(" ");
Modified: slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/profiler/StopWatch.java
==============================================================================
--- slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/profiler/StopWatch.java (original)
+++ slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/profiler/StopWatch.java Wed Jul 23 22:34:11 2008
@@ -25,37 +25,36 @@
package org.slf4j.profiler;
-public class StopWatch {
+public class StopWatch implements TimeInstrument {
+ private String name;
+ private long startTime;
+ private long stopTime;
+ TimeInstrumentStatus status;
- enum Status {
- STARTED, STOPPED;
+ public StopWatch(String name) {
+ start(name);
}
-
- final String name;
- final long startTime;
- long stopTime;
- Status status;
- public StopWatch(String name) {
+ public void start(String name) {
this.name = name;
- this.startTime = System.nanoTime();
- this.status = Status.STARTED;
+ startTime = System.nanoTime();
+ status = TimeInstrumentStatus.STARTED;
}
-
+
public String getName() {
return name;
}
- public StopWatch stop() {
- if(status == Status.STOPPED) {
+ public TimeInstrument stop() {
+ if(status == TimeInstrumentStatus.STOPPED) {
return this;
}
return stop(System.nanoTime());
}
public StopWatch stop(long stopTime) {
- this.status = Status.STOPPED;
+ this.status = TimeInstrumentStatus.STOPPED;
this.stopTime = stopTime;
return this;
}
@@ -73,7 +72,7 @@
break;
case STOPPED:
buf.append("elapsed time: ");
- buf.append(Util.durationInDunrationUnitsAsStr(getResultInNanos(), DurationUnit.MICROSECOND));
+ buf.append(Util.durationInDunrationUnitsAsStr(elapsedTime(), DurationUnit.MICROSECOND));
break;
default:
new IllegalStateException("Status " + status + " is not expected");
@@ -81,12 +80,20 @@
return buf.toString();
}
- public final long getResultInNanos() {
- if (status == Status.STARTED) {
+ public final long elapsedTime() {
+ if (status == TimeInstrumentStatus.STARTED) {
return 0;
} else {
return stopTime - startTime;
}
}
+ public TimeInstrumentStatus getStatus() {
+ return status;
+ }
+
+ public void print() {
+ System.out.println(toString());
+ }
+
}
Added: slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/profiler/TimeInstrumentStatus.java
==============================================================================
--- (empty file)
+++ slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/profiler/TimeInstrumentStatus.java Wed Jul 23 22:34:11 2008
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+
+
+
+/**
+ * A StopWatch can be in two states: STARTED or STOPPED.
+ */
+
+package org.slf4j.profiler;
+
+enum TimeInstrumentStatus {
+ STARTED, STOPPED;
+}
\ No newline at end of file
Modified: slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/profiler/Util.java
==============================================================================
--- slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/profiler/Util.java (original)
+++ slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/profiler/Util.java Wed Jul 23 22:34:11 2008
@@ -34,7 +34,7 @@
private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("0.000");
static DurationUnit selectDurationUnitForDisplay(StopWatch sw) {
- return selectDurationUnitForDisplay(sw.getResultInNanos());
+ return selectDurationUnitForDisplay(sw.elapsedTime());
}
static DurationUnit selectDurationUnitForDisplay(long durationInNanos) {
@@ -63,7 +63,7 @@
static String durationInDunrationUnitsAsStr(StringBuffer buf, StopWatch sw) {
DurationUnit du = selectDurationUnitForDisplay(sw);
- return durationInDunrationUnitsAsStr(sw.getResultInNanos(), du);
+ return durationInDunrationUnitsAsStr(sw.elapsedTime(), du);
}
static String durationInDunrationUnitsAsStr(long nanos, DurationUnit durationUnit) {
Added: slf4j/trunk/slf4j-ext/src/test/java/org/slf4j/profiler/ProfilerDemo.java
==============================================================================
--- (empty file)
+++ slf4j/trunk/slf4j-ext/src/test/java/org/slf4j/profiler/ProfilerDemo.java Wed Jul 23 22:34:11 2008
@@ -0,0 +1,50 @@
+package org.slf4j.profiler;
+
+
+
+/**
+ *
+ * This demo illustrates usage of SLF4J profilers.
+ *
+ *
+ * We have been given the task of generating a large number, say N,
+ * of random integers. We need to transform that array into a smaller array
+ * containing only prime numbers. The new array has to be sorted.
+ *
+ *
+ * While tackling this problem, we would like to measure the
+ * time spent in each subtask.
+ *
+ *
+ * A typical output for this demo would be:
+
+ + Profiler [DEMO]
+|-- elapsed time [RANDOM] 0.089 seconds.
+|---+ Profiler [SORT_AND_PRUNE]
+ |-- elapsed time [SORT] 0.221 seconds.
+ |-- elapsed time [PRUNE_COMPOSITES] 11.567 seconds.
+ |-- Subtotal [SORT_AND_PRUNE] 11.788 seconds.
+|-- elapsed time [SORT_AND_PRUNE] 11.788 seconds.
+|-- Total [DEMO] 11.877 seconds.
+
+ *
+ * @author Ceki Gulcu
+ */
+public class ProfilerDemo {
+
+ public static void main(String[] args) {
+ Profiler profiler = new Profiler("DEMO");
+ ProfilerRegistry profilerRegistry = ProfilerRegistry.getThreadContextInstance();
+ profiler.registerWith(profilerRegistry);
+
+ profiler.start("RANDOM");
+ RandomIntegerArrayGenerator riag = new RandomIntegerArrayGenerator();
+ int n = 100*1000;
+ int[] randomArray = riag.generate(n);
+
+ profiler.startNested(SortAndPruneComposites.NESTED_PROFILER_NAME);
+ SortAndPruneComposites pruner = new SortAndPruneComposites(randomArray);
+ pruner.sortAndPruneComposites();
+ profiler.stop().print();
+ }
+}
Modified: slf4j/trunk/slf4j-ext/src/test/java/org/slf4j/profiler/ProfilerTest.java
==============================================================================
--- slf4j/trunk/slf4j-ext/src/test/java/org/slf4j/profiler/ProfilerTest.java (original)
+++ slf4j/trunk/slf4j-ext/src/test/java/org/slf4j/profiler/ProfilerTest.java Wed Jul 23 22:34:11 2008
@@ -26,18 +26,26 @@
import junit.framework.TestCase;
-
import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.slf4j.LoggerFactory;
-public class ProfilerTest extends TestCase{
+public class ProfilerTest extends TestCase {
Logger logger = LoggerFactory.getLogger(ProfilerTest.class);
- public void smoke() {
+ public void setUp() throws Exception {
+ super.setUp();
+ }
+ public void testSmoke() {
Profiler profiler = new Profiler("SMOKE");
- System.out.println("Hello");
profiler.stop();
+ StopWatch gSW = profiler.globalStopWatch;
+
+ // verify
+ profiler.sanityCheck();
+ assertEquals(TimeInstrumentStatus.STOPPED, gSW.status);
+ assertEquals(0, profiler.childTimeInstrumentList.size());
+ assertNull(profiler.getLastTimeInstrument());
}
public void testBasicProfiling() {
@@ -46,35 +54,35 @@
profiler.start("doX");
doX(1);
- profiler.start("doYYYYY");
- for (int i = 0; i < 5; i++) {
- doY(i);
- }
+ profiler.start("doY");
+ doY(10);
+
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();
- }
-
-
+ profiler.stop();
+
+ // verify
+ profiler.sanityCheck();
+ StopWatch gSW = profiler.globalStopWatch;
+ assertEquals(TimeInstrumentStatus.STOPPED, gSW.status);
+ assertEquals(3, profiler.childTimeInstrumentList.size());
+ assertNotNull(profiler.getLastTimeInstrument());
+ assertEquals("doZ", profiler.getLastTimeInstrument().getName());
+ }
+
+ // + Profiler [BAS]
+ // |-- elapsed time [doX] 1.272 milliseconds.
+ // |-- elapsed time [doYYYYY] 25.398 milliseconds.
+ // |--+ Profiler [subtask]
+ // |-- elapsed time [n1] 1.434 milliseconds.
+ // |-- elapsed time [n2] 5.855 milliseconds.
+ // |-- Total elapsed time [subtask] 7.321 milliseconds.
+ // |-- elapsed time [doZ] 3.211 milliseconds.
+ // |-- Total elapsed time [BAS] 30.317 milliseconds.
public void testNestedProfiling() {
+
Profiler profiler = new Profiler("BAS");
-
+ profiler.setLogger(logger);
profiler.start("doX");
doX(1);
@@ -86,10 +94,26 @@
doSubtask(nested);
profiler.start("doZ");
doZ(2);
- profiler.stop().print();
+ profiler.stop();
+
+ // verify
+ profiler.sanityCheck();
+ StopWatch gSW = profiler.globalStopWatch;
+ assertEquals(TimeInstrumentStatus.STOPPED, gSW.status);
+ //assertEquals(3, profiler.stopwatchList.size());
+ assertEquals(4, profiler.childTimeInstrumentList.size());
+ assertNotNull(profiler.getLastTimeInstrument());
+ assertEquals("doZ", profiler.getLastTimeInstrument().getName());
+
}
- void doX(int millis) {
+ private void doX(int millis) {
+ delay(millis);
+ }
+ private void doY(int millis) {
+ delay(millis);
+ }
+ private void doZ(int millis) {
delay(millis);
}
@@ -102,13 +126,6 @@
nested.stop();
}
- void doY(int millis) {
- delay(millis);
- }
-
- void doZ(int millis) {
- delay(millis);
- }
void delay(int millis) {
try {
Added: slf4j/trunk/slf4j-ext/src/test/java/org/slf4j/profiler/RandomIntegerArrayGenerator.java
==============================================================================
--- (empty file)
+++ slf4j/trunk/slf4j-ext/src/test/java/org/slf4j/profiler/RandomIntegerArrayGenerator.java Wed Jul 23 22:34:11 2008
@@ -0,0 +1,16 @@
+package org.slf4j.profiler;
+
+import java.util.Random;
+
+public class RandomIntegerArrayGenerator {
+ Random rand = new Random(11);
+
+ int[] generate(int size) {
+ int[] result = new int[size];
+ for(int i = 0; i < size; i++) {
+ int r = rand.nextInt();
+ result[i] = r;
+ }
+ return result;
+ }
+}
Added: slf4j/trunk/slf4j-ext/src/test/java/org/slf4j/profiler/SortAndPruneComposites.java
==============================================================================
--- (empty file)
+++ slf4j/trunk/slf4j-ext/src/test/java/org/slf4j/profiler/SortAndPruneComposites.java Wed Jul 23 22:34:11 2008
@@ -0,0 +1,69 @@
+package org.slf4j.profiler;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+public class SortAndPruneComposites {
+
+ static String NESTED_PROFILER_NAME = "SORT_AND_PRUNE";
+
+ final int[] originalArray;
+ final int originalArrrayLength;
+
+ public SortAndPruneComposites(int[] randomArray) {
+ this.originalArray = randomArray;
+ this.originalArrrayLength = randomArray.length;
+
+ }
+
+ public int[] sortAndPruneComposites() {
+
+ ProfilerRegistry profilerRegistry = ProfilerRegistry.getThreadContextInstance();
+ Profiler sortProfiler = profilerRegistry.get(NESTED_PROFILER_NAME);
+ sortProfiler.start("SORT");
+ int[] sortedArray = sort();
+ sortProfiler.start("PRUNE_COMPOSITES");
+ int result[] = pruneComposites(sortedArray);
+
+ return result;
+ }
+
+ private int[] sort() {
+ int[] sortedArray = new int[originalArrrayLength];
+ System.arraycopy(originalArray, 0, sortedArray, 0, originalArrrayLength);
+ Arrays.sort(sortedArray);
+ return sortedArray;
+ }
+
+ int[] pruneComposites(int[] sortedArray) {
+ ArrayList primesArray = new ArrayList();
+ for(int i = 0; i < originalArrrayLength; i++) {
+ int n = sortedArray[i];
+ if(isPrime(n)) {
+ primesArray.add(n);
+ }
+ }
+ int resultSize = primesArray.size();
+ int[] result = new int[resultSize];
+
+ for(int i = 0; i < resultSize; i++) {
+ result[i] = primesArray.get(i);
+ }
+ return result;
+ }
+
+ public boolean isPrime(int n) {
+ if(n < 2) {
+ return false;
+ }
+ if(n%2 == 0) {
+ return false;
+ }
+ for(int i = 3; i*i <=n; i += 2) {
+ if(n%i ==0) {
+ return false;
+ }
+ }
+ return true;
+ }
+}
Modified: slf4j/trunk/slf4j-site/src/site/pages/docs.html
==============================================================================
--- slf4j/trunk/slf4j-site/src/site/pages/docs.html (original)
+++ slf4j/trunk/slf4j-site/src/site/pages/docs.html Wed Jul 23 22:34:11 2008
@@ -29,9 +29,14 @@
FAQ
Bridging legacy APIs
SLF4J migrator
+ SLF4J extensions
+
log4j-over-slf4j
javadocs
- sources
+
+ sources ,
+ test sources
+
Articles
Added: slf4j/trunk/slf4j-site/src/site/pages/extensions.html
==============================================================================
--- (empty file)
+++ slf4j/trunk/slf4j-site/src/site/pages/extensions.html Wed Jul 23 22:34:11 2008
@@ -0,0 +1,120 @@
+
+
+
+
+SLF4J extensions
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
SLF4J extensions
+
+
SLF4J extensions are packaged within slf4j-ext.jar
+ which ships with SLF4J.
+
+
Profilers
+
+
What is a profiler?
+
+
According to wikipedia, profiling
+ is the investigation of a program's behavior using information
+ gathered as the program runs, i.e. it is a form of dynamic program
+ analysis, as opposed to static code analysis. The usual goal of
+ performance analysis is to determine which parts of a program to
+ optimize for speed or memory usage.
+
+
+
SLF4J profilers, a.k.a. poor man's profilers, will help the
+ developer gather performance data. Essentially, a profiler
+ consists of one or more stopwatches. Stopwatches are driven
+ (started/stopped) by statements in the source code . An
+ example, should make the point clearer.
+
+
+
Basic example
+
+
+
Example: Using the profiler
+
+
+
+import ch.qos.logback.classic.stopwatch.Profiler;
+
+public class BasicUsageExample {
+
+ public static void main(String[] args) {
+ Profiler profiler = new Profiler("BASIC");
+ profiler.start("A");
+ doA();
+
+ profiler.start("B");
+ for (int i = 0; i < 5; i++) {
+ doSubtaskTwo(i);
+ }
+ profiler.start("doOther");
+ doOther();
+ System.out.println(profiler.stop().toString() );
+ }
+ ... cut
+
+
Running the above example will output the following output.
+
+
+ Profiler [BASIC]
+|-- elapsed time [A] 0.288 milliseconds.
+|-- elapsed time [B] 24.717 milliseconds.
+|-- elapsed time [Other] 22.085 milliseconds.
+|-- Total elapsed time [BASIC] 50.691 milliseconds.
+
+
+
Instantiating a profiler starts a global stopwatch. Each call to
+ the start() method starts a new and named stopwatch. In addition to
+ sarting a named stopwatch, the start() method also causes the
+ previous stopwatch to stop. Thus, the call to
+ profiler.start("A")
starts a stopwatch named "A". The
+ subsequent call to profiler.start("B")
starts
+ stopwatch "B" and simultanously stops the stopwatch named
+ "A". Invoking the stop()
on a profiler method stops
+ the last stopwatch as well as the global stopwatch which was
+ started when the profiler was instantiated.
+
+
+
+
Profiler nesting
+
+
Profilers can also be nested. By nesting profilers, it is
+ possible to measure a task which itself has subtasks that need to
+ be timed and measured.
+
+
+
Starting a nested profiler will stop any previously started
+ stopwatch or nested profiler associated with the parent profiler.
+
+
+
Often times, the subtask is implemented by a different class as
+ the class hosting the parent profiler. Using the
+ ProfilerRegistry
is a convinient way of passing a
+ nested profiler to an object outside the current object.
+
+
+
Example: ProfilerDemo
+
+
+
+
+
+
From ceki at slf4j.org Wed Jul 23 22:45:44 2008
From: ceki at slf4j.org (ceki at slf4j.org)
Date: Wed, 23 Jul 2008 22:45:44 +0200 (CEST)
Subject: [slf4j-dev] svn commit: r1076 -
slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/profiler
Message-ID: <20080723204544.8C7BA1807F3@pixie.qos.ch>
Author: ceki
Date: Wed Jul 23 22:45:44 2008
New Revision: 1076
Added:
slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/profiler/TimeInstrument.java
Log:
- TimeInstrument was omitted in the previous commit by mistake
Added: slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/profiler/TimeInstrument.java
==============================================================================
--- (empty file)
+++ slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/profiler/TimeInstrument.java Wed Jul 23 22:45:44 2008
@@ -0,0 +1,24 @@
+package org.slf4j.profiler;
+
+public interface TimeInstrument {
+
+ /**
+ * All time instruments are named entities.
+ * @return the name of this instrument
+ */
+ String getName();
+
+
+ TimeInstrumentStatus getStatus();
+ void start(String name);
+ TimeInstrument stop();
+
+ /**
+ * Time elapsed between start and stop, in nanoseconds.
+ *
+ * @return time elapsed in nanoseconds
+ */
+ long elapsedTime();
+
+ void print();
+}
From bugzilla-daemon at pixie.qos.ch Sat Jul 26 02:01:12 2008
From: bugzilla-daemon at pixie.qos.ch (bugzilla-daemon at pixie.qos.ch)
Date: Sat, 26 Jul 2008 02:01:12 +0200 (CEST)
Subject: [slf4j-dev] [Bug 92] New: Typo in documentation
Message-ID:
http://bugzilla.slf4j.org/show_bug.cgi?id=92
Summary: Typo in documentation
Product: SLF4J
Version: 1.5.x
Platform: All
OS/Version: All
Status: NEW
Severity: minor
Priority: P4
Component: Core API
AssignedTo: dev at slf4j.org
ReportedBy: cowwoc at bbs.darktech.org
MDC.put()'s Javadoc reads:
"The code>val parameter"
This should be replaced with:
"The val
parameter"
--
Configure bugmail: http://bugzilla.slf4j.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug, or are watching the assignee.
From ceki at slf4j.org Mon Jul 28 18:52:50 2008
From: ceki at slf4j.org (ceki at slf4j.org)
Date: Mon, 28 Jul 2008 18:52:50 +0200 (CEST)
Subject: [slf4j-dev] svn commit: r1077 -
slf4j/trunk/slf4j-api/src/main/java/org/slf4j
Message-ID: <20080728165250.DF977A0F4F@pixie.qos.ch>
Author: ceki
Date: Mon Jul 28 18:52:49 2008
New Revision: 1077
Modified:
slf4j/trunk/slf4j-api/src/main/java/org/slf4j/MDC.java
Log:
Fixed a typo reported in bug 92
Modified: slf4j/trunk/slf4j-api/src/main/java/org/slf4j/MDC.java
==============================================================================
--- slf4j/trunk/slf4j-api/src/main/java/org/slf4j/MDC.java (original)
+++ slf4j/trunk/slf4j-api/src/main/java/org/slf4j/MDC.java Mon Jul 28 18:52:49 2008
@@ -90,7 +90,7 @@
/**
* Put a context value (the val
parameter) as identified with
* the key
parameter into the current thread's context map.
- * The key
parameter cannot be null. The code>val parameter
+ * The key
parameter cannot be null. The val
parameter
* can be null only if the underlying implementation supports it.
*
*
From bugzilla-daemon at pixie.qos.ch Mon Jul 28 18:55:38 2008
From: bugzilla-daemon at pixie.qos.ch (bugzilla-daemon at pixie.qos.ch)
Date: Mon, 28 Jul 2008 18:55:38 +0200 (CEST)
Subject: [slf4j-dev] [Bug 92] Typo in documentation
In-Reply-To:
Message-ID: <20080728165538.965F8A2F80@pixie.qos.ch>
http://bugzilla.slf4j.org/show_bug.cgi?id=92
listid at qos.ch changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|NEW |RESOLVED
Resolution| |FIXED
------- Comment #1 from listid at qos.ch 2008-07-28 18:55 -------
Thank you for this report. Bug was fixed in revision 1077
--
Configure bugmail: http://bugzilla.slf4j.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug, or are watching the assignee.
From ceki at slf4j.org Mon Jul 28 19:00:36 2008
From: ceki at slf4j.org (ceki at slf4j.org)
Date: Mon, 28 Jul 2008 19:00:36 +0200 (CEST)
Subject: [slf4j-dev] svn commit: r1078 -
slf4j/trunk/slf4j-site/src/site/pages
Message-ID: <20080728170037.096B318083B@pixie.qos.ch>
Author: ceki
Date: Mon Jul 28 19:00:36 2008
New Revision: 1078
Modified:
slf4j/trunk/slf4j-site/src/site/pages/faq.html
Log:
typo fix as reported in bug 91 by Gwyn Evans
Modified: slf4j/trunk/slf4j-site/src/site/pages/faq.html
==============================================================================
--- slf4j/trunk/slf4j-site/src/site/pages/faq.html (original)
+++ slf4j/trunk/slf4j-site/src/site/pages/faq.html Mon Jul 28 19:00:36 2008
@@ -1052,7 +1052,7 @@
be concerned about. However, if the hosting class is shared
between several applications, then all instances of the shared
class will log into the context of the application which
- happened to fist load the shared class into memory - hardly the
+ happened to first load the shared class into memory - hardly the
behavior expected by the user.
From bugzilla-daemon at pixie.qos.ch Mon Jul 28 19:01:36 2008
From: bugzilla-daemon at pixie.qos.ch (bugzilla-daemon at pixie.qos.ch)
Date: Mon, 28 Jul 2008 19:01:36 +0200 (CEST)
Subject: [slf4j-dev] [Bug 91] Typo in FAQ
In-Reply-To:
Message-ID: <20080728170136.09490A0D8F@pixie.qos.ch>
http://bugzilla.slf4j.org/show_bug.cgi?id=91
listid at qos.ch changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|NEW |RESOLVED
Resolution| |FIXED
------- Comment #1 from listid at qos.ch 2008-07-28 19:01 -------
Gwyn, thank you for this report. It was fixed in revision 1078
--
Configure bugmail: http://bugzilla.slf4j.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug, or are watching the assignee.
From ceki at slf4j.org Mon Jul 28 22:57:42 2008
From: ceki at slf4j.org (ceki at slf4j.org)
Date: Mon, 28 Jul 2008 22:57:42 +0200 (CEST)
Subject: [slf4j-dev] svn commit: r1079 - in slf4j/trunk:
slf4j-ext/src/main/java/org/slf4j/profiler
slf4j-ext/src/test/java/org/slf4j/profiler
slf4j-ext/src/test/resources slf4j-site/src/site/pages
Message-ID: <20080728205742.B8168A2633@pixie.qos.ch>
Author: ceki
Date: Mon Jul 28 22:57:41 2008
New Revision: 1079
Added:
slf4j/trunk/slf4j-ext/src/test/java/org/slf4j/profiler/BasicProfilerDemo.java
slf4j/trunk/slf4j-ext/src/test/java/org/slf4j/profiler/NestedProfilerDemo.java
- copied, changed from r1075, /slf4j/trunk/slf4j-ext/src/test/java/org/slf4j/profiler/ProfilerDemo.java
slf4j/trunk/slf4j-ext/src/test/java/org/slf4j/profiler/NestedProfilerDemo2.java
slf4j/trunk/slf4j-ext/src/test/resources/
slf4j/trunk/slf4j-ext/src/test/resources/log4j.properties
slf4j/trunk/slf4j-site/src/site/pages/support.html
Removed:
slf4j/trunk/slf4j-ext/src/test/java/org/slf4j/profiler/ProfilerDemo.java
Modified:
slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/profiler/Profiler.java
slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/profiler/StopWatch.java
slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/profiler/TimeInstrument.java
slf4j/trunk/slf4j-ext/src/test/java/org/slf4j/profiler/SortAndPruneComposites.java
slf4j/trunk/slf4j-site/src/site/pages/extensions.html
slf4j/trunk/slf4j-site/src/site/pages/index.html
Log:
- improved Profiler docs and other minor changes
Modified: slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/profiler/Profiler.java
==============================================================================
--- slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/profiler/Profiler.java (original)
+++ slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/profiler/Profiler.java Mon Jul 28 22:57:41 2008
@@ -30,7 +30,6 @@
import org.slf4j.Marker;
import org.slf4j.MarkerFactory;
-
// + Profiler [BAS]
// |-- elapsed time [doX] 0 milliseconds.
// |-- elapsed time [doYYYYY] 56 milliseconds.
@@ -192,6 +191,9 @@
public void log() {
Marker profilerMarker = MarkerFactory.getMarker(PROFILER_MARKER_NAME);
+ if(logger == null) {
+ throw new NullPointerException("If you invoke the log() method, then you must associate a logger with this profiler.");
+ }
if (logger.isDebugEnabled(profilerMarker)) {
DurationUnit du = Util.selectDurationUnitForDisplay(globalStopWatch);
String r = buildProfilerString(du, TOP_PROFILER_FIRST_PREFIX, TOTAL_ELAPSED, "");
@@ -238,20 +240,4 @@
buf.append(SpacePadder.LINE_SEP);
}
- static void XXXbuildStringForGlobalStopWatch(StringBuffer buf,
- String indentation, StopWatch sw, DurationUnit du) {
- buf.append(indentation);
- buf.append("|--");
- //buf.append(prefix);
- //buf.append(" Total elapsed time ");
- SpacePadder.leftPad(buf, "[" + sw.getName() + "]", MIN_SW_NAME_LENGTH);
- buf.append(" ");
- String timeStr = Util.durationInDunrationUnitsAsStr(sw.elapsedTime(),
- du);
- SpacePadder.leftPad(buf, timeStr, MIN_SW_ELAPSED_TIME_NUMBER_LENGTH);
- buf.append(" ");
- Util.appendDurationUnitAsStr(buf, du);
- buf.append(SpacePadder.LINE_SEP);
- }
-
}
Modified: slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/profiler/StopWatch.java
==============================================================================
--- slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/profiler/StopWatch.java (original)
+++ slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/profiler/StopWatch.java Mon Jul 28 22:57:41 2008
@@ -96,4 +96,8 @@
System.out.println(toString());
}
+ public void log() {
+ throw new UnsupportedOperationException("A stopwatch instance does not know how to log");
+ }
+
}
Modified: slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/profiler/TimeInstrument.java
==============================================================================
--- slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/profiler/TimeInstrument.java (original)
+++ slf4j/trunk/slf4j-ext/src/main/java/org/slf4j/profiler/TimeInstrument.java Mon Jul 28 22:57:41 2008
@@ -21,4 +21,6 @@
long elapsedTime();
void print();
+
+ void log();
}
Added: slf4j/trunk/slf4j-ext/src/test/java/org/slf4j/profiler/BasicProfilerDemo.java
==============================================================================
--- (empty file)
+++ slf4j/trunk/slf4j-ext/src/test/java/org/slf4j/profiler/BasicProfilerDemo.java Mon Jul 28 22:57:41 2008
@@ -0,0 +1,63 @@
+package org.slf4j.profiler;
+
+/**
+ *
+ * This demo illustrates usage of SLF4J profilers.
+ *
+ *
+ * We have been given the task of generating a large number, say N, of random
+ * integers. We need to transform that array into a smaller array containing
+ * only prime numbers. The new array has to be sorted.
+ *
+ *
+ * While tackling this problem, we would like to measure the time spent in each
+ * subtask.
+ *
+ *
+ * A typical output for this demo would be:
+ *
+ *
+ + Profiler [BASIC]
+ |-- elapsed time [A] 213.186 milliseconds.
+ |-- elapsed time [B] 2499.107 milliseconds.
+ |-- elapsed time [OTHER] 3300.752 milliseconds.
+ |-- Total [BASIC] 6014.161 milliseconds.
+
+ *
+ * @author Ceki Gulcu
+ */
+public class BasicProfilerDemo {
+
+ public static void main(String[] args) {
+ // create a profiler called "BASIC"
+ Profiler profiler = new Profiler("BASIC");
+ profiler.start("A");
+ doA();
+
+ profiler.start("B");
+ doB();
+
+ profiler.start("OTHER");
+ doOther();
+ profiler.stop().print();
+ }
+
+ static private void doA() {
+ delay(200);
+ }
+
+ static private void doB() {
+ delay(2500);
+ }
+
+ static private void doOther() {
+ delay(3300);
+ }
+
+ static private void delay(int millis) {
+ try {
+ Thread.sleep(millis);
+ } catch (InterruptedException e) {
+ }
+ }
+}
Copied: slf4j/trunk/slf4j-ext/src/test/java/org/slf4j/profiler/NestedProfilerDemo.java (from r1075, /slf4j/trunk/slf4j-ext/src/test/java/org/slf4j/profiler/ProfilerDemo.java)
==============================================================================
--- /slf4j/trunk/slf4j-ext/src/test/java/org/slf4j/profiler/ProfilerDemo.java (original)
+++ slf4j/trunk/slf4j-ext/src/test/java/org/slf4j/profiler/NestedProfilerDemo.java Mon Jul 28 22:57:41 2008
@@ -30,21 +30,33 @@
*
* @author Ceki Gulcu
*/
-public class ProfilerDemo {
+public class NestedProfilerDemo {
public static void main(String[] args) {
+ // create a profiler called "DEMO"
Profiler profiler = new Profiler("DEMO");
+
+ // register this profiler in the thread context's profiler registry
ProfilerRegistry profilerRegistry = ProfilerRegistry.getThreadContextInstance();
profiler.registerWith(profilerRegistry);
+ // start a stopwatch called "RANDOM"
profiler.start("RANDOM");
- RandomIntegerArrayGenerator riag = new RandomIntegerArrayGenerator();
- int n = 100*1000;
- int[] randomArray = riag.generate(n);
+ RandomIntegerArrayGenerator riaGenerator = new RandomIntegerArrayGenerator();
+ int n = 10*1000;
+ int[] randomArray = riaGenerator.generate(n);
+ // create and start a nested profiler called "SORT_AND_PRUNE"
+ // By virtue of its parent-child relationship with the "DEMO"
+ // profiler, and the previous registration of the parent profiler,
+ // this nested profiler will be automatically registered
+ // with the thread context's profiler registry
profiler.startNested(SortAndPruneComposites.NESTED_PROFILER_NAME);
+
SortAndPruneComposites pruner = new SortAndPruneComposites(randomArray);
pruner.sortAndPruneComposites();
+
+ // stop and print the "DEMO" printer
profiler.stop().print();
}
}
Added: slf4j/trunk/slf4j-ext/src/test/java/org/slf4j/profiler/NestedProfilerDemo2.java
==============================================================================
--- (empty file)
+++ slf4j/trunk/slf4j-ext/src/test/java/org/slf4j/profiler/NestedProfilerDemo2.java Mon Jul 28 22:57:41 2008
@@ -0,0 +1,42 @@
+package org.slf4j.profiler;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+
+/**
+ *
+ * This demo illustrates usage of SLF4J profilers. It is almost identical to
+ * the first NestProfilerDemo, except that it uses a logger instead of
+ * printing its output on the console.
+ *
+
+ * @author Ceki Gulcu
+ */
+public class NestedProfilerDemo2 {
+
+ static Logger logger = LoggerFactory.getLogger(NestedProfilerDemo2.class);
+
+ public static void main(String[] args) {
+ Profiler profiler = new Profiler("DEMO");
+ // associate a logger with the profiler
+ profiler.setLogger(logger);
+
+ ProfilerRegistry profilerRegistry = ProfilerRegistry.getThreadContextInstance();
+ profiler.registerWith(profilerRegistry);
+
+ profiler.start("RANDOM");
+ RandomIntegerArrayGenerator riaGenerator = new RandomIntegerArrayGenerator();
+ int n = 10*1000;
+ int[] randomArray = riaGenerator.generate(n);
+
+ profiler.startNested(SortAndPruneComposites.NESTED_PROFILER_NAME);
+
+ SortAndPruneComposites pruner = new SortAndPruneComposites(randomArray);
+ pruner.sortAndPruneComposites();
+
+ // stop and log
+ profiler.stop().log();
+ }
+}
Modified: slf4j/trunk/slf4j-ext/src/test/java/org/slf4j/profiler/SortAndPruneComposites.java
==============================================================================
--- slf4j/trunk/slf4j-ext/src/test/java/org/slf4j/profiler/SortAndPruneComposites.java (original)
+++ slf4j/trunk/slf4j-ext/src/test/java/org/slf4j/profiler/SortAndPruneComposites.java Mon Jul 28 22:57:41 2008
@@ -17,11 +17,14 @@
}
public int[] sortAndPruneComposites() {
-
+ // retrieve previously registered profiler named "SORT_AND_PRUNE"
ProfilerRegistry profilerRegistry = ProfilerRegistry.getThreadContextInstance();
Profiler sortProfiler = profilerRegistry.get(NESTED_PROFILER_NAME);
+
+ // start a new stopwatch called SORT
sortProfiler.start("SORT");
int[] sortedArray = sort();
+ // start a new stopwatch called PRUNE_COMPOSITES
sortProfiler.start("PRUNE_COMPOSITES");
int result[] = pruneComposites(sortedArray);
Added: slf4j/trunk/slf4j-ext/src/test/resources/log4j.properties
==============================================================================
--- (empty file)
+++ slf4j/trunk/slf4j-ext/src/test/resources/log4j.properties Mon Jul 28 22:57:41 2008
@@ -0,0 +1,6 @@
+
+log4j.rootLogger=DEBUG, CONSOLE
+
+log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
+log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
+log4j.appender.CONSOLE.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
Modified: slf4j/trunk/slf4j-site/src/site/pages/extensions.html
==============================================================================
--- slf4j/trunk/slf4j-site/src/site/pages/extensions.html (original)
+++ slf4j/trunk/slf4j-site/src/site/pages/extensions.html Mon Jul 28 22:57:41 2008
@@ -48,45 +48,43 @@
Basic example
- Example: Using the profiler
+ Example: Using the profiler: BasicProfilerDemo
-
+
[omitted]
+32 public class BasicProfilerDemo {
+33
+34 public static void main(String[] args) {
+35 // create a profiler called "BASIC"
+36 Profiler profiler = new Profiler("BASIC");
+37 profiler.start("A");
+38 doA();
+39
+40 profiler.start("B");
+41 doB();
+42
+43 profiler.start("OTHER");
+44 doOther();
+45 profiler.stop().print();
+46 }
+[omitted]
-import ch.qos.logback.classic.stopwatch.Profiler;
-
-public class BasicUsageExample {
-
- public static void main(String[] args) {
- Profiler profiler = new Profiler("BASIC");
- profiler.start("A");
- doA();
-
- profiler.start("B");
- for (int i = 0; i < 5; i++) {
- doSubtaskTwo(i);
- }
- profiler.start("doOther");
- doOther();
- System.out.println(profiler.stop().toString() );
- }
- ... cut
Running the above example will output the following output.
+ Profiler [BASIC]
-|-- elapsed time [A] 0.288 milliseconds.
-|-- elapsed time [B] 24.717 milliseconds.
-|-- elapsed time [Other] 22.085 milliseconds.
-|-- Total elapsed time [BASIC] 50.691 milliseconds.
-
+|-- elapsed time [A] 220.487 milliseconds.
+|-- elapsed time [B] 2499.866 milliseconds.
+|-- elapsed time [OTHER] 3300.745 milliseconds.
+|-- Total [BASIC] 6022.568 milliseconds.
Instantiating a profiler starts a global stopwatch. Each call to
the start() method starts a new and named stopwatch. In addition to
- sarting a named stopwatch, the start() method also causes the
+ starting a named stopwatch, the start() method also causes the
previous stopwatch to stop. Thus, the call to
profiler.start("A")
starts a stopwatch named "A". The
subsequent call to profiler.start("B")
starts
- stopwatch "B" and simultanously stops the stopwatch named
+ stopwatch "B" and simultaneously stops the stopwatch named
"A". Invoking the stop()
on a profiler method stops
the last stopwatch as well as the global stopwatch which was
started when the profiler was instantiated.
@@ -106,12 +104,191 @@
Often times, the subtask is implemented by a different class as
the class hosting the parent profiler. Using the
- ProfilerRegistry
is a convinient way of passing a
- nested profiler to an object outside the current object.
+ ProfilerRegistry
is a convenient way of passing a
+ nested profiler to an object outside the current object. Each
+ thread has its own profiler registry which can be retrieved by
+ invoking the getThreadContextInstance()
method.
Example: ProfilerDemo
+ href="xref-test/org/slf4j/profiler/NestedProfilerDemo.html">NestedProfilerDemo
+
+
+ 33 public class NestedProfilerDemo {
+34
+35 public static void main(String[] args) {
+36 // create a profiler called "DEMO"
+37 Profiler profiler = new Profiler("DEMO");
+38
+39 // register this profiler in the thread context's profiler registry
+40 ProfilerRegistry profilerRegistry = ProfilerRegistry.getThreadContextInstance();
+41 profiler.registerWith(profilerRegistry);
+42
+43 // start a stopwatch called "RANDOM"
+44 profiler.start("RANDOM");
+45 RandomIntegerArrayGenerator riaGenerator = new RandomIntegerArrayGenerator();
+46 int n = 1000*1000;
+47 int[] randomArray = riaGenerator.generate(n);
+48
+49 // create and start a nested profiler called "SORT_AND_PRUNE"
+50 // By virtue of its parent-child relationship with the "DEMO"
+51 // profiler, and the previous registration of the parent profiler,
+52 // this nested profiler will be automatically registered
+53 // with the thread context's profiler registry
+54 profiler.startNested(SortAndPruneComposites.NESTED_PROFILER_NAME);
+55
+56 SortAndPruneComposites pruner = new SortAndPruneComposites(randomArray);
+57 pruner.sortAndPruneComposites();
+58
+59 // stop and print the "DEMO" printer
+60 profiler.stop().print();
+61 }
+62 }
+
+ Here is the relevant excerpt from the SortAndPruneComposites
+ class.
+
+
+ [omitted]
+6 public class SortAndPruneComposites {
+7
+8 static String NESTED_PROFILER_NAME = "SORT_AND_PRUNE";
+9
+10 final int[] originalArray;
+11 final int originalArrrayLength;
+12
+13 public SortAndPruneComposites(int[] randomArray) {
+14 this.originalArray = randomArray;
+15 this.originalArrrayLength = randomArray.length;
+16
+17 }
+18
+19 public int[] sortAndPruneComposites() {
+20 // retrieve previously registered profiler named "SORT_AND_PRUNE"
+21 ProfilerRegistry profilerRegistry = ProfilerRegistry.getThreadContextInstance();
+22 Profiler sortProfiler = profilerRegistry.get(NESTED_PROFILER_NAME);
+23
+24 // start a new stopwatch called SORT
+25 sortProfiler.start("SORT");
+26 int[] sortedArray = sort();
+27 // start a new stopwatch called PRUNE_COMPOSITES
+28 sortProfiler.start("PRUNE_COMPOSITES");
+29 int result[] = pruneComposites(sortedArray);
+30
+31 return result;
+32 }
+[omitted]
+
+
+ On a Dual-Core Intel CPU clocked at 3.2 GHz, running the
+ ProfilerDemo
application yields the following output:
+
+ + Profiler [DEMO]
+|-- elapsed time [RANDOM] 70.524 milliseconds.
+|---+ Profiler [SORT_AND_PRUNE]
+ |-- elapsed time [SORT] 665.281 milliseconds.
+ |-- elapsed time [PRUNE_COMPOSITES] 5695.515 milliseconds.
+ |-- Subtotal [SORT_AND_PRUNE] 6360.866 milliseconds.
+|-- elapsed time [SORT_AND_PRUNE] 6360.866 milliseconds.
+|-- Total [DEMO] 6433.922 milliseconds.
+
+ From the above, we learn that generating 1'000'000 random
+ integers takes 70 ms, sorting them 665 ms, and pruning the composite
+ (non-prime) integers 5695 ms, for a grand total of 6433 ms. Given
+ that pruning composites takes most of the CPU effort, any future
+ optimizations efforts would be directed at the pruning part.
+
+
+ With just a few well-placed profiler calls we were able to
+ identify hot-spots in our application. Also note that passing a
+ profiler to a target class could be achieved by registering it in a
+ profiler registry and then retrieving it in the target class.
+
+
+ Printing using a logger
+
+ Invoking profiler.print
will always print the
+ output on the console. If you wish to leave the profiler code in
+ production, then you probably need more control over the output
+ destination.
+
+
+ To use a logger, you need to associate a logger of your choice
+ with the profiler and then invoke the log()
method
+ instead of print()
, as the next example illustrates.
+
+
+ Profiler with a logger: NestedProfilerDemo2
+
+
+ [omitted]
+17 public class NestedProfilerDemo2 {
+18
+19 static Logger logger = LoggerFactory.getLogger(NestedProfilerDemo2.class);
+20
+21 public static void main(String[] args) {
+22 Profiler profiler = new Profiler("DEMO");
+23 // associate a logger with the profiler
+24 profiler.setLogger(logger);
+25
+26 ProfilerRegistry profilerRegistry = ProfilerRegistry.getThreadContextInstance();
+27 profiler.registerWith(profilerRegistry);
+28
+29 profiler.start("RANDOM");
+30 RandomIntegerArrayGenerator riaGenerator = new RandomIntegerArrayGenerator();
+31 int n = 10*1000;
+32 int[] randomArray = riaGenerator.generate(n);
+33
+34 profiler.startNested(SortAndPruneComposites.NESTED_PROFILER_NAME);
+35
+36 SortAndPruneComposites pruner = new SortAndPruneComposites(randomArray);
+37 pruner.sortAndPruneComposites();
+38
+39 // stop and log
+40 profiler.stop().log() ;
+41 }
+42 }
+
+ The output generated by this example will depend on the logging
+ environment, but should be very similar to the output generated by
+ the previous NestedProfilerDemo
example.
+
+
+ The log() method logs at level DEBUG using a marker named
+ "PROFILER".
+
+ If your logging system supports markers, e.g. logback, you could
+ specifically enable or disable output generated by SLF4J
+ profilers. Here is logback configuration file disabling output for
+ any logging event bearing the "PROFILER" marker, even if the logger
+ used by the profiler is enabled for the debug level.
+
+
+
+ logback configuration disabling logging from profilers, and only
+ profilers
+
+ <configuration>
+
+ <turboFilter class="ch.qos.logback.classic.turbo.MarkerFilter">
+ <Marker>PROFILER</Marker>
+ <OnMatch>DENY</OnMatch>
+ </turboFilter>
+
+ <appender name="STDOUT"
+ class="ch.qos.logback.core.ConsoleAppender">
+ <layout class="ch.qos.logback.classic.PatternLayout">
+ <Pattern>%-5level %logger{36} - %msg%n</Pattern>
+ </layout>
+ </appender>
+
+ <root>
+ <level value="DEBUG" />
+ <appender-ref ref="STDOUT" />
+ </root>
+</configuration>
+
+
+
+