dmesg: adjust timestamps according to suspended time
Timestamps in kernel log comes from monotonic clocksource which does not tick when system suspended. Suspended time easily sums into hours and days rendering human readable timestamps in dmesg useless. Adjusting timestamps accouring to current delta between boottime and monotonic clocksources produces accurate timestamps for messages printed since last resume. Which are supposed to be most interesting. Signed-off-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
This commit is contained in:
parent
4d4f56baad
commit
9bf622dad9
|
@ -15,6 +15,8 @@
|
||||||
|
|
||||||
extern int get_boot_time(struct timeval *boot_time);
|
extern int get_boot_time(struct timeval *boot_time);
|
||||||
|
|
||||||
|
extern time_t get_suspended_time(void);
|
||||||
|
|
||||||
extern int gettime_monotonic(struct timeval *tv);
|
extern int gettime_monotonic(struct timeval *tv);
|
||||||
|
|
||||||
#endif /* UTIL_LINUX_MONOTONIC_H */
|
#endif /* UTIL_LINUX_MONOTONIC_H */
|
||||||
|
|
|
@ -48,6 +48,18 @@ int get_boot_time(struct timeval *boot_time)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
time_t get_suspended_time(void)
|
||||||
|
{
|
||||||
|
#if defined(CLOCK_BOOTTIME) && defined(CLOCK_MONOTONIC)
|
||||||
|
struct timespec boot, mono;
|
||||||
|
|
||||||
|
if (clock_gettime(CLOCK_BOOTTIME, &boot) == 0 &&
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &mono) == 0)
|
||||||
|
return boot.tv_sec - mono.tv_sec;
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int gettime_monotonic(struct timeval *tv)
|
int gettime_monotonic(struct timeval *tv)
|
||||||
{
|
{
|
||||||
#ifdef CLOCK_MONOTONIC
|
#ifdef CLOCK_MONOTONIC
|
||||||
|
|
|
@ -161,6 +161,8 @@ source used for the logs is
|
||||||
.B not updated after
|
.B not updated after
|
||||||
system
|
system
|
||||||
.BR SUSPEND / RESUME .
|
.BR SUSPEND / RESUME .
|
||||||
|
Timestamps are adjusted according to current delta between boottime and monotonic
|
||||||
|
clocks, this works only for messages printed after last resume.
|
||||||
.IP "\fB\-t\fR, \fB\-\-notime\fR"
|
.IP "\fB\-t\fR, \fB\-\-notime\fR"
|
||||||
Do not print kernel's timestamps.
|
Do not print kernel's timestamps.
|
||||||
.IP "\fB\-\-time\-format\fR \fIformat\fR"
|
.IP "\fB\-\-time\-format\fR \fIformat\fR"
|
||||||
|
|
|
@ -169,6 +169,7 @@ struct dmesg_control {
|
||||||
struct timeval lasttime; /* last printed timestamp */
|
struct timeval lasttime; /* last printed timestamp */
|
||||||
struct tm lasttm; /* last localtime */
|
struct tm lasttm; /* last localtime */
|
||||||
struct timeval boot_time; /* system boot time */
|
struct timeval boot_time; /* system boot time */
|
||||||
|
time_t suspended_time; /* time spent in suspeneded state */
|
||||||
|
|
||||||
int action; /* SYSLOG_ACTION_* */
|
int action; /* SYSLOG_ACTION_* */
|
||||||
int method; /* DMESG_METHOD_* */
|
int method; /* DMESG_METHOD_* */
|
||||||
|
@ -824,7 +825,7 @@ static struct tm *record_localtime(struct dmesg_control *ctl,
|
||||||
struct dmesg_record *rec,
|
struct dmesg_record *rec,
|
||||||
struct tm *tm)
|
struct tm *tm)
|
||||||
{
|
{
|
||||||
time_t t = ctl->boot_time.tv_sec + rec->tv.tv_sec;
|
time_t t = ctl->boot_time.tv_sec + ctl->suspended_time + rec->tv.tv_sec;
|
||||||
return localtime_r(&t, tm);
|
return localtime_r(&t, tm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -852,7 +853,7 @@ static char *iso_8601_time(struct dmesg_control *ctl, struct dmesg_record *rec,
|
||||||
char *buf, size_t bufsz)
|
char *buf, size_t bufsz)
|
||||||
{
|
{
|
||||||
struct timeval tv = {
|
struct timeval tv = {
|
||||||
.tv_sec = ctl->boot_time.tv_sec + rec->tv.tv_sec,
|
.tv_sec = ctl->boot_time.tv_sec + ctl->suspended_time + rec->tv.tv_sec,
|
||||||
.tv_usec = rec->tv.tv_usec
|
.tv_usec = rec->tv.tv_usec
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1301,8 +1302,16 @@ static inline int dmesg_get_boot_time(struct timeval *tv)
|
||||||
|
|
||||||
return get_boot_time(tv);
|
return get_boot_time(tv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline time_t dmesg_get_suspended_time(void)
|
||||||
|
{
|
||||||
|
if (getenv("DMESG_TEST_BOOTIME"))
|
||||||
|
return 0;
|
||||||
|
return get_suspended_time();
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
# define dmesg_get_boot_time get_boot_time
|
# define dmesg_get_boot_time get_boot_time
|
||||||
|
# define dmesg_get_suspended_time get_suspended_time
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
|
@ -1499,9 +1508,12 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
if ((is_timefmt(&ctl, RELTIME) ||
|
if ((is_timefmt(&ctl, RELTIME) ||
|
||||||
is_timefmt(&ctl, CTIME) ||
|
is_timefmt(&ctl, CTIME) ||
|
||||||
is_timefmt(&ctl, ISO8601))
|
is_timefmt(&ctl, ISO8601))) {
|
||||||
&& dmesg_get_boot_time(&ctl.boot_time) != 0)
|
if (dmesg_get_boot_time(&ctl.boot_time) != 0)
|
||||||
ctl.time_fmt = DMESG_TIMEFTM_NONE;
|
ctl.time_fmt = DMESG_TIMEFTM_NONE;
|
||||||
|
else
|
||||||
|
ctl.suspended_time = dmesg_get_suspended_time();
|
||||||
|
}
|
||||||
|
|
||||||
if (delta)
|
if (delta)
|
||||||
switch (ctl.time_fmt) {
|
switch (ctl.time_fmt) {
|
||||||
|
|
Loading…
Reference in New Issue