static bool arg_local = false;
static bool arg_this_boot = false;
static const char *arg_directory = NULL;
+static int arg_priorities = 0xFF;
static int help(void) {
" -l --local Only local entries\n"
" -b --this-boot Show data only from current boot\n"
" -D --directory=PATH Show journal files from directory\n"
+ " -p --priority=RANGE Show only messages within the specified priority range\n"
" --header Show journal header information\n"
" --new-id128 Generate a new 128 Bit id\n",
program_invocation_short_name);
{ "this-boot", no_argument, NULL, 'b' },
{ "directory", required_argument, NULL, 'D' },
{ "header", no_argument, NULL, ARG_HEADER },
+ { "priority", no_argument, NULL, 'p' },
{ NULL, 0, NULL, 0 }
};
assert(argc >= 0);
assert(argv);
- while ((c = getopt_long(argc, argv, "hfo:an:qlbD:", options, NULL)) >= 0) {
+ while ((c = getopt_long(argc, argv, "hfo:an:qlbD:p:", options, NULL)) >= 0) {
switch (c) {
arg_print_header = true;
break;
+ case 'p': {
+ const char *dots;
+
+ dots = strstr(optarg, "..");
+ if (dots) {
+ char *a;
+ int from, to, i;
+
+ /* a range */
+ a = strndup(optarg, dots - optarg);
+ if (!a)
+ return log_oom();
+
+ from = log_level_from_string(a);
+ to = log_level_from_string(dots + 2);
+ free(a);
+
+ if (from < 0 || to < 0) {
+ log_error("Failed to parse log level range %s", optarg);
+ return -EINVAL;
+ }
+
+ arg_priorities = 0;
+
+ if (from < to) {
+ for (i = from; i <= to; i++)
+ arg_priorities |= 1 << i;
+ } else {
+ for (i = to; i <= from; i++)
+ arg_priorities |= 1 << i;
+ }
+
+ } else {
+ int p, i;
+
+ p = log_level_from_string(optarg);
+ if (p < 0) {
+ log_error("Unknown log level %s", optarg);
+ return -EINVAL;
+ }
+
+ arg_priorities = 0;
+
+ for (i = 0; i <= p; i++)
+ arg_priorities |= 1 << i;
+ }
+
+ break;
+ }
+
case '?':
return -EINVAL;
return 1;
}
+static bool on_tty(void) {
+ static int t = -1;
+
+ /* Note that this is invoked relatively early, before we start
+ * the pager. That means the value we return reflects whether
+ * we originally were started on a tty, not if we currently
+ * are. But this is intended, since we want colour and so on
+ * when run in our own pager. */
+
+ if (_unlikely_(t < 0))
+ t = isatty(STDOUT_FILENO) > 0;
+
+ return t;
+}
+
static int generate_new_id128(void) {
sd_id128_t id;
int r;
t = strappend("_EXE=", path);
if (!t) {
free(p);
- log_error("Out of memory");
- return -ENOMEM;
+ return log_oom();
}
r = sd_journal_add_match(j, t, 0);
sd_id128_t boot_id;
int r;
+ assert(j);
+
if (!arg_this_boot)
return 0;
return 0;
}
+static int add_priorities(sd_journal *j) {
+ char match[] = "PRIORITY=0";
+ int i, r;
+
+ assert(j);
+
+ if (arg_priorities == 0xFF)
+ return 0;
+
+ for (i = LOG_EMERG; i <= LOG_DEBUG; i++)
+ if (arg_priorities & (1 << i)) {
+ match[sizeof(match)-2] = '0' + i;
+
+ log_info("adding match %s", match);
+
+ r = sd_journal_add_match(j, match, strlen(match));
+ if (r < 0) {
+ log_error("Failed to add match: %s", strerror(-r));
+ return r;
+ }
+ }
+
+ return 0;
+}
+
int main(int argc, char *argv[]) {
int r;
sd_journal *j = NULL;
bool need_seek = false;
sd_id128_t previous_boot_id;
bool previous_boot_id_valid = false;
+ bool have_pager;
log_parse_environment();
log_open();
if (r < 0)
goto finish;
+ r = add_priorities(j);
+ if (r < 0)
+ goto finish;
+
if (!arg_quiet) {
usec_t start, end;
char start_buf[FORMAT_TIMESTAMP_MAX], end_buf[FORMAT_TIMESTAMP_MAX];
goto finish;
}
- if (!arg_no_pager && !arg_follow) {
- columns();
- pager_open();
- }
+ on_tty();
+ have_pager = !arg_no_pager && !arg_follow && pager_open();
if (arg_output == OUTPUT_JSON) {
fputc('[', stdout);
for (;;) {
for (;;) {
sd_id128_t boot_id;
+ int flags =
+ arg_show_all * OUTPUT_SHOW_ALL |
+ have_pager * OUTPUT_FULL_WIDTH |
+ on_tty() * OUTPUT_COLOR;
if (need_seek) {
r = sd_journal_next(j);
line ++;
- r = output_journal(j, arg_output, line, 0, arg_show_all);
+ r = output_journal(j, arg_output, line, 0, flags);
if (r < 0)
goto finish;