[gnome-logs/wip/gl-journal: 1/5] Add simple journal query method



commit c2e22263021822db541233ffd00618d56a64c913
Author: David King <davidk gnome org>
Date:   Wed Oct 2 17:20:38 2013 +0100

    Add simple journal query method

 src/gl-journal.c |  158 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/gl-journal.h |   17 ++++++
 2 files changed, 175 insertions(+), 0 deletions(-)
---
diff --git a/src/gl-journal.c b/src/gl-journal.c
index 26bf9f4..42e6a15 100644
--- a/src/gl-journal.c
+++ b/src/gl-journal.c
@@ -19,6 +19,7 @@
 #include "gl-journal.h"
 
 #include <glib-unix.h>
+#include <stdlib.h>
 
 typedef struct
 {
@@ -132,6 +133,163 @@ gl_journal_init (GlJournal *self)
 
 }
 
+GList *
+gl_journal_query (GlJournal *self, const GlJournalQuery *query)
+{
+    GlJournalPrivate *priv;
+    sd_journal *journal;
+    gint ret;
+    gsize i;
+    GList *results = NULL;
+
+    g_return_val_if_fail (GL_JOURNAL (self), NULL);
+    g_return_val_if_fail (query != NULL, NULL);
+
+    priv = gl_journal_get_instance_private (self);
+    journal = priv->journal;
+
+    ret = sd_journal_seek_tail (journal);
+
+    if (ret < 0)
+    {
+        g_warning ("Error seeking to end of systemd journal: %s",
+                   g_strerror (-ret));
+    }
+
+    for (i = 0; i < query->n_results; i++)
+    {
+        /* TODO: Handle matches. */
+        GlJournalResult *result;
+
+        const gchar *message;
+        const gchar *comm;
+        const gchar *priority;
+        gsize length;
+
+        ret = sd_journal_previous (journal);
+
+        if (ret < 0)
+        {
+            g_warning ("Error setting cursor to end of systemd journal: %s",
+                       g_strerror (-ret));
+            break;
+        }
+        else if (ret == 0)
+        {
+            g_debug ("End of systemd journal reached");
+            break;
+        }
+
+        result = g_slice_new (GlJournalResult);
+
+        ret = sd_journal_get_realtime_usec (journal, &result->timestamp);
+
+        if (ret < 0)
+        {
+            g_warning ("Error getting timestamp from systemd journal: %s",
+                       g_strerror (-ret));
+            goto out;
+        }
+
+        ret = sd_journal_get_cursor (journal, &result->cursor);
+
+        if (ret < 0)
+        {
+            g_warning ("Error getting cursor for current journal entry: %s",
+                       g_strerror (-ret));
+            goto out;
+        }
+
+        ret = sd_journal_test_cursor (journal, result->cursor);
+
+        if (ret < 0)
+        {
+            g_warning ("Error testing cursor string: %s", g_strerror (-ret));
+            free (result->cursor);
+            result->cursor = NULL;
+            goto out;
+        }
+        else if (ret == 0)
+        {
+            g_warning ("Cursor string does not match journal entry");
+            /* Not a problem at this point, but would be when seeking to the
+             * cursor later on. */
+        }
+
+        ret = sd_journal_get_catalog (journal, &result->catalog);
+
+        if (ret == -ENOENT)
+        {
+            g_debug ("No message for this log entry was found in the catalog");
+            result->catalog = NULL;
+        }
+        else if (ret < 0)
+        {
+            g_warning ("Error while getting message from catalog: %s",
+                       g_strerror (-ret));
+            free (result->cursor);
+            goto out;
+        }
+
+        ret = sd_journal_get_data (journal, "_COMM", (const void **)&comm,
+                                   &length);
+
+        if (ret < 0)
+        {
+            g_debug ("Unable to get commandline from systemd journal: %s",
+                     g_strerror (-ret));
+            comm = "_COMM=";
+        }
+
+        result->comm = strchr (comm, '=') + 1;
+
+        ret = sd_journal_get_data (journal, "MESSAGE", (const void **)&message,
+                                   &length);
+
+        if (ret < 0)
+        {
+            g_warning ("Error getting message from systemd journal: %s",
+                       g_strerror (-ret));
+            free (result->cursor);
+            free (result->catalog);
+            goto out;
+        }
+
+        result->message = strchr (message, '=') + 1;
+
+        ret = sd_journal_get_data (journal, "PRIORITY",
+                                   (const void **)&priority, &length);
+
+        if (ret == -ENOENT)
+        {
+            g_warning ("No priority was set for this message");
+            free (result->cursor);
+            free (result->catalog);
+            goto out;
+        }
+        else if (ret < 0)
+        {
+            g_warning ("Error getting priority from systemd journal: %s",
+                       g_strerror (-ret));
+            free (result->cursor);
+            free (result->catalog);
+            goto out;
+        }
+
+        result->priority = atoi (strchr (priority, '=') + 1);
+
+        results = g_list_prepend (results, result);
+        continue;
+
+out:
+        g_slice_free (GlJournalResult, result);
+    }
+
+    sd_journal_flush_matches (journal);
+
+    return g_list_reverse (results);
+}
+
 sd_journal *
 gl_journal_get_journal (GlJournal *self)
 {
diff --git a/src/gl-journal.h b/src/gl-journal.h
index 3c54706..bfd5ee7 100644
--- a/src/gl-journal.h
+++ b/src/gl-journal.h
@@ -26,6 +26,22 @@ G_BEGIN_DECLS
 
 typedef struct
 {
+    gsize n_results;
+    gchar **matches;
+} GlJournalQuery;
+
+typedef struct
+{
+    guint64 timestamp;
+    gchar *cursor;
+    const gchar *message;
+    const gchar *comm;
+    gchar *catalog;
+    guint priority;
+} GlJournalResult;
+
+typedef struct
+{
     /*< private >*/
     GObject parent_instance;
 } GlJournal;
@@ -40,6 +56,7 @@ typedef struct
 #define GL_JOURNAL(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GL_TYPE_JOURNAL, GlJournal))
 
 GType gl_journal_get_type (void);
+GList * gl_journal_query (GlJournal *self, const GlJournalQuery *query);
 sd_journal * gl_journal_get_journal (GlJournal *self);
 GlJournal * gl_journal_new (void);
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]