sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject [sis] branch geoapi-4.0 updated: Fix logging.properties configuration (it is now effective). Log messages in a file (with more details) in addition to console when using NetBeans project. Provide more visual hint when a log message spans more than one line.
Date Sat, 25 Aug 2018 12:43:56 GMT
This is an automated email from the ASF dual-hosted git repository.

desruisseaux pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git


The following commit(s) were added to refs/heads/geoapi-4.0 by this push:
     new 121f50d  Fix logging.properties configuration (it is now effective). Log messages
in a file (with more details) in addition to console when using NetBeans project. Provide
more visual hint when a log message spans more than one line.
121f50d is described below

commit 121f50d9f40016d7343694ecca9edbded7f00ee5
Author: Martin Desruisseaux <martin.desruisseaux@geomatys.com>
AuthorDate: Sat Aug 25 14:27:57 2018 +0200

    Fix logging.properties configuration (it is now effective). Log messages in a file (with
more details) in addition to console when using NetBeans project.
    Provide more visual hint when a log message spans more than one line.
---
 .../apache/sis/util/logging/MonolineFormatter.java | 73 ++++++++++++++++++----
 .../sis/util/logging/MonolineFormatterTest.java    | 13 ++--
 src/main/config/logging.properties                 | 21 +++++--
 3 files changed, 85 insertions(+), 22 deletions(-)

