[gnome-control-center] log: Reimplement logging and debugging



commit 1187f147af7a63583ff3acc62cf2cfe9fa7e8882
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Fri Apr 6 23:18:26 2018 -0300

    log: Reimplement logging and debugging
    
    This commit replaces the old rudimentary log handler
    by a shinier version of it. It also introduces the
    debugging macros that I usually add to the apps,
    including the CC_TRACE_MSG() macro for tracing.

 meson.build            |   8 ++
 meson_options.txt      |   1 +
 shell/cc-application.c |   6 +-
 shell/cc-debug.h.in    | 229 +++++++++++++++++++++++++++++++++++++++++++++++++
 shell/cc-log.c         | 107 +++++++++++++++++++++++
 shell/cc-log.h         |  25 ++++++
 shell/cc-shell-log.c   |  62 -------------
 shell/cc-shell-log.h   |  32 -------
 shell/meson.build      |  13 ++-
 9 files changed, 386 insertions(+), 97 deletions(-)
---
diff --git a/meson.build b/meson.build
index 20aeb9fc1..dfc14f106 100644
--- a/meson.build
+++ b/meson.build
@@ -25,6 +25,9 @@ host_is_linux_not_s390 = host_is_linux and not host_machine.cpu().contains('s390
 
 cc = meson.get_compiler('c')
 
+# Tracing
+enable_tracing = get_option('tracing')
+
 config_h = configuration_data()
 
 # defines
@@ -269,5 +272,10 @@ output += '** NetworkManager (Network panel): ' + host_is_linux.to_string() + '\
 output += '** wacom (Wacom tablet panel): ' + host_is_linux_not_s390.to_string() + '\n'
 output += '** Wayland: ' + enable_wayland.to_string() + '\n'
 output += '** gnome-session libexecdir: ' + gnome_session_libexecdir + '\n'
+
+if enable_tracing
+  output += '** Tracing enabled \n'
+endif
+
 output += 'End options'
 message(output)
diff --git a/meson_options.txt b/meson_options.txt
index 7498af4d6..a01c11553 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -2,4 +2,5 @@ option('cheese', type: 'boolean', value: true, description: 'build with cheese w
 option('documentation', type: 'boolean', value: false, description: 'build documentation')
 option('gnome_session_libexecdir', type: 'string', value: '', description: 'Directory for gnome-session\'s 
libexecdir')
 option('ibus', type: 'boolean', value: true, description: 'build with IBus support')
+option('tracing', type: 'boolean', value: false, description: 'add extra debugging information')
 option('wayland', type: 'boolean', value: true, description: 'build with Wayland support')
diff --git a/shell/cc-application.c b/shell/cc-application.c
index 144cbeeb6..3f828f3a6 100644
--- a/shell/cc-application.c
+++ b/shell/cc-application.c
@@ -26,9 +26,9 @@
 #include <gio/gio.h>
 
 #include "cc-application.h"
+#include "cc-log.h"
 #include "cc-object-storage.h"
 #include "cc-panel-loader.h"
-#include "cc-shell-log.h"
 #include "cc-window.h"
 
 #if defined(HAVE_WACOM) || defined(HAVE_CHEESE)
@@ -158,7 +158,9 @@ cc_application_command_line (GApplication            *application,
   options = g_application_command_line_get_options_dict (command_line);
 
   debug = g_variant_dict_contains (options, "verbose");
-  cc_shell_log_set_debug (debug);
+
+  if (debug)
+    cc_log_init ();
 
   gtk_window_present (GTK_WINDOW (self->window));
 
diff --git a/shell/cc-debug.h.in b/shell/cc-debug.h.in
new file mode 100644
index 000000000..72962970d
--- /dev/null
+++ b/shell/cc-debug.h.in
@@ -0,0 +1,229 @@
+/* cc-debug.h.in
+ *
+ * Copyright © 2018 Georges Basile Stavracas Neto <georges stavracas gmail com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include <glib.h>
+
+/**
+ * SECTION:cc-debug
+ * @short_description: Debugging macros
+ * @title:Debugging
+ * @stability:stable
+ *
+ * Macros used for tracing and debugging code. These
+ * are only valid when Calendar is compiled with tracing
+ * suppoer (pass `--enable-tracing` to the configure
+ * script to do that).
+ */
+
+G_BEGIN_DECLS
+
+#ifndef CC_ENABLE_TRACE
+# define CC_ENABLE_TRACE @ENABLE_TRACING@
+#endif
+#if CC_ENABLE_TRACE != 1
+# undef CC_ENABLE_TRACE
+#endif
+
+/**
+ * CC_LOG_LEVEL_TRACE: (skip)
+ */
+#ifndef CC_LOG_LEVEL_TRACE
+# define CC_LOG_LEVEL_TRACE ((GLogLevelFlags)(1 << G_LOG_LEVEL_USER_SHIFT))
+#endif
+
+#ifdef CC_ENABLE_TRACE
+
+/**
+ * CC_TRACE_MSG:
+ * @fmt: printf-like format of the message
+ * @...: arguments for @fmt
+ *
+ * Prints a trace message.
+ */
+# define CC_TRACE_MSG(fmt, ...)                                        \
+   g_log(G_LOG_DOMAIN, CC_LOG_LEVEL_TRACE, "  MSG: %s():%d: " fmt,     \
+         G_STRFUNC, __LINE__, ##__VA_ARGS__)
+
+/**
+ * CC_PROBE:
+ *
+ * Prints a probing message. Put this macro in the code when
+ * you want to check the program reaches a certain section
+ * of code.
+ */
+# define CC_PROBE                                                      \
+   g_log(G_LOG_DOMAIN, CC_LOG_LEVEL_TRACE, "PROBE: %s():%d",           \
+         G_STRFUNC, __LINE__)
+
+/**
+ * CC_TODO:
+ * @_msg: the message to print
+ *
+ * Prints a TODO message.
+ */
+# define CC_TODO(_msg)                                                 \
+   g_log(G_LOG_DOMAIN, CC_LOG_LEVEL_TRACE, " TODO: %s():%d: %s",       \
+         G_STRFUNC, __LINE__, _msg)
+
+/**
+ * CC_ENTRY:
+ *
+ * Prints an entry message. This shouldn't be used in
+ * critical functions. Place this at the beggining of
+ * the function, before any assertion.
+ */
+# define CC_ENTRY                                                      \
+   g_log(G_LOG_DOMAIN, CC_LOG_LEVEL_TRACE, "ENTRY: %s():%d",           \
+         G_STRFUNC, __LINE__)
+
+/**
+ * CC_EXIT:
+ *
+ * Prints an exit message. This shouldn't be used in
+ * critical functions. Place this at the end of
+ * the function, after any relevant code. If the
+ * function returns something, use CC_RETURN()
+ * instead.
+ */
+# define CC_EXIT                                                       \
+   G_STMT_START {                                                        \
+      g_log(G_LOG_DOMAIN, CC_LOG_LEVEL_TRACE, " EXIT: %s():%d",        \
+            G_STRFUNC, __LINE__);                                        \
+      return;                                                            \
+   } G_STMT_END
+
+/**
+ * CC_GOTO:
+ * @_l: goto tag
+ *
+ * Logs a goto jump.
+ */
+# define CC_GOTO(_l)                                                   \
+   G_STMT_START {                                                        \
+      g_log(G_LOG_DOMAIN, CC_LOG_LEVEL_TRACE, " GOTO: %s():%d ("#_l")",\
+            G_STRFUNC, __LINE__);                                        \
+      goto _l;                                                           \
+   } G_STMT_END
+
+/**
+ * CC_RETURN:
+ * @_r: the return value.
+ *
+ * Prints an exit message, and returns @_r. See #CC_EXIT.
+ */
+# define CC_RETURN(_r)                                                 \
+   G_STMT_START {                                                        \
+      g_log(G_LOG_DOMAIN, CC_LOG_LEVEL_TRACE, " EXIT: %s():%d ",       \
+            G_STRFUNC, __LINE__);                                        \
+      return _r;                                                         \
+   } G_STMT_END
+
+#else
+
+/**
+ * CC_TODO:
+ * @_msg: the message to print
+ *
+ * Prints a TODO message.
+ */
+# define CC_TODO(_msg)
+
+/**
+ * CC_PROBE:
+ *
+ * Prints a probing message.
+ */
+# define CC_PROBE
+
+/**
+ * CC_TRACE_MSG:
+ * @fmt: printf-like format of the message
+ * @...: arguments for @fmt
+ *
+ * Prints a trace message.
+ */
+# define CC_TRACE_MSG(fmt, ...)
+
+/**
+ * CC_ENTRY:
+ *
+ * Prints a probing message. This shouldn't be used in
+ * critical functions. Place this at the beggining of
+ * the function, before any assertion.
+ */
+# define CC_ENTRY
+
+/**
+ * CC_GOTO:
+ * @_l: goto tag
+ *
+ * Logs a goto jump.
+ */
+# define CC_GOTO(_l)   goto _l
+
+/**
+ * CC_EXIT:
+ *
+ * Prints an exit message. This shouldn't be used in
+ * critical functions. Place this at the end of
+ * the function, after any relevant code. If the
+ * function returns somethin, use CC_RETURN()
+ * instead.
+ */
+# define CC_EXIT       return
+
+/**
+ * CC_RETURN:
+ * @_r: the return value.
+ *
+ * Prints an exit message, and returns @_r. See #CC_EXIT.
+ */
+# define CC_RETURN(_r) return _r
+#endif
+
+/**
+ * _CC_BUG: (skip)
+ */
+#define _CC_BUG(Component, Description, File, Line, Func, ...)                        \
+  G_STMT_START {                                                                        \
+    g_printerr ("-----------------------------------------------------------------\n"); \
+    g_printerr ("You've found a bug in Calendar or one of its dependent libraries.\n"); \
+    g_printerr ("Please help us help you by filing a bug report at:\n");                \
+    g_printerr ("\n");                                                                  \
+    g_printerr ("@BUGREPORT_URL@&component=%s\n", Component);                           \
+    g_printerr ("\n");                                                                  \
+    g_printerr ("%s:%d in function %s()\n", File, Line, Func);                          \
+    g_printerr ("\n");                                                                  \
+    g_printerr (Description"\n", ##__VA_ARGS__);                                        \
+    g_printerr ("-----------------------------------------------------------------\n"); \
+  } G_STMT_END
+
+/**
+ * CC_BUG:
+ * @Component: the component
+ * @Description: the description
+ * @...: extra arguments
+ *
+ * Logs a bug-friendly message.
+ */
+#define CC_BUG(Component, Description, ...) \
+  _CC_BUG(Component, Description, __FILE__, __LINE__, G_STRFUNC, ##__VA_ARGS__)
+
+G_END_DECLS
diff --git a/shell/cc-log.c b/shell/cc-log.c
new file mode 100644
index 000000000..5f6645cbe
--- /dev/null
+++ b/shell/cc-log.c
@@ -0,0 +1,107 @@
+/* cc-shell-log.c
+ *
+ * Copyright © 2018 Georges Basile Stavracas Neto <georges stavracas gmail com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cc-debug.h"
+#include "cc-log.h"
+
+#include <unistd.h>
+#include <glib.h>
+
+G_LOCK_DEFINE_STATIC (channel_lock);
+
+GIOChannel *standard_channel = NULL;
+
+static const gchar* ignored_domains[] =
+{
+  "GdkPixbuf",
+  NULL
+};
+
+static const gchar *
+log_level_str (GLogLevelFlags log_level)
+{
+  switch (((gulong)log_level & G_LOG_LEVEL_MASK))
+    {
+    case G_LOG_LEVEL_ERROR:    return "   \033[1;31mERROR\033[0m";
+    case G_LOG_LEVEL_CRITICAL: return "\033[1;35mCRITICAL\033[0m";
+    case G_LOG_LEVEL_WARNING:  return " \033[1;33mWARNING\033[0m";
+    case G_LOG_LEVEL_MESSAGE:  return " \033[1;34mMESSAGE\033[0m";
+    case G_LOG_LEVEL_INFO:     return "    \033[1;32mINFO\033[0m";
+    case G_LOG_LEVEL_DEBUG:    return "   \033[1;32mDEBUG\033[0m";
+    case CC_LOG_LEVEL_TRACE:   return "   \033[1;36mTRACE\033[0m";
+    default:                   return " UNKNOWN";
+    }
+}
+
+static void
+log_handler (const gchar    *domain,
+             GLogLevelFlags  log_level,
+             const gchar    *message,
+             gpointer        user_data)
+{
+  GTimeVal tv;
+  struct tm tt;
+  time_t t;
+  const gchar *level;
+  gchar ftime[32];
+  gchar *buffer;
+
+  /* Skip ignored log domains */
+  if (domain && g_strv_contains (ignored_domains, domain))
+    return;
+
+  level = log_level_str (log_level);
+  g_get_current_time (&tv);
+  t = (time_t) tv.tv_sec;
+  tt = *localtime (&t);
+  strftime (ftime, sizeof (ftime), "%H:%M:%S", &tt);
+  buffer = g_strdup_printf ("%s.%04ld  %24s: %s: %s\n",
+                            ftime,
+                            tv.tv_usec / 1000,
+                            domain,
+                            level,
+                            message);
+
+  /* Safely write to the channel */
+  G_LOCK (channel_lock);
+
+  g_io_channel_write_chars (standard_channel, buffer, -1, NULL, NULL);
+  g_io_channel_flush (standard_channel, NULL);
+
+  G_UNLOCK (channel_lock);
+
+  g_free (buffer);
+}
+
+void
+cc_log_init (void)
+{
+  static gsize initialized = FALSE;
+
+  if (g_once_init_enter (&initialized))
+    {
+      standard_channel = g_io_channel_unix_new (STDOUT_FILENO);
+
+      g_setenv ("G_MESSAGES_DEBUG", "all", TRUE);
+
+      g_log_set_default_handler (log_handler, NULL);
+
+      g_once_init_leave (&initialized, TRUE);
+    }
+}
+
diff --git a/shell/cc-log.h b/shell/cc-log.h
new file mode 100644
index 000000000..2d04c0ba7
--- /dev/null
+++ b/shell/cc-log.h
@@ -0,0 +1,25 @@
+/* cc-log.h
+ *
+ * Copyright © 2018 Georges Basile Stavracas Neto <georges stavracas gmail com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+G_BEGIN_DECLS
+
+void cc_log_init (void);
+
+G_END_DECLS
diff --git a/shell/meson.build b/shell/meson.build
index 0946ada74..62270358c 100644
--- a/shell/meson.build
+++ b/shell/meson.build
@@ -46,12 +46,12 @@ common_sources = files(
   'cc-application.c',
   'cc-editable-entry.c',
   'cc-hostname-entry.c',
+  'cc-log.c',
   'cc-object-storage.c',
   'cc-panel-loader.c',
   'cc-panel.c',
   'cc-shell-category-view.c',
   'cc-shell-item-view.c',
-  'cc-shell-log.c',
   'cc-shell.c',
   'hostname-helper.c',
   'list-box-helper.c',
@@ -91,6 +91,17 @@ if host_is_linux_not_s390
   shell_deps += wacom_deps
 endif
 
+# Debug
+debug_conf = configuration_data()
+debug_conf.set('BUGREPORT_URL', 'http://bugzilla.gnome.org/enter_bug.cgi?product=' + meson.project_name())
+debug_conf.set10('ENABLE_TRACING', enable_tracing)
+
+sources += configure_file(
+  input: 'cc-debug.h.in',
+  output: 'cc-debug.h',
+  configuration: debug_conf
+)
+
 executable(
   meson.project_name(),
   sources,


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