]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
dmesg: add --since and --until
authorKarel Zak <kzak@redhat.com>
Wed, 21 Oct 2020 10:03:45 +0000 (12:03 +0200)
committerKarel Zak <kzak@redhat.com>
Wed, 21 Oct 2020 10:09:18 +0000 (12:09 +0200)
$ date
Wed 21 Oct 2020 12:05:07 PM CEST

$ dmesg --ctime --since '1 hour ago'
[Wed Oct 21 11:47:13 2020] AAA
[Wed Oct 21 11:55:48 2020] BBB

$ dmesg --ctime --since '1 hour ago' --until '10 minutes ago'
[Wed Oct 21 11:47:13 2020] AAA

Addresses: https://github.com/karelzak/util-linux/issues/1166
Signed-off-by: Karel Zak <kzak@redhat.com>
bash-completion/dmesg
sys-utils/dmesg.1
sys-utils/dmesg.c

index 02f2fc7a62d47612f17f37f2403f577ce5b557f5..00772993c25b73bf46f51f4ab932852084b61d8c 100644 (file)
@@ -57,6 +57,8 @@ _dmesg_module()
                --follow
                --follow-new
                --decode
+               --since
+               --until
                --help
                --version"
        COMPREPLY=( $(compgen -W "${OPTS[*]}" -- $cur) )
index 4bec7892bb90e4500c9f05fd4a4206962a8aeb5a..b38766826c1ee1822166b9336efa70c42d574582 100644 (file)
@@ -162,6 +162,14 @@ system
 .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\-\-since \fItime\fR"
+Display record since the specified time.  The time is possible to specify in absolute way
+as well as by relative notation (e.g. '1 hour ago').  Be aware that the timestamp could
+be inaccurate and see \fB\-\-ctime\fR for more details.
+.IP "\fB\-\-until \fItime\fR"
+Display record until the specified time.  The time is possible to specify in absolute way
+as well as by relative notation (e.g. '1 hour ago').  Be aware that the timestamp could
+be inaccurate and see \fB\-\-ctime\fR for more details.
 .IP "\fB\-t\fR, \fB\-\-notime\fR"
 Do not print kernel's timestamps.
 .IP "\fB\-\-time\-format\fR \fIformat\fR"
index c7759857e274ef20075dcd67c4a8390e69e12a25..fa1dd2dffce5a6b2da659039d600af7bdcc0417c 100644 (file)
@@ -180,6 +180,9 @@ struct dmesg_control {
        ssize_t         kmsg_first_read;/* initial read() return code */
        char            kmsg_buf[BUFSIZ];/* buffer to read kmsg data */
 
+       time_t          since;          /* filter records by time */
+       time_t          until;          /* filter records by time */
+
        /*
         * For the --file option we mmap whole file. The unnecessary (already
         * printed) pages are always unmapped. The result is that we have in
@@ -303,6 +306,9 @@ static void __attribute__((__noreturn__)) usage(void)
        fputs(_("     --time-format <format>  show timestamp using the given format:\n"
                "                               [delta|reltime|ctime|notime|iso]\n"
                "Suspending/resume will make ctime and iso timestamps inaccurate.\n"), out);
+       fputs(_("     --since <time>          display the lines since the specified time\n"), out);
+       fputs(_("     --until <time>          display the lines until the specified time\n"), out);
+
        fputs(USAGE_SEPARATOR, out);
        printf(USAGE_HELP_OPTIONS(29));
        fputs(_("\nSupported log facilities:\n"), out);
@@ -778,6 +784,11 @@ static int get_next_syslog_record(struct dmesg_control *ctl,
        return 1;
 }
 
+static time_t record_time(struct dmesg_control *ctl, struct dmesg_record *rec)
+{
+       return ctl->boot_time.tv_sec + ctl->suspended_time + rec->tv.tv_sec;
+}
+
 static int accept_record(struct dmesg_control *ctl, struct dmesg_record *rec)
 {
        if (ctl->fltr_lev && (rec->facility < 0 ||
@@ -788,6 +799,12 @@ static int accept_record(struct dmesg_control *ctl, struct dmesg_record *rec)
                              !isset(ctl->facilities, rec->facility)))
                return 0;
 
+       if (ctl->since && ctl->since >= record_time(ctl, rec))
+               return 0;
+
+       if (ctl->until && ctl->until <= record_time(ctl, rec))
+               return 0;
+
        return 1;
 }
 
@@ -825,7 +842,7 @@ static struct tm *record_localtime(struct dmesg_control *ctl,
                                   struct dmesg_record *rec,
                                   struct tm *tm)
 {
-       time_t t = ctl->boot_time.tv_sec + ctl->suspended_time + rec->tv.tv_sec;
+       time_t t = record_time(ctl, rec);
        return localtime_r(&t, tm);
 }
 
@@ -1333,7 +1350,9 @@ int main(int argc, char *argv[])
        int colormode = UL_COLORMODE_UNDEF;
        enum {
                OPT_TIME_FORMAT = CHAR_MAX + 1,
-               OPT_NOESC
+               OPT_NOESC,
+               OPT_SINCE,
+               OPT_UNTIL
        };
 
        static const struct option longopts[] = {
@@ -1352,6 +1371,7 @@ int main(int argc, char *argv[])
                { "help",          no_argument,       NULL, 'h' },
                { "kernel",        no_argument,       NULL, 'k' },
                { "level",         required_argument, NULL, 'l' },
+               { "since",         required_argument, NULL, OPT_SINCE },
                { "syslog",        no_argument,       NULL, 'S' },
                { "raw",           no_argument,       NULL, 'r' },
                { "read-clear",    no_argument,       NULL, 'c' },
@@ -1361,6 +1381,7 @@ int main(int argc, char *argv[])
                { "noescape",      no_argument,       NULL, OPT_NOESC },
                { "notime",        no_argument,       NULL, 't' },
                { "nopager",       no_argument,       NULL, 'P' },
+               { "until",         required_argument, NULL, OPT_UNTIL },
                { "userspace",     no_argument,       NULL, 'u' },
                { "version",       no_argument,       NULL, 'V' },
                { "time-format",   required_argument, NULL, OPT_TIME_FORMAT },
@@ -1491,7 +1512,22 @@ int main(int argc, char *argv[])
                case OPT_NOESC:
                        ctl.noesc = 1;
                        break;
-
+               case OPT_SINCE:
+               {
+                       usec_t p;
+                       if (parse_timestamp(optarg, &p) < 0)
+                               errx(EXIT_FAILURE, _("invalid time value \"%s\""), optarg);
+                       ctl.since = (time_t) (p / 1000000);
+                       break;
+               }
+               case OPT_UNTIL:
+               {
+                       usec_t p;
+                       if (parse_timestamp(optarg, &p) < 0)
+                               errx(EXIT_FAILURE, _("invalid time value \"%s\""), optarg);
+                       ctl.until = (time_t) (p / 1000000);
+                       break;
+               }
                case 'h':
                        usage();
                case 'V':