[gnome-notes] Add and use new logger



commit 9b5c62ba0182f80dd2d13ff19c1ddbcc42d73f25
Author: Mohammed Sadiq <sadiq sadiqpk org>
Date:   Mon Apr 19 07:39:21 2021 +0530

    Add and use new logger
    
    This helps provider better logs.  With this, the user can now run
    with `-v` for verbose logs, use more `-v` to be more verbose,
    eg `bijiben -vvvvv` log shall be very verbose

 src/bjb-application.c                          |  17 ++
 src/bjb-log.c                                  | 274 +++++++++++++++++++++++++
 src/bjb-log.h                                  |  49 +++++
 src/bjb-main.c                                 |   2 +
 src/libbiji/biji-manager.c                     |   2 +
 src/libbiji/biji-tracker.c                     |   2 +
 src/libbiji/provider/biji-local-note.c         |   2 +
 src/libbiji/provider/biji-memo-provider.c      |   1 +
 src/libbiji/provider/biji-nextcloud-note.c     |   2 +
 src/libbiji/provider/biji-nextcloud-provider.c |   2 +
 src/meson.build                                |   1 +
 11 files changed, 354 insertions(+)
---
diff --git a/src/bjb-application.c b/src/bjb-application.c
index 00d8436..c4910cb 100644
--- a/src/bjb-application.c
+++ b/src/bjb-application.c
@@ -18,6 +18,8 @@
  * with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#define G_LOG_DOMAIN "bjb-application"
+
 #include "config.h"
 
 #include <glib/gi18n.h>
@@ -27,6 +29,8 @@
 #include "bjb-settings.h"
 #include "bjb-window-base.h"
 #include "bjb-import-dialog.h"
