]> granicus.if.org Git - apache/commitdiff
Add microsecond timestamps to the error log.
authorRainer Jung <rjung@apache.org>
Mon, 7 Jun 2010 12:30:05 +0000 (12:30 +0000)
committerRainer Jung <rjung@apache.org>
Mon, 7 Jun 2010 12:30:05 +0000 (12:30 +0000)
The new function ap_recent_ctime_ex allows for
optional formatting hints. It checks the provided buffer
length and returns the number of consumed bytes. This is necessary,
because when using options, the length of the formatted time string
is no longer constant.

The only option implemented currently is the addition of microsecond
fractions to the timestamp.

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@952203 13f79535-47bb-0310-9956-ffa450edef68

include/util_time.h
server/log.c
server/util_time.c

index c99602da9489a00ffe8f1f6dec666d9db68d6d6c..16706cff865ab5bb2da519e6e26a557afb911c7a 100644 (file)
@@ -40,6 +40,13 @@ extern "C" {
  */
 #define AP_TIME_RECENT_THRESHOLD 15
 
+/* Options for ap_recent_ctime_ex */
+/* No extension */
+#define AP_CTIME_OPTION_NONE    0x0
+/* Add sub second timestamps with micro second resolution */
+#define AP_CTIME_OPTION_USEC    0x1
+
+
 /**
  * convert a recent time to its human readable components in local timezone
  * @param tm the exploded time
@@ -73,9 +80,26 @@ AP_DECLARE(apr_status_t) ap_explode_recent_gmt(apr_time_exp_t *tm,
  * format a recent timestamp in the ctime() format.
  * @param date_str String to write to.
  * @param t the time to convert 
+ * @note Consider using ap_recent_ctime_ex instead.
+ * @return APR_SUCCESS iff successful
  */
 AP_DECLARE(apr_status_t) ap_recent_ctime(char *date_str, apr_time_t t);
 
+
+/**
+ * format a recent timestamp in an extended ctime() format.
+ * @param date_str String to write to.
+ * @param t the time to convert 
+ * @param option Additional formatting options (AP_CTIME_OPTION_*).
+ * @param len Pointer to an int containing the length of the provided buffer.
+ *        On successful return it contains the number of bytes written to the
+ *        buffer.
+ * @return APR_SUCCESS iff successful, APR_ENOMEM if buffer was to short.
+ */
+AP_DECLARE(apr_status_t) ap_recent_ctime_ex(char *date_str, apr_time_t t,
+                                            int option, int *len);
+
+
 /**
  * format a recent timestamp in the RFC822 format
  * @param date_str String to write to (must have length >= APR_RFC822_DATE_LEN)
index 39d6f6bf60d4c27ec899a2070090c183edbd2a3a..2ed087d74e2ed1c2c25a65aac71258f18ab7fc39 100644 (file)
@@ -609,11 +609,16 @@ static void log_error_core(const char *file, int line, int module_index,
     }
 
     if (logf && ((level & APLOG_STARTUP) != APLOG_STARTUP)) {
+        int time_len;
+
         errstr[0] = '[';
-        ap_recent_ctime(errstr + 1, apr_time_now());
-        errstr[1 + APR_CTIME_LEN - 1] = ']';
-        errstr[1 + APR_CTIME_LEN    ] = ' ';
-        len = 1 + APR_CTIME_LEN + 1;
+        len = 1;
+        time_len = MAX_STRING_LEN - len;
+        ap_recent_ctime_ex(errstr + len, apr_time_now(),
+                           AP_CTIME_OPTION_USEC, &time_len);
+        len += time_len -1;
+        errstr[len++] = ']';
+        errstr[len++] = ' ';
     } else {
         len = 0;
     }
index 172cfa52a2b21db83abc22c812d52cdfb37cadc2..4e0df9912e20fda045562fa2e30e4eb2e935046a 100644 (file)
 
 #include "util_time.h"
 
+
+/* Number of characters needed to format the microsecond part of a timestamp.
+ * Microseconds have 6 digits plus one separator character makes 7.
+ *   */
+#define AP_CTIME_USEC_LENGTH      7
+
+
 /* Cache for exploded values of recent timestamps
  */
 
@@ -144,6 +151,13 @@ AP_DECLARE(apr_status_t) ap_explode_recent_gmt(apr_time_exp_t * tm,
 }
 
 AP_DECLARE(apr_status_t) ap_recent_ctime(char *date_str, apr_time_t t)
+{
+    int len = APR_CTIME_LEN;
+    return ap_recent_ctime_ex(date_str, t, AP_CTIME_OPTION_NONE, &len);
+}
+
+AP_DECLARE(apr_status_t) ap_recent_ctime_ex(char *date_str, apr_time_t t,
+                                            int option, int *len)
 {
     /* ### This code is a clone of apr_ctime(), except that it
      * uses ap_explode_recent_localtime() instead of apr_time_exp_lt().
@@ -151,9 +165,28 @@ AP_DECLARE(apr_status_t) ap_recent_ctime(char *date_str, apr_time_t t)
     apr_time_exp_t xt;
     const char *s;
     int real_year;
+    int needed;
+
+
+    /* Calculate the needed buffer length */
+    needed = APR_CTIME_LEN;
+    if (option & AP_CTIME_OPTION_USEC) {
+        needed += AP_CTIME_USEC_LENGTH;
+    }
+
+    /* Check the provided buffer length */
+    if (len && *len >= needed) {
+        *len = needed;
+    }
+    else {
+        if (len != NULL) {
+            *len = 0;
+        }
+        return APR_ENOMEM;
+    }
 
-    /* example: "Wed Jun 30 21:49:08 1993" */
-    /*           123456789012345678901234  */
+    /* example without options: "Wed Jun 30 21:49:08 1993" */
+    /*                           123456789012345678901234  */
 
     ap_explode_recent_localtime(&xt, t);
     s = &apr_day_snames[xt.tm_wday][0];
@@ -177,6 +210,15 @@ AP_DECLARE(apr_status_t) ap_recent_ctime(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) {
+        int div;
+        int usec = (int)xt.tm_usec;
+        *date_str++ = '.';
+        for (div=100000; div>0; div=div/10) {
+            *date_str++ = usec / div + '0';
+            usec = usec % div;
+        }
+    }
     *date_str++ = ' ';
     real_year = 1900 + xt.tm_year;
     *date_str++ = real_year / 1000 + '0';