summaryrefslogtreecommitdiff
path: root/src/gl-journal.c
diff options
context:
space:
mode:
authorJonathan Kang <jonathan121537@gmail.com>2015-11-09 11:23:04 +0800
committerJonathan Kang <jonathan121537@gmail.com>2015-11-12 19:59:30 +0800
commit21e890edc58c16cdef3fc4a9b92f555d8c99cf94 (patch)
tree567408ab8671ad04adb58b098ca8cb0e0f64c4d1 /src/gl-journal.c
parentfffee96fe16ebaea5b0109ce16b10ecdeec10349 (diff)
downloadgnome-logs-21e890edc58c16cdef3fc4a9b92f555d8c99cf94.tar.gz
Only fetch the latest 5 boots to improve startup time
https://bugzilla.gnome.org/show_bug.cgi?id=757807
Diffstat (limited to 'src/gl-journal.c')
-rw-r--r--src/gl-journal.c183
1 files changed, 72 insertions, 111 deletions
diff --git a/src/gl-journal.c b/src/gl-journal.c
index 6b3d4d5..80587d6 100644
--- a/src/gl-journal.c
+++ b/src/gl-journal.c
@@ -43,12 +43,6 @@ struct _GlJournalEntry
G_DEFINE_TYPE (GlJournalEntry, gl_journal_entry, G_TYPE_OBJECT);
-/* "_BOOT_ID=" contains 9 characters, and 33 more characters is needed to
- * store the string formated from a 128-bit ID. The ID will be formatted as
- * 32 lowercase hexadecimal digits and be terminated by a NUL byte. So an
- * array of with a size 42 is need. */
-static char match[42] = "_BOOT_ID=";
-
typedef struct
{
sd_journal *journal;
@@ -94,120 +88,135 @@ gl_journal_get_current_boot_time (GlJournal *journal,
return NULL;
}
-static gint
-boot_id_cmp (const void *a, const void *b)
+static gchar *
+gl_journal_get_data (GlJournal *self,
+ const gchar *field,
+ GError **error)
{
- guint64 _a, _b;
+ GlJournalPrivate *priv;
+ gint ret;
+ gconstpointer data;
+ gsize length;
+ gsize prefix_len;
+
+ g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+ g_return_val_if_fail (field != NULL, NULL);
+
+ priv = gl_journal_get_instance_private (self);
+ ret = sd_journal_get_data (priv->journal, field, &data, &length);
+
+ if (ret < 0)
+ {
+ gint code;
+
+ switch (-ret)
+ {
+ case ENOENT:
+ code = GL_JOURNAL_ERROR_NO_FIELD;
+ break;
+ case EADDRNOTAVAIL:
+ code = GL_JOURNAL_ERROR_INVALID_POINTER;
+ break;
+ default:
+ code = GL_JOURNAL_ERROR_FAILED;
+ break;
+ }
+
+ g_set_error (error, GL_JOURNAL_ERROR, code,
+ "Unable to get field ā€˜%sā€™ from systemd journal: %s",
+ field, g_strerror (-ret));
- _a = ((const GlJournalBootID *)a)->realtime_first;
- _b = ((const GlJournalBootID *)b)->realtime_first;
+ return NULL;
+ }
- return _a < _b ? -1 : (_a > _b ? 1 : 0);
+ /* Field data proper starts after the first '='. */
+ prefix_len = strchr (data, '=') - (const gchar *)data + 1;
+
+ /* Trim the prefix off the beginning of the field. */
+ return g_strndup ((const gchar *)data + prefix_len, length - prefix_len);
}
static void
gl_journal_get_boots (GlJournal *journal)
{
GlJournalPrivate *priv;
- int r;
- const void *data;
- size_t length;
+ gint r;
+ gint i;
g_return_if_fail (GL_JOURNAL (journal));
priv = gl_journal_get_instance_private (journal);
- r = sd_journal_query_unique (priv->journal, "_BOOT_ID");
+ r = sd_journal_seek_tail (priv->journal);
if (r < 0)
{
- g_warning ("Error reading unique data fields: %s", g_strerror (-r));
+ g_warning ("Error seeking to the end of the journal: %s",
+ g_strerror (-r));
}
- SD_JOURNAL_FOREACH_UNIQUE (priv->journal, data, length)
+ /* only fetch the latest 5 boots */
+ for (i = 0; i < 5; i++)
{
gchar *boot_match;
+ gchar *id;
GlJournalBootID boot_id;
- sd_id128_t id;
-
- r = sd_id128_from_string (((const char *)data) + strlen ("_BOOT_ID="),
- &id);
- if (r < 0)
- {
- g_warning ("Error parsing strings into 128-bit IDs: %s",
- g_strerror (-r));
- continue;
- }
-
- /* convert id.boot_id into boot_match */
- sd_id128_to_string (id, match + 9);
- boot_match = g_strdup (match);
- boot_id.boot_match = boot_match;
- r = sd_journal_add_match (priv->journal, data, length);
- if (r < 0)
- {
- g_warning ("Error adding entry match: %s", g_strerror (-r));
- }
-
- r = sd_journal_seek_head (priv->journal);
- if (r < 0)
- {
- g_warning ("Error seeking to the beginning of the journal: %s\n",
- g_strerror (-r));
- }
+ sd_journal_flush_matches (priv->journal);
- r = sd_journal_next (priv->journal);
+ r = sd_journal_previous (priv->journal);
if (r < 0)
{
- g_warning ("Error advance the read pointer in the journal: %s",
+ g_warning ("Error retreating the read pointer in the journal: %s",
g_strerror (-r));
}
else if (r == 0)
{
- goto flush;
+ break;
}
r = sd_journal_get_realtime_usec (priv->journal,
- &boot_id.realtime_first);
+ &boot_id.realtime_last);
if (r < 0)
{
g_warning ("Error retrieving the sender timestamps: %s",
g_strerror (-r));
}
- r = sd_journal_seek_tail (priv->journal);
+ id = gl_journal_get_data (journal, "_BOOT_ID", NULL);
+ boot_match = g_strconcat ("_BOOT_ID=", id, NULL);
+ boot_id.boot_match = boot_match;
+ g_free (id);
+
+ r = sd_journal_add_match (priv->journal, boot_id.boot_match, 0);
if (r < 0)
{
- g_warning ("Error seeking to the end of the journal: %s\n",
- g_strerror (-r));
+ g_warning ("Error adding entry match: %s", g_strerror (-r));
}
- r = sd_journal_previous (priv->journal);
+ r = sd_journal_seek_head (priv->journal);
if (r < 0)
{
- g_warning ("Error retreat the read pointer in the journal: %s",
+ g_warning ("Error seeking to the beginning of the journal: %s",
g_strerror (-r));
}
- else if (r == 0)
+
+ r = sd_journal_next (priv->journal);
+ if (r < 0)
{
- goto flush;
+ g_warning ("Error advancing the read pointer in the journal: %s",
+ g_strerror (-r));
}
r = sd_journal_get_realtime_usec (priv->journal,
- &boot_id.realtime_last);
+ &boot_id.realtime_first);
if (r < 0)
{
g_warning ("Error retrieving the sender timestamps: %s",
g_strerror (-r));
}
- priv->boot_ids = g_array_append_val (priv->boot_ids, boot_id);
-
- flush:
- sd_journal_flush_matches (priv->journal);
+ priv->boot_ids = g_array_prepend_val (priv->boot_ids, boot_id);
}
-
- g_array_sort (priv->boot_ids, boot_id_cmp);
}
GArray *
@@ -338,54 +347,6 @@ gl_journal_init (GlJournal *self)
gl_journal_get_boots (self);
}
-static gchar *
-gl_journal_get_data (GlJournal *self,
- const gchar *field,
- GError **error)
-{
- GlJournalPrivate *priv;
- gint ret;
- gconstpointer data;
- gsize length;
- gsize prefix_len;
-
- g_return_val_if_fail (error == NULL || *error == NULL, NULL);
- g_return_val_if_fail (field != NULL, NULL);
-
- priv = gl_journal_get_instance_private (self);
- ret = sd_journal_get_data (priv->journal, field, &data, &length);
-
- if (ret < 0)
- {
- gint code;
-
- switch (-ret)
- {
- case ENOENT:
- code = GL_JOURNAL_ERROR_NO_FIELD;
- break;
- case EADDRNOTAVAIL:
- code = GL_JOURNAL_ERROR_INVALID_POINTER;
- break;
- default:
- code = GL_JOURNAL_ERROR_FAILED;
- break;
- }
-
- g_set_error (error, GL_JOURNAL_ERROR, code,
- "Unable to get field ā€˜%sā€™ from systemd journal: %s",
- field, g_strerror (-ret));
-
- return NULL;
- }
-
- /* Field data proper starts after the first '='. */
- prefix_len = strchr (data, '=') - (const gchar *)data + 1;
-
- /* Trim the prefix off the beginning of the field. */
- return g_strndup ((const gchar *)data + prefix_len, length - prefix_len);
-}
-
static GlJournalEntry *
_gl_journal_query_entry (GlJournal *self)
{