[systemd-devel] [PATCH] journalctl: add --reverse option to show the newest lines first

Lennart Poettering lennart at poettering.net
Fri Mar 1 04:14:43 PST 2013


On Fri, 01.03.13 10:27, Lukas Nykryn (lnykryn at redhat.com) wrote:

Thanks! Applied!

> ---
>  man/journalctl.xml       |  8 +++++++
>  src/journal/journalctl.c | 58 +++++++++++++++++++++++++++++++++++++++++++-----
>  2 files changed, 60 insertions(+), 6 deletions(-)
> 
> diff --git a/man/journalctl.xml b/man/journalctl.xml
> index 5ed0e1f..ca940fe 100644
> --- a/man/journalctl.xml
> +++ b/man/journalctl.xml
> @@ -185,6 +185,14 @@
>                          </varlistentry>
>  
>                          <varlistentry>
> +                                <term><option>-r</option></term>
> +                                <term><option>--reverse</option></term>
> +
> +                                <listitem><para>Reverse output, so the newest
> +                                entries are displayed first.</para></listitem>
> +                        </varlistentry>
> +
> +                        <varlistentry>
>                                  <term><option>-o</option></term>
>                                  <term><option>--output=</option></term>
>  
> diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c
> index 9084509..4c9862f 100644
> --- a/src/journal/journalctl.c
> +++ b/src/journal/journalctl.c
> @@ -77,6 +77,7 @@ static bool arg_since_set = false, arg_until_set = false;
>  static const char *arg_unit = NULL;
>  static const char *arg_field = NULL;
>  static bool arg_catalog = false;
> +static bool arg_reverse = false;
>  
>  static enum {
>          ACTION_SHOW,
> @@ -103,6 +104,7 @@ static int help(void) {
>                 "  -f --follow            Follow journal\n"
>                 "  -n --lines[=INTEGER]   Number of journal entries to show\n"
>                 "     --no-tail           Show all lines, even in follow mode\n"
> +               "  -r --reverse           Show the newest entries first\n"
>                 "  -o --output=STRING     Change journal output mode (short, short-monotonic,\n"
>                 "                         verbose, export, json, json-pretty, json-sse, cat)\n"
>                 "  -x --catalog           Add message explanations where available\n"
> @@ -184,6 +186,7 @@ static int parse_argv(int argc, char *argv[]) {
>                  { "catalog",      no_argument,       NULL, 'x'              },
>                  { "list-catalog", no_argument,       NULL, ARG_LIST_CATALOG },
>                  { "update-catalog",no_argument,      NULL, ARG_UPDATE_CATALOG },
> +                { "reverse",      no_argument,       NULL, 'r'              },
>                  { NULL,           0,                 NULL, 0                }
>          };
>  
> @@ -192,7 +195,7 @@ static int parse_argv(int argc, char *argv[]) {
>          assert(argc >= 0);
>          assert(argv);
>  
> -        while ((c = getopt_long(argc, argv, "hfo:an::qmbD:p:c:u:F:x", options, NULL)) >= 0) {
> +        while ((c = getopt_long(argc, argv, "hfo:an::qmbD:p:c:u:F:xr", options, NULL)) >= 0) {
>  
>                  switch (c) {
>  
> @@ -424,6 +427,10 @@ static int parse_argv(int argc, char *argv[]) {
>                          arg_action = ACTION_UPDATE_CATALOG;
>                          break;
>  
> +                case 'r':
> +                        arg_reverse = true;
> +                        break;
> +
>                  default:
>                          log_error("Unknown option code %c", c);
>                          return -EINVAL;
> @@ -443,6 +450,11 @@ static int parse_argv(int argc, char *argv[]) {
>                  return -EINVAL;
>          }
>  
> +        if (arg_follow && arg_reverse) {
> +                log_error("Please specify either --reverse= or --follow=, not both.");
> +                return -EINVAL;
> +        }
> +
>          return 1;
>  }
>  
> @@ -997,10 +1009,12 @@ int main(int argc, char *argv[]) {
>                          log_error("Failed to seek to cursor: %s", strerror(-r));
>                          goto finish;
>                  }
> +                if (!arg_reverse)
> +                        r = sd_journal_next(j);
> +                else
> +                        r = sd_journal_previous(j);
>  
> -                r = sd_journal_next(j);
> -
> -        } else if (arg_since_set) {
> +        } else if (arg_since_set && !arg_reverse) {
>                  r = sd_journal_seek_realtime_usec(j, arg_since);
>                  if (r < 0) {
>                          log_error("Failed to seek to date: %s", strerror(-r));
> @@ -1008,6 +1022,14 @@ int main(int argc, char *argv[]) {
>                  }
>                  r = sd_journal_next(j);
>  
> +        } else if (arg_until_set && arg_reverse) {
> +                r = sd_journal_seek_realtime_usec(j, arg_until);
> +                if (r < 0) {
> +                        log_error("Failed to seek to date: %s", strerror(-r));
> +                        goto finish;
> +                }
> +                r = sd_journal_previous(j);
> +
>          } else if (arg_lines >= 0) {
>                  r = sd_journal_seek_tail(j);
>                  if (r < 0) {
> @@ -1017,6 +1039,15 @@ int main(int argc, char *argv[]) {
>  
>                  r = sd_journal_previous_skip(j, arg_lines);
>  
> +        } else if (arg_reverse) {
> +                r = sd_journal_seek_tail(j);
> +                if (r < 0) {
> +                        log_error("Failed to seek to tail: %s", strerror(-r));
> +                        goto finish;
> +                }
> +
> +                r = sd_journal_previous(j);
> +
>          } else {
>                  r = sd_journal_seek_head(j);
>                  if (r < 0) {
> @@ -1061,7 +1092,10 @@ int main(int argc, char *argv[]) {
>                          int flags;
>  
>                          if (need_seek) {
> -                                r = sd_journal_next(j);
> +                                if(!arg_reverse)
> +                                        r = sd_journal_next(j);
> +                                else
> +                                        r = sd_journal_previous(j);
>                                  if (r < 0) {
>                                          log_error("Failed to iterate through journal: %s", strerror(-r));
>                                          goto finish;
> @@ -1071,7 +1105,7 @@ int main(int argc, char *argv[]) {
>                          if (r == 0)
>                                  break;
>  
> -                        if (arg_until_set) {
> +                        if (arg_until_set && !arg_reverse) {
>                                  usec_t usec;
>  
>                                  r = sd_journal_get_realtime_usec(j, &usec);
> @@ -1083,6 +1117,18 @@ int main(int argc, char *argv[]) {
>                                          goto finish;
>                          }
>  
> +                        if (arg_since_set && arg_reverse) {
> +                                usec_t usec;
> +
> +                                r = sd_journal_get_realtime_usec(j, &usec);
> +                                if (r < 0) {
> +                                        log_error("Failed to determine timestamp: %s", strerror(-r));
> +                                        goto finish;
> +                                }
> +                                if (usec < arg_since)
> +                                        goto finish;
> +                        }
> +
>                          if (!arg_merge) {
>                                  sd_id128_t boot_id;
>  


Lennart

-- 
Lennart Poettering - Red Hat, Inc.


More information about the systemd-devel mailing list