You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by rm...@apache.org on 2016/04/05 19:30:52 UTC

tomee git commit: TOMEE-1769 allow to configure formatter pattern on LocalFileHandler

Repository: tomee
Updated Branches:
  refs/heads/master 7da1bd748 -> 1cbe8e350


TOMEE-1769 allow to configure formatter pattern on LocalFileHandler


Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/1cbe8e35
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/1cbe8e35
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/1cbe8e35

Branch: refs/heads/master
Commit: 1cbe8e350ad3f78665bceb661437e711ac541790
Parents: 7da1bd7
Author: Romain manni-Bucau <rm...@gmail.com>
Authored: Tue Apr 5 19:30:18 2016 +0200
Committer: Romain manni-Bucau <rm...@gmail.com>
Committed: Tue Apr 5 19:30:18 2016 +0200

----------------------------------------------------------------------
 .../jul/handler/rotating/LocalFileHandler.java  | 120 ++++++++++++++++++-
 .../LocalFileHandlerPatternFormatterTest.java   |  48 ++++++++
 2 files changed, 165 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tomee/blob/1cbe8e35/tomee/tomee-juli/src/main/java/org/apache/tomee/jul/handler/rotating/LocalFileHandler.java
----------------------------------------------------------------------
diff --git a/tomee/tomee-juli/src/main/java/org/apache/tomee/jul/handler/rotating/LocalFileHandler.java b/tomee/tomee-juli/src/main/java/org/apache/tomee/jul/handler/rotating/LocalFileHandler.java
index b662b6d..fcb557c 100644
--- a/tomee/tomee-juli/src/main/java/org/apache/tomee/jul/handler/rotating/LocalFileHandler.java
+++ b/tomee/tomee-juli/src/main/java/org/apache/tomee/jul/handler/rotating/LocalFileHandler.java
@@ -26,10 +26,13 @@ import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.OutputStreamWriter;
 import java.io.PrintWriter;
+import java.io.StringWriter;
 import java.io.UnsupportedEncodingException;
 import java.nio.file.Files;
 import java.nio.file.attribute.BasicFileAttributes;
 import java.sql.Timestamp;
+import java.util.Date;
+import java.util.Locale;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReadWriteLock;
@@ -42,7 +45,6 @@ import java.util.logging.Handler;
 import java.util.logging.Level;
 import java.util.logging.LogManager;
 import java.util.logging.LogRecord;
-import java.util.logging.SimpleFormatter;
 import java.util.regex.Pattern;
 import java.util.zip.Deflater;
 import java.util.zip.GZIPOutputStream;
@@ -67,6 +69,8 @@ import java.util.zip.ZipOutputStream;
  * | archiveOlderThan          | -1 days                                           | how many days files are kept before being compressed
  * | purgeOlderThan            | -1 days                                           | how many days files are kept before being deleted, note: it applies on archives and not log files so 2 days of archiving and 3 days of purge makes it deleted after 5 days.
  * | compressionLevel          | -1                                                | In case of zip archiving the zip compression level (-1 for off or 0-9).
+ * | formatterPattern          | -                                                 | SimpleFormatter pattern (ignored if formatter is provided).
+ * | formatterLocale           | -                                                 | Locale to use.
  * |===
  * <p/>
  * NOTE: archiving and purging are done only when a file is rotated, it means it can be ignored during days if there is no logging activity.
@@ -172,10 +176,10 @@ public class LocalFileHandler extends Handler {
             try {
                 setFormatter(Formatter.class.cast(cl.loadClass(formatterName).newInstance()));
             } catch (final Exception e) {
-                setFormatter(new SimpleFormatter());
+                setFormatter(newSimpleFormatter(className));
             }
         } else {
-            setFormatter(new SimpleFormatter());
+            setFormatter(newSimpleFormatter(className));
         }
 
         setErrorManager(new ErrorManager());
@@ -183,6 +187,63 @@ public class LocalFileHandler extends Handler {
         lastTimestamp = System.currentTimeMillis();
     }
 
