summaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
authorMohammed Sadiq <sadiq@sadiqpk.org>2021-06-07 17:41:23 +0530
committerGeorges Basile Stavracas Neto <georges.stavracas@gmail.com>2022-12-01 11:44:17 +0000
commit3b121805ed9f7e4bcdef9c731c09f407a7759099 (patch)
treebeadb7c5c2caac85113f49210028f1676b25dbd6 /shell
parent9285b0deb52a3f1866ede882c7b176c28dea8722 (diff)
downloadgnome-control-center-3b121805ed9f7e4bcdef9c731c09f407a7759099.tar.gz
log: Improve logging
The 'tracing' build option is no longer needed. And the verbosity of logs can be set by providing '-v' multiple times.
Diffstat (limited to 'shell')
-rw-r--r--shell/cc-application.c18
-rw-r--r--shell/cc-debug.h.in229
-rw-r--r--shell/cc-log.c480
-rw-r--r--shell/cc-log.h69
-rw-r--r--shell/cc-panel-list.c2
-rw-r--r--shell/cc-window.c2
-rw-r--r--shell/main.c2
-rw-r--r--shell/meson.build11
8 files changed, 517 insertions, 296 deletions
diff --git a/shell/cc-application.c b/shell/cc-application.c
index a51568bae..2ae0fbe2d 100644
--- a/shell/cc-application.c
+++ b/shell/cc-application.c
@@ -53,11 +53,16 @@ static void help_activated (GSimpleAction *action,
GVariant *parameter,
gpointer user_data);
+static gboolean cmd_verbose_cb (const char *option_name,
+ const char *value,
+ gpointer data,
+ GError **error);
+
G_DEFINE_TYPE (CcApplication, cc_application, ADW_TYPE_APPLICATION)
const GOptionEntry all_options[] = {
{ "version", 0, 0, G_OPTION_ARG_NONE, NULL, N_("Display version number"), NULL },
- { "verbose", 'v', 0, G_OPTION_ARG_NONE, NULL, N_("Enable verbose mode"), NULL },
+ { "verbose", 'v', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, cmd_verbose_cb, N_("Enable verbose mode"), NULL },
{ "search", 's', 0, G_OPTION_ARG_STRING, NULL, N_("Search for the string"), "SEARCH" },
{ "list", 'l', 0, G_OPTION_ARG_NONE, NULL, N_("List possible panel names and exit"), NULL },
{ G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_FILENAME_ARRAY, NULL, N_("Panel to display"), N_("[PANEL] [ARGUMENT…]") },
@@ -90,6 +95,17 @@ help_activated (GSimpleAction *action,
GDK_CURRENT_TIME);
}
+static gboolean
+cmd_verbose_cb (const char *option_name,
+ const char *value,
+ gpointer data,
+ GError **error)
+{
+ cc_log_increase_verbosity ();
+
+ return TRUE;
+}
+
static void
launch_panel_activated (GSimpleAction *action,
GVariant *parameter,
diff --git a/shell/cc-debug.h.in b/shell/cc-debug.h.in
deleted file mode 100644
index 226f82e03..000000000
--- a/shell/cc-debug.h.in
+++ /dev/null
@@ -1,229 +0,0 @@
-/* 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 Settings 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 Settings 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
index dba4f5a26..e4434b3ca 100644
--- a/shell/cc-log.c
+++ b/shell/cc-log.c
@@ -1,6 +1,8 @@
-/* cc-shell-log.c
+/* -*- mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*- */
+/* cc-log.c
*
* Copyright © 2018 Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
+ * Copyright 2022 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
@@ -14,88 +16,464 @@
*
* 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):
+ * Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
+ * Mohammed Sadiq <sadiq@sadiqpk.org>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
*/
-#include "cc-debug.h"
+#include <glib.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+
#include "cc-log.h"
-#include <unistd.h>
-#include <glib.h>
+#define DEFAULT_DOMAIN_PREFIX "cc"
+
+char *domains;
+static int verbosity;
+gboolean any_domain;
+gboolean no_anonymize;
+gboolean stderr_is_journal;
+gboolean fatal_criticals, fatal_warnings;
-G_LOCK_DEFINE_STATIC (channel_lock);
+/* Copied from GLib, LGPLv2.1+ */
+static void
+_g_log_abort (gboolean breakpoint)
+{
+ gboolean debugger_present;
+
+ if (g_test_subprocess ())
+ {
+ /* If this is a test case subprocess then it probably caused
+ * this error message on purpose, so just exit() rather than
+ * abort()ing, to avoid triggering any system crash-reporting
+ * daemon.
+ */
+ _exit (1);
+ }
+
+#ifdef G_OS_WIN32
+ debugger_present = IsDebuggerPresent ();
+#else
+ /* Assume GDB is attached. */
+ debugger_present = TRUE;
+#endif /* !G_OS_WIN32 */
-GIOChannel *standard_channel = NULL;
+ if (debugger_present && breakpoint)
+ G_BREAKPOINT ();
+ else
+ g_abort ();
+}
-static const gchar* ignored_domains[] =
+static gboolean
+should_show_log_for_level (GLogLevelFlags log_level,
+ int verbosity_level)
{
- "GdkPixbuf",
- NULL
-};
+ if (verbosity_level >= 5)
+ return TRUE;
+
+ if (log_level & CC_LOG_LEVEL_TRACE)
+ return verbosity_level >= 4;
-static const gchar *
-log_level_str (GLogLevelFlags log_level)
+ if (log_level & G_LOG_LEVEL_DEBUG)
+ return verbosity_level >= 3;
+
+ if (log_level & G_LOG_LEVEL_INFO)
+ return verbosity_level >= 2;
+
+ if (log_level & G_LOG_LEVEL_MESSAGE)
+ return verbosity_level >= 1;
+
+ return FALSE;
+}
+
+static gboolean
+matches_domain (const char *log_domains,
+ const char *domain)
{
- switch (((gulong)log_level & G_LOG_LEVEL_MASK))
+ g_auto(GStrv) domain_list = NULL;
+
+ if (!log_domains || !*log_domains ||
+ !domain || !*domain)
+ return FALSE;
+
+ domain_list = g_strsplit (log_domains, ",", -1);
+
+ for (guint i = 0; domain_list[i]; i++)
{
- 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";
+ if (g_str_has_prefix (domain, domain_list[i]))
+ return TRUE;
}
+
+ return FALSE;
+}
+
+static gboolean
+should_log (const char *log_domain,
+ GLogLevelFlags log_level)
+{
+ g_assert (log_domain);
+
+ /* Ignore custom flags set */
+ log_level = log_level & ~CC_LOG_DETAILED;
+
+ /* Don't skip serious logs */
+ if (log_level & (G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING))
+ return TRUE;
+
+ if (any_domain && domains) {
+ /* If domain is “all” show logs upto debug regardless of the verbosity */
+ if (log_level & ~CC_LOG_LEVEL_TRACE)
+ return TRUE;
+
+ /* If the log is trace level, log if verbosity >= 4 */
+ return verbosity >= 4;
+ }
+
+ if (!domains && g_str_has_prefix (log_domain, DEFAULT_DOMAIN_PREFIX))
+ return should_show_log_for_level (log_level, verbosity);
+
+ if (domains && matches_domain (domains, log_domain))
+ return should_show_log_for_level (log_level, verbosity);
+
+ /* If we didn't handle domains in the preceding statement,
+ * we should no longer log them */
+ if (domains)
+ return FALSE;
+
+ /* GdkPixbuf and Gvc logs are too much verbose, skip unless asked not to. */
+ if (verbosity < 8 &&
+ (g_strcmp0 (log_domain, "GdkPixbuf") == 0 ||
+ g_strcmp0 (log_domain, "Gvc") == 0) &&
+ (!domains || !strstr (domains, log_domain)))
+ return FALSE;
+
+ if (verbosity >= 6)
+ return TRUE;
+
+ return FALSE;
}
static void
-log_handler (const gchar *domain,
- GLogLevelFlags log_level,
- const gchar *message,
- gpointer user_data)
+log_str_append_log_domain (GString *log_str,
+ const char *log_domain,
+ gboolean color)
{
- g_autoptr(GDateTime) now = NULL;
- const gchar *level;
- g_autofree gchar *ftime = NULL;
- g_autofree gchar *buffer = NULL;
+ 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;
- /* Skip ignored log domains */
- if (domain && g_strv_contains (ignored_domains, domain))
- return;
+ g_assert (log_domain && *log_domain);
- level = log_level_str (log_level);
- now = g_date_time_new_now_local ();
- ftime = g_date_time_format (now, "%H:%M:%S");
- buffer = g_strdup_printf ("%s.%04d %24s: %s: %s\n",
- ftime,
- g_date_time_get_microsecond (now) / 1000,
- domain,
- level,
- message);
+ i = g_str_hash (log_domain) % G_N_ELEMENTS (colors);
- /* Safely write to the channel */
- G_LOCK (channel_lock);
+ if (color)
+ g_string_append (log_str, colors[i]);
+ g_string_append_printf (log_str, "%20s", log_domain);
- g_io_channel_write_chars (standard_channel, buffer, -1, NULL, NULL);
- g_io_channel_flush (standard_channel, NULL);
+ if (color)
+ g_string_append (log_str, "\033[0m");
+}
+
+static const char *
+get_log_level_prefix (GLogLevelFlags log_level,
+ gboolean use_color)
+{
+ /* Ignore custom flags set */
+ log_level = log_level & ~CC_LOG_DETAILED;
- G_UNLOCK (channel_lock);
+ 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 CC_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 CC_LOG_LEVEL_TRACE: return " TRACE";
+ default: return " UNKNOWN";
+ }
+ }
+}
+
+static GLogWriterOutput
+cc_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 &&
+ 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));
+
+ if (log_level & CC_LOG_DETAILED)
+ {
+ const char *code_func = NULL, *code_line = NULL;
+ for (guint i = 0; i < n_fields; i++)
+ {
+ const GLogField *field = &fields[i];
+
+ if (!code_func && g_strcmp0 (field->key, "CODE_FUNC") == 0)
+ code_func = field->value;
+ else if (!code_line && g_strcmp0 (field->key, "CODE_LINE") == 0)
+ code_line = field->value;
+
+ if (code_func && code_line)
+ break;
+ }
+
+ if (code_func)
+ {
+ g_string_append_printf (log_str, "%s():", code_func);
+
+ if (code_line)
+ g_string_append_printf (log_str, "%s:", code_line);
+ g_string_append_c (log_str, ' ');
+ }
+ }
+
+ g_string_append (log_str, log_message);
+
+ fprintf (stream, "%s\n", log_str->str);
+ fflush (stream);
+
+ if (fatal_criticals &&
+ (log_level & G_LOG_LEVEL_CRITICAL))
+ log_level |= G_LOG_FLAG_FATAL;
+ else if (fatal_warnings &&
+ (log_level & (G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING)))
+ log_level |= G_LOG_FLAG_FATAL;
+
+ if (log_level & (G_LOG_FLAG_FATAL | G_LOG_LEVEL_ERROR))
+ _g_log_abort (!(log_level & G_LOG_FLAG_RECURSION));
+
+ return G_LOG_WRITER_HANDLED;
+}
+
+static GLogWriterOutput
+cc_log_handler (GLogLevelFlags log_level,
+ const GLogField *fields,
+ gsize n_fields,
+ gpointer user_data)
+{
+ const char *log_domain = NULL;
+ const char *log_message = NULL;
+
+ 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 = "**";
+
+ if (!log_message)
+ log_message = "(NULL) message";
+
+ if (!should_log (log_domain, log_level))
+ return G_LOG_WRITER_HANDLED;
+
+ return cc_log_write (log_level, log_domain, log_message,
+ fields, n_fields, user_data);
+}
+
+static void
+cc_log_finalize (void)
+{
+ g_clear_pointer (&domains, g_free);
}
void
cc_log_init (void)
{
- static gsize initialized = FALSE;
+ static gsize initialized = 0;
if (g_once_init_enter (&initialized))
{
- standard_channel = g_io_channel_unix_new (STDOUT_FILENO);
+ 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;
- g_setenv ("G_MESSAGES_DEBUG", "all", TRUE);
+ if (domains && strstr (domains, "no-anonymize"))
+ {
+ any_domain = TRUE;
+ no_anonymize = TRUE;
+ g_clear_pointer (&domains, g_free);
+ }
- g_log_set_default_handler (log_handler, NULL);
+ if (g_strcmp0 (g_getenv ("G_DEBUG"), "fatal-criticals") == 0)
+ fatal_criticals = TRUE;
+ else if (g_strcmp0 (g_getenv ("G_DEBUG"), "fatal-warnings") == 0)
+ fatal_warnings = TRUE;
- g_once_init_leave (&initialized, TRUE);
+ stderr_is_journal = g_log_writer_is_journald (fileno (stderr));
+ g_log_set_writer_func (cc_log_handler, NULL, NULL);
+ g_once_init_leave (&initialized, 1);
+ atexit (cc_log_finalize);
}
}
+void
+cc_log_increase_verbosity (void)
+{
+ verbosity++;
+}
+
+int
+cc_log_get_verbosity (void)
+{
+ return verbosity;
+}
+
+void
+cc_log (const char *domain,
+ GLogLevelFlags log_level,
+ const char *value,
+ const char *file,
+ const char *line,
+ const char *func,
+ const char *message_format,
+ ...)
+{
+ g_autoptr(GString) str = NULL;
+ va_list args;
+
+ if (!message_format || !*message_format)
+ return;
+
+ if (!should_log (domain, log_level))
+ return;
+
+ str = g_string_new (NULL);
+ va_start (args, message_format);
+ g_string_append_vprintf (str, message_format, args);
+ va_end (args);
+
+ cc_log_anonymize_value (str, value);
+ g_log_structured (domain, log_level,
+ "CODE_FILE", file,
+ "CODE_LINE", line,
+ "CODE_FUNC", func,
+ "MESSAGE", "%s", str->str);
+}
+
+void
+cc_log_anonymize_value (GString *str,
+ const char *value)
+{
+ gunichar c, next_c, prev_c;
+
+ if (!value || !*value)
+ return;
+
+ g_assert (str);
+
+ if (str->len && str->str[str->len - 1] != ' ')
+ g_string_append_c (str, ' ');
+
+ if (no_anonymize)
+ {
+ g_string_append (str, value);
+ return;
+ }
+
+ if (!g_utf8_validate (value, -1, NULL))
+ {
+ g_string_append (str, "******");
+ return;
+ }
+
+ c = g_utf8_get_char (value);
+ g_string_append_unichar (str, c);
+
+ value = g_utf8_next_char (value);
+
+ while (*value)
+ {
+ prev_c = c;
+ c = g_utf8_get_char (value);
+
+ value = g_utf8_next_char (value);
+ next_c = g_utf8_get_char (value);
+
+ if (!g_unichar_isalnum (c))
+ g_string_append_unichar (str, c);
+ else if (!g_unichar_isalnum (prev_c) || !g_unichar_isalnum (next_c))
+ g_string_append_unichar (str, c);
+ else
+ g_string_append_c (str, '#');
+ }
+}
diff --git a/shell/cc-log.h b/shell/cc-log.h
index 2d04c0ba7..eee0e11bc 100644
--- a/shell/cc-log.h
+++ b/shell/cc-log.h
@@ -1,6 +1,8 @@
+/* -*- mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*- */
/* cc-log.h
*
- * Copyright © 2018 Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
+ * Copyright 2018 Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
+ * 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
@@ -14,12 +16,75 @@
*
* 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):
+ * Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
+ * Mohammed Sadiq <sadiq@sadiqpk.org>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
*/
#pragma once
+#include <glib.h>
+
G_BEGIN_DECLS
-void cc_log_init (void);
+#ifndef CC_LOG_LEVEL_TRACE
+# define CC_LOG_LEVEL_TRACE ((GLogLevelFlags)(1 << G_LOG_LEVEL_USER_SHIFT))
+# define CC_LOG_DETAILED ((GLogLevelFlags)(1 << (G_LOG_LEVEL_USER_SHIFT + 1)))
+#endif
+
+#define CC_DEBUG_MSG(fmt, ...) \
+ cc_log (G_LOG_DOMAIN, \
+ G_LOG_LEVEL_DEBUG | CC_LOG_DETAILED, \
+ NULL, __FILE__, G_STRINGIFY (__LINE__), \
+ G_STRFUNC, fmt, ##__VA_ARGS__)
+#define CC_TRACE_MSG(fmt, ...) \
+ cc_log (G_LOG_DOMAIN, \
+ CC_LOG_LEVEL_TRACE | CC_LOG_DETAILED, \
+ NULL, __FILE__, G_STRINGIFY (__LINE__), \
+ G_STRFUNC, fmt, ##__VA_ARGS__)
+#define CC_TRACE(fmt, ...) \
+ cc_log (G_LOG_DOMAIN, \
+ CC_LOG_LEVEL_TRACE, \
+ NULL, __FILE__, G_STRINGIFY (__LINE__), \
+ G_STRFUNC, fmt, ##__VA_ARGS__)
+#define CC_TODO(_msg) \
+ g_log_structured (G_LOG_DOMAIN, CC_LOG_LEVEL_TRACE, \
+ "MESSAGE", " TODO: %s():%d: %s", \
+ G_STRFUNC, __LINE__, _msg)
+#define CC_ENTRY \
+ g_log_structured (G_LOG_DOMAIN, CC_LOG_LEVEL_TRACE, \
+ "MESSAGE", "ENTRY: %s():%d", \
+ G_STRFUNC, __LINE__)
+#define CC_EXIT \
+ G_STMT_START { \
+ g_log_structured (G_LOG_DOMAIN, CC_LOG_LEVEL_TRACE, \
+ "MESSAGE", "EXIT: %s():%d", \
+ G_STRFUNC, __LINE__); \
+ return; \
+ } G_STMT_END
+#define CC_RETURN(_r) \
+ G_STMT_START { \
+ g_log_structured (G_LOG_DOMAIN, CC_LOG_LEVEL_TRACE, \
+ "MESSAGE", "EXIT: %s():%d ", \
+ G_STRFUNC, __LINE__); \
+ return _r; \
+ } G_STMT_END
+
+void cc_log_init (void);
+void cc_log_increase_verbosity (void);
+int cc_log_get_verbosity (void);
+void cc_log (const char *domain,
+ GLogLevelFlags log_level,
+ const char *value,
+ const char *file,
+ const char *line,
+ const char *func,
+ const char *message_format,
+ ...) G_GNUC_PRINTF (7, 8);
+void cc_log_anonymize_value (GString *str,
+ const char *value);
G_END_DECLS
diff --git a/shell/cc-panel-list.c b/shell/cc-panel-list.c
index 185b16d0a..d8823b8b5 100644
--- a/shell/cc-panel-list.c
+++ b/shell/cc-panel-list.c
@@ -22,7 +22,7 @@
#include <string.h>
-#include "cc-debug.h"
+#include "cc-log.h"
#include "cc-panel-list.h"
#include "cc-util.h"
diff --git a/shell/cc-window.c b/shell/cc-window.c
index 15d71247f..4ffdc8a70 100644
--- a/shell/cc-window.c
+++ b/shell/cc-window.c
@@ -24,7 +24,7 @@
#include <config.h>
-#include "cc-debug.h"
+#include "cc-log.h"
#include "cc-window.h"
#include <glib/gi18n.h>
diff --git a/shell/main.c b/shell/main.c
index 4a6125e1f..7ba5b3465 100644
--- a/shell/main.c
+++ b/shell/main.c
@@ -30,6 +30,7 @@
#include <X11/Xlib.h>
#endif
+#include "cc-log.h"
#include "cc-application.h"
static void
@@ -52,6 +53,7 @@ main (gint argc,
textdomain (GETTEXT_PACKAGE);
setlocale (LC_ALL, "");
+ cc_log_init ();
initialize_dependencies (&argc, &argv);
diff --git a/shell/meson.build b/shell/meson.build
index 8fe111a02..4811f0c82 100644
--- a/shell/meson.build
+++ b/shell/meson.build
@@ -56,17 +56,6 @@ common_sources = files(
generated_sources = files()
-# Debug
-debug_conf = configuration_data()
-debug_conf.set('BUGREPORT_URL', 'https://gitlab.gnome.org/GNOME/' + meson.project_name() + '/issues/new')
-debug_conf.set10('ENABLE_TRACING', enable_tracing)
-
-generated_sources += configure_file(
- input : 'cc-debug.h.in',
- output : 'cc-debug.h',
- configuration : debug_conf
-)
-
#Resources
resource_data = files(
'cc-panel-list.ui',