+#include "bjb-log.h"
+
 
 struct _BjbApplication
 {
@@ -79,6 +83,17 @@ GVariant       *text_size_mapping_set       (const GValue       *value,
                                              const GVariantType *expected_type,
                                              gpointer            user_data);
 
+static gboolean
+cmd_verbose_cb (const char  *option_name,
+                const char  *value,
+                gpointer     data,
+                GError     **error)
+{
+  bjb_log_increase_verbosity ();
+
+  return TRUE;
+}
+
 static void
 on_window_activated_cb (BjbWindowBase  *window,
                         gboolean        available,
@@ -231,6 +246,8 @@ bjb_application_init (BjbApplication *self)
 {
   GApplication *app = G_APPLICATION (self);
   const GOptionEntry cmd_options[] = {
+    { "verbose", 'v', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, cmd_verbose_cb,
+      N_("Show verbose logs"), NULL},
     { "version", 0, 0, G_OPTION_ARG_NONE, NULL,
       N_("Show the application’s version"), NULL},
     { "new-note", 0, 0, G_OPTION_ARG_NONE, &self->new_note,
diff --git a/src/bjb-log.c b/src/bjb-log.c
new file mode 100644
index 0000000..b375e0f
--- /dev/null
+++ b/src/bjb-log.c
@@ -0,0 +1,274 @@
+/* -*- mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*- */
+/* bjb-log.c
+ *
+ * Copyright 2021 Mohammed Sadiq <sadiq sadiqpk org>
+ *
+ * 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/>.
+ *
+ * Author(s):
+ *   Mohammed Sadiq <sadiq sadiqpk org>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include <glib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#include "bjb-log.h"
+
+#define DEFAULT_DOMAIN "bjb"
+
+char *domains;
+static int verbosity;
+gboolean any_domain;
+gboolean stderr_is_journal;
+
+static void
+log_str_append_log_domain (GString    *log_str,
+                           const char *log_domain,
+                           gboolean    color)
+{
+  static const char *colors[] = {
+    "\033[1;32m",
+    "\033[1;33m",
+    "\033[1;35m",
+    "\033[1;36m",
+    "\033[1;91m",
+    "\033[1;92m",
+    "\033[1;93m",
+    "\033[1;94m",
+    "\033[1;95m",
+    "\033[1;96m",
+  };
+  guint i;
+
+  g_assert (log_domain && *log_domain);
+
+  i = g_str_hash (log_domain) % G_N_ELEMENTS (colors);
+
+  if (color)
+    g_string_append (log_str, colors[i]);
+  g_string_append_printf (log_str, "%20s", log_domain);
+
+  if (color)
+    g_string_append (log_str, "\033[0m");
+}
+
+static const char *
+get_log_level_prefix (GLogLevelFlags log_level,
+                      gboolean       use_color)
+{
+  if (use_color)
+    {
+      switch ((int)log_level)        /* Same colors as used in GLib */
+        {
+        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;32mMESSAGE\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 BJB_LOG_LEVEL_TRACE:  return "   \033[1;36mTRACE\033[0m";
+        default:                   return " UNKNOWN";
+        }
+    }
+  else
+    {
+      switch ((int)log_level)
+        {
+        case G_LOG_LEVEL_ERROR:    return "   ERROR";
+        case G_LOG_LEVEL_CRITICAL: return "CRITICAL";
+        case G_LOG_LEVEL_WARNING:  return " WARNING";
+        case G_LOG_LEVEL_MESSAGE:  return " MESSAGE";
+        case G_LOG_LEVEL_INFO:     return "    INFO";
+        case G_LOG_LEVEL_DEBUG:    return "   DEBUG";
+        case BJB_LOG_LEVEL_TRACE:  return "   TRACE";
+        default:                   return " UNKNOWN";
+        }
+    }
+}
+
+static GLogWriterOutput
+bjb_log_write (GLogLevelFlags   log_level,
+               const char      *log_domain,
+               const char      *log_message,
+               const GLogField *fields,
+               gsize            n_fields,
+               gpointer         user_data)
+{
+  g_autoptr(GString) log_str = NULL;
+  FILE *stream = stdout;
+  gboolean can_color;
+
+  if (stderr_is_journal)
+    if (g_log_writer_journald (log_level, fields, n_fields, user_data) == G_LOG_WRITER_HANDLED)
+      return G_LOG_WRITER_HANDLED;
+
+  if (log_level & (G_LOG_LEVEL_ERROR |
+                   G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING))
+    stream = stderr;
+
+  log_str = g_string_new (NULL);
+
+  /* Add local time */
+  {
+    char buffer[32];
+    struct tm tm_now;
+    time_t sec_now;
+    gint64 now;
+
+    now = g_get_real_time ();
+    sec_now = now / G_USEC_PER_SEC;
+    tm_now = *localtime (&sec_now);
+    strftime (buffer, sizeof (buffer), "%H:%M:%S", &tm_now);
+
+    g_string_append_printf (log_str, "%s.%04d ", buffer,
+                            (int)((now % G_USEC_PER_SEC) / 100));
+  }
+
+  can_color = g_log_writer_supports_color (fileno (stream));
+  log_str_append_log_domain (log_str, log_domain, can_color);
+  g_string_append_printf (log_str, "[%5d]:", getpid ());
+
+  g_string_append_printf (log_str, "%s: ", get_log_level_prefix (log_level, can_color));
+  g_string_append (log_str, log_message);
+
+  fprintf (stream, "%s\n", log_str->str);
+  fflush (stream);
+
+  return G_LOG_WRITER_HANDLED;
+}
+
+static GLogWriterOutput
+bjb_log_handler (GLogLevelFlags   log_level,
+                 const GLogField *fields,
+                 gsize            n_fields,
+                 gpointer         user_data)
+{
+  const char *log_domain = NULL;
+  const char *log_message = NULL;
+
+  /* If domain is “all” show logs upto debug regardless of the verbosity */
+  switch ((int)log_level)
+    {
+    case G_LOG_LEVEL_MESSAGE:
+      if (any_domain && domains)
+        break;
+      if (verbosity < 1)
+        return G_LOG_WRITER_HANDLED;
+      break;
+
+    case G_LOG_LEVEL_INFO:
+      if (any_domain && domains)
+        break;
+      if (verbosity < 2)
+        return G_LOG_WRITER_HANDLED;
+      break;
+
+    case G_LOG_LEVEL_DEBUG:
+      if (any_domain && domains)
+        break;
+      if (verbosity < 3)
+        return G_LOG_WRITER_HANDLED;
+      break;
+
+    case BJB_LOG_LEVEL_TRACE:
+      if (verbosity < 4)
+      return G_LOG_WRITER_HANDLED;
+      break;
+
+    default:
+      break;
+    }
+
+  for (guint i = 0; (!log_domain || !log_message) && i < n_fields; i++)
+    {
+      const GLogField *field = &fields[i];
+
+      if (g_strcmp0 (field->key, "GLIB_DOMAIN") == 0)
+        log_domain = field->value;
+      else if (g_strcmp0 (field->key, "MESSAGE") == 0)
+        log_message = field->value;
+    }
+
+  if (!log_domain)
+    log_domain = "**";
+
+  /* Skip logs from other domains if verbosity level is low */
+  if (any_domain && !domains &&
+      verbosity < 5 &&
+      log_level > G_LOG_LEVEL_MESSAGE &&
+      !strstr (log_domain, DEFAULT_DOMAIN))
+    return G_LOG_WRITER_HANDLED;
+
+  /* GdkPixbuf logs are too much verbose, skip unless asked not to. */
+  if (g_strcmp0 (log_domain, "GdkPixbuf") == 0 &&
+      !strstr (domains, log_domain))
+    return G_LOG_WRITER_HANDLED;
+
+  if (!log_message)
+    log_message = "(NULL) message";
+
+  if (any_domain)
+    return bjb_log_write (log_level, log_domain, log_message,
+                          fields, n_fields, user_data);
+
+  if (!log_domain || strstr (domains, log_domain))
+    return bjb_log_write (log_level, log_domain, log_message,
+                          fields, n_fields, user_data);
+
+  return G_LOG_WRITER_HANDLED;
+}
+
+static void
+bjb_log_finalize (void)
+{
+  g_clear_pointer (&domains, g_free);
+}
+
+void
+bjb_log_init (void)
+{
+  static gsize initialized = 0;
+
+  if (g_once_init_enter (&initialized))
+    {
+      domains = g_strdup (g_getenv ("G_MESSAGES_DEBUG"));
+
+      if (domains && !*domains)
+        g_clear_pointer (&domains, g_free);
+
+      if (!domains || g_str_equal (domains, "all"))
+        any_domain = TRUE;
+
+      stderr_is_journal = g_log_writer_is_journald (fileno (stderr));
+      g_log_set_writer_func (bjb_log_handler, NULL, NULL);
+      g_once_init_leave (&initialized, 1);
+      atexit (bjb_log_finalize);
+    }
+}
+
+void
+bjb_log_increase_verbosity (void)
+{
+  verbosity++;
+}
+
+int
+bjb_log_get_verbosity (void)
+{
+  return verbosity;
+}
diff --git a/src/bjb-log.h b/src/bjb-log.h
new file mode 100644
index 0000000..6787d1e
--- /dev/null
+++ b/src/bjb-log.h
@@ -0,0 +1,49 @@
+/* -*- mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*- */
+/* bjb-log.h
+ *
+ * Copyright 2021 Mohammed Sadiq <sadiq sadiqpk org>
+ *
+ * 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/>.
+ *
+ * Author(s):
+ *   Mohammed Sadiq <sadiq sadiqpk org>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#ifndef BJB_LOG_LEVEL_TRACE
+# define BJB_LOG_LEVEL_TRACE ((GLogLevelFlags)(1 << G_LOG_LEVEL_USER_SHIFT))
+#endif
+
+#define BJB_TRACE_MSG(fmt, ...)                         \
+  g_log_structured (G_LOG_DOMAIN, BJB_LOG_LEVEL_TRACE,  \
+                    "MESSAGE", "%s():%d: " fmt,         \
+                    G_STRFUNC, __LINE__, ##__VA_ARGS__)
+#define BJB_TRACE(fmt, ...)                             \
+  g_log_structured (G_LOG_DOMAIN, BJB_LOG_LEVEL_TRACE,  \
+                    "MESSAGE",  fmt, ##__VA_ARGS__)
+#define BJB_DEBUG_MSG(fmt, ...)                         \
+  g_log_structured (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG,    \
+                    "MESSAGE", "%s():%d: " fmt,         \
+                    G_STRFUNC, __LINE__, ##__VA_ARGS__)
+#define BJB_TODO(_msg)                                  \
+  g_log_structured (G_LOG_DOMAIN, BJB_LOG_LEVEL_TRACE,  \
+                    "MESSAGE", "TODO: %s():%d: %s",     \
+                    G_STRFUNC, __LINE__, _msg)
+
+void bjb_log_init               (void);
+void bjb_log_increase_verbosity (void);
+int  bjb_log_get_verbosity      (void);
diff --git a/src/bjb-main.c b/src/bjb-main.c
index b500354..3960f2a 100644
--- a/src/bjb-main.c
+++ b/src/bjb-main.c
@@ -22,6 +22,7 @@
 #include <libbiji/libbiji.h>
 
 #include "bjb-application.h"
+#include "bjb-log.h"
 
 int
 main (int argc, char *argv[])
@@ -32,6 +33,7 @@ main (int argc, char *argv[])
   bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
   textdomain (GETTEXT_PACKAGE);
 
+  bjb_log_init ();
   app = bjb_application_new ();
   return g_application_run (G_APPLICATION (app), argc, argv);
 }
diff --git a/src/libbiji/biji-manager.c b/src/libbiji/biji-manager.c
index 9ad7919..35dcfe9 100644
--- a/src/libbiji/biji-manager.c
+++ b/src/libbiji/biji-manager.c
@@ -15,6 +15,8 @@
  * with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#define G_LOG_DOMAIN "bjb-manager"
+
 #include <gtk/gtk.h>
 
 #include "config.h"
diff --git a/src/libbiji/biji-tracker.c b/src/libbiji/biji-tracker.c
index 37eaf89..3717515 100644
--- a/src/libbiji/biji-tracker.c
+++ b/src/libbiji/biji-tracker.c
@@ -15,6 +15,8 @@
  * with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#define G_LOG_DOMAIN "bjb-tracker"
+
 #include "config.h"
 
 #include "biji-item.h"
diff --git a/src/libbiji/provider/biji-local-note.c b/src/libbiji/provider/biji-local-note.c
index a1e1177..5fde1ff 100644
--- a/src/libbiji/provider/biji-local-note.c
+++ b/src/libbiji/provider/biji-local-note.c
@@ -15,6 +15,8 @@
  * with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#define G_LOG_DOMAIN "bjb-local-note"
+
 #include "biji-local-note.h"
 #include "biji-tracker.h"
 #include "serializer/biji-lazy-serializer.h"
diff --git a/src/libbiji/provider/biji-memo-provider.c b/src/libbiji/provider/biji-memo-provider.c
index c797b86..ff2274f 100644
--- a/src/libbiji/provider/biji-memo-provider.c
+++ b/src/libbiji/provider/biji-memo-provider.c
@@ -24,6 +24,7 @@
  * TODO: check this
  */
 
+#define G_LOG_DOMAIN "bjb-memo-provider"
 
 #include <libecal/libecal.h>        /* ECalClient      */
 #include "biji-tracker.h"
diff --git a/src/libbiji/provider/biji-nextcloud-note.c b/src/libbiji/provider/biji-nextcloud-note.c
index 3274c07..d7b42ee 100644
--- a/src/libbiji/provider/biji-nextcloud-note.c
+++ b/src/libbiji/provider/biji-nextcloud-note.c
@@ -18,6 +18,8 @@
  * SPDX-License-Identifier: GPL-3.0-or-later
  */
 
+#define G_LOG_DOMAIN "bjb-nextcloud-note"
+
 #include <curl/curl.h>
 #include <json-glib/json-glib.h>
 
diff --git a/src/libbiji/provider/biji-nextcloud-provider.c b/src/libbiji/provider/biji-nextcloud-provider.c
index 51b2bd8..0f7f54b 100644
--- a/src/libbiji/provider/biji-nextcloud-provider.c
+++ b/src/libbiji/provider/biji-nextcloud-provider.c
@@ -18,6 +18,8 @@
  * SPDX-License-Identifier: GPL-3.0-or-later
  */
 
+#define G_LOG_DOMAIN "bjb-nextcloud-provider"
+
 #include <curl/curl.h>
 #include <json-glib/json-glib.h>
 
diff --git a/src/meson.build b/src/meson.build
index 4328774..fb7b860 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -1,6 +1,7 @@
 subdir('libbiji')
 
 sources = files(
+  'bjb-log.c',
   'bjb-application.c',
   'bjb-color-button.c',
   'bjb-controller.c',


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