Lets user view journald log from VM in a similar format as journalctl
uses.
Fixes RFE: journal reader in guestfish
---
cat/log.c | 4 +++
fish/journal.c | 3 +-
generator/Makefile.am | 6 ++--
generator/actions.ml | 22 ++++++++++++
generator/journal.ml | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++
generator/main.ml | 3 ++
6 files changed, 131 insertions(+), 4 deletions(-)
create mode 100644 generator/journal.ml
diff --git a/cat/log.c b/cat/log.c
index f05eae0..157ee55 100644
--- a/cat/log.c
+++ b/cat/log.c
@@ -36,6 +36,7 @@
#include "guestfs.h"
#include "options.h"
+#include "journal.h"
/* Currently open libguestfs handle. */
guestfs_h *g;
@@ -279,6 +280,9 @@ do_log_journal (void)
if (guestfs_journal_open (g, JOURNAL_DIR) == -1)
return -1;
+ if (journal_view ("~3axv") == -1)
+ return -1;
+
if (guestfs_journal_close (g) == -1)
return -1;
diff --git a/fish/journal.c b/fish/journal.c
index 9afdf60..579a1d1 100644
--- a/fish/journal.c
+++ b/fish/journal.c
@@ -83,9 +83,8 @@ lookup_field (char field)
int
journal_view (const char *fields)
{
- int r;
int errors = 0;
- while ((r = guestfs_journal_next(g)) > 0) {
+ while (guestfs_journal_next(g) > 0) {
CLEANUP_FREE_XATTR_LIST struct guestfs_xattr_list *xattrs = NULL;
int64_t ts;
int priority = LOG_INFO;
diff --git a/generator/Makefile.am b/generator/Makefile.am
index a3fe50d..bd466c2 100644
--- a/generator/Makefile.am
+++ b/generator/Makefile.am
@@ -37,6 +37,7 @@ sources = \
haskell.ml \
java.ml \
lua.ml \
+ journal.ml \
main.ml \
ocaml.ml \
optgroups.ml \
@@ -60,13 +61,14 @@ sources = \
objects = \
types.cmo \
utils.cmo \
+ pr.cmo \
+ docstrings.cmo \
+ journal.cmo \
actions.cmo \
structs.cmo \
optgroups.cmo \
prepopts.cmo \
events.cmo \
- pr.cmo \
- docstrings.cmo \
checks.cmo \
c.cmo \
xdr.cmo \
diff --git a/generator/actions.ml b/generator/actions.ml
index 13c8bc8..e914fd3 100644
--- a/generator/actions.ml
+++ b/generator/actions.ml
@@ -21,6 +21,8 @@
open Types
open Utils
+open Journal
+
(* Default settings for all action fields. So we copy and override
* this struct by writing '{ defaults with name = &c }'
*)
@@ -12897,6 +12899,26 @@ environment variable.
See also L</hexdump>." };
{ defaults with
+ name = "journal_view";
+ shortdesc = "view journald log";
+ longdesc = " journal-view [FORMAT]
+
+View journald log in format similar to journalctl.
+
+=over
+
+"
+^ (Journal.ops_to_pod_string ()) ^
+"
+=back
+
+Default format is C<~3axv>
+
+For fields description see C<man SYSTEMD.JOURNAL-FIELDS>
+
+Use C<journal-open> first." };
+
+ { defaults with
name = "lcd";
shortdesc = "change working directory";
longdesc = " lcd directory
diff --git a/generator/journal.ml b/generator/journal.ml
new file mode 100644
index 0000000..46d93cd
--- /dev/null
+++ b/generator/journal.ml
@@ -0,0 +1,97 @@
+(* libguestfs
+ * Copyright (C) 2015 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *)
+
+(* Please read generator/README first. *)
+
+open Printf
+
+open String
+open Docstrings
+open Pr
+
+open Char
+open List
+
+(* Arguments used by journal-view command *)
+
+type op_type = Options of (char * string) list;; (* option, option name*)
+
+let op = Options [
+ (* Trusted fields *)
+ ('a', "_PID");
+ ('b', "_UID");
+ ('c', "_GID");
+ ('d', "_COMM");
+ ('e', "_EXE");
+ ('f', "_CMDLINE");
+ ('g', "_CAP_EFFECTIVE");
+ ('h', "_AUDIT_SESSION");
+ ('i', "_AUDIT_LOGINUID");
+ ('j', "_SYSTEMD_CGROUP");
+ ('k', "_SYSTEMD_SESSION");
+ ('l', "_SYSTEMD_UNIT");
+ ('m', "_SYSTEMD_USER_UNIT");
+ ('n', "_SYSTEMD_OWNER_UID");
+ ('o', "_SYSTEMD_SLICE");
+ ('p', "_SELINUX_CONTEXT");
+ ('q', "_SOURCE_REALTIME_TIMESTAMP");
+ ('r', "_BOOT_ID");
+ ('s', "_MACHINE_ID");
+ ('t', "_HOSTNAME");
+ ('u', "_TRANSPORT");
+ (* User fields *)
+ ('v', "MESSAGE");
+ ('w', "MESSAGE_ID");
+ ('x', "PRIORITY");
+ ('y', "CODE_FILE");
+ ('z', "CODE_LINE");
+ ('0', "CODE_FUNC");
+ ('1', "ERRNO");
+ ('2', "SYSLOG_FACILITY");
+ ('3', "SYSLOG_IDENTIFIER");
+ ('4', "SYSLOG_PID");
+ ('~', "timestamp")
+];;
+
+let deopt x = match x with Options y -> y;;
+
+let string_list_to_string s = List.fold_left (fun a b -> a ^ b) "" s;;
+
+let ops_to_pod_string () =
+ List.fold_left (fun a b -> a ^ b) ""
+ (List.map (fun (a,b) -> "=item " ^ escaped a ^ " " ^ b ^
"\n\n")
+ (deopt op));;
+
+let ops_to_c_array arrname () =
+ let decl = "static const char *const " ^ arrname ^ "[] = {\n" in
+ decl ^ String.concat ",\n"
+ (List.map (fun (a,b) -> " \"" ^ escaped a ^ "\",
\"" ^ b ^ "\"")
+ (deopt op)) ^ "\n};";;
+
+let generate_journal_h () =
+ generate_header CStyle LGPLv2plus;
+ pr "#include <config.h>\n";
+ pr "\n";
+ pr "#ifndef JOURNAL_H\n";
+ pr "#define JOURNAL_H\n";
+ pr "\n";
+ pr "%s\n" (ops_to_c_array "journal_fields" ());
+ pr "\n";
+ pr "/* in journal.c */\n";
+ pr "extern int journal_view (const char *fields);\n";
+ pr "#endif /* JOURNAL_H */\n";
diff --git a/generator/main.ml b/generator/main.ml
index 1e0e7d6..639920d 100644
--- a/generator/main.ml
+++ b/generator/main.ml
@@ -46,6 +46,7 @@ open Golang
open Bindtests
open Errnostring
open Customize
+open Journal
let perror msg = function
| Unix_error (err, _, _) ->
@@ -212,6 +213,8 @@ Run it from the top source directory using the command
output_to "customize/customize-synopsis.pod"
generate_customize_synopsis_pod;
output_to "customize/customize-options.pod" generate_customize_options_pod;
+ output_to "fish/journal.h" generate_journal_h;
+
(* Generate the list of files generated -- last. *)
printf "generated %d lines of code\n" (get_lines_generated ());
let files = List.sort compare (get_files_generated ()) in
--
1.9.3