diff options
author | Philip Withnall <philip@tecnocode.co.uk> | 2011-04-23 01:14:20 +0100 |
---|---|---|
committer | Philip Withnall <philip@tecnocode.co.uk> | 2011-05-02 21:23:58 +0100 |
commit | 4292b07504c13e70fba6c1b23b1a043cb2120fa3 (patch) | |
tree | cf5a93d5d4e9ef50850ce7454e6d5879e38db8a1 /folks | |
parent | 26ea12bdcfbca8ba00b859a59db357a9608e5b39 (diff) |
Allow printing out status information at runtime
When Folks.Debug.print-status is emitted, BackendStore, IndividualAggregator
and Tpf.PersonaStore will now print out their status, including a list
of all the loaded backends, persona stores, aggregated individuals and their
personas.
Folks.Debug.print-status could be emitted as a result of the client process
receiving SIGUSR2, for example.
Helps: bgo#648533
Diffstat (limited to 'folks')
-rw-r--r-- | folks/backend-store.vala | 69 | ||||
-rw-r--r-- | folks/debug.vala | 50 | ||||
-rw-r--r-- | folks/individual-aggregator.vala | 85 |
3 files changed, 204 insertions, 0 deletions
diff --git a/folks/backend-store.vala b/folks/backend-store.vala index 18ee698..d8c21d8 100644 --- a/folks/backend-store.vala +++ b/folks/backend-store.vala @@ -139,6 +139,8 @@ public class Folks.BackendStore : Object { /* register the core debug messages */ this._debug._register_domain (G_LOG_DOMAIN); + this._debug.print_status.connect (this._debug_print_status); + this._modules = new HashMap<string,unowned Module> (str_hash, str_equal); this._backend_hash = new HashMap<string,Backend> (str_hash, str_equal); this._prepared_backends = new HashMap<string,Backend> (str_hash, @@ -159,10 +161,77 @@ public class Folks.BackendStore : Object { } } + /* Disconnect from the debug handler */ + this._debug.print_status.disconnect (this._debug_print_status); + this._debug = null; + /* manually clear the singleton instance */ _instance = null; } + private void _debug_print_status (Debug debug) + { + const string domain = Debug.STATUS_LOG_DOMAIN; + const LogLevelFlags level = LogLevelFlags.LEVEL_INFO; + + debug.print_heading (domain, level, "BackendStore (%p)", this); + debug.print_line (domain, level, "%u Backends:", + this._backend_hash.size); + + debug.indent (); + + foreach (var backend in this._backend_hash.values) + { + debug.print_heading (domain, level, "Backend (%p)", backend); + debug.print_key_value_pairs (domain, level, + "Ref. count", this.ref_count.to_string (), + "Name", backend.name, + "Prepared?", backend.is_prepared ? "yes" : "no" + ); + debug.print_line (domain, level, "%u PersonaStores:", + backend.persona_stores.size); + + debug.indent (); + + foreach (var persona_store in backend.persona_stores.values) + { + string trust_level = null; + + switch (persona_store.trust_level) + { + case PersonaStoreTrust.NONE: + trust_level = "none"; + break; + case PersonaStoreTrust.PARTIAL: + trust_level = "partial"; + break; + case PersonaStoreTrust.FULL: + trust_level = "full"; + break; + default: + assert_not_reached (); + } + + debug.print_heading (domain, level, "PersonaStore (%p)", + persona_store); + debug.print_key_value_pairs (domain, level, + "Ref. count", this.ref_count.to_string (), + "ID", persona_store.id, + "Prepared?", persona_store.is_prepared ? "yes" : "no", + "Writeable?", persona_store.is_writeable ? "yes" : "no", + "Trust level", trust_level, + "Persona count", persona_store.personas.size.to_string () + ); + } + + debug.unindent (); + } + + debug.unindent (); + + debug.print_line (domain, level, ""); + } + /** * Prepare the BackendStore for use. * diff --git a/folks/debug.vala b/folks/debug.vala index 5bade93..6acad1d 100644 --- a/folks/debug.vala +++ b/folks/debug.vala @@ -114,6 +114,38 @@ public class Folks.Debug : Object } } + /** + * Signal emitted in the main thread whenever objects should print their + * current status. All significant objects in the library should connect + * to this and print their current status in some suitable format when it's + * emitted. + * + * Client processes should emit this signal by calling + * {@link Debug.emit_print_status}. + * + * @since UNRELEASED + */ + public signal void print_status (); + + /** + * Log domain for the status messages logged as a result of calling + * {@link Debug.emit_print_status(). + * + * This could be used in conjunction with a log handler to redirect the + * status information to a debug window or log file, for example. + * + * @since UNRELEASED + */ + public const string STATUS_LOG_DOMAIN = "folks-status"; + + private void _print_status_log_handler_cb (string? log_domain, + LogLevelFlags log_levels, + string message) + { + /* Print directly to stdout without any adornments */ + GLib.stdout.printf ("%s\n", message); + } + private void _log_handler_cb (string? log_domain, LogLevelFlags log_levels, string message) @@ -222,6 +254,11 @@ public class Folks.Debug : Object private Debug () { /* Private constructor for singleton */ + + /* Install a log handler for log messages emitted as a result of + * Debug.print-status being emitted. */ + Log.set_handler (Debug.STATUS_LOG_DOMAIN, LogLevelFlags.LEVEL_MASK, + this._print_status_log_handler_cb); } ~Debug () @@ -234,6 +271,19 @@ public class Folks.Debug : Object } /** + * Causes all significant objects in the library to print their current + * status to standard output, obeying the options set on this + * {@link Debug} instance for colouring and other formatting. + * + * @since UNRELEASED + */ + public void emit_print_status () + { + print ("Dumping status information…\n"); + this.print_status (); + } + + /** * Increment the indentation level used when printing output through the * object. * diff --git a/folks/individual-aggregator.vala b/folks/individual-aggregator.vala index be208e7..ddaf293 100644 --- a/folks/individual-aggregator.vala +++ b/folks/individual-aggregator.vala @@ -63,6 +63,7 @@ public class Folks.IndividualAggregator : Object private HashTable<string, Individual> _link_map; private bool _linking_enabled = true; private bool _is_prepared = false; + private Debug _debug; private string _configured_writeable_store_type_id; private static const string _FOLKS_CONFIG_KEY = "/system/folks/backends/primary_store"; @@ -176,6 +177,8 @@ public class Folks.IndividualAggregator : Object this._link_map = new HashTable<string, Individual> (str_hash, str_equal); this._backends = new HashSet<Backend> (); + this._debug = Debug.dup (); + this._debug.print_status.connect (this._debug_print_status); /* Check out the configured writeable store */ var store_type_id = Environment.get_variable ("FOLKS_WRITEABLE_STORE"); @@ -215,6 +218,88 @@ public class Folks.IndividualAggregator : Object this._backend_store.backend_available.disconnect ( this._backend_available_cb); this._backend_store = null; + + this._debug.print_status.disconnect (this._debug_print_status); + } + + private void _debug_print_status (Debug debug) + { + const string domain = Debug.STATUS_LOG_DOMAIN; + const LogLevelFlags level = LogLevelFlags.LEVEL_INFO; + + debug.print_heading (domain, level, "IndividualAggregator (%p)", this); + debug.print_key_value_pairs (domain, level, + "Ref. count", this.ref_count.to_string (), + "Writeable store", "%p".printf (this._writeable_store), + "Linking enabled?", this._linking_enabled ? "yes" : "no", + "Prepared?", this._is_prepared ? "yes" : "no" + ); + + debug.print_line (domain, level, + "%u Individuals:", this.individuals.size); + debug.indent (); + + foreach (var individual in this.individuals.values) + { + string trust_level = null; + + switch (individual.trust_level) + { + case TrustLevel.NONE: + trust_level = "none"; + break; + case TrustLevel.PERSONAS: + trust_level = "personas"; + break; + default: + assert_not_reached (); + } + + debug.print_heading (domain, level, "Individual (%p)", individual); + debug.print_key_value_pairs (domain, level, + "Ref. count", individual.ref_count.to_string (), + "ID", individual.id, + "User?", individual.is_user ? "yes" : "no", + "Trust level", trust_level + ); + debug.print_line (domain, level, "%u Personas:", + individual.personas.size); + + debug.indent (); + + foreach (var persona in individual.personas) + { + debug.print_heading (domain, level, "Persona (%p)", persona); + debug.print_key_value_pairs (domain, level, + "Ref. count", persona.ref_count.to_string (), + "UID", persona.uid, + "IID", persona.iid, + "Display ID", persona.display_id, + "User?", persona.is_user ? "yes" : "no" + ); + } + + debug.unindent (); + } + + debug.unindent (); + + debug.print_line (domain, level, "%u entries in the link map:", + this._link_map.size ()); + debug.indent (); + + var iter = HashTableIter<string, Individual> (this._link_map); + string link_key; + Individual individual; + while (iter.next (out link_key, out individual) == true) + { + debug.print_line (domain, level, + "%s → %p", link_key, individual); + } + + debug.unindent (); + + debug.print_line (domain, level, ""); } /** |