In data lunedì 31 agosto 2015 15:07:37, Maros Zatko ha scritto:
Lets user view journald log from VM in a similar format as
journalctl
uses.
"Let the user view the journald log from a guest, with a format similar
to what 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;
This should be part of patch #1 if possible.
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;
Ditto.
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.
"journalctl" could be linkified, so L<journalctl(1)>.
+
+=over
+
+"
+^ (Journal.ops_to_pod_string ()) ^
+"
+=back
+
+Default format is C<~3axv>
"The default format is C<~3axv>."
+
+For fields description see C<man SYSTEMD.JOURNAL-FIELDS>
There's the proper format for linking man pages, so it should be
L<systemd.journal-fields(7)>.
+
+Use C<journal-open> first." };
C<guestfs_journal_open> here, so it gets proper linking.
+
+ { 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
I guess you don't need to open List, if later you always use it like
List.foo.
+
+(* Arguments used by journal-view command *)
+
+type op_type = Options of (char * string) list;; (* option, option name*)
What is Options? I cannot find it neither in the OCaml standard library
nor in the generator own types...
As a style note, usually ;; at the end of top-level statements are not
used in libguestfs' code.
+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;;
Considering you always call deopt on 'op', declaring it as
(char * string) list should be enough, I guess.
+let string_list_to_string s = List.fold_left (fun a b -> a ^ b)
"" s;;
Using String.concat would make it easier to read/understand... although
seems not used at all.
+let ops_to_pod_string () =
+ List.fold_left (fun a b -> a ^ b) ""
String.concat here would be easier.
+ (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
Considering it does not change, you could put the array opening and
closing directly in the printed C code.
+ decl ^ String.concat ",\n"
+ (List.map (fun (a,b) -> " \"" ^ escaped a ^ "\",
\"" ^ b ^ "\"")
+ (deopt op)) ^ "\n};";;
IMHO this could be inline in generate_journal_h, just using List.iter
to print each line in the array.
+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";
The generated code here could be better: instead of generating an array
each field code (as string) and name one after the other, have a list
of structs:
static const struct JournalField {
char field;
const char *name;
} fields[] = {
{ 'a', "_PID" },
...
};
From what I see in these patches, it seems like the array with fields
is just an implementation detail of journal_view, and thus not worth
exposing in journal.h. Maybe generate a journal-fields.h (or even .c)
to include directly in journal.c, so journal.h can stay as
non-generated file.
Thanks,
--
Pino Toscano