This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch 8.5.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/8.5.x by this push:
     new e931ab0  BZ 64190 Add 'proper' ms support to OneLineFormatter.
e931ab0 is described below

commit e931ab087ef4317b6fc568397aa25126964f5632
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Tue Mar 3 14:36:08 2020 +0000

    BZ 64190 Add 'proper' ms support to OneLineFormatter.
    
    S SS or SSS can now be used (once) anywhere in the format String.
    Format strings without S SS or SSS are now ~30% faster
    The current default (effectively "dd-MMM-yyyy HH:mm:ss.SSS") is within
    less than 1% of the old implementation.
    Using S SS or SSS anywhere but the very end doubles the time taken to
    generate the timestamp.
---
 java/org/apache/juli/OneLineFormatter.java         | 77 +++++++++++++++++++---
 .../TestOneLineFormatterMillisPerformance.java     | 70 ++++++++++++++++++++
 webapps/docs/changelog.xml                         |  5 ++
 3 files changed, 142 insertions(+), 10 deletions(-)

diff --git a/java/org/apache/juli/OneLineFormatter.java 
b/java/org/apache/juli/OneLineFormatter.java
index 75845cf..fad37b0 100644
--- a/java/org/apache/juli/OneLineFormatter.java
+++ b/java/org/apache/juli/OneLineFormatter.java
@@ -51,7 +51,7 @@ public class OneLineFormatter extends Formatter {
     };
 
     /* Timestamp format */
-    private static final String DEFAULT_TIME_FORMAT = "dd-MMM-yyyy HH:mm:ss";
+    private static final String DEFAULT_TIME_FORMAT = "dd-MMM-yyyy 
HH:mm:ss.SSS";
 
     /**
      * The size of our global date format cache
@@ -68,6 +68,8 @@ public class OneLineFormatter extends Formatter {
      */
     private ThreadLocal<DateFormatCache> localDateCache;
 