+    private Formatter newSimpleFormatter(final String className) {
+        final String defaultFormat = System.getProperty("java.util.logging.SimpleFormatter.format", "%1$tb %1$td, %1$tY %1$tl:%1$tM:%1$tS %1$Tp %2$s%n%4$s: %5$s%6$s%n");
+        final String format = getProperty(className + ".formatterPattern", defaultFormat);
+        final String locale = getProperty(className + ".formatterLocale", null);
+        return new PatternFormatter(format, locale == null ? Locale.getDefault() : newLocale(locale));
+    }
+
+    private Locale newLocale(final String str) { // LocaleUtils [lang3]
+        if (str == null) {
+            return null;
+        }
+        if (str.isEmpty()) {
+            return new Locale("", "");
+        }
+        if (str.contains("#")) {
+            throw new IllegalArgumentException("Invalid locale format: " + str);
+        }
+        final int len = str.length();
+        if (len < 2) {
+            throw new IllegalArgumentException("Invalid locale format: " + str);
+        }
+        final char ch0 = str.charAt(0);
+        if (ch0 == '_') {
+            if (len < 3) {
+                throw new IllegalArgumentException("Invalid locale format: " + str);
+            }
+            final char ch1 = str.charAt(1);
+            final char ch2 = str.charAt(2);
+            if (!Character.isUpperCase(ch1) || !Character.isUpperCase(ch2)) {
+                throw new IllegalArgumentException("Invalid locale format: " + str);
+            }
+            if (len == 3) {
+                return new Locale("", str.substring(1, 3));
+            }
+            if (len < 5) {
+                throw new IllegalArgumentException("Invalid locale format: " + str);
+            }
+            if (str.charAt(3) != '_') {
+                throw new IllegalArgumentException("Invalid locale format: " + str);
+            }
+            return new Locale("", str.substring(1, 3), str.substring(4));
+        }
+
+        final String[] split = str.split("_", -1);
+        final int occurrences = split.length -1;
+        switch (occurrences) {
+            case 0:
+                return new Locale(str.toUpperCase(Locale.ENGLISH));
+            case 1:
+                return new Locale(split[0], split[1]);
+            case 2:
+                return new Locale(split[0], split[1], split[2]);
+            default:
+                throw new IllegalArgumentException("Invalid locale format: " + str);
+        }
+    }
+
     protected String currentDate() {
         return new Timestamp(System.currentTimeMillis()).toString().substring(0, 10);
     }
@@ -550,4 +611,57 @@ public class LocalFileHandler extends Handler {
             out.close();
         }
     }
+
+    public static class PatternFormatter extends Formatter {
+        private final ThreadLocal<Date> date = new ThreadLocal<Date>() {
+            @Override
+            protected Date initialValue() {
+                return new Date();
+            }
+        };
+
+        private final String format;
+        private final Locale locale;
+
+        public PatternFormatter(final String format, final Locale locale) {
+            this.format = format;
+            this.locale = locale;
+        }
+
+        @Override
+        public String format(final LogRecord record) {
+            final Date date = this.date.get();
+            date.setTime(record.getMillis());
+
+            String source;
+            if (record.getSourceClassName() != null) {
+                source = record.getSourceClassName();
+                if (record.getSourceMethodName() != null) {
+                    source += " " + record.getSourceMethodName();
+                }
+            } else {
+                source = record.getLoggerName();
+            }
+
+            final String message = formatMessage(record);
+
+            String throwable = "";
+            final Throwable thrown = record.getThrown();
+            if (thrown != null) {
+                final StringWriter sw = new StringWriter();
+                final PrintWriter pw = new PrintWriter(sw);
+                pw.println();
+                thrown.printStackTrace(pw);
+                pw.close();
+                throwable = sw.toString();
+            }
+
+            return String.format(
+                    locale, format,
+                    date, source,
+                    record.getLoggerName(),
+                    Locale.ENGLISH == locale ? record.getLevel().getName() : record.getLevel().getLocalizedName(),
+                    message, throwable);
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/tomee/blob/1cbe8e35/tomee/tomee-juli/src/test/java/org/apache/tomee/jul/handler/rotating/LocalFileHandlerPatternFormatterTest.java
----------------------------------------------------------------------
diff --git a/tomee/tomee-juli/src/test/java/org/apache/tomee/jul/handler/rotating/LocalFileHandlerPatternFormatterTest.java b/tomee/tomee-juli/src/test/java/org/apache/tomee/jul/handler/rotating/LocalFileHandlerPatternFormatterTest.java
new file mode 100644
index 0000000..a5f7e4f
--- /dev/null
+++ b/tomee/tomee-juli/src/test/java/org/apache/tomee/jul/handler/rotating/LocalFileHandlerPatternFormatterTest.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomee.jul.handler.rotating;
+
+import org.junit.Test;
+
+import java.util.Locale;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+
+import static org.junit.Assert.assertEquals;
+
+public class LocalFileHandlerPatternFormatterTest {
+    @Test
+    public void format() {
+        final LogRecord record = new LogRecord(Level.FINE, "test message");
+        record.setLoggerName("logger");
+        record.setLevel(Level.FINER);
+        record.setMillis(123456789);
+        record.setSourceClassName("my.class.Name");
+        record.setSourceMethodName("aMethod");
+
+        // default
+        assertEquals(
+                "Jan 02, 1970 my.class.Name aMethod\nFINER: test message\n",
+                new LocalFileHandler.PatternFormatter("%1$tb %1$td, %1$tY %1$tl:%1$tM:%1$tS %1$Tp %2$s%n%4$s: %5$s%6$s%n", Locale.ENGLISH)
+                        .format(record).replace("\r", "").replaceFirst("1970.*my"/*skip time*/, "1970 my"));
+
+        // simple
+        assertEquals(
+                "test message\n",
+                new LocalFileHandler.PatternFormatter("%5$s%n", Locale.ENGLISH).format(record).replace("\r", ""));
+    }
+}