chiark / gitweb /
journalctl: show systemd messages about unit for -u
[elogind.git] / src / journal / journalctl.c
index 4c9862fa6ce5a83c080c189bcae6febf09feb753..65114b2ff8a219711c56d5d1adc4ba9bf41f5d7e 100644 (file)
@@ -38,6 +38,7 @@
 #include <systemd/sd-journal.h>
 
 #include "log.h"
 #include <systemd/sd-journal.h>
 
 #include "log.h"
+#include "logs-show.h"
 #include "util.h"
 #include "path-util.h"
 #include "build.h"
 #include "util.h"
 #include "path-util.h"
 #include "build.h"
@@ -56,6 +57,7 @@
 #define DEFAULT_FSS_INTERVAL_USEC (15*USEC_PER_MINUTE)
 
 static OutputMode arg_output = OUTPUT_SHORT;
 #define DEFAULT_FSS_INTERVAL_USEC (15*USEC_PER_MINUTE)
 
 static OutputMode arg_output = OUTPUT_SHORT;
+static bool arg_pager_end = false;
 static bool arg_follow = false;
 static bool arg_full = false;
 static bool arg_all = false;
 static bool arg_follow = false;
 static bool arg_full = false;
 static bool arg_all = false;
@@ -75,6 +77,7 @@ static usec_t arg_interval = DEFAULT_FSS_INTERVAL_USEC;
 static usec_t arg_since, arg_until;
 static bool arg_since_set = false, arg_until_set = false;
 static const char *arg_unit = NULL;
 static usec_t arg_since, arg_until;
 static bool arg_since_set = false, arg_until_set = false;
 static const char *arg_unit = NULL;
+static bool arg_unit_system;
 static const char *arg_field = NULL;
 static bool arg_catalog = false;
 static bool arg_reverse = false;
 static const char *arg_field = NULL;
 static bool arg_catalog = false;
 static bool arg_reverse = false;
@@ -100,7 +103,9 @@ static int help(void) {
                "  -c --cursor=CURSOR     Start showing entries from specified cursor\n"
                "  -b --this-boot         Show data only from current boot\n"
                "  -u --unit=UNIT         Show data only from the specified unit\n"
                "  -c --cursor=CURSOR     Start showing entries from specified cursor\n"
                "  -b --this-boot         Show data only from current boot\n"
                "  -u --unit=UNIT         Show data only from the specified unit\n"
+               "     --user-unit=UNIT    Show data only from the specified user session unit\n"
                "  -p --priority=RANGE    Show only messages within the specified priority range\n"
                "  -p --priority=RANGE    Show only messages within the specified priority range\n"
+               "  -e --pager-end         Immediately jump to end of the journal in the pager\n"
                "  -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"
                "  -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"
@@ -152,6 +157,7 @@ static int parse_argv(int argc, char *argv[]) {
                 ARG_DISK_USAGE,
                 ARG_SINCE,
                 ARG_UNTIL,
                 ARG_DISK_USAGE,
                 ARG_SINCE,
                 ARG_UNTIL,
+                ARG_USER_UNIT,
                 ARG_LIST_CATALOG,
                 ARG_UPDATE_CATALOG
         };
                 ARG_LIST_CATALOG,
                 ARG_UPDATE_CATALOG
         };
