summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Hughes <richard@hughsie.com>2010-09-17 16:15:38 +0100
committerRichard Hughes <richard@hughsie.com>2010-09-17 16:15:38 +0100
commit260e62d872f6433348469500247b4db3ae11dd7b (patch)
tree00a32e64d551791c3011e22f3d99d0d3fc712f5c
parent7e45ad91ed0b990ca6ca80a962a6c464a094a712 (diff)
Only save by default 7 days data to stop the log files becoming huge. Fixes rh#634228
Parsing huge log files at startup will demolish startup time. Cull old entries when the file is resaved to keep them sane. Also add the needed self tests to check this in the future.
-rw-r--r--src/up-history.c88
-rw-r--r--src/up-history.h8
-rw-r--r--src/up-self-test.c109
3 files changed, 176 insertions, 29 deletions
diff --git a/src/up-history.c b/src/up-history.c
index ef8e542..aa6689e 100644
--- a/src/up-history.c
+++ b/src/up-history.c
@@ -36,7 +36,9 @@ static void up_history_finalize (GObject *object);
#define UP_HISTORY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), UP_TYPE_HISTORY, UpHistoryPrivate))
-#define UP_HISTORY_SAVE_INTERVAL 10*60 /* seconds */
+#define UP_HISTORY_FILE_HEADER "PackageKit Profile"
+#define UP_HISTORY_SAVE_INTERVAL (10*60) /* seconds */
+#define UP_HISTORY_DEFAULT_MAX_DATA_AGE (7*24*60*60) /* seconds */
struct UpHistoryPrivate
{
@@ -51,6 +53,7 @@ struct UpHistoryPrivate
GPtrArray *data_time_full;
GPtrArray *data_time_empty;
guint save_id;
+ guint max_data_age;
};
enum {
@@ -59,7 +62,15 @@ enum {
};
G_DEFINE_TYPE (UpHistory, up_history, G_TYPE_OBJECT)
-#define UP_HISTORY_FILE_HEADER "PackageKit Profile"
+
+/**
+ * up_history_set_max_data_age:
+ **/
+void
+up_history_set_max_data_age (UpHistory *history, guint max_data_age)
+{
+ history->priv->max_data_age = max_data_age;
+}
/**
* up_history_array_copy_cb:
@@ -397,7 +408,7 @@ up_history_get_filename (UpHistory *history, const gchar *type)
* Saves a copy of the list to a file
**/
static gboolean
-up_history_array_to_file (GPtrArray *list, const gchar *filename)
+up_history_array_to_file (UpHistory *history, GPtrArray *list, const gchar *filename)
{
guint i;
UpHistoryItem *item;
@@ -405,11 +416,24 @@ up_history_array_to_file (GPtrArray *list, const gchar *filename)
GString *string;
gboolean ret = TRUE;
GError *error = NULL;
+ GTimeVal time_now;
+ guint time_item;
+ guint cull_count = 0;
+
+ /* get current time */
+ g_get_current_time (&time_now);
/* generate data */
string = g_string_new ("");
for (i=0; i<list->len; i++) {
item = g_ptr_array_index (list, i);
+
+ /* only save entries for the last 24 hours */
+ time_item = up_history_item_get_time (item);
+ if (time_now.tv_sec - time_item > history->priv->max_data_age) {
+ cull_count++;
+ continue;
+ }
part = up_history_item_to_string (item);
if (part == NULL) {
ret = FALSE;
@@ -420,6 +444,9 @@ up_history_array_to_file (GPtrArray *list, const gchar *filename)
}
part = g_string_free (string, FALSE);
+ /* how many did we kill? */
+ egg_debug ("culled %i of %i", cull_count, list->len);
+
/* we failed to convert to string */
if (!ret) {
egg_warning ("failed to convert");
@@ -499,38 +526,46 @@ out:
/**
* up_history_save_data:
**/
-static gboolean
+gboolean
up_history_save_data (UpHistory *history)
{
- gchar *filename;
+ gboolean ret = FALSE;
+ gchar *filename_rate = NULL;
+ gchar *filename_charge = NULL;
+ gchar *filename_time_full = NULL;
+ gchar *filename_time_empty = NULL;
/* we have an ID? */
if (history->priv->id == NULL) {
egg_warning ("no ID, cannot save");
- return FALSE;
+ goto out;
}
- /* save rate history to disk */
- filename = up_history_get_filename (history, "rate");
- up_history_array_to_file (history->priv->data_rate, filename);
- g_free (filename);
+ /* get filenames */
+ filename_rate = up_history_get_filename (history, "rate");
+ filename_charge = up_history_get_filename (history, "charge");
+ filename_time_full = up_history_get_filename (history, "time-full");
+ filename_time_empty = up_history_get_filename (history, "time-empty");
- /* save charge history to disk */
- filename = up_history_get_filename (history, "charge");
- up_history_array_to_file (history->priv->data_charge, filename);
- g_free (filename);
-
- /* save charge history to disk */
- filename = up_history_get_filename (history, "time-full");
- up_history_array_to_file (history->priv->data_time_full, filename);
- g_free (filename);
-
- /* save charge history to disk */
- filename = up_history_get_filename (history, "time-empty");
- up_history_array_to_file (history->priv->data_time_empty, filename);
- g_free (filename);
-
- return TRUE;
+ /* save to disk */
+ ret = up_history_array_to_file (history, history->priv->data_rate, filename_rate);
+ if (!ret)
+ goto out;
+ ret = up_history_array_to_file (history, history->priv->data_charge, filename_charge);
+ if (!ret)
+ goto out;
+ ret = up_history_array_to_file (history, history->priv->data_time_full, filename_time_full);
+ if (!ret)
+ goto out;
+ ret = up_history_array_to_file (history, history->priv->data_time_empty, filename_time_empty);
+ if (!ret)
+ goto out;
+out:
+ g_free (filename_rate);
+ g_free (filename_charge);
+ g_free (filename_time_full);
+ g_free (filename_time_empty);
+ return ret;
}
/**
@@ -842,6 +877,7 @@ up_history_init (UpHistory *history)
history->priv->data_time_full = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
history->priv->data_time_empty = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
history->priv->save_id = 0;
+ history->priv->max_data_age = UP_HISTORY_DEFAULT_MAX_DATA_AGE;
}
/**
diff --git a/src/up-history.h b/src/up-history.h
index f29879a..50b506d 100644
--- a/src/up-history.h
+++ b/src/up-history.h
@@ -60,8 +60,7 @@ typedef enum {
GType up_history_get_type (void);
-UpHistory *up_history_new (void);
-void up_history_test (gpointer user_data);
+UpHistory *up_history_new (void);
GPtrArray *up_history_get_data (UpHistory *history,
UpHistoryType type,
@@ -79,8 +78,11 @@ gboolean up_history_set_rate_data (UpHistory *history,
gdouble rate);
gboolean up_history_set_time_full_data (UpHistory *history,
gint64 time);
-gboolean up_history_set_time_empty_data (UpHistory *history,
+gboolean up_history_set_time_empty_data (UpHistory *history,
gint64 time);
+void up_history_set_max_data_age (UpHistory *history,
+ guint max_data_age);
+gboolean up_history_save_data (UpHistory *history);
G_END_DECLS
diff --git a/src/up-self-test.c b/src/up-self-test.c
index dfcb202..5efe6ef 100644
--- a/src/up-self-test.c
+++ b/src/up-self-test.c
@@ -22,6 +22,8 @@
#include "config.h"
#include <glib-object.h>
+#include <glib/gstdio.h>
+#include <up-history-item.h>
#include "egg-debug.h"
#include "up-backend.h"
@@ -113,15 +115,121 @@ up_test_device_list_func (void)
}
static void
+up_test_history_remove_temp_files (void)
+{
+ gchar *filename;
+ filename = g_build_filename (PACKAGE_LOCALSTATE_DIR, "lib", "upower", "history-time-full-test.dat", NULL);
+ g_unlink (filename);
+ g_free (filename);
+ filename = g_build_filename (PACKAGE_LOCALSTATE_DIR, "lib", "upower", "history-time-empty-test.dat", NULL);
+ g_unlink (filename);
+ g_free (filename);
+ filename = g_build_filename (PACKAGE_LOCALSTATE_DIR, "lib", "upower", "history-charge-test.dat", NULL);
+ g_unlink (filename);
+ g_free (filename);
+ filename = g_build_filename (PACKAGE_LOCALSTATE_DIR, "lib", "upower", "history-rate-test.dat", NULL);
+ g_unlink (filename);
+ g_free (filename);
+}
+
+static void
up_test_history_func (void)
{
UpHistory *history;
+ gboolean ret;
+ GPtrArray *array;
+ gchar *filename;
+ UpHistoryItem *item;
history = up_history_new ();
g_assert (history != NULL);
+ /* is this a distcheck with no writable root? */
+ if (g_strstr_len (PACKAGE_LOCALSTATE_DIR, -1, "_inst") != NULL)
+ goto distcheck_skip;
+
+ /* remove previous test files */
+ up_test_history_remove_temp_files ();
+
+ /* setup fresh environment */
+ ret = up_history_set_id (history, "test");
+ g_assert (ret);
+
+ /* get nonexistant data */
+ array = up_history_get_data (history, UP_HISTORY_TYPE_CHARGE, 10, 100);
+ g_assert (array != NULL);
+ g_assert_cmpint (array->len, ==, 0);
+
+ /* setup some fake device */
+ up_history_set_state (history, UP_DEVICE_STATE_CHARGING);
+ up_history_set_charge_data (history, 90);
+ up_history_set_rate_data (history, 1.00f);
+ up_history_set_time_empty_data (history, 12345);
+ up_history_set_time_full_data (history, 54321);
+
+ /* sleep for a little bit */
+ g_usleep (3 * G_USEC_PER_SEC);
+ up_history_set_charge_data (history, 91);
+ up_history_set_rate_data (history, 1.01f);
+ up_history_set_time_empty_data (history, 12344);
+ up_history_set_time_full_data (history, 54320);
+
+ /* get data for last 10 seconds */
+ array = up_history_get_data (history, UP_HISTORY_TYPE_CHARGE, 10, 100);
+ g_assert (array != NULL);
+ g_assert_cmpint (array->len, ==, 2);
+
+ /* get the first item, which should be the most recent */
+ item = g_ptr_array_index (array, 0);
+ g_assert (item != NULL);
+ g_assert_cmpint (up_history_item_get_value (item), ==, 91);
+ g_assert_cmpint (up_history_item_get_time (item), >, 1000000);
+ g_ptr_array_unref (array);
+
+ /* force a save to disk */
+ ret = up_history_save_data (history);
+ g_assert (ret);
+ g_object_unref (history);
+
+ /* ensure the file was created */
+ filename = g_build_filename (PACKAGE_LOCALSTATE_DIR, "lib", "upower", "history-charge-test.dat", NULL);
+ g_assert (g_file_test (filename, G_FILE_TEST_EXISTS));
+ g_free (filename);
+
+ /* ensure we can load from disk */
+ history = up_history_new ();
+ up_history_set_id (history, "test");
+
+ /* get data for last 10 seconds */
+ array = up_history_get_data (history, UP_HISTORY_TYPE_CHARGE, 10, 100);
+ g_assert (array != NULL);
+ g_assert_cmpint (array->len, ==, 3); /* we have inserted an unknown as the first entry */
+ item = g_ptr_array_index (array, 1);
+ g_assert (item != NULL);
+ g_assert_cmpint (up_history_item_get_value (item), ==, 91);
+ g_assert_cmpint (up_history_item_get_time (item), >, 1000000);
+ g_ptr_array_unref (array);
+
+ /* ensure old entries are purged */
+ up_history_set_max_data_age (history, 2);
+ g_usleep (2 * G_USEC_PER_SEC);
+ g_object_unref (history);
+
+ /* ensure only 2 points are returned */
+ history = up_history_new ();
+ up_history_set_id (history, "test");
+ array = up_history_get_data (history, UP_HISTORY_TYPE_CHARGE, 10, 100);
+ g_assert (array != NULL);
+ g_assert_cmpint (array->len, ==, 2);
+ g_ptr_array_unref (array);
+
+distcheck_skip:
+
/* unref */
g_object_unref (history);
+
+ /* remove these test files */
+ up_test_history_remove_temp_files ();
}
static void
@@ -165,6 +273,7 @@ main (int argc, char **argv)
{
g_type_init ();
g_test_init (&argc, &argv, NULL);
+ egg_debug_init (&argc, &argv);
/* tests go here */
g_test_add_func ("/power/backend", up_test_backend_func);