summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilliam Jon McCann <jmccann@redhat.com>2010-06-11 15:53:22 -0400
committerWilliam Jon McCann <jmccann@redhat.com>2010-06-11 15:55:34 -0400
commitc9f2292339540d4b9d8940bcef16b7485480c8d9 (patch)
tree90fa4532648bc0575492e5ba8630f4de78ef9e0e
parentb8a961f91105df661957f6b86922f744bac8b91c (diff)
Add a --since option to show entries in a time window
Doesn't load any history files it doesn't need to which should help performance on systems with long histories. https://bugs.freedesktop.org/show_bug.cgi?id=25660
-rw-r--r--tools/ck-history.c96
1 files changed, 74 insertions, 22 deletions
diff --git a/tools/ck-history.c b/tools/ck-history.c
index 606106c..d02caaa 100644
--- a/tools/ck-history.c
+++ b/tools/ck-history.c
@@ -62,8 +62,8 @@ typedef enum {
static GList *all_events = NULL;
-static gboolean
-process_event_line (const char *line)
+static CkLogEvent *
+parse_event_line (const char *line)
{
GString *str;
CkLogEvent *event;
@@ -72,47 +72,80 @@ process_event_line (const char *line)
event = ck_log_event_new_from_string (str);
g_string_free (str, TRUE);
- if (event != NULL) {
- all_events = g_list_prepend (all_events, event);
- }
-
- return TRUE;
+ return event;
}
static gboolean
-process_log_gzstream (gzFile *fstream)
+process_log_gzstream (gzFile *fstream,
+ GTimeVal *since)
{
- char line[MAX_LINE_LEN];
+ char line[MAX_LINE_LEN];
+ gboolean hit_since;
+ GList *events;
+ events = NULL;
+ hit_since = FALSE;
while (gzgets (fstream, line, sizeof (line)) != Z_NULL) {
+ CkLogEvent *event;
+
if (strlen (line) == sizeof (line) - 1) {
g_warning ("Log line truncated");
}
- process_event_line (line);
+ event = parse_event_line (line);
+ if (event == NULL) {
+ continue;
+ }
+
+ if (since == NULL || event->timestamp.tv_sec >= since->tv_sec) {
+ events = g_list_prepend (events, event);
+ } else {
+ hit_since = TRUE;
+ }
}
- return TRUE;
+ all_events = g_list_concat (all_events, events);
+
+ return !hit_since;
}
static gboolean
-process_log_stream (FILE *fstream)
+process_log_stream (FILE *fstream,
+ GTimeVal *since)
{
- char line[MAX_LINE_LEN];
+ char line[MAX_LINE_LEN];
+ gboolean hit_since;
+ GList *events;
+ events = NULL;
+ hit_since = FALSE;
while (fgets (line, sizeof (line), fstream) != NULL) {
+ CkLogEvent *event;
+
if (strlen (line) == sizeof (line) - 1) {
g_warning ("Log line truncated");
}
- process_event_line (line);
+ event = parse_event_line (line);
+ if (event == NULL) {
+ continue;
+ }
+
+ if (since == NULL || event->timestamp.tv_sec >= since->tv_sec) {
+ events = g_list_prepend (events, event);
+ } else {
+ hit_since = TRUE;
+ }
}
- return TRUE;
+ all_events = g_list_concat (all_events, events);
+
+ return !hit_since;
}
static gboolean
-process_log_file (const char *filename)
+process_log_file (const char *filename,
+ GTimeVal *since)
{
gboolean ret;
@@ -131,7 +164,7 @@ process_log_file (const char *filename)
errmsg);
return FALSE;
}
- ret = process_log_gzstream (f);
+ ret = process_log_gzstream (f, since);
gzclose (f);
} else {
FILE *f;
@@ -143,7 +176,7 @@ process_log_file (const char *filename)
g_strerror (errno));
return FALSE;
}
- ret = process_log_stream (f);
+ ret = process_log_stream (f, since);
fclose (f);
}
@@ -180,11 +213,14 @@ get_log_file_list (void)
files = g_list_prepend (files, filename);
};
+ /* Return the list in reverse time order, newest first */
+ files = g_list_reverse (files);
+
return files;
}
static gboolean
-process_logs (void)
+process_logs (GTimeVal *since)
{
gboolean ret;
GList *files;
@@ -199,8 +235,7 @@ process_logs (void)
char *filename;
filename = l->data;
-
- res = process_log_file (filename);
+ res = process_log_file (filename, since);
if (! res) {
goto out;
}
@@ -843,6 +878,8 @@ main (int argc,
GError *error = NULL;
int report_type;
int uid;
+ GTimeVal timestamp;
+ gboolean use_since;
static gboolean do_version = FALSE;
static gboolean report_last_compat = FALSE;
static gboolean report_last = FALSE;
@@ -851,6 +888,7 @@ main (int argc,
static char *username = NULL;
static char *seat = NULL;
static char *session_type = NULL;
+ static char *since = NULL;
static GOptionEntry entries [] = {
{ "version", 'V', 0, G_OPTION_ARG_NONE, &do_version, N_("Version of this application"), NULL },
{ "frequent", 0, 0, G_OPTION_ARG_NONE, &report_frequent, N_("Show listing of frequent users"), NULL },
@@ -860,6 +898,7 @@ main (int argc,
{ "seat", 's', 0, G_OPTION_ARG_STRING, &seat, N_("Show entries for the specified seat"), N_("SEAT") },
{ "session-type", 't', 0, G_OPTION_ARG_STRING, &session_type, N_("Show entries for the specified session type"), N_("TYPE") },
{ "user", 'u', 0, G_OPTION_ARG_STRING, &username, N_("Show entries for the specified user"), N_("NAME") },
+ { "since", 0, 0, G_OPTION_ARG_STRING, &since, N_("Show entries since the specified time (ISO 8601 format)"), N_("DATETIME") },
{ NULL }
};
@@ -880,6 +919,15 @@ main (int argc,
exit (1);
}
+ use_since = FALSE;
+ if (since != NULL) {
+ use_since = g_time_val_from_iso8601 (since, &timestamp);
+ if (! use_since) {
+ g_warning ("Invalid ISO 8601 time value");
+ exit (1);
+ }
+ }
+
if (report_last_compat) {
report_type = REPORT_TYPE_LAST_COMPAT;
} else if (report_last) {
@@ -902,7 +950,11 @@ main (int argc,
uid = -1;
}
- process_logs ();
+ if (use_since) {
+ process_logs (&timestamp);
+ } else {
+ process_logs (NULL);
+ }
generate_report (report_type, uid, seat, session_type);
free_events ();