diff options
author | Rainer Jung <rjung@apache.org> | 2010-06-07 12:30:05 +0000 |
---|---|---|
committer | Rainer Jung <rjung@apache.org> | 2010-06-07 12:30:05 +0000 |
commit | 3a00cf67f3709b198370bb159f3cc05863160fb3 (patch) | |
tree | 718d4e8550ffc04626e564e29c42b7efa718ef41 | |
parent | 8909a59a12817e20f500aac712d8d5717f0c8ddb (diff) | |
download | httpd-3a00cf67f3709b198370bb159f3cc05863160fb3.tar.gz |
Add microsecond timestamps to the error log.
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
-rw-r--r-- | include/util_time.h | 24 | ||||
-rw-r--r-- | server/log.c | 13 | ||||
-rw-r--r-- | server/util_time.c | 46 |
3 files changed, 77 insertions, 6 deletions
diff --git a/include/util_time.h b/include/util_time.h index c99602da94..16706cff86 100644 --- a/include/util_time.h +++ b/include/util_time.h @@ -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) diff --git a/server/log.c b/server/log.c index 39d6f6bf60..2ed087d74e 100644 --- a/server/log.c +++ b/server/log.c @@ -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; } diff --git a/server/util_time.c b/server/util_time.c index 172cfa52a2..4e0df9912e 100644 --- a/server/util_time.c +++ b/server/util_time.c @@ -16,6 +16,13 @@ #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 */ @@ -145,15 +152,41 @@ 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(). */ 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'; |