]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
Merge r1931452, r1931453 from trunk:
authorJoe Orton <jorton@apache.org>
Tue, 2 Jun 2026 13:54:17 +0000 (13:54 +0000)
committerJoe Orton <jorton@apache.org>
Tue, 2 Jun 2026 13:54:17 +0000 (13:54 +0000)
core: Add millisecond support to ErrorLogFormat time specifiers

%{m} prints the timestamp in millisecond-resolution.

* include/util_time.h:
  Define new AP_CTIME_OPTION_MSEC option for printing time in milliseconds
  format.

* server/util_time.c (ap_recent_ctime_ex):
  Handle AP_CTIME_OPTION_MSEC to print time in a millisecond format.

* server/log.c (log_ctime):
  Recognize the m time option in both fast-path and composite %{...}t formats.

Submitted by: Luboš Uhliarik <luhliari redhat.com>

* server/log.c (log_ctime): Fix syntax error in r1931452
  (added by me when tweaking whitespace, not from the PR author).

Reviewed by: jorton, covener, jim
Github: closes #599

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1934884 13f79535-47bb-0310-9956-ffa450edef68

changes-entries/log-msec.txt [new file with mode: 0644]
docs/manual/mod/core.xml
include/util_time.h
server/log.c
server/util_time.c

diff --git a/changes-entries/log-msec.txt b/changes-entries/log-msec.txt
new file mode 100644 (file)
index 0000000..dd4567e
--- /dev/null
@@ -0,0 +1,3 @@
+  *) core: Add support for %{m}t in ErrorLogFormat to log milli-second
+     time resolution (in addition to existing %{u}t for micro-seconds).
+     [Luboš Uhliarik <luhliari redhat.com>]
index 7d109f2106afb60d9318959408e95bdf4d27e3ba..f8381904534993178eb3cfa2149d2ec0b3051e70 100644 (file)
@@ -1795,6 +1795,9 @@ ErrorLogFormat "[%t] [%l] [pid %P] %F: %E: [client %a] %M"
     <tr><td><code>%{u}t</code></td>
         <td>The current time including micro-seconds</td></tr>
 
+    <tr><td><code>%{m}t</code></td>
+        <td>The current time including milliseconds</td></tr>
+
     <tr><td><code>%{cu}t</code></td>
         <td>The current time in ISO 8601 extended format (compact), including
             micro-seconds</td></tr>
index 92082182e3caf6da6415c71813f926a1c0f371de..7305a3e0a00fb5f26c0773df8e55d5864eaf5935 100644 (file)
@@ -49,6 +49,8 @@ extern "C" {
 #define AP_CTIME_OPTION_COMPACT 0x2
 /* Add timezone offset from GMT ([+-]hhmm) */
 #define AP_CTIME_OPTION_GMTOFF  0x4
+/* Add sub second timestamps with millisecond resolution */
+#define AP_CTIME_OPTION_MSEC    0x8
 
 
 /**
index 9576d071c275dcca8432c2748014237786e2acf2..438171d113d1fc3269be21cb977772913dd0f2fa 100644 (file)
@@ -664,9 +664,15 @@ static int log_ctime(const ap_errorlog_info *info, const char *arg,
         if (arg[0] == 'u' && !arg[1]) { /* no ErrorLogFormat (fast path) */
             option |= AP_CTIME_OPTION_USEC;
         }
-        else if (!ap_strchr_c(arg, '%')) { /* special "%{cuz}t" formats */
+        else if (arg[0] == 'm' && !arg[1]) { /* no ErrorLogFormat (fast path) - msec */
+            option |= AP_CTIME_OPTION_MSEC;
+        }
+        else if (!ap_strchr_c(arg, '%')) { /* special "%{mcuz}t" formats */
             while (*arg) {
                 switch (*arg++) {
+                case 'm':
+                    option |= AP_CTIME_OPTION_MSEC;
+                    break;
                 case 'u':
                     option |= AP_CTIME_OPTION_USEC;
                     break;
index 299b53c25354051c9b31363bbd9cfe1a9e2fb19f..51f1e32d0f650601817d60bd847fa054842b64f2 100644 (file)
  *   */
 #define AP_CTIME_USEC_LENGTH      7
 
+/* Number of characters needed to format the millisecond part of a timestamp.
+ * Milliseconds have 3 digits plus one separator character makes 4.
+ *   */
+#define AP_CTIME_MSEC_LENGTH      4
+
 /* Length of ISO 8601 date/time (including trailing '\0') */
 #define AP_CTIME_COMPACT_LEN      20
 
@@ -182,6 +187,9 @@ AP_DECLARE(apr_status_t) ap_recent_ctime_ex(char *date_str, apr_time_t t,
     if (option & AP_CTIME_OPTION_USEC) {
         needed += AP_CTIME_USEC_LENGTH;
     }
+    else if (option & AP_CTIME_OPTION_MSEC) {
+        needed += AP_CTIME_MSEC_LENGTH;
+    }
 
     if (option & AP_CTIME_OPTION_GMTOFF) {
         needed += AP_CTIME_GMTOFF_LEN;
@@ -242,11 +250,16 @@ AP_DECLARE(apr_status_t) ap_recent_ctime_ex(char *date_str, apr_time_t t,
     *date_str++ = ':';
     *date_str++ = xt.tm_sec / 10 + '0';
     *date_str++ = xt.tm_sec % 10 + '0';
-    if (option & AP_CTIME_OPTION_USEC) {
+    if (option & (AP_CTIME_OPTION_USEC|AP_CTIME_OPTION_MSEC)) {
         int div;
         int usec = (int)xt.tm_usec;
         *date_str++ = '.';
-        for (div=100000; div>0; div=div/10) {
+        div = 100000;
+        if (!(option & AP_CTIME_OPTION_USEC)) {
+            usec = usec / 1000;
+            div = 100;
+        }
+        for (; div>0; div=div/10) {
             *date_str++ = usec / div + '0';
             usec = usec % div;
         }