[gnome-todo] logging: Add logging capabilities



commit 18b41ff015359ed97a755a3eae08f046b5ada74b
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Thu Jan 18 19:37:41 2018 -0200

    logging: Add logging capabilities
    
    This makes debugging and logging messages a breeze.

 meson.build           |   2 +
 meson_options.txt     |   1 +
 src/gtd-application.c |   7 +-
 src/gtd-debug.h.in    | 229 ++++++++++++++++++++++++++++++++++++++++++++++++++
 src/logging/gtd-log.c | 107 +++++++++++++++++++++++
 src/logging/gtd-log.h |  27 ++++++
 src/meson.build       |  20 +++++
 7 files changed, 392 insertions(+), 1 deletion(-)
---
diff --git a/meson.build b/meson.build
index 9fb412a..69cc156 100644
--- a/meson.build
+++ b/meson.build
@@ -37,6 +37,7 @@ revision = 0
 libversion = '@0@.@1@.@2@'.format(soversion, current, revision)
 
 gnome_todo_debug = get_option('buildtype').contains('debug')
+gnome_todo_tracing = get_option('tracing')
 
 cc = meson.get_compiler('c')
 
@@ -46,6 +47,7 @@ config_h.set_quoted('GETTEXT_PACKAGE', meson.project_name())
 
 # debug options
 config_h.set('GNOME_TODO_ENABLE_DEBUG', gnome_todo_debug)
+config_h.set('ENABLE_TRACING', gnome_todo_tracing)
 config_h.set('NDEBUG', not gnome_todo_debug)
 
 # package