@@ -160,6 +166,7 @@ static int parse_argv(int argc, char *argv[]) {
                 { "help",         no_argument,       NULL, 'h'              },
                 { "version" ,     no_argument,       NULL, ARG_VERSION      },
                 { "no-pager",     no_argument,       NULL, ARG_NO_PAGER     },
                 { "help",         no_argument,       NULL, 'h'              },
                 { "version" ,     no_argument,       NULL, ARG_VERSION      },
                 { "no-pager",     no_argument,       NULL, ARG_NO_PAGER     },
+                { "pager-end",    no_argument,       NULL, 'e'              },
                 { "follow",       no_argument,       NULL, 'f'              },
                 { "output",       required_argument, NULL, 'o'              },
                 { "all",          no_argument,       NULL, 'a'              },
                 { "follow",       no_argument,       NULL, 'f'              },
                 { "output",       required_argument, NULL, 'o'              },
                 { "all",          no_argument,       NULL, 'a'              },
@@ -182,6 +189,7 @@ static int parse_argv(int argc, char *argv[]) {
                 { "since",        required_argument, NULL, ARG_SINCE        },
                 { "until",        required_argument, NULL, ARG_UNTIL        },
                 { "unit",         required_argument, NULL, 'u'              },
                 { "since",        required_argument, NULL, ARG_SINCE        },
                 { "until",        required_argument, NULL, ARG_UNTIL        },
                 { "unit",         required_argument, NULL, 'u'              },
+                { "user-unit",    required_argument, NULL, ARG_USER_UNIT    },
                 { "field",        required_argument, NULL, 'F'              },
                 { "catalog",      no_argument,       NULL, 'x'              },
                 { "list-catalog", no_argument,       NULL, ARG_LIST_CATALOG },
                 { "field",        required_argument, NULL, 'F'              },
                 { "catalog",      no_argument,       NULL, 'x'              },
                 { "list-catalog", no_argument,       NULL, ARG_LIST_CATALOG },
@@ -195,7 +203,7 @@ static int parse_argv(int argc, char *argv[]) {
         assert(argc >= 0);
         assert(argv);
 
         assert(argc >= 0);
         assert(argv);
 
-        while ((c = getopt_long(argc, argv, "hfo:an::qmbD:p:c:u:F:xr", options, NULL)) >= 0) {
+        while ((c = getopt_long(argc, argv, "hefo:an::qmbD:p:c:u:F:xr", options, NULL)) >= 0) {
 
                 switch (c) {
 
 
                 switch (c) {
 
@@ -212,6 +220,14 @@ static int parse_argv(int argc, char *argv[]) {
                         arg_no_pager = true;
                         break;
 
                         arg_no_pager = true;
                         break;
 
+                case 'e':
+                        arg_pager_end = true;
+
+                        if (arg_lines < 0)
+                                arg_lines = 1000;
+
+                        break;
+
                 case 'f':
                         arg_follow = true;
                         break;
                 case 'f':
                         arg_follow = true;
                         break;
@@ -406,6 +422,12 @@ static int parse_argv(int argc, char *argv[]) {
 
                 case 'u':
                         arg_unit = optarg;
 
                 case 'u':
                         arg_unit = optarg;
+                        arg_unit_system = true;
+                        break;
+
+                case ARG_USER_UNIT:
+                        arg_unit = optarg;
+                        arg_unit_system = false;
                         break;
 
                 case '?':
                         break;
 
                 case '?':
@@ -583,15 +605,12 @@ static int add_unit(sd_journal *j) {
         if (!u)
                 return log_oom();
 
         if (!u)
                 return log_oom();
 
-        m = strappend("_SYSTEMD_UNIT=", u);
-        if (!m)
-                return log_oom();
-
-        r = sd_journal_add_match(j, m, strlen(m));
-        if (r < 0) {
-                log_error("Failed to add match: %s", strerror(-r));
+        if (arg_unit_system)
+                r = add_matches_for_unit(j, u);
+        else
+                r = add_matches_for_user_unit(j, u, getuid());
+        if (r < 0)
                 return r;
                 return r;
-        }
 
         return 0;
 }
 
         return 0;
 }
@@ -859,16 +878,16 @@ static int verify(sd_journal *j) {
 static int access_check(void) {
 
 #ifdef HAVE_ACL
 static int access_check(void) {
 
 #ifdef HAVE_ACL
-        if (access("/var/log/journal", F_OK) < 0 && geteuid() != 0 && in_group("adm") <= 0) {
-                log_error("Unprivileged users can't see messages unless persistent log storage is enabled. Users in the group 'adm' can always see messages.");
+        if (access("/var/log/journal", F_OK) < 0 && geteuid() != 0 && in_group("systemd-journal") <= 0) {
+                log_error("Unprivileged users can't see messages unless persistent log storage is enabled. Users in the group 'systemd-journal' can always see messages.");
                 return -EACCES;
         }
 
                 return -EACCES;
         }
 
-        if (!arg_quiet && geteuid() != 0 && in_group("adm") <= 0)
-                log_warning("Showing user generated messages only. Users in the group 'adm' can see all messages. Pass -q to turn this notice off.");
+        if (!arg_quiet && geteuid() != 0 && in_group("systemd-journal") <= 0)
+                log_warning("Showing user generated messages only. Users in the group 'systemd-journal' can see all messages. Pass -q to turn this notice off.");
 #else
 #else
-        if (geteuid() != 0 && in_group("adm") <= 0) {
-                log_error("No access to messages. Only users in the group 'adm' can see messages.");
+        if (geteuid() != 0 && in_group("systemd-journal") <= 0) {
+                log_error("No access to messages. Only users in the group 'systemd-journal' can see messages.");
                 return -EACCES;
         }
 #endif
                 return -EACCES;
         }
 #endif
@@ -1064,7 +1083,7 @@ int main(int argc, char *argv[]) {
         }
 
         if (!arg_no_pager && !arg_follow)
         }
 
         if (!arg_no_pager && !arg_follow)
-                pager_open();
+                pager_open(arg_pager_end);
 
         if (!arg_quiet) {
                 usec_t start, end;
 
         if (!arg_quiet) {
                 usec_t start, end;
@@ -1092,7 +1111,7 @@ int main(int argc, char *argv[]) {
                         int flags;
 
                         if (need_seek) {
                         int flags;
 
                         if (need_seek) {
-                                if(!arg_reverse)
+                                if (!arg_reverse)
                                         r = sd_journal_next(j);
                                 else
                                         r = sd_journal_previous(j);
                                         r = sd_journal_next(j);
                                 else
                                         r = sd_journal_previous(j);