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

remm 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 22ad695  Update request start time using nanoTime
22ad695 is described below

commit 22ad69571c019f4d84ccc522298dddb4f8fa8d70
Author: remm <r...@apache.org>
AuthorDate: Thu Feb 27 16:49:04 2020 +0100

    Update request start time using nanoTime
    
    get/setStartTime are still there, not sure about existing use. Another
    patch round could deprecate them.
    Also change the access log to be the start of the request (a small part
    of 63286).
---
 TOMCAT-NEXT.txt                                    |  6 ++---
 .../apache/catalina/connector/CoyoteAdapter.java   |  7 +++---
 .../catalina/valves/AbstractAccessLogValve.java    | 16 +++++--------
 java/org/apache/coyote/AbstractProcessor.java      |  1 +
 java/org/apache/coyote/Request.java                | 10 ++++++++
 java/org/apache/coyote/RequestInfo.java            | 28 ++++++++++++----------
 java/org/apache/coyote/Response.java               |  2 +-
 java/org/apache/coyote/ajp/AjpProcessor.java       |  1 +
 .../apache/coyote/http11/Http11InputBuffer.java    |  3 +++
 java/org/apache/coyote/http2/Stream.java           |  3 +++
 webapps/docs/changelog.xml                         |  4 ++++
 11 files changed, 50 insertions(+), 31 deletions(-)

diff --git a/TOMCAT-NEXT.txt b/TOMCAT-NEXT.txt
index ab47a46..34e3adf 100644
--- a/TOMCAT-NEXT.txt
+++ b/TOMCAT-NEXT.txt
@@ -41,11 +41,9 @@ New items for 10.0.x onwards:
  4. RFC 3986 states (section 2.2) that a %nn encoded delimiter is NOT 
equivalent
     to the decoded form. Provide an option not to decode delimiters in %nn 
form.
 
- 5. BZ 56966. Refactor internal request timing to use System.nanoTime()
+ 5. BZ 63286. Make behaviour of %D and %T consistent with httpd.
 
- 6. BZ 63286. Make behaviour of %D and %T consistent with httpd.
-
- 7. Refactor DefaultServlet to use Ranges in parseRanges().
+ 6. Refactor DefaultServlet to use Ranges in parseRanges().
 
 Deferred until 10.1.x:
 
diff --git a/java/org/apache/catalina/connector/CoyoteAdapter.java 
b/java/org/apache/catalina/connector/CoyoteAdapter.java
index 1a1430b..18b8025 100644
--- a/java/org/apache/catalina/connector/CoyoteAdapter.java
+++ b/java/org/apache/catalina/connector/CoyoteAdapter.java
@@ -20,6 +20,7 @@ import java.io.IOException;
 import java.nio.charset.Charset;
 import java.nio.charset.StandardCharsets;
 import java.util.EnumSet;