diff --git a/meson_options.txt b/meson_options.txt
index 359d0b5..f809050 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -6,5 +6,6 @@ option('today_panel_plugin', type: 'boolean', value: true, description: 'enable
 option('unscheduled_panel_plugin', type: 'boolean', value: true, description: 'enable Unscheduled Tasks 
Panel plugin')
 option('todo_txt_plugin', type: 'boolean', value: true, description: 'enable Todo.Txt plugin')
 option('todoist_plugin', type: 'boolean', value: true, description: 'enable Todoist plugin')
+option('tracing', type: 'boolean', value: false, description: 'enable application tracing')
 option('gtk_doc', type: 'boolean', value: false, description: 'use gtk-doc to build documentation')
 option('introspection', type: 'boolean', value: true, description: 'Enable GObject Introspection (depends on 
GObject)')
diff --git a/src/gtd-application.c b/src/gtd-application.c
index bbd6a52..b7c94e5 100644
--- a/src/gtd-application.c
+++ b/src/gtd-application.c
@@ -22,6 +22,7 @@
 
 #include "gtd-application.h"
 #include "gtd-initial-setup-window.h"
+#include "gtd-log.h"
 #include "gtd-manager.h"
 #include "gtd-manager-protected.h"
 #include "gtd-plugin-dialog.h"
@@ -67,7 +68,8 @@ static void           gtd_application_quit                        (GSimpleAction
 G_DEFINE_TYPE (GtdApplication, gtd_application, GTK_TYPE_APPLICATION)
 
 static GOptionEntry cmd_options[] = {
-  { "quit", 'q', 0, G_OPTION_ARG_NONE, NULL, N_("Quit GNOME To Do"), NULL }
+  { "quit", 'q', 0, G_OPTION_ARG_NONE, NULL, N_("Quit GNOME To Do"), NULL },
+  { "debug", 'd', 0, G_OPTION_ARG_NONE, NULL, N_("Enable debug messages"), NULL },
 };
 
 static const GActionEntry gtd_application_entries[] = {
@@ -299,6 +301,9 @@ gtd_application_command_line (GApplication            *app,
 
   options = g_application_command_line_get_options_dict (command_line);
 
+  if (g_variant_dict_contains (options, "debug"))
+    gtd_log_init ();
+
   if (g_variant_dict_contains (options, "quit"))
     {
       g_application_quit (app);
diff --git a/src/gtd-debug.h.in b/src/gtd-debug.h.in
new file mode 100644
index 0000000..7c66508
--- /dev/null
+++ b/src/gtd-debug.h.in
@@ -0,0 +1,229 @@
+/* gtd-debug.h.in
+ *
+ * Copyright (C) 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 3 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:gtd-debug
+ * @short_description: Debugging macros
+ * @title:Debugging
+ * @stability:stable
+ *
+ * Macros used for tracing and debugging code. These
+ * are only valid when To Do is compiled with tracing
+ * suppoer (pass `--enable-tracing` to the configure
+ * script to do that).
+ */
+
+G_BEGIN_DECLS
+
+#ifndef GTD_ENABLE_TRACE
+# define GTD_ENABLE_TRACE @ENABLE_TRACING@
+#endif
+#if GTD_ENABLE_TRACE != 1
+# undef GTD_ENABLE_TRACE
+#endif
+
+/**
+ * GTD_LOG_LEVEL_TRACE: (skip)
+ */
+#ifndef GTD_LOG_LEVEL_TRACE
+# define GTD_LOG_LEVEL_TRACE ((GLogLevelFlags)(1 << G_LOG_LEVEL_USER_SHIFT))
+#endif
+
+#ifdef GTD_ENABLE_TRACE
+
+/**
+ * GTD_TRACE_MSG:
+ * @fmt: printf-like format of the message
+ * @...: arguments for @fmt
+ *
+ * Prints a trace message.
+ */
+# define GTD_TRACE_MSG(fmt, ...)                                        \
+   g_log(G_LOG_DOMAIN, GTD_LOG_LEVEL_TRACE, "  MSG: %s():%d: " fmt,     \
+         G_STRFUNC, __LINE__, ##__VA_ARGS__)
+
+/**
+ * GTD_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 GTD_PROBE                                                      \
+   g_log(G_LOG_DOMAIN, GTD_LOG_LEVEL_TRACE, "PROBE: %s():%d",           \
+         G_STRFUNC, __LINE__)
+
+/**
+ * GTD_TODO:
+ * @_msg: the message to print
+ *
+ * Prints a TODO message.
+ */
+# define GTD_TODO(_msg)                                                 \
+   g_log(G_LOG_DOMAIN, GTD_LOG_LEVEL_TRACE, " TODO: %s():%d: %s",       \
+         G_STRFUNC, __LINE__, _msg)
+
+/**
+ * GTD_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 GTD_ENTRY                                                      \
+   g_log(G_LOG_DOMAIN, GTD_LOG_LEVEL_TRACE, "ENTRY: %s():%d",           \
+         G_STRFUNC, __LINE__)
+
+/**
+ * GTD_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 GTD_RETURN()
+ * instead.
+ */
+# define GTD_EXIT                                                       \
+   G_STMT_START {                                                        \
+      g_log(G_LOG_DOMAIN, GTD_LOG_LEVEL_TRACE, " EXIT: %s():%d",        \
+            G_STRFUNC, __LINE__);                                        \
+      return;                                                            \
+   } G_STMT_END
+
+/**
+ * GTD_GOTO:
+ * @_l: goto tag
+ *
+ * Logs a goto jump.
+ */
+# define GTD_GOTO(_l)                                                   \
+   G_STMT_START {                                                        \
+      g_log(G_LOG_DOMAIN, GTD_LOG_LEVEL_TRACE, " GOTO: %s():%d ("#_l")",\
+            G_STRFUNC, __LINE__);                                        \
+      goto _l;                                                           \
+   } G_STMT_END
+
+/**
+ * GTD_RETURN:
+ * @_r: the return value.
+ *
+ * Prints an exit message, and returns @_r. See #GTD_EXIT.
+ */
+# define GTD_RETURN(_r)                                                 \
+   G_STMT_START {                                                        \
+      g_log(G_LOG_DOMAIN, GTD_LOG_LEVEL_TRACE, " EXIT: %s():%d ",       \
+            G_STRFUNC, __LINE__);                                        \
+      return _r;                                                         \
+   } G_STMT_END
+
+#else
+
+/**
+ * GTD_TODO:
+ * @_msg: the message to print
+ *
+ * Prints a TODO message.
+ */
+# define GTD_TODO(_msg)
+
+/**
+ * GTD_PROBE:
+ *
+ * Prints a probing message.
+ */
+# define GTD_PROBE
+
+/**
+ * GTD_TRACE_MSG:
+ * @fmt: printf-like format of the message
+ * @...: arguments for @fmt
+ *
+ * Prints a trace message.
+ */
+# define GTD_TRACE_MSG(fmt, ...)
+
+/**
+ * GTD_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 GTD_ENTRY
+
+/**
+ * GTD_GOTO:
+ * @_l: goto tag
+ *
+ * Logs a goto jump.
+ */
+# define GTD_GOTO(_l)   goto _l
+
+/**
+ * GTD_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 GTD_RETURN()
+ * instead.
+ */
+# define GTD_EXIT       return
+
+/**
+ * GTD_RETURN:
+ * @_r: the return value.
+ *
+ * Prints an exit message, and returns @_r. See #GTD_EXIT.
+ */
+# define GTD_RETURN(_r) return _r
+#endif
+
+/**
+ * _GTD_BUG: (skip)
+ */
+#define _GTD_BUG(Component, Description, File, Line, Func, ...)                        \
+  G_STMT_START {                                                                        \
+    g_printerr ("-----------------------------------------------------------------\n"); \
+    g_printerr ("You've found a bug in To Do 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
+
+/**
+ * GTD_BUG:
+ * @Component: the component
+ * @Description: the description
+ * @...: extra arguments
+ *
+ * Logs a bug-friendly message.
+ */
+#define GTD_BUG(Component, Description, ...) \
+  _GTD_BUG(Component, Description, __FILE__, __LINE__, G_STRFUNC, ##__VA_ARGS__)
+
+G_END_DECLS
diff --git a/src/logging/gtd-log.c b/src/logging/gtd-log.c
new file mode 100644
index 0000000..96c0cf2
--- /dev/null
+++ b/src/logging/gtd-log.c
@@ -0,0 +1,107 @@
+/* gtd-log.c
+ *
+ * Copyright (C) 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 3 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 "gtd-debug.h"
+#include "gtd-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 GTD_LOG_LEVEL_TRACE: return "   \033[1;36mTRACE\033[0m";
+
+    default:
+      return " UNKNOWN";
+    }
+}
+
+static void
+gtd_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
+gtd_log_init (void)
+{
+  static gsize initialized = FALSE;
+
+  if (g_once_init_enter (&initialized))
+    {
+      standard_channel = g_io_channel_unix_new (STDOUT_FILENO);
+
+      g_log_set_default_handler (gtd_log_handler, NULL);
+
+      g_once_init_leave (&initialized, TRUE);
+    }
+}
+
diff --git a/src/logging/gtd-log.h b/src/logging/gtd-log.h
new file mode 100644
index 0000000..0ad53a8
--- /dev/null
+++ b/src/logging/gtd-log.h
@@ -0,0 +1,27 @@
+/* gtd-log.h
+ *
+ * Copyright (C) 2017 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 3 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-object.h>
+
+G_BEGIN_DECLS
+
+void                 gtd_log_init                               (void);
+
+G_END_DECLS
diff --git a/src/meson.build b/src/meson.build
index dee0792..1e32a9c 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -44,6 +44,7 @@ sources = files(
   'interfaces/gtd-activatable.c',
   'interfaces/gtd-panel.c',
   'interfaces/gtd-provider.c',
+  'logging/gtd-log.c',
   'notification/gtd-notification.c',
   'notification/gtd-notification-widget.c',
   'provider/gtd-provider-popover.c',
@@ -99,6 +100,7 @@ incs = [
   include_directories(
     'engine',
     'provider',
+    'logging',
     'notification',
     'interfaces',
     'views',
@@ -125,6 +127,24 @@ if host_machine.system().contains('linux')
 endif
 
 
+#########
+# Debug #
+#########
+
+debug_conf = configuration_data()
+debug_conf.set('BUGREPORT_URL', 'https://gitlab.gnome.org/GNOME/gnome-todo/issues/new')
+debug_conf.set10('ENABLE_TRACING', gnome_todo_tracing)
+
+
+debug = 'gtd-debug.h'
+
+sources += configure_file(
+          input: debug + '.in',
+         output: debug,
+  configuration: debug_conf,
+)
+
+
 ##############
 # gnome-todo #
 ##############


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