diff --git a/core/sis-utility/src/main/java/org/apache/sis/util/logging/MonolineFormatter.java
b/core/sis-utility/src/main/java/org/apache/sis/util/logging/MonolineFormatter.java
index bc460e2..00fb831 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/util/logging/MonolineFormatter.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/util/logging/MonolineFormatter.java
@@ -164,11 +164,18 @@ public class MonolineFormatter extends Formatter {
     private static final boolean SHOW_LEVEL = true;
 
     /**
-     * Number of spaces to colorize at the beginning of lines that are continuation of a
single log record.
+     * Number of characters or spaces to colorize at the beginning of lines that are continuation
of a single log record.
+     * This count includes the {@link #CONTINUATION_MARK} character. Should not be smaller
than 2 since the algorithm in
+     * this class needs one white space after {@link #CONTINUATION_MARK}.
      */
     private static final int CONTINUATION_MARGIN = 4;
 
     /**
+     * The character to write at the beginning of lines that are continuation of a single
log record.
+     */
+    static final char CONTINUATION_MARK = '┃', CONTINUATION_END = '╹';
+
+    /**
      * Minimal number of stack trace elements to print before and after the "interesting"
elements.
      * The "interesting" elements are the first stack trace elements, and the element which
point
      * to the method that produced the log record.
@@ -277,7 +284,21 @@ public class MonolineFormatter extends Formatter {
     private final PrintWriter printer;
 
     /**
-     * Constructs a default {@code MonolineFormatter}.
+     * Constructs a default {@code MonolineFormatter}. This no-argument constructor is invoked
+     * by the logging system if the {@code logging.properties} file contains the following
line:
+     *
+     * {@preformat text
+     *   java.util.logging.ConsoleHandler.formatter = org.apache.sis.util.logging.MonolineFormatter
+     * }
+     *
+     * @since 1.0
+     */
+    public MonolineFormatter() {
+        this(null);
+    }
+
+    /**
+     * Constructs a {@code MonolineFormatter} configured for the given handler.
      *
      * <div class="section">Auto-configuration from the handler</div>
      * Formatters are often associated to a particular handler. If this handler is known,
giving it at
@@ -393,6 +414,8 @@ loop:   for (int i=0; ; i++) {
         }
         synchronized (buffer) {
             this.header = header;
+            buffer.setLength(0);
+            buffer.append(header);
         }
     }
 
@@ -626,7 +649,7 @@ loop:   for (int i=0; ; i++) {
     }
 
     /**
-     * Formats the given log record and return the formatted string.
+     * Formats the given log record and returns the formatted string.
      * See the <a href="#overview">class javadoc</a> for information on the log
format.
      *
      * @param  record  the log record to be formatted.
@@ -648,7 +671,7 @@ loop:   for (int i=0; ; i++) {
             }
             buffer.setLength(header.length());
             /*
-             * Appends the time (e.g. "00:00:12.365"). The time pattern can be set either
+             * Append the time (e.g. "00:00:12.365"). The time pattern can be set either
              * programmatically by a call to 'setTimeFormat(…)', or in logging.properties
              * file with the "org.apache.sis.util.logging.MonolineFormatter.time" property.
              */
@@ -658,7 +681,7 @@ loop:   for (int i=0; ; i++) {
                 buffer.append(' ');
             }
             /*
-             * Appends the level (e.g. "FINE"). We do not provide the option to turn level
off for now.
+             * Append the level (e.g. "FINE"). We do not provide the option to turn level
off for now.
              * This level will be formatted with a colorized background if ANSI escape sequences
are enabled.
              */
             int margin = buffer.length();
@@ -675,7 +698,7 @@ loop:   for (int i=0; ; i++) {
                 buffer.append(levelReset).append(' ');
             }
             /*
-             * Appends the logger name or source class name, in long of short form.
+             * Append the logger name or source class name, in long of short form.
              * The name may be formatted in bold characters if ANSI escape sequences are
enabled.
              */
             String source;
@@ -709,9 +732,13 @@ loop:   for (int i=0; ; i++) {
             String bodyLineSeparator = writer.getLineSeparator();
             final String lineSeparator = System.lineSeparator();
             if (bodyLineSeparator.length() != lineSeparator.length() + margin + 1) {
-                final int highlight = Math.min(CONTINUATION_MARGIN, margin);
-                bodyLineSeparator = lineSeparator + levelColor + CharSequences.spaces(highlight)
-                                                  + levelReset + CharSequences.spaces(margin
- highlight + 1);
+                if (CONTINUATION_MARGIN != 0) {
+                    final int highlight = Math.min(CONTINUATION_MARGIN, margin);
+                    bodyLineSeparator = lineSeparator + levelColor + CONTINUATION_MARK +
CharSequences.spaces(highlight - 1)
+                                                      + levelReset + CharSequences.spaces(margin
- highlight + 1);
+                } else {
+                    bodyLineSeparator = lineSeparator;
+                }
                 writer.setLineSeparator(bodyLineSeparator);
             }
             if (faint) {
@@ -747,12 +774,34 @@ loop:   for (int i=0; ; i++) {
             } catch (IOException e) {
                 throw new AssertionError(e);
             }
-            buffer.setLength(CharSequences.skipTrailingWhitespaces(buffer, 0, buffer.length()));
+            /*
+             * We wrote the main content, but maybe with some extra lines. Trim the last
lines by skipping white spaces
+             * and line separator (EOL). If the 'bodyLineSeparator' margin is found immediately
before the white spaces
+             * and EOL that we skipped, we repeat this process until we find at least one
non-white character after the
+             * 'bodyLineSeparator'.
+             */
+            int lastMargin = buffer.length();
+            do {
+                length = CharSequences.skipTrailingWhitespaces(buffer, 0, lastMargin);
+                lastMargin = buffer.lastIndexOf(bodyLineSeparator);
+                buffer.setLength(length);
+                length -= lastMargin;
+            } while (length > 0 && length <= bodyLineSeparator.length());
             if (faint) {
                 buffer.append(X364.NORMAL.sequence());
             }
-            buffer.append(lineSeparator);
-            return buffer.toString();
+            /*
+             * At this point we finished to write the message, except for the final line
separator.
+             * If the message spans more than one line, there is CONTINUATION_MARK characters
in the
+             * margin. Replace the last occurrence of those characters by CONTINUATION_END.
+             */
+            lastMargin = CharSequences.indexOf(buffer, CONTINUATION_MARK,
+                            lastMargin + lineSeparator.length(),
+                            lastMargin + bodyLineSeparator.length());
+            if (lastMargin >= 0) {
+                buffer.setCharAt(lastMargin, CONTINUATION_END);
+            }
+            return buffer.append(lineSeparator).toString();
         }
     }
 
diff --git a/core/sis-utility/src/test/java/org/apache/sis/util/logging/MonolineFormatterTest.java
b/core/sis-utility/src/test/java/org/apache/sis/util/logging/MonolineFormatterTest.java
index 6060d3b..5613336 100644
--- a/core/sis-utility/src/test/java/org/apache/sis/util/logging/MonolineFormatterTest.java
+++ b/core/sis-utility/src/test/java/org/apache/sis/util/logging/MonolineFormatterTest.java
@@ -30,7 +30,7 @@ import static org.apache.sis.test.Assert.*;
  * Tests the {@link MonolineFormatter} class.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.3
+ * @version 1.0
  * @since   0.3
  * @module
  */
@@ -65,10 +65,15 @@ public final strictfp class MonolineFormatterTest extends TestCase {
         final StringBuilder buffer = new StringBuilder(expected.length() + 40)
                 .append(levelLocalized)
                 .append(CharSequences.spaces(margin - levelLocalized.length()))
-                .append(expected, levelToReplace.length() + 1, expected.length()); // +1
is for skipping '\t'.
-        final String spaces = CharSequences.spaces(margin).toString();
+                .append(expected, levelToReplace.length() + 1, expected.length());      //
+1 is for skipping '\t'.
+        final String spaces = MonolineFormatter.CONTINUATION_MARK
+                            + CharSequences.spaces(margin - 1).toString();
+        int positionOfLast = -1;
         for (int i=margin; (i=buffer.indexOf("\n\t", i)) >= 0; i += margin) {
-            buffer.replace(++i, i+1, spaces); // Replace only tabulation, leave new line.
+            buffer.replace(positionOfLast = ++i, i+1, spaces);                          //
Replace only tabulation, leave new line.
+        }
+        if (positionOfLast >= 0) {
+            buffer.setCharAt(positionOfLast, MonolineFormatter.CONTINUATION_END);
         }
         return buffer.toString();
     }
diff --git a/src/main/config/logging.properties b/src/main/config/logging.properties
index 7437a3c..ff0136c 100644
--- a/src/main/config/logging.properties
+++ b/src/main/config/logging.properties
@@ -14,19 +14,28 @@
 
 # Handlers installed during VM startup.
 # These classes must be on the system classpath.
-handlers= java.util.logging.ConsoleHandler
+handlers = java.util.logging.FileHandler, java.util.logging.ConsoleHandler
 
 # Default global logging level.
-.level= CONFIG
+.level = CONFIG
 
 # Enable debugging information for Apache SIS packages.
-org.apache.sis.level= FINE
+org.apache.sis.level = FINE
 
 # Set the message that are printed on the console to FINE and above.
 # FINE provides debugging information normally hidden in production.
 java.util.logging.ConsoleHandler.level = FINE
 
-# The MonolineFormatter is specific to Apache SIS and optional.
-# See its javadoc for information on configuration options.
+# MonolineFormatter is optional and specific to Apache SIS. Its default configuration
+# does not show source class and method names. We use this configuration because more
+# complete information are saved in the "workspace/java.log" file. Uncomment the next
+# line if class and method names are desired. See MonolineFormatter class javadoc for
+# more information about configuration options.
 java.util.logging.ConsoleHandler.formatter = org.apache.sis.util.logging.MonolineFormatter
-org.apache.sis.util.logging.MonolineFormatter.source = class.method
+#org.apache.sis.util.logging.MonolineFormatter.source = class.method
+
+# Copy the logs in a file in the working directory. Those logs contain time stamp
+# together with source class and method names.  The file has unlimited length and
+# is overwritten at each execution.
+java.util.logging.FileHandler.pattern = java.log
+java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter


Mime
View raw message