+import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 import jakarta.servlet.ReadListener;
@@ -273,8 +274,8 @@ public class CoyoteAdapter implements Adapter {
             // Access logging
             if (!success || !request.isAsync()) {
                 long time = 0;
-                if (req.getStartTime() != -1) {
-                    time = System.currentTimeMillis() - req.getStartTime();
+                if (req.getStartTimeNanos() != -1) {
+                    time = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - 
req.getStartTimeNanos());
                 }
                 Context context = request.getContext();
                 if (context != null) {
@@ -402,7 +403,7 @@ public class CoyoteAdapter implements Adapter {
                 // The other possibility is that an error occurred early in
                 // processing and the request could not be mapped to a Context.
                 // Log via the host or engine in that case.
-                long time = System.currentTimeMillis() - req.getStartTime();
+                long time = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - 
req.getStartTimeNanos());
                 if (context != null) {
                     context.logAccess(request, response, time, false);
                 } else if (response.isError()) {
diff --git a/java/org/apache/catalina/valves/AbstractAccessLogValve.java 
b/java/org/apache/catalina/valves/AbstractAccessLogValve.java
index 47685ea..5cc1f03 100644
--- a/java/org/apache/catalina/valves/AbstractAccessLogValve.java
+++ b/java/org/apache/catalina/valves/AbstractAccessLogValve.java
@@ -30,6 +30,7 @@ import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 import java.util.TimeZone;
+import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 import jakarta.servlet.RequestDispatcher;
@@ -699,14 +700,9 @@ public abstract class AbstractAccessLogValve extends 
ValveBase implements Access
             return;
         }
 
-        /**
-         * XXX This is a bit silly, but we want to have start and stop time and
-         * duration consistent. It would be better to keep start and stop
-         * simply in the request and/or response object and remove time
-         * (duration) from the interface.
-         */
-        long start = request.getCoyoteRequest().getStartTime();
-        Date date = getDate(start + time);
+        long elapsed = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - 
request.getCoyoteRequest().getStartTimeNanos());
+        // Date for access log should be the beginning of the request
+        Date date = getDate(System.currentTimeMillis() - elapsed);
 
         CharArrayWriter result = charArrayWriters.pop();
         if (result == null) {
@@ -1372,8 +1368,8 @@ public abstract class AbstractAccessLogValve extends 
ValveBase implements Access
             if (commitTime == -1) {
                 buf.append('-');
             } else {
-                long delta = commitTime - 
request.getCoyoteRequest().getStartTime();
-                buf.append(Long.toString(delta));
+                long delta = commitTime - 
request.getCoyoteRequest().getStartTimeNanos();
+                
buf.append(Long.toString(TimeUnit.NANOSECONDS.toMillis(delta)));
             }
         }
     }
diff --git a/java/org/apache/coyote/AbstractProcessor.java 
b/java/org/apache/coyote/AbstractProcessor.java
index 254950e..5af3710 100644
--- a/java/org/apache/coyote/AbstractProcessor.java
+++ b/java/org/apache/coyote/AbstractProcessor.java
@@ -978,6 +978,7 @@ public abstract class AbstractProcessor extends 
AbstractProcessorLight implement
         setSocketWrapper(socketWrapper);
         // Setup the minimal request information
         request.setStartTime(System.currentTimeMillis());
+        request.setStartTimeNanos(System.nanoTime());
         // Setup the minimal response information
         response.setStatus(400);
         response.setError();
diff --git a/java/org/apache/coyote/Request.java 
b/java/org/apache/coyote/Request.java
index deff3f4..3c095cb 100644
--- a/java/org/apache/coyote/Request.java
+++ b/java/org/apache/coyote/Request.java
@@ -154,6 +154,7 @@ public final class Request {
     private long bytesRead=0;
     // Time of the request - useful to avoid repeated calls to 
System.currentTime
     private long startTime = -1;
+    private long startTimeNanos = -1;
     private int available = 0;
 
     private final RequestInfo reqProcessorMX=new RequestInfo(this);
@@ -571,6 +572,14 @@ public final class Request {
         this.startTime = startTime;
     }
 
+    public long getStartTimeNanos() {
+        return startTimeNanos;
+    }
+
+    public void setStartTimeNanos(long startTimeNanos) {
+        this.startTimeNanos = startTimeNanos;
+    }
+
     // -------------------- Per-Request "notes" --------------------
 
 
@@ -647,6 +656,7 @@ public final class Request {
         allDataReadEventSent.set(false);
 
         startTime = -1;
+        startTimeNanos = -1;
     }
 
     // -------------------- Info  --------------------
diff --git a/java/org/apache/coyote/RequestInfo.java 
b/java/org/apache/coyote/RequestInfo.java
index 30216b7..23cfb27 100644
--- a/java/org/apache/coyote/RequestInfo.java
+++ b/java/org/apache/coyote/RequestInfo.java
@@ -17,6 +17,8 @@
 
 package org.apache.coyote;
 
+import java.util.concurrent.TimeUnit;
+
 import javax.management.ObjectName;
 
 
@@ -125,11 +127,11 @@ public class RequestInfo  {
     public long getRequestProcessingTime() {
         // Not perfect, but good enough to avoid returning strange values due 
to
         // concurrent updates.
-        long startTime = req.getStartTime();
+        long startTime = req.getStartTimeNanos();
         if (getStage() == org.apache.coyote.Constants.STAGE_ENDED || startTime 
< 0) {
             return 0;
         } else {
-            return System.currentTimeMillis() - startTime;
+            return TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - 
startTime);
         }
     }
 
@@ -153,24 +155,24 @@ public class RequestInfo  {
     private long lastRequestProcessingTime = 0;
 
 
-    /** Called by the processor before recycling the request. It'll collect
+    /**
+     * Called by the processor before recycling the request. It'll collect
      * statistic information.
      */
     void updateCounters() {
-        bytesReceived+=req.getBytesRead();
-        bytesSent+=req.getResponse().getContentWritten();
+        bytesReceived += req.getBytesRead();
+        bytesSent += req.getResponse().getContentWritten();
 
         requestCount++;
-        if( req.getResponse().getStatus() >=400 )
+        if (req.getResponse().getStatus() >= 400) {
             errorCount++;
-        long t0=req.getStartTime();
-        long t1=System.currentTimeMillis();
-        long time=t1-t0;
+        }
+        long time = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - 
req.getStartTimeNanos());
         this.lastRequestProcessingTime = time;
-        processingTime+=time;
-        if( maxTime < time ) {
-            maxTime=time;
-            maxRequestUri=req.requestURI().toString();
+        processingTime += time;
+        if (maxTime < time) {
+            maxTime = time;
+            maxRequestUri = req.requestURI().toString();
         }
     }
 
diff --git a/java/org/apache/coyote/Response.java 
b/java/org/apache/coyote/Response.java
index 54a4844..9555538 100644
--- a/java/org/apache/coyote/Response.java
+++ b/java/org/apache/coyote/Response.java
@@ -258,7 +258,7 @@ public final class Response {
 
     public void setCommitted(boolean v) {
         if (v && !this.committed) {
-            this.commitTime = System.currentTimeMillis();
+            this.commitTime = System.nanoTime();
         }
         this.committed = v;
     }
diff --git a/java/org/apache/coyote/ajp/AjpProcessor.java 
b/java/org/apache/coyote/ajp/AjpProcessor.java
index a333d04..562fc67 100644
--- a/java/org/apache/coyote/ajp/AjpProcessor.java
+++ b/java/org/apache/coyote/ajp/AjpProcessor.java
@@ -395,6 +395,7 @@ public class AjpProcessor extends AbstractProcessor {
                     break;
                 }
                 request.setStartTime(System.currentTimeMillis());
+                request.setStartTimeNanos(System.nanoTime());
             } catch (IOException e) {
                 setErrorState(ErrorState.CLOSE_CONNECTION_NOW, e);
                 break;
diff --git a/java/org/apache/coyote/http11/Http11InputBuffer.java 
b/java/org/apache/coyote/http11/Http11InputBuffer.java
index 04543ef..59a01f7 100644
--- a/java/org/apache/coyote/http11/Http11InputBuffer.java
+++ b/java/org/apache/coyote/http11/Http11InputBuffer.java
@@ -378,6 +378,9 @@ public class Http11InputBuffer implements InputBuffer, 
ApplicationBufferHandler
                 if (request.getStartTime() < 0) {
                     request.setStartTime(System.currentTimeMillis());
                 }
+                if (request.getStartTimeNanos() < 0) {
+                    request.setStartTimeNanos(System.nanoTime());
+                }
                 chr = byteBuffer.get();
             } while ((chr == Constants.CR) || (chr == Constants.LF));
             byteBuffer.position(byteBuffer.position() - 1);
diff --git a/java/org/apache/coyote/http2/Stream.java 
b/java/org/apache/coyote/http2/Stream.java
index 65d636d..647ddf6 100644
--- a/java/org/apache/coyote/http2/Stream.java
+++ b/java/org/apache/coyote/http2/Stream.java
@@ -132,6 +132,9 @@ class Stream extends AbstractStream implements 
HeaderEmitter {
         if (this.coyoteRequest.getStartTime() < 0) {
             this.coyoteRequest.setStartTime(System.currentTimeMillis());
         }
+        if (this.coyoteRequest.getStartTimeNanos() < 0) {
+            this.coyoteRequest.setStartTimeNanos(System.nanoTime());
+        }
     }
 
 
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 13def23..ebe4117 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -91,6 +91,10 @@
         A zero length AJP secret will now behave as if it has not been
         specified. (remm)
       </fix>
+      <update>
+        <bug>56966</bug>: Add use of System.nanoTime to track request
+        execution time. (remm)
+      </update>
     </changelog>
   </subsection>
   <subsection name="Cluster">


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

Reply via email to