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>

    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 28 22:57:41 2008 @@ -108,6 +108,7 @@
  • Display tag
  • GMaven
  • H2 Database
  • +
  • Gradle
  • GreenMail
  • HA-JDBC
  • Hibernate
  • Added: slf4j/trunk/slf4j-site/src/site/pages/support.html ============================================================================== --- (empty file) +++ slf4j/trunk/slf4j-site/src/site/pages/support.html Mon Jul 28 22:57:41 2008 @@ -0,0 +1,43 @@ + + + + +Log4j Bridge + + + + + + + + +
    + +
    + +
    + +

    Contractual Support

    + + +

    The following companies, listed in alphabetical order, offer + contractual support for SLF4J. +

    + +
      +
    • QOS.ch, in Lausanne, Swizerland. For more information visit + QOS.ch's support page.
    • +
    + + + + +
    + + + + From ceki at slf4j.org Mon Jul 28 23:09:18 2008 From: ceki at slf4j.org (ceki at slf4j.org) Date: Mon, 28 Jul 2008 23:09:18 +0200 (CEST) Subject: [slf4j-dev] svn commit: r1080 - slf4j/trunk/slf4j-site/src/site/pages Message-ID: <20080728210918.078561808E9@pixie.qos.ch> Author: ceki Date: Mon Jul 28 23:09:17 2008 New Revision: 1080 Modified: slf4j/trunk/slf4j-site/src/site/pages/extensions.html slf4j/trunk/slf4j-site/src/site/pages/news.html Log: - doc improvements 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 23:09:17 2008 @@ -42,7 +42,7 @@ 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. + example should make the point clearer.

    Basic example

    @@ -211,12 +211,13 @@

    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. + destination. This can be accomplished by associating a logger of + your choice with a profiler.

    -

    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. +

    After you have associated a logger with a profiler, you would + invoke the log() method instead of print() + previously, as the next example illustrates.

    Profiler with a logger: 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 previous NestedProfilerDemo example.

    The log() method logs at level DEBUG using a marker named Modified: slf4j/trunk/slf4j-site/src/site/pages/news.html ============================================================================== --- slf4j/trunk/slf4j-site/src/site/pages/news.html (original) +++ slf4j/trunk/slf4j-site/src/site/pages/news.html Mon Jul 28 23:09:17 2008 @@ -30,6 +30,15 @@


    +

    XX xth, 2008 - Release of SLF4J 1.5.3

    + +

    Added a new module called slf4j-ext for slf4j-extensions. See its documentation for further + details.

    + + +
    +

    June 8th, 2008 - Release of SLF4J 1.5.2

    Improvements to SLF4J documentation as well as fix of http://bugzilla.slf4j.org/show_bug.cgi?id=93 Summary: Small glitch/inconsistency in MessageFormatter.format(..) behaviour as well as testcase Product: SLF4J Version: 1.5.x Platform: All OS/Version: Windows XP Status: NEW Severity: minor Priority: P1 Component: Core API AssignedTo: dev at slf4j.org ReportedBy: joern at huxhorn.de While I was reimplementing the formatting logic of MessageFormatter.format(..) for Lilith I found something that is most likely a small glitch in the implementation as well as the test. I used all the slf4j testcases to verify my implementation and one of the tests failed: result = MessageFormatter.format("Value {} is smaller than \\{", i1, i2); assertEquals("Value 1 is smaller than \\{", result); To be honest, I don't understand why this test does not fail. The result that I would expect (and that my implementation produces) would be "Value 1 is smaller than {" since the { is properly escaped by a \. Another testcase that follows directly seems to indicate that an escaped parameter start character should simply be printed, regardless if a } follows or not. result = MessageFormatter.format("Value {} is smaller than \\{tail", i1, i2); assertEquals("Value 1 is smaller than {tail", result); I can't see a reasonable semantic difference between an escaped { in the middle or at the end of a message pattern. So I'd suggest to change the aforementioned testcase to result = MessageFormatter.format("Value {} is smaller than \\{", i1, i2); assertEquals("Value 1 is smaller than {", result); and change the implementation accordingly. I don't consider this as a big problem since it's a very, very special case, i.e. it will only show up if the message pattern ends with an escaped {. -- 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 Wed Jul 30 13:53:48 2008 From: bugzilla-daemon at pixie.qos.ch (bugzilla-daemon at pixie.qos.ch) Date: Wed, 30 Jul 2008 13:53:48 +0200 (CEST) Subject: [slf4j-dev] [Bug 71] JCL loggers are Serializable, jcl104-over-slf4j logger is not In-Reply-To: Message-ID: <20080730115348.577EEA2ED0@pixie.qos.ch> http://bugzilla.slf4j.org/show_bug.cgi?id=71 manfred.geiler at gmail.com changed: What |Removed |Added ---------------------------------------------------------------------------- Status|RESOLVED |REOPENED Resolution|FIXED | ------- Comment #2 from manfred.geiler at gmail.com 2008-07-30 13:53 ------- Only marking the logger references as transient is not enough. Deserialized instances would throw NPEs immediately. The transient logger reference must also be created lazily like in JCL. I fear the lack of that lazy-init concept is an overall design weakness of SLF4J. All org.slf4j.Logger implementations (eg. Log4jLoggerAdapter) have these two problems: - not Serializable - eager binding to the actual logging system instead of lazy creation This makes it impossible to use non-static loggers in serializable classes at all. Please reconsider the current architecture, it is a severe con against JCL. -- 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 Wed Jul 30 17:40:55 2008 From: bugzilla-daemon at pixie.qos.ch (bugzilla-daemon at pixie.qos.ch) Date: Wed, 30 Jul 2008 17:40:55 +0200 (CEST) Subject: [slf4j-dev] [Bug 71] JCL loggers are Serializable, jcl104-over-slf4j logger is not In-Reply-To: Message-ID: <20080730154055.B14AA9F133@pixie.qos.ch> http://bugzilla.slf4j.org/show_bug.cgi?id=71 listid at qos.ch changed: What |Removed |Added ---------------------------------------------------------------------------- Status|REOPENED |ASSIGNED ------- Comment #3 from listid at qos.ch 2008-07-30 17:40 ------- Manfred, I am not following. Transient references are not serialized. So by construction, after serialization they are null. Would it be possible for you to supply a test case showing how code relying on SLF4J loggers fails while code relying on JCL loggers would not? The following code may be start: package org.slf4j; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import junit.framework.TestCase; public class SerializationTest extends TestCase { public void testSmoke() throws Exception { ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos); Logger logger = LoggerFactory.getLogger("x"); Apple apple = new Apple(); apple.setLogger(logger); oos.writeObject(apple); ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bais); Apple apple2= (Apple) ois.readObject(); } } package org.slf4j; import java.io.Serializable; public class Apple implements Serializable { private static final long serialVersionUID = 1L; transient Logger logger; void setLogger(Logger logger) { this.logger = logger; } void doIt() { logger.debug("hello"); } } -- 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 Wed Jul 30 18:25:21 2008 From: bugzilla-daemon at pixie.qos.ch (bugzilla-daemon at pixie.qos.ch) Date: Wed, 30 Jul 2008 18:25:21 +0200 (CEST) Subject: [slf4j-dev] [Bug 71] JCL loggers are Serializable, jcl104-over-slf4j logger is not In-Reply-To: Message-ID: <20080730162521.6765318037B@pixie.qos.ch> http://bugzilla.slf4j.org/show_bug.cgi?id=71 ------- Comment #4 from listid at qos.ch 2008-07-30 18:25 ------- Created an attachment (id=41) --> (http://bugzilla.slf4j.org/attachment.cgi?id=41&action=view) Part of test case 1/3 -- 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 Wed Jul 30 18:25:41 2008 From: bugzilla-daemon at pixie.qos.ch (bugzilla-daemon at pixie.qos.ch) Date: Wed, 30 Jul 2008 18:25:41 +0200 (CEST) Subject: [slf4j-dev] [Bug 71] JCL loggers are Serializable, jcl104-over-slf4j logger is not In-Reply-To: Message-ID: <20080730162541.24C3C18037B@pixie.qos.ch> http://bugzilla.slf4j.org/show_bug.cgi?id=71 ------- Comment #5 from listid at qos.ch 2008-07-30 18:25 ------- Created an attachment (id=42) --> (http://bugzilla.slf4j.org/attachment.cgi?id=42&action=view) Part of test case 2/3 -- 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 Wed Jul 30 18:25:58 2008 From: bugzilla-daemon at pixie.qos.ch (bugzilla-daemon at pixie.qos.ch) Date: Wed, 30 Jul 2008 18:25:58 +0200 (CEST) Subject: [slf4j-dev] [Bug 71] JCL loggers are Serializable, jcl104-over-slf4j logger is not In-Reply-To: Message-ID: <20080730162558.9C46B18069C@pixie.qos.ch> http://bugzilla.slf4j.org/show_bug.cgi?id=71 ------- Comment #6 from listid at qos.ch 2008-07-30 18:25 ------- Created an attachment (id=43) --> (http://bugzilla.slf4j.org/attachment.cgi?id=43&action=view) Part of test case 3/3 -- 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 Wed Jul 30 18:33:31 2008 From: bugzilla-daemon at pixie.qos.ch (bugzilla-daemon at pixie.qos.ch) Date: Wed, 30 Jul 2008 18:33:31 +0200 (CEST) Subject: [slf4j-dev] [Bug 71] JCL loggers are Serializable, jcl104-over-slf4j logger is not In-Reply-To: Message-ID: <20080730163331.14610A13A0@pixie.qos.ch> http://bugzilla.slf4j.org/show_bug.cgi?id=71 ------- Comment #7 from listid at qos.ch 2008-07-30 18:33 ------- If I understand correctly, you mean that non-transient references to JCL loggers survive serialization whereas non-transient references to SLF4J loggers do not. By survive serialization, I mean that the deserialized logger instance is fully functional. Test case is included in the attachments. -- 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 Wed Jul 30 22:20:23 2008 From: ceki at slf4j.org (ceki at slf4j.org) Date: Wed, 30 Jul 2008 22:20:23 +0200 (CEST) Subject: [slf4j-dev] svn commit: r1081 - slf4j/trunk/slf4j-site/src/site/pages Message-ID: <20080730202024.C9483180061@pixie.qos.ch> Author: ceki Date: Wed Jul 30 22:20:22 2008 New Revision: 1081 Modified: slf4j/trunk/slf4j-site/src/site/pages/docs.html Log: - fix the javadocs link for offline site 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 30 22:20:22 2008 @@ -32,7 +32,7 @@

  • SLF4J extensions
  • log4j-over-slf4j
  • -
  • javadocs
  • +
  • javadocs
  • sources, test sources From ceki at slf4j.org Wed Jul 30 23:11:24 2008 From: ceki at slf4j.org (ceki at slf4j.org) Date: Wed, 30 Jul 2008 23:11:24 +0200 (CEST) Subject: [slf4j-dev] svn commit: r1082 - in slf4j/trunk: slf4j-api/src/main/java/org/slf4j/helpers slf4j-jcl/src/main/java/org/slf4j/impl slf4j-jdk14/src/main/java/org/slf4j/impl slf4j-log4j12/src/main/java/org/slf4j/impl slf4j-nop/src/main/java/org/slf4j/impl slf4j-simple/src/main/java/org/slf4j/impl Message-ID: <20080730211124.11B621809D7@pixie.qos.ch> Author: ceki Date: Wed Jul 30 23:11:23 2008 New Revision: 1082 Added: slf4j/trunk/slf4j-api/src/main/java/org/slf4j/helpers/NamedLoggerBase.java Modified: slf4j/trunk/slf4j-api/src/main/java/org/slf4j/helpers/MarkerIgnoringBase.java slf4j/trunk/slf4j-jcl/src/main/java/org/slf4j/impl/JCLLoggerAdapter.java slf4j/trunk/slf4j-jdk14/src/main/java/org/slf4j/impl/JDK14LoggerAdapter.java slf4j/trunk/slf4j-log4j12/src/main/java/org/slf4j/impl/Log4jLoggerAdapter.java slf4j/trunk/slf4j-nop/src/main/java/org/slf4j/impl/NOPLogger.java slf4j/trunk/slf4j-simple/src/main/java/org/slf4j/impl/SimpleLogger.java Log: - fix bug 71 by adding a readResolve method in all Logger implementations. The readResolve method returns the value computed by LoggerFactory.getLogger(name) where name is the serialized value of name for the current instance. Modified: slf4j/trunk/slf4j-api/src/main/java/org/slf4j/helpers/MarkerIgnoringBase.java ============================================================================== --- slf4j/trunk/slf4j-api/src/main/java/org/slf4j/helpers/MarkerIgnoringBase.java (original) +++ slf4j/trunk/slf4j-api/src/main/java/org/slf4j/helpers/MarkerIgnoringBase.java Wed Jul 30 23:11:23 2008 @@ -36,7 +36,7 @@ * * @author Ceki Gulcu */ -public abstract class MarkerIgnoringBase implements Logger { +public abstract class MarkerIgnoringBase extends NamedLoggerBase implements Logger { public boolean isTraceEnabled(Marker marker) { return isTraceEnabled(); @@ -162,4 +162,5 @@ public String toString() { return this.getClass().getName()+"("+getName()+")"; } + } Added: slf4j/trunk/slf4j-api/src/main/java/org/slf4j/helpers/NamedLoggerBase.java ============================================================================== --- (empty file) +++ slf4j/trunk/slf4j-api/src/main/java/org/slf4j/helpers/NamedLoggerBase.java Wed Jul 30 23:11:23 2008 @@ -0,0 +1,44 @@ +package org.slf4j.helpers; + +import java.io.ObjectStreamException; +import java.io.Serializable; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Serves as base class for named logger implementation. More significantly, this + * class establishes deserialization behavior. See @see #readResolve. + * + * @author Ceki Gulcu + * @since 1.5.3 + */ +abstract class NamedLoggerBase implements Logger, Serializable { + + protected String name; + + public String getName() { + return name; + } + + /** + * Replace this instance with a homonymous (same name) logger returned + * by LoggerFactory. Note that this method is only called during + * deserialization. + * + *

    + * This approach will work well if the desired ILoggerFactory is the one + * references by LoggerFactory. However, if the user manages its logger hierarchy + * through a different (non-static) mechanism, e.g. dependency injection, then + * this approach would be mostly counterproductive. + * + * @return logger with same name as returned by LoggerFactory + * @throws ObjectStreamException + */ + protected Object readResolve() throws ObjectStreamException { + // using getName() instead of this.name works even for + // NOPLogger + return LoggerFactory.getLogger(getName()); + } + +} Modified: slf4j/trunk/slf4j-jcl/src/main/java/org/slf4j/impl/JCLLoggerAdapter.java ============================================================================== --- slf4j/trunk/slf4j-jcl/src/main/java/org/slf4j/impl/JCLLoggerAdapter.java (original) +++ slf4j/trunk/slf4j-jcl/src/main/java/org/slf4j/impl/JCLLoggerAdapter.java Wed Jul 30 23:11:23 2008 @@ -38,8 +38,9 @@ * @author Ceki Gülcü */ public final class JCLLoggerAdapter extends MarkerIgnoringBase { + + private static final long serialVersionUID = 4141593417490482209L; final Log log; - final String name; // WARN: JCLLoggerAdapter constructor should have only package access so // that only JCLLoggerFactory be able to create one. @@ -48,10 +49,6 @@ this.name = name; } - public String getName() { - return name; - } - /** * Delegates to the {@link Log#isTraceEnabled} method of the underlying * {@link Log} instance. Modified: slf4j/trunk/slf4j-jdk14/src/main/java/org/slf4j/impl/JDK14LoggerAdapter.java ============================================================================== --- slf4j/trunk/slf4j-jdk14/src/main/java/org/slf4j/impl/JDK14LoggerAdapter.java (original) +++ slf4j/trunk/slf4j-jdk14/src/main/java/org/slf4j/impl/JDK14LoggerAdapter.java Wed Jul 30 23:11:23 2008 @@ -53,16 +53,16 @@ */ public final class JDK14LoggerAdapter extends MarkerIgnoringBase implements LocationAwareLogger { + + private static final long serialVersionUID = -8053026990503422791L; + final java.util.logging.Logger logger; // WARN: JDK14LoggerAdapter constructor should have only package access so // that only JDK14LoggerFactory be able to create one. JDK14LoggerAdapter(java.util.logging.Logger logger) { this.logger = logger; - } - - public String getName() { - return logger.getName(); + this.name = logger.getName(); } /** Modified: slf4j/trunk/slf4j-log4j12/src/main/java/org/slf4j/impl/Log4jLoggerAdapter.java ============================================================================== --- slf4j/trunk/slf4j-log4j12/src/main/java/org/slf4j/impl/Log4jLoggerAdapter.java (original) +++ slf4j/trunk/slf4j-log4j12/src/main/java/org/slf4j/impl/Log4jLoggerAdapter.java Wed Jul 30 23:11:23 2008 @@ -33,8 +33,12 @@ package org.slf4j.impl; +import java.io.ObjectStreamException; +import java.io.Serializable; + import org.apache.log4j.Level; import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.slf4j.Marker; import org.slf4j.helpers.MarkerIgnoringBase; import org.slf4j.helpers.MessageFormatter; @@ -57,8 +61,11 @@ * @author Ceki Gülcü */ public final class Log4jLoggerAdapter extends MarkerIgnoringBase implements - LocationAwareLogger { - final org.apache.log4j.Logger logger; + LocationAwareLogger, Serializable { + + private static final long serialVersionUID = 6182834493563598289L; + + final transient org.apache.log4j.Logger logger; /** * Following the pattern discussed in pages 162 through 168 of "The complete @@ -75,6 +82,7 @@ // only Log4jLoggerFactory be able to create one. Log4jLoggerAdapter(org.apache.log4j.Logger logger) { this.logger = logger; + this.name = logger.getName(); traceCapable = isTraceCapable(); } @@ -87,10 +95,6 @@ } } - public String getName() { - return logger.getName(); - } - /** * Is this logger instance enabled for the TRACE level? * @@ -602,4 +606,5 @@ } logger.log(callerFQCN, log4jLevel, msg, t); } + } Modified: slf4j/trunk/slf4j-nop/src/main/java/org/slf4j/impl/NOPLogger.java ============================================================================== --- slf4j/trunk/slf4j-nop/src/main/java/org/slf4j/impl/NOPLogger.java (original) +++ slf4j/trunk/slf4j-nop/src/main/java/org/slf4j/impl/NOPLogger.java Wed Jul 30 23:11:23 2008 @@ -43,6 +43,9 @@ * @author Ceki Gülcü */ public class NOPLogger extends MarkerIgnoringBase { + + private static final long serialVersionUID = -517220405410904473L; + /** * The unique instance of NOPLogger. */ Modified: slf4j/trunk/slf4j-simple/src/main/java/org/slf4j/impl/SimpleLogger.java ============================================================================== --- slf4j/trunk/slf4j-simple/src/main/java/org/slf4j/impl/SimpleLogger.java (original) +++ slf4j/trunk/slf4j-simple/src/main/java/org/slf4j/impl/SimpleLogger.java Wed Jul 30 23:11:23 2008 @@ -62,6 +62,9 @@ * @author Ceki Gülcü */ public class SimpleLogger extends MarkerIgnoringBase { + + private static final long serialVersionUID = -6560244151660620173L; + /** * Mark the time when this class gets loaded into memory. */ @@ -71,7 +74,6 @@ private static String INFO_STR = "INFO"; private static String WARN_STR = "WARN"; private static String ERROR_STR = "ERROR"; - String name; /** * Package access allows only {@link SimpleLoggerFactory} to instantiate @@ -81,10 +83,6 @@ this.name = name; } - public String getName() { - return name; - } - /** * Always returns false. * @return always false From bugzilla-daemon at pixie.qos.ch Wed Jul 30 23:17:42 2008 From: bugzilla-daemon at pixie.qos.ch (bugzilla-daemon at pixie.qos.ch) Date: Wed, 30 Jul 2008 23:17:42 +0200 (CEST) Subject: [slf4j-dev] [Bug 71] JCL loggers are Serializable, jcl104-over-slf4j logger is not In-Reply-To: Message-ID: <20080730211742.22DA3180A67@pixie.qos.ch> http://bugzilla.slf4j.org/show_bug.cgi?id=71 listid at qos.ch changed: What |Removed |Added ---------------------------------------------------------------------------- Status|ASSIGNED |RESOLVED Resolution| |FIXED ------- Comment #8 from listid at qos.ch 2008-07-30 23:17 ------- Adding a readResolve method in all Logger implementations should fix this bug. I believe that this approach would achieve the same affect as lazy initialization in JCL. Changes already implemented and committed in revision 1082 [1]. Manfred, I would appreciate if you could verify that the changes work for you. [1] http://svn.slf4j.org/viewvc?view=rev&revision=1082 -- 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 Thu Jul 31 15:00:36 2008 From: bugzilla-daemon at pixie.qos.ch (bugzilla-daemon at pixie.qos.ch) Date: Thu, 31 Jul 2008 15:00:36 +0200 (CEST) Subject: [slf4j-dev] [Bug 94] New: The org.log4j.Category class is missing the getInstance() methods Message-ID: http://bugzilla.slf4j.org/show_bug.cgi?id=94 Summary: The org.log4j.Category class is missing the getInstance() methods Product: SLF4J Version: 1.5.x Platform: PC OS/Version: Windows XP Status: NEW Severity: major Priority: P1 Component: log4j-over-slf4j AssignedTo: dev at slf4j.org ReportedBy: michael at rumpfonline.de The JFig (http://jfig.sourceforge.net/) class org.igfay.util.PropertyUtility class uses the deprecated method org.log4j.Category.getInstance(String) which is not yet provided by SLF4J. [7/31/08 14:49:45:704 CEST] 00000018 ServletWrappe E SRVE0100E: Did not realize init() exception thrown by servlet ActionServlet: java.lang.NoSuchMethodError: org/apache/log4j/Category.getInstance(Ljava/lang/String;)Lorg/apache/log4j/Category; at org.igfay.util.PropertyUtility.(PropertyUtility.java:17) at java.lang.Class.initializeImpl(Native Method) at java.lang.Class.initialize(Class.java:339) at org.igfay.jfig.JFigParser.(JFigParser.java:37) at java.lang.Class.initializeImpl(Native Method) at java.lang.Class.initialize(Class.java:339) at java.lang.Class.initialize(Class.java:318) at org.igfay.jfig.JFig.getParser(JFig.java:323) at org.igfay.jfig.JFig.processConfig(JFig.java:185) at org.igfay.jfig.JFig.(JFig.java:58) at org.igfay.jfig.JFig.initialize(JFig.java:215) -- 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 Thu Jul 31 15:08:38 2008 From: bugzilla-daemon at pixie.qos.ch (bugzilla-daemon at pixie.qos.ch) Date: Thu, 31 Jul 2008 15:08:38 +0200 (CEST) Subject: [slf4j-dev] [Bug 95] New: The org.log4j.Category class is missing the getInstance() methods Message-ID: http://bugzilla.slf4j.org/show_bug.cgi?id=95 Summary: The org.log4j.Category class is missing the getInstance() methods Product: SLF4J Version: 1.5.x Platform: PC OS/Version: Windows XP Status: NEW Severity: major Priority: P1 Component: log4j-over-slf4j AssignedTo: dev at slf4j.org ReportedBy: michael at rumpfonline.de The JFig (http://jfig.sourceforge.net/) class org.igfay.util.PropertyUtility class uses the deprecated method org.log4j.Category.getInstance(String) which is not yet provided by SLF4J. [7/31/08 14:49:45:704 CEST] 00000018 ServletWrappe E SRVE0100E: Did not realize init() exception thrown by servlet ActionServlet: java.lang.NoSuchMethodError: org/apache/log4j/Category.getInstance(Ljava/lang/String;)Lorg/apache/log4j/Category; at org.igfay.util.PropertyUtility.(PropertyUtility.java:17) at java.lang.Class.initializeImpl(Native Method) at java.lang.Class.initialize(Class.java:339) at org.igfay.jfig.JFigParser.(JFigParser.java:37) at java.lang.Class.initializeImpl(Native Method) at java.lang.Class.initialize(Class.java:339) at java.lang.Class.initialize(Class.java:318) at org.igfay.jfig.JFig.getParser(JFig.java:323) at org.igfay.jfig.JFig.processConfig(JFig.java:185) at org.igfay.jfig.JFig.(JFig.java:58) at org.igfay.jfig.JFig.initialize(JFig.java:215) -- 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 Thu Jul 31 15:10:16 2008 From: bugzilla-daemon at pixie.qos.ch (bugzilla-daemon at pixie.qos.ch) Date: Thu, 31 Jul 2008 15:10:16 +0200 (CEST) Subject: [slf4j-dev] [Bug 94] The org.log4j.Category class is missing the getInstance() methods In-Reply-To: Message-ID: <20080731131016.B468F12084C@pixie.qos.ch> http://bugzilla.slf4j.org/show_bug.cgi?id=94 michael at rumpfonline.de changed: What |Removed |Added ---------------------------------------------------------------------------- Status|NEW |RESOLVED Resolution| |DUPLICATE ------- Comment #1 from michael at rumpfonline.de 2008-07-31 15:10 ------- The Bugzilla had some issues connecting to the MYSQL database *** This bug has been marked as a duplicate of bug 95 *** -- 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 Thu Jul 31 15:10:16 2008 From: bugzilla-daemon at pixie.qos.ch (bugzilla-daemon at pixie.qos.ch) Date: Thu, 31 Jul 2008 15:10:16 +0200 (CEST) Subject: [slf4j-dev] [Bug 95] The org.log4j.Category class is missing the getInstance() methods In-Reply-To: Message-ID: <20080731131016.F0A4418005D@pixie.qos.ch> http://bugzilla.slf4j.org/show_bug.cgi?id=95 ------- Comment #1 from michael at rumpfonline.de 2008-07-31 15:10 ------- *** Bug 94 has been marked as a duplicate of this bug. *** -- 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 Thu Jul 31 15:10:27 2008 From: bugzilla-daemon at pixie.qos.ch (bugzilla-daemon at pixie.qos.ch) Date: Thu, 31 Jul 2008 15:10:27 +0200 (CEST) Subject: [slf4j-dev] [Bug 95] The org.log4j.Category class is missing the getInstance() methods In-Reply-To: Message-ID: <20080731131027.CEB48180A71@pixie.qos.ch> http://bugzilla.slf4j.org/show_bug.cgi?id=95 ------- Comment #2 from michael at rumpfonline.de 2008-07-31 15:10 ------- Here the Javadoc from the Category class: ============================================================= This class has been deprecated and replaced by the Logger subclass. It will be kept around to preserve backward compatibility until mid 2003. Logger is a subclass of Category, i.e. it extends Category. In other words, a logger is a category. Thus, all operations that can be performed on a category can be performed on a logger. Internally, whenever log4j is asked to produce a Category object, it will instead produce a Logger object. Log4j 1.2 will never produce Category objects but only Logger instances. In order to preserve backward compatibility, methods that previously accepted category objects still continue to accept category objects. For example, the following are all legal and will work as expected. // Deprecated form: Category cat = Category.getInstance("foo.bar") // Preferred form for retrieving loggers: Logger logger = Logger.getLogger("foo.bar") ======================================================================= This issue can be fixed by copying the code from Category.getLogger(String/Class) to Category.getInstance(String/Class). -- 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 Thu Jul 31 15:25:51 2008 From: bugzilla-daemon at pixie.qos.ch (bugzilla-daemon at pixie.qos.ch) Date: Thu, 31 Jul 2008 15:25:51 +0200 (CEST) Subject: [slf4j-dev] [Bug 95] The org.log4j.Category class is missing the getInstance() methods In-Reply-To: Message-ID: <20080731132551.20D9912080D@pixie.qos.ch> http://bugzilla.slf4j.org/show_bug.cgi?id=95 ------- Comment #3 from listid at qos.ch 2008-07-31 15:25 ------- Hello Michael, You are talking about log4j-over-slf4j module, are you? -- 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 Thu Jul 31 15:44:43 2008 From: ceki at slf4j.org (ceki at slf4j.org) Date: Thu, 31 Jul 2008 15:44:43 +0200 (CEST) Subject: [slf4j-dev] svn commit: r1083 - slf4j/trunk/log4j-over-slf4j/src/main/java/org/apache/log4j Message-ID: <20080731134443.9F308180AE7@pixie.qos.ch> Author: ceki Date: Thu Jul 31 15:44:42 2008 New Revision: 1083 Modified: slf4j/trunk/log4j-over-slf4j/src/main/java/org/apache/log4j/Category.java Log: - added getInstance methods to the Category class This fixes bug 95, http://bugzilla.slf4j.org/show_bug.cgi?id=95 Modified: slf4j/trunk/log4j-over-slf4j/src/main/java/org/apache/log4j/Category.java ============================================================================== --- slf4j/trunk/log4j-over-slf4j/src/main/java/org/apache/log4j/Category.java (original) +++ slf4j/trunk/log4j-over-slf4j/src/main/java/org/apache/log4j/Category.java Thu Jul 31 15:44:42 2008 @@ -55,6 +55,14 @@ } } + public static Logger getInstance(Class clazz) { + return getLogger(clazz); + } + + public static Logger getInstance(String name) { + return getLogger(name); + } + public static Logger getLogger(String name) { return Log4jLoggerFactory.getLogger(name); } From bugzilla-daemon at pixie.qos.ch Thu Jul 31 15:45:27 2008 From: bugzilla-daemon at pixie.qos.ch (bugzilla-daemon at pixie.qos.ch) Date: Thu, 31 Jul 2008 15:45:27 +0200 (CEST) Subject: [slf4j-dev] [Bug 95] The org.log4j.Category class is missing the getInstance() methods In-Reply-To: Message-ID: <20080731134527.BAC10180B44@pixie.qos.ch> http://bugzilla.slf4j.org/show_bug.cgi?id=95 listid at qos.ch changed: What |Removed |Added ---------------------------------------------------------------------------- Status|NEW |RESOLVED Resolution| |FIXED ------- Comment #4 from listid at qos.ch 2008-07-31 15:45 ------- Fixed in revision 1083 -- 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 Thu Jul 31 15:54:57 2008 From: bugzilla-daemon at pixie.qos.ch (bugzilla-daemon at pixie.qos.ch) Date: Thu, 31 Jul 2008 15:54:57 +0200 (CEST) Subject: [slf4j-dev] [Bug 95] The org.log4j.Category class is missing the getInstance() methods In-Reply-To: Message-ID: <20080731135457.8C7F4180B00@pixie.qos.ch> http://bugzilla.slf4j.org/show_bug.cgi?id=95 ------- Comment #5 from michael at rumpfonline.de 2008-07-31 15:54 ------- I wanted to send a fix as well, but you are too fast for me ;) -- 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 Thu Jul 31 16:11:18 2008 From: ceki at slf4j.org (ceki at slf4j.org) Date: Thu, 31 Jul 2008 16:11:18 +0200 (CEST) Subject: [slf4j-dev] svn commit: r1084 - slf4j/trunk/slf4j-log4j12/src/main/java/org/slf4j/impl Message-ID: <20080731141118.DE41D70528@pixie.qos.ch> Author: ceki Date: Thu Jul 31 16:11:18 2008 New Revision: 1084 Modified: slf4j/trunk/slf4j-log4j12/src/main/java/org/slf4j/impl/Log4jLoggerAdapter.java Log: - if(logger.isTraceEnabled()) check in trace(...) methods throw a NoMuchMethodException when used with older versions of log4j. Replaced with if(isTraceEnabled()) which downgrades to DEBUG for older log4j versions. Fixes or re-fixes bug 68 http://bugzilla.slf4j.org/show_bug.cgi?id=68 Modified: slf4j/trunk/slf4j-log4j12/src/main/java/org/slf4j/impl/Log4jLoggerAdapter.java ============================================================================== --- slf4j/trunk/slf4j-log4j12/src/main/java/org/slf4j/impl/Log4jLoggerAdapter.java (original) +++ slf4j/trunk/slf4j-log4j12/src/main/java/org/slf4j/impl/Log4jLoggerAdapter.java Thu Jul 31 16:11:18 2008 @@ -33,12 +33,10 @@ package org.slf4j.impl; -import java.io.ObjectStreamException; import java.io.Serializable; import org.apache.log4j.Level; import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.slf4j.Marker; import org.slf4j.helpers.MarkerIgnoringBase; import org.slf4j.helpers.MessageFormatter; @@ -133,7 +131,7 @@ * the argument */ public void trace(String format, Object arg) { - if (logger.isTraceEnabled()) { + if (isTraceEnabled()) { String msgStr = MessageFormatter.format(format, arg); logger.log(FQCN, traceCapable ? Level.TRACE : Level.DEBUG, msgStr, null); } @@ -156,7 +154,7 @@ * the second argument */ public void trace(String format, Object arg1, Object arg2) { - if (logger.isTraceEnabled()) { + if (isTraceEnabled()) { String msgStr = MessageFormatter.format(format, arg1, arg2); logger.log(FQCN, traceCapable ? Level.TRACE : Level.DEBUG, msgStr, null); } @@ -177,7 +175,7 @@ * an array of arguments */ public void trace(String format, Object[] argArray) { - if (logger.isTraceEnabled()) { + if (isTraceEnabled()) { String msgStr = MessageFormatter.arrayFormat(format, argArray); logger.log(FQCN, traceCapable ? Level.TRACE : Level.DEBUG, msgStr, null); } From bugzilla-daemon at pixie.qos.ch Thu Jul 31 16:24:38 2008 From: bugzilla-daemon at pixie.qos.ch (bugzilla-daemon at pixie.qos.ch) Date: Thu, 31 Jul 2008 16:24:38 +0200 (CEST) Subject: [slf4j-dev] [Bug 68] java.lang.NoSuchMethodError: org.apache.log4j.Logger.isTraceEnabled()Z In-Reply-To: Message-ID: <20080731142438.70576705A8@pixie.qos.ch> http://bugzilla.slf4j.org/show_bug.cgi?id=68 listid at qos.ch changed: What |Removed |Added ---------------------------------------------------------------------------- Status|REOPENED |RESOLVED Resolution| |FIXED ------- Comment #5 from listid at qos.ch 2008-07-31 16:24 ------- Michael, Thank you for reopening this bug and supplying a patch. Fixed in revision 1084. As a side note, it would have been more efficient if your report included a short description of the bug as you observed it. The description was buried in your patch, which was not a patch but a complete version of Log4jLoggerAdapter.java. When I first read your report, I thought you were using an older version of SLF4J without the fix supplied by David Rauschenbach. It is only after I manually did a diff of your version of Log4jLoggerAdapter and the current version that the issue became clear. In short, I think you'll get better responses for on your contributions by describing them in a little more context and detail. -- 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 Thu Jul 31 16:55:51 2008 From: ceki at slf4j.org (ceki at slf4j.org) Date: Thu, 31 Jul 2008 16:55:51 +0200 (CEST) Subject: [slf4j-dev] svn commit: r1085 - slf4j/trunk/slf4j-jdk14/src/main/java/org/slf4j/impl Message-ID: <20080731145551.8C625705A8@pixie.qos.ch> Author: ceki Date: Thu Jul 31 16:55:51 2008 New Revision: 1085 Modified: slf4j/trunk/slf4j-jdk14/src/main/java/org/slf4j/impl/JDK14LoggerAdapter.java Log: - added a check before invoking JUL logger. This check improves performance for disabled log statements. Moreover, it is not redundant as callers of the LocationAwareLogger.log method in various bridges do not perform the check (at this time). This fixes bug 90, http://bugzilla.slf4j.org/show_bug.cgi?id=90 Modified: slf4j/trunk/slf4j-jdk14/src/main/java/org/slf4j/impl/JDK14LoggerAdapter.java ============================================================================== --- slf4j/trunk/slf4j-jdk14/src/main/java/org/slf4j/impl/JDK14LoggerAdapter.java (original) +++ slf4j/trunk/slf4j-jdk14/src/main/java/org/slf4j/impl/JDK14LoggerAdapter.java Thu Jul 31 16:55:51 2008 @@ -626,7 +626,7 @@ record.setSourceMethodName(ste.getMethodName()); } } - + public void log(Marker marker, String callerFQCN, int level, String message, Throwable t) { Level julLevel; @@ -650,6 +650,13 @@ throw new IllegalStateException("Level number " + level + " is not recognized."); } - log(callerFQCN, julLevel, message, t); + // the logger.isLoggable check avoids the unconditional + // construction of location data for disabled log + // statements. As of 2008-07-31, callers of this method + // do not perform this check. See also + // http://bugzilla.slf4j.org/show_bug.cgi?id=90 + if(logger.isLoggable(julLevel)) { + log(callerFQCN, julLevel, message, t); + } } } From bugzilla-daemon at pixie.qos.ch Thu Jul 31 16:59:24 2008 From: bugzilla-daemon at pixie.qos.ch (bugzilla-daemon at pixie.qos.ch) Date: Thu, 31 Jul 2008 16:59:24 +0200 (CEST) Subject: [slf4j-dev] [Bug 90] Missing check for isLoggable in slf4j-jdk14 In-Reply-To: Message-ID: <20080731145924.D0FD8705F9@pixie.qos.ch> http://bugzilla.slf4j.org/show_bug.cgi?id=90 listid at qos.ch changed: What |Removed |Added ---------------------------------------------------------------------------- Status|NEW |RESOLVED Resolution| |FIXED ------- Comment #1 from listid at qos.ch 2008-07-31 16:59 ------- Hello Matthew, Fixed in revision 1085. Good call. -- 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 Thu Jul 31 17:18:32 2008 From: bugzilla-daemon at pixie.qos.ch (bugzilla-daemon at pixie.qos.ch) Date: Thu, 31 Jul 2008 17:18:32 +0200 (CEST) Subject: [slf4j-dev] [Bug 87] Clarify manual/joran wording In-Reply-To: Message-ID: <20080731151832.5BDB27A731@pixie.qos.ch> http://bugzilla.slf4j.org/show_bug.cgi?id=87 listid at qos.ch changed: What |Removed |Added ---------------------------------------------------------------------------- Status|NEW |RESOLVED Resolution| |LATER ------- Comment #9 from listid at qos.ch 2008-07-31 17:18 ------- Transferring bug to logback's jira as LBSITE-16. See http://jira.qos.ch/browse/LBSITE-16 -- 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 Thu Jul 31 21:44:30 2008 From: bugzilla-daemon at pixie.qos.ch (bugzilla-daemon at pixie.qos.ch) Date: Thu, 31 Jul 2008 21:44:30 +0200 (CEST) Subject: [slf4j-dev] [Bug 93] Small glitch/inconsistency in MessageFormatter.format(..) behaviour as well as testcase In-Reply-To: Message-ID: <20080731194430.EAD467BB70@pixie.qos.ch> http://bugzilla.slf4j.org/show_bug.cgi?id=93 Ceki Gulcu changed: What |Removed |Added ---------------------------------------------------------------------------- Resolution| |WONTFIX Status|NEW |RESOLVED CC| |listid at qos.ch --- Comment #1 from Ceki Gulcu 2008-07-31 21:44:30 --- Hi Joern, Thank you for taking the time to report this issue. The current implementation suspends escaping if the '{' is found as the last character of the format string.This ensures that there are other characters following the '{' keeping the rest of the implementation simpler. For example, the following code does not need to be checked for out of bounds char delimStop = messagePattern.charAt(j + 1); However, I agree with you that this behavior is not consistent with what you expect. If in your implementation you would rather enforce escaping, even if '{' is the last character of the format message, that would be reasonable. I rather keep the implementation simple rather than perfectly consistent in all possible aspects. As you say, it's too much of a border case. -- Configure bugmail: http://bugzilla.slf4j.org/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- You are the assignee for the bug. From ceki at slf4j.org Thu Jul 31 22:51:04 2008 From: ceki at slf4j.org (ceki at slf4j.org) Date: Thu, 31 Jul 2008 22:51:04 +0200 (CEST) Subject: [slf4j-dev] svn commit: r1086 - in slf4j/trunk/slf4j-api/src: main/java/org/slf4j/helpers test/java/org/slf4j/helpers Message-ID: <20080731205104.AC04C7A78C@pixie.qos.ch> Author: ceki Date: Thu Jul 31 22:51:04 2008 New Revision: 1086 Modified: slf4j/trunk/slf4j-api/src/main/java/org/slf4j/helpers/MessageFormatter.java slf4j/trunk/slf4j-api/src/test/java/org/slf4j/helpers/MessageFormatterTest.java Log: - add support for array values in parameters For example, log.debug("a:{},i:{}", "A", new int[] {1, 2}}); will print as "a:A,i:[1, 2]" instead of "a:A,i:[I at 6ca1c" as previously log.debug("a:{},b:{},i:{},", new Object[] {"A", "B", new int[] {1, 2}}); will print as "a:A,b:B,i:[1, 2]" instead of "a:A,b:B,i:[I at 90c78" as previously This enhancement was proposed by "lizongbo" 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 Thu Jul 31 22:51:04 2008 @@ -24,12 +24,20 @@ package org.slf4j.helpers; +import java.util.Arrays; + +// contributors: lizongbo + /** * Formats messages according to very simple substitution rules. Substitutions * can be made 1, 2 or more arguments. *

    * For example, - *

    MessageFormatter.format("Hi {}.", "there");
    + * + *
    + * MessageFormatter.format("Hi {}.", "there");
    + * 
    + * * will return the string "Hi there.". *

    * The {} pair is called the formatting anchor. It serves to @@ -40,14 +48,22 @@ * pattern itself but do not want them to be interpreted as a formatting * 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.". + * 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 behavior just described can be overridden by - * escaping the escape character '\'. Calling - *

    MessageFormatter.format("File name is C:\\\\{}.", "file.zip");
    + * 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". * *

    @@ -60,7 +76,7 @@ static final char DELIM_START = '{'; static final char DELIM_STOP = '}'; private static final char ESCAPE_CHAR = '\\'; - + /** * Performs single argument substitution for the 'messagePattern' passed as * parameter. @@ -75,9 +91,10 @@ *

    * * @param messagePattern - * The message pattern which will be parsed and formatted + * The message pattern which will be parsed and formatted * @param argument - * The argument to be substituted in place of the formatting anchor + * The argument to be substituted in place of the formatting + * anchor * @return The formatted message */ public static String format(String messagePattern, Object arg) { @@ -98,13 +115,13 @@ * will return the string "Hi Alice. My name is Bob.". * * @param messagePattern - * The message pattern which will be parsed and formatted + * The message pattern which will be parsed and formatted * @param arg1 - * The argument to be substituted in place of the first formatting - * anchor + * The argument to be substituted in place of the first + * formatting anchor * @param arg2 - * The argument to be substituted in place of the second formatting - * anchor + * The argument to be substituted in place of the second + * formatting anchor * @return The formatted message */ public static String format(String messagePattern, Object arg1, Object arg2) { @@ -117,10 +134,10 @@ * arguments can be passed in an array. * * @param messagePattern - * The message pattern which will be parsed and formatted + * The message pattern which will be parsed and formatted * @param argArray - * An array of arguments to be substituted in place of formatting - * anchors + * An array of arguments to be substituted in place of + * formatting anchors * @return The formatted message */ public static String arrayFormat(String messagePattern, Object[] argArray) { @@ -131,10 +148,10 @@ int len = messagePattern.length(); int j = messagePattern.indexOf(DELIM_START); - if(argArray == null) { + if (argArray == null) { return messagePattern; } - + StringBuffer sbuf = new StringBuffer(messagePattern.length() + 50); for (int L = 0; L < argArray.length; L++) { @@ -154,7 +171,7 @@ char delimStop = messagePattern.charAt(j + 1); if (isEscapedDelimeter(messagePattern, j)) { - if(!isDoubleEscaped(messagePattern, j)) { + if (!isDoubleEscaped(messagePattern, j)) { L--; // DELIM_START was escaped, thus should not be incremented sbuf.append(messagePattern.substring(i, j - 1)); sbuf.append(DELIM_START); @@ -163,8 +180,9 @@ // The escape character preceding the delemiter start is // itself escaped: "abc x:\\{}" // we have to consume one backward slash - sbuf.append(messagePattern.substring(i, j-1)); - sbuf.append(argArray[L]); + sbuf.append(messagePattern.substring(i, j - 1)); + appendParameter(sbuf, argArray[L]); + // sbuf.append(argArray[L]); i = j + 2; } } else if ((delimStop != DELIM_STOP)) { @@ -174,7 +192,7 @@ } else { // normal case sbuf.append(messagePattern.substring(i, j)); - sbuf.append(argArray[L]); + appendParameter(sbuf, argArray[L]); i = j + 2; } } @@ -206,4 +224,31 @@ return false; } } + + // special treatment of array values was suggested by 'lizongbo' + private static void appendParameter(StringBuffer sbuf, Object o) { + if (o != null && o.getClass().isArray()) { + // check for primitive arrays because they unfortunately + // cannot be cast to Object[] + if (o instanceof boolean[]) { + sbuf.append(Arrays.toString((boolean[]) o)); + } else if (o instanceof byte[]) { + sbuf.append(Arrays.toString((byte[]) o)); + } else if (o instanceof char[]) { + sbuf.append(Arrays.toString((char[]) o)); + } else if (o instanceof short[]) { + sbuf.append(Arrays.toString((short[]) o)); + } else if (o instanceof int[]) { + sbuf.append(Arrays.toString((int[]) o)); + } else if (o instanceof long[]) { + sbuf.append(Arrays.toString((long[]) o)); + } else if (o instanceof float[]) { + sbuf.append(Arrays.toString((float[]) o)); + } else { + sbuf.append(Arrays.toString((Object[]) o)); + } + } else { + sbuf.append(o); + } + } } Modified: slf4j/trunk/slf4j-api/src/test/java/org/slf4j/helpers/MessageFormatterTest.java ============================================================================== --- slf4j/trunk/slf4j-api/src/test/java/org/slf4j/helpers/MessageFormatterTest.java (original) +++ slf4j/trunk/slf4j-api/src/test/java/org/slf4j/helpers/MessageFormatterTest.java Thu Jul 31 22:51:04 2008 @@ -33,56 +33,59 @@ package org.slf4j.helpers; +import java.util.Arrays; + import org.slf4j.helpers.MessageFormatter; import junit.framework.TestCase; - /** * @author Ceki Gulcu - * + * */ public class MessageFormatterTest extends TestCase { - + Integer i1 = new Integer(1); Integer i2 = new Integer(2); Integer i3 = new Integer(3); - + public void testNull() { String result; result = MessageFormatter.format(null, i1); assertEquals(null, result); } - + public void testNullParam() { String result; - + result = MessageFormatter.format("Value is {}.", null); assertEquals("Value is null.", result); - + result = MessageFormatter.format("Val1 is {}, val2 is {}.", null, null); assertEquals("Val1 is null, val2 is null.", result); - + result = MessageFormatter.format("Val1 is {}, val2 is {}.", i1, null); assertEquals("Val1 is 1, val2 is null.", result); - + result = MessageFormatter.format("Val1 is {}, val2 is {}.", null, i2); assertEquals("Val1 is null, val2 is 2.", result); - - result = MessageFormatter.arrayFormat("Val1 is {}, val2 is {}, val3 is {}", new Integer[]{null, null, null}); + + result = MessageFormatter.arrayFormat("Val1 is {}, val2 is {}, val3 is {}", + new Integer[] { null, null, null }); assertEquals("Val1 is null, val2 is null, val3 is null", result); - - result = MessageFormatter.arrayFormat("Val1 is {}, val2 is {}, val3 is {}", new Integer[]{null, i2, i3}); + + result = MessageFormatter.arrayFormat("Val1 is {}, val2 is {}, val3 is {}", + new Integer[] { null, i2, i3 }); assertEquals("Val1 is null, val2 is 2, val3 is 3", result); - - result = MessageFormatter.arrayFormat("Val1 is {}, val2 is {}, val3 is {}", new Integer[]{null, null, i3}); + + result = MessageFormatter.arrayFormat("Val1 is {}, val2 is {}, val3 is {}", + new Integer[] { null, null, i3 }); assertEquals("Val1 is null, val2 is null, val3 is 3", result); } - - + public void testOneParameter() { String result; - + result = MessageFormatter.format("Value is {}.", i3); assertEquals("Value is 3.", result); @@ -94,13 +97,13 @@ result = MessageFormatter.format("No subst", i3); assertEquals("No subst", result); - + result = MessageFormatter.format("Incorrect {subst", i3); assertEquals("Incorrect {subst", result); - + result = MessageFormatter.format("Value is \\{bla} {}", i3); assertEquals("Value is {bla} 3", result); - + result = MessageFormatter.format("Escaped \\{} subst", i3); assertEquals("Escaped {} subst", result); @@ -109,51 +112,52 @@ result = MessageFormatter.format("\\{}Escaped", i3); assertEquals("{}Escaped", result); - + result = MessageFormatter.format("File name is \\{{}}.", "App folder.zip"); assertEquals("File name is {App folder.zip}.", result); - + // escaping the escape character - result = MessageFormatter.format("File name is C:\\\\{}.", "App folder.zip"); + result = MessageFormatter + .format("File name is C:\\\\{}.", "App folder.zip"); assertEquals("File name is C:\\App folder.zip.", result); } - + public void testTwoParameters() { String result; - result = MessageFormatter.format("Value {} is smaller than {}.", i1, i2); assertEquals("Value 1 is smaller than 2.", result); - + result = MessageFormatter.format("Value {} is smaller than {}", i1, i2); assertEquals("Value 1 is smaller than 2", result); - + result = MessageFormatter.format("{}{}", i1, i2); assertEquals("12", result); - + result = MessageFormatter.format("Val1={}, Val2={", i1, i2); assertEquals("Val1=1, Val2={", result); result = MessageFormatter.format("Value {} is smaller than \\{}", i1, i2); assertEquals("Value 1 is smaller than {}", result); - - result = MessageFormatter.format("Value {} is smaller than \\{} tail", i1, i2); - assertEquals("Value 1 is smaller than {} tail", result); + + result = MessageFormatter.format("Value {} is smaller than \\{} tail", i1, + i2); + assertEquals("Value 1 is smaller than {} tail", result); result = MessageFormatter.format("Value {} is smaller than \\{", i1, i2); - assertEquals("Value 1 is smaller than \\{", result); - - result = MessageFormatter.format("Value {} is smaller than \\{tail", i1, i2); - assertEquals("Value 1 is smaller than {tail", result); - - + assertEquals("Value 1 is smaller than \\{", result); + + result = MessageFormatter + .format("Value {} is smaller than \\{tail", i1, i2); + assertEquals("Value 1 is smaller than {tail", result); + result = MessageFormatter.format("Value \\{} is smaller than {}", i1, i2); - assertEquals("Value {} is smaller than 1", result); + assertEquals("Value {} is smaller than 1", result); } - + public void testNullArray() { String result; - + String msg0 = "msg0"; String msg1 = "msg1 {}"; String msg2 = "msg2 {} {}"; @@ -163,44 +167,69 @@ result = MessageFormatter.arrayFormat(msg0, args); assertEquals(msg0, result); - + result = MessageFormatter.arrayFormat(msg1, args); assertEquals(msg1, result); - + result = MessageFormatter.arrayFormat(msg2, args); assertEquals(msg2, result); - + result = MessageFormatter.arrayFormat(msg3, args); assertEquals(msg3, result); } - public void testArray() { + + // tests the case when the parameters are supplied in a single array + public void testArrayFormat() { String result; - Integer[] ia = new Integer[] {i1, i2, i3}; + Integer[] ia = new Integer[] { i1, i2, i3 }; - result = MessageFormatter.arrayFormat("Value {} is smaller than {} and {}.", ia); + result = MessageFormatter.arrayFormat( + "Value {} is smaller than {} and {}.", ia); assertEquals("Value 1 is smaller than 2 and 3.", result); - + result = MessageFormatter.arrayFormat("{}{}{}", ia); assertEquals("123", result); - + result = MessageFormatter.arrayFormat("Value {} is smaller than {}.", ia); assertEquals("Value 1 is smaller than 2.", result); - + result = MessageFormatter.arrayFormat("Value {} is smaller than {}", ia); assertEquals("Value 1 is smaller than 2", result); - + result = MessageFormatter.arrayFormat("Val={}, {, Val={}", ia); assertEquals("Val=1, {, Val={}", result); - + result = MessageFormatter.arrayFormat("Val={}, \\{, Val={}", ia); assertEquals("Val=1, {, Val=2", result); - - + result = MessageFormatter.arrayFormat("Val1={}, Val2={", ia); assertEquals("Val1=1, Val2={", result); - + } + + public void testArrayValues() { + + String result; + + Integer p0 = i1; + Integer[] p1 = new Integer[] { i2, i3 }; + + System.out.println("[" + Arrays.toString(new int[] { 1, 2 }) + "]"); + + result = MessageFormatter.format("{}{}", p0, p1); + assertEquals(p0 + Arrays.toString(p1), result); + + { + Object[] pa = new Object[] { "a", p1 }; + result = MessageFormatter.arrayFormat("{}{}", pa); + assertEquals("a" + Arrays.toString(p1), result); + } + { + Object[] pa = new Object[] { "a", new int[] { 1, 2 } }; + result = MessageFormatter.arrayFormat("{}{}", pa); + assertEquals("a" + Arrays.toString(new int[] { 1, 2 }), result); + } } }