You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2020/03/03 14:36:40 UTC
[tomcat] branch master updated: BZ 64190 Add 'proper' ms support to
OneLineFormatter.
This is an automated email from the ASF dual-hosted git repository.
markt pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/master by this push:
new 4ad0a71 BZ 64190 Add 'proper' ms support to OneLineFormatter.
4ad0a71 is described below
commit 4ad0a71bc11de50e0fe23fc38e6e67f134aa0589
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 cf486e2..38a525b 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -160,6 +160,11 @@
Expand the coverage of the French translations provided with Apache
Tomcat. (remm)
</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's <code>OneLineFormatter</code>. (markt)
+ </add>
</changelog>
</subsection>
</section>
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org
Re: [tomcat] branch master updated: BZ 64190 Add 'proper' ms support
to OneLineFormatter.
Posted by Mark Thomas <ma...@apache.org>.
On 04/03/2020 17:27, Christopher Schultz wrote:
> Mark,
>
> On 3/3/20 09:36, markt@apache.org wrote:
>> This is an automated email from the ASF dual-hosted git
>> repository.
>
>> markt pushed a commit to branch master in repository
>> https://gitbox.apache.org/repos/asf/tomcat.git
>
>
>> The following commit(s) were added to refs/heads/master by this
>> push: new 4ad0a71 BZ 64190 Add 'proper' ms support to
>> OneLineFormatter. 4ad0a71 is described below
>
>> commit 4ad0a71bc11de50e0fe23fc38e6e67f134aa0589 Author: Mark Thomas
>> <ma...@apache.org> AuthorDate: Tue Mar 3 14:36:08 2020 +0000
>
>> BZ 64190 Add 'proper' ms support to OneLineFormatter.
<snip/>
>> int insertStart = cachedTimeStamp.indexOf('#');
>
> Should the literal '#' be the DateFormatCache.msecPattern constant
> instead? It's unlikely to change, but it's slightly less "magic
> character"-ish if you reference the constant.
Yes, that would be better.
Mark
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org
Re: [tomcat] branch master updated: BZ 64190 Add 'proper' ms support
to OneLineFormatter.
Posted by Christopher Schultz <ch...@christopherschultz.net>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
Mark,
On 3/3/20 09:36, markt@apache.org wrote:
> This is an automated email from the ASF dual-hosted git
> repository.
>
> markt pushed a commit to branch master in repository
> https://gitbox.apache.org/repos/asf/tomcat.git
>
>
> The following commit(s) were added to refs/heads/master by this
> push: new 4ad0a71 BZ 64190 Add 'proper' ms support to
> OneLineFormatter. 4ad0a71 is described below
>
> commit 4ad0a71bc11de50e0fe23fc38e6e67f134aa0589 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('#');
Should the literal '#' be the DateFormatCache.msecPattern constant
instead? It's unlikely to change, but it's slightly less "magic
character"-ish if you reference the constant.
- -chris
-----BEGIN PGP SIGNATURE-----
Comment: Using GnuPG with Thunderbird - https://www.enigmail.net/
iQIyBAEBCAAdFiEEMmKgYcQvxMe7tcJcHPApP6U8pFgFAl5f5RQACgkQHPApP6U8
pFh7tg/1GQOhbIMta5RdMwrNVuF6W+HuXDJsTWPg8gk+qkAHhy/aTtJT6MwTAhVs
wuJk12LkNLjP8PNDAyOXtkSZNQPH3Qjt3z+d5gtW0wSIqpluHKPwDCsbLv7ZobMr
mEUcwcH17h0IGNm2OC0qIU9i3MQ1NMf4/myuqMaW7nheukwYEQTxclNJCuJA98cM
ZK3sgsVTue07XZgtmaf7FO+PwQoQwbzkA5abht4Ia6mAgyeHEZpjXxWaV+Q+a/pf
pUhpYHGkEg2TfJqEaw56vt9lwnSR+yKFKb3p1NoItlSJGJRhh+/CH35bRPzUi6lF
b6W5A9Q5D8azOQ7u64d31nCUuxVZm3X4gktZaZl0wwGo6cn5xieAHUllIOSmMZ1A
17DR7vsVZBRgk/ieh9kW1jlW1FSzdCT0phkLNk1dYDmf8n16PHJTQw/MgX8Ziwzz
YIeA7LBFys8+frOHLwH5YMyqaZDMpciikDAOP+j5+NHOqMBzJ9nsNIkYbVk5riPu
XBSB927xpEkN1/ir1yIRyrCU+4ctCytQXEkzbEflL2pdXu2e9+sKewpEsaKlN8eN
9XHZe4cReSHbEvZYJNXoZH4EEo2TXYExcxDepMX5RKvGe5mQzxYT7aWnYnb/et0/
CtCihP25QArKO6661RG8YFpzlvBcdLhTQX/WouTNAyF4JiseFg==
=MhoK
-----END PGP SIGNATURE-----
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org