diff options
author | Csaba Henk <csaba@redhat.com> | 2020-03-12 08:20:31 +0100 |
---|---|---|
committer | Xavi Hernandez <xhernandez@redhat.com> | 2020-06-15 12:41:10 +0000 |
commit | 9a4f91abc07e77165baa7f0499a4887ec9f3e4fe (patch) | |
tree | 95b8f0d685674b85283a9f683f716d95b5636c50 /libglusterfs/src/glusterfs | |
parent | 71dd19f710b81136f318b3a95ae430971198ee70 (diff) |
Indicate timezone offsets in timestamps
Logs and other output carrying timestamps
will have now timezone offsets indicated, eg.:
[2020-03-12 07:01:05.584482 +0000] I [MSGID: 106143] [glusterd-pmap.c:388:pmap_registry_remove] 0-pmap: removing brick (null) on port 49153
To this end,
- gf_time_fmt() now inserts timezone offset via %z strftime(3) template.
- A new utility function has been added, gf_time_fmt_tv(), that
takes a struct timeval pointer (*tv) instead of a time_t value to
specify the time. If tv->tv_usec is negative,
gf_time_fmt_tv(... tv ...)
is equivalent to
gf_time_fmt(... tv->tv_sec ...)
Otherwise it also inserts tv->tv_usec to the formatted string.
- Building timestamps of usec precision has been converted to
gf_time_fmt_tv, which is necessary because the method of appending
a period and the usec value to the end of the timestamp does not work
if the timestamp has zone offset, but it's also beneficial in terms of
eliminating repetition.
- The buffer passed to gf_time_fmt/gf_time_fmt_tv has been unified to
be of GF_TIMESTR_SIZE size (256). We need slightly larger buffer space
to accommodate the zone offset and it's preferable to use a buffer
which is undisputedly large enough.
This change does *not* do the following:
- Retaining a method of timestamp creation without timezone offset.
As to my understanding we don't need such backward compatibility
as the code just emits timestamps to logs and other diagnostic
texts, and doesn't do any later processing on them that would rely
on their format. An exception to this, ie. a case where timestamp
is built for internal use, is graph.c:fill_uuid(). As far as I can
see, what matters in that case is the uniqueness of the produced
string, not the format.
- Implementing a single-token (space free) timestamp format.
While some timestamp formats used to be single-token, now all of
them will include a space preceding the offset indicator. Again,
I did not see a use case where this could be significant in terms
of representation.
- Moving the codebase to a single unified timestamp format and
dropping the fmt argument of gf_time_fmt/gf_time_fmt_tv.
While the gf_timefmt_FT format is almost ubiquitous, there are
a few cases where different formats are used. I'm not convinced
there is any reason to not use gf_timefmt_FT in those cases too,
but I did not want to make a decision in this regard.
Change-Id: I0af73ab5d490cca7ed8d07a2ce7ac22a6df2920a
Updates: #837
Signed-off-by: Csaba Henk <csaba@redhat.com>
Diffstat (limited to 'libglusterfs/src/glusterfs')
-rw-r--r-- | libglusterfs/src/glusterfs/common-utils.h | 33 |
1 files changed, 29 insertions, 4 deletions
diff --git a/libglusterfs/src/glusterfs/common-utils.h b/libglusterfs/src/glusterfs/common-utils.h index 13e413c3632..69c258d678f 100644 --- a/libglusterfs/src/glusterfs/common-utils.h +++ b/libglusterfs/src/glusterfs/common-utils.h @@ -148,6 +148,9 @@ trap(void); #define GF_THREAD_NAME_LIMIT 16 #define GF_THREAD_NAME_PREFIX "glfs_" +/* Advisory buffer size for formatted timestamps (see gf_time_fmt) */ +#define GF_TIMESTR_SIZE 256 + /* * we could have initialized these as +ve values and treated * them as negative while comparing etc.. (which would have @@ -790,7 +793,7 @@ typedef enum { } gf_timefmts; static inline char * -gf_time_fmt(char *dst, size_t sz_dst, time_t utime, unsigned int fmt) +gf_time_fmt_tv(char *dst, size_t sz_dst, struct timeval *tv, unsigned int fmt) { extern void _gf_timestuff(const char ***, const char ***); static gf_timefmts timefmt_last = (gf_timefmts)-1; @@ -798,6 +801,8 @@ gf_time_fmt(char *dst, size_t sz_dst, time_t utime, unsigned int fmt) static const char **zeros; struct tm tm, *res; int localtime = 0; + int len = 0; + int pos = 0; if (timefmt_last == ((gf_timefmts)-1)) { _gf_timestuff(&fmts, &zeros); @@ -807,15 +812,35 @@ gf_time_fmt(char *dst, size_t sz_dst, time_t utime, unsigned int fmt) fmt = gf_timefmt_default; } localtime = gf_log_get_localtime(); - res = localtime ? localtime_r(&utime, &tm) : gmtime_r(&utime, &tm); - if (utime && (res != NULL)) { - strftime(dst, sz_dst, fmts[fmt], &tm); + res = localtime ? localtime_r(&tv->tv_sec, &tm) + : gmtime_r(&tv->tv_sec, &tm); + if (tv->tv_sec && (res != NULL)) { + len = strftime(dst, sz_dst, fmts[fmt], &tm); + if (len == 0) + return dst; + pos += len; + if (tv->tv_usec >= 0) { + len = snprintf(dst + pos, sz_dst - pos, ".%" GF_PRI_SUSECONDS, + tv->tv_usec); + if (len >= sz_dst - pos) + return dst; + pos += len; + } + strftime(dst + pos, sz_dst - pos, " %z", &tm); } else { strncpy(dst, "N/A", sz_dst); } return dst; } +static inline char * +gf_time_fmt(char *dst, size_t sz_dst, time_t utime, unsigned int fmt) +{ + struct timeval tv = {utime, -1}; + + return gf_time_fmt_tv(dst, sz_dst, &tv, fmt); +} + /* This function helps us use gfid (unique identity) to generate inode's unique * number in glusterfs. */ |