+    private volatile MillisHandling millisHandling = MillisHandling.APPEND;
+
 
     public OneLineFormatter() {
         String timeFormat = LogManager.getLogManager().getProperty(
@@ -86,12 +88,31 @@ public class OneLineFormatter extends Formatter {
      *                   {@link java.text.SimpleDateFormat} syntax
      */
     public void setTimeFormat(final String timeFormat) {
+        final String cachedTimeFormat;
+
+        if (timeFormat.endsWith(".SSS")) {
+            cachedTimeFormat = timeFormat.substring(0,  timeFormat.length() - 
4);
+            millisHandling = MillisHandling.APPEND;
+        } else if (timeFormat.contains("SSS")) {
+            millisHandling = MillisHandling.REPLACE_SSS;
+            cachedTimeFormat = timeFormat;
+        } else if (timeFormat.contains("SS")) {
+            millisHandling = MillisHandling.REPLACE_SS;
+            cachedTimeFormat = timeFormat;
+        } else if (timeFormat.contains("S")) {
+            millisHandling = MillisHandling.REPLACE_S;
+            cachedTimeFormat = timeFormat;
+        } else {
+            millisHandling = MillisHandling.NONE;
+            cachedTimeFormat = timeFormat;
+        }
+
         final DateFormatCache globalDateCache =
-                new DateFormatCache(globalCacheSize, timeFormat, null);
+                new DateFormatCache(globalCacheSize, cachedTimeFormat, null);
         localDateCache = new ThreadLocal<DateFormatCache>() {
             @Override
             protected DateFormatCache initialValue() {
-                return new DateFormatCache(localCacheSize, timeFormat, 
globalDateCache);
+                return new DateFormatCache(localCacheSize, cachedTimeFormat, 
globalDateCache);
             }
         };
     }
@@ -156,18 +177,45 @@ public class OneLineFormatter extends Formatter {
     }
 
     protected void addTimestamp(StringBuilder buf, long timestamp) {
-        buf.append(localDateCache.get().getFormat(timestamp));
-        long frac = timestamp % 1000;
-        buf.append('.');
-        if (frac < 100) {
-            if (frac < 10) {
+        String cachedTimeStamp = localDateCache.get().getFormat(timestamp);
+        if (millisHandling == MillisHandling.NONE) {
+            buf.append(cachedTimeStamp);
+        } else if (millisHandling == MillisHandling.APPEND) {
+            buf.append(cachedTimeStamp);
+            long frac = timestamp % 1000;
+            buf.append('.');
+            if (frac < 100) {
+                if (frac < 10) {
+                    buf.append('0');
+                    buf.append('0');
+                } else {
+                    buf.append('0');
+                }
+            }
+            buf.append(frac);
+        } else {
+            // Some version of replace
+            long frac = timestamp % 1000;
+            // Formatted string may vary in length so the insert point may vary
+            int insertStart = cachedTimeStamp.indexOf('#');
+            buf.append(cachedTimeStamp.subSequence(0, insertStart));
+            if (frac < 100 && millisHandling == MillisHandling.REPLACE_SSS) {
                 buf.append('0');
+                if (frac < 10) {
+                    buf.append('0');
+                }
+            } else if (frac < 10 && millisHandling == 
MillisHandling.REPLACE_SS) {
                 buf.append('0');
+            }
+            buf.append(frac);
+            if (millisHandling == MillisHandling.REPLACE_SSS) {
+                buf.append(cachedTimeStamp.substring(insertStart + 3));
+            } else if (millisHandling == MillisHandling.REPLACE_SS) {
+                buf.append(cachedTimeStamp.substring(insertStart + 2));
             } else {
-                buf.append('0');
+                buf.append(cachedTimeStamp.substring(insertStart + 1));
             }
         }
-        buf.append(frac);
     }
 
 
@@ -250,4 +298,13 @@ public class OneLineFormatter extends Formatter {
             super.println(x);
         }
     }
+
+
+    private static enum MillisHandling {
+        NONE,
+        APPEND,
+        REPLACE_S,
+        REPLACE_SS,
+        REPLACE_SSS,
+    }
 }
diff --git a/test/org/apache/juli/TestOneLineFormatterMillisPerformance.java 
b/test/org/apache/juli/TestOneLineFormatterMillisPerformance.java
new file mode 100644
index 0000000..b7c0cab
--- /dev/null
+++ b/test/org/apache/juli/TestOneLineFormatterMillisPerformance.java
@@ -0,0 +1,70 @@
+/*
+ * 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.juli;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+
+@RunWith(Parameterized.class)
+public class TestOneLineFormatterMillisPerformance {
+
+    @Parameterized.Parameters(name = "{index}: format[{0}]")
+    public static Collection<Object[]> parameters() {
+
+        List<Object[]> parameterSets = new ArrayList<>();
+
+        parameterSets.add(new String[] { "dd-MMM-yyyy HH:mm:ss.SSS" });
+        parameterSets.add(new String[] { "dd-MMM-yyyy HH:mm:ss.SS" });
+        parameterSets.add(new String[] { "dd-MMM-yyyy HH:mm:ss.S" });
+        parameterSets.add(new String[] { "dd-MMM-yyyy HH:mm:ss" });
+        parameterSets.add(new String[] { "dd-MMM-yyyy HH:mm:ss XXX" });
+        parameterSets.add(new String[] { "dd-MMM-yyyy HH:mm:ss.SSSXXX" });
+        parameterSets.add(new String[] { "dd-MMM-yyyy HH:mm:ss.SSXXX" });
+        parameterSets.add(new String[] { "dd-MMM-yyyy HH:mm:ss.SXXX" });
+        parameterSets.add(new String[] { "SSS dd-MMM-yyyy HH:mm:ss" });
+        parameterSets.add(new String[] { "SS dd-MMM-yyyy HH:mm:ss" });
+        parameterSets.add(new String[] { "S dd-MMM-yyyy HH:mm:ss" });
+
+        return parameterSets;
+    }
+
+
+    @Parameter(0)
+    public String timestampFormat;
+
+    @Test
+    public void testMillisHandling() {
+        OneLineFormatter olf = new OneLineFormatter();
+        olf.setTimeFormat(timestampFormat);
+
+        long timeStamp = System.currentTimeMillis();
+        StringBuilder buf = new StringBuilder(64);
+
+        long start = System.nanoTime();
+        for (int i = 0; i < 10000000; i++) {
+            buf.setLength(0);
+            olf.addTimestamp(buf, timeStamp);
+        }
+        System.out.println("Format: [" + timestampFormat + "], Output: [" + 
buf + "], Duration: [" + (System.nanoTime() - start) + "] ns");
+    }
+}
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 61dba28..3f46d73 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -170,6 +170,11 @@
         Expand the coverage of the Korean translations provided with Apache
         Tomcat. Contributions provided by B. Cansmile Cha. (markt)
       </add>
+      <add>
+        <bug>64190</bug>: Add support for specifing milliseconds (using
+        <code>S</code>, <code>SS</code> or <code>SSS</code>) in the timestamp
+        used by JULI&apos;s <code>OneLineFormatter</code>. (markt)
+      </add>
     </changelog>
   </subsection>
 </section>


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to