log: Improve logging
The 'tracing' build option is no longer needed. And the verbosity of logs can be set by providing '-v' multiple times.
This commit is contained in:
parent
9285b0deb5
commit
3b121805ed
15 changed files with 522 additions and 308 deletions
|
@ -637,7 +637,6 @@
|
|||
}
|
||||
],
|
||||
"config-opts" : [
|
||||
"-Dtracing=true",
|
||||
"-Dprofile=development"
|
||||
]
|
||||
}
|
||||
|
|
|
@ -25,9 +25,6 @@ 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()
|
||||
|
||||
py = import('python')
|
||||
|
@ -313,7 +310,6 @@ configure_file(
|
|||
summary({
|
||||
'Documentation': get_option('documentation'),
|
||||
'Tests': get_option('tests'),
|
||||
'Tracing': enable_tracing,
|
||||
'Optimized': control_center_optimized,
|
||||
})
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@ option('ibus', type: 'boolean', value: true, description: 'build with IBus suppo
|
|||
option('privileged_group', type: 'string', value: 'wheel', description: 'name of group that has elevated permissions')
|
||||
option('snap', type: 'boolean', value: false, description: 'build with Snap support')
|
||||
option('tests', type: 'boolean', value: true, description: 'build tests')
|
||||
option('tracing', type: 'boolean', value: false, description: 'add extra debugging information')
|
||||
option('wayland', type: 'boolean', value: true, description: 'build with Wayland support')
|
||||
option('profile', type: 'combo', choices: ['default','development'], value: 'default')
|
||||
option('malcontent', type: 'boolean', value: false, description: 'build with malcontent support')
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
#include "cc-list-row.h"
|
||||
|
||||
#include "shell/cc-application.h"
|
||||
#include "shell/cc-debug.h"
|
||||
#include "shell/cc-log.h"
|
||||
#include "shell/cc-object-storage.h"
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
#include <glib/gi18n-lib.h>
|
||||
|
||||
#include "shell/cc-application.h"
|
||||
#include "shell/cc-debug.h"
|
||||
#include "shell/cc-log.h"
|
||||
#include "cc-wacom-panel.h"
|
||||
#include "cc-wacom-page.h"
|
||||
#include "cc-wacom-ekr-page.h"
|
||||
|
|
|
@ -42,7 +42,6 @@
|
|||
#include "cc-wwan-resources.h"
|
||||
|
||||
#include "shell/cc-application.h"
|
||||
#include "shell/cc-debug.h"
|
||||
#include "shell/cc-object-storage.h"
|
||||
|
||||
/**
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
#include "cc-wwan-resources.h"
|
||||
|
||||
#include "shell/cc-application.h"
|
||||
#include "shell/cc-debug.h"
|
||||
#include "shell/cc-log.h"
|
||||
#include "shell/cc-object-storage.h"
|
||||
|
||||
typedef enum {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
484
shell/cc-log.c
484
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"
|
||||
|
||||
G_LOCK_DEFINE_STATIC (channel_lock);
|
||||
char *domains;
|
||||
static int verbosity;
|
||||
gboolean any_domain;
|
||||
gboolean no_anonymize;
|
||||
gboolean stderr_is_journal;
|
||||
gboolean fatal_criticals, fatal_warnings;
|
||||
|
||||
GIOChannel *standard_channel = NULL;
|
||||
|
||||
static const gchar* ignored_domains[] =
|
||||
/* Copied from GLib, LGPLv2.1+ */
|
||||
static void
|
||||
_g_log_abort (gboolean breakpoint)
|
||||
{
|
||||
"GdkPixbuf",
|
||||
NULL
|
||||
};
|
||||
gboolean debugger_present;
|
||||
|
||||
static const gchar *
|
||||
log_level_str (GLogLevelFlags log_level)
|
||||
{
|
||||
switch (((gulong)log_level & G_LOG_LEVEL_MASK))
|
||||
if (g_test_subprocess ())
|
||||
{
|
||||
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 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 */
|
||||
|
||||
if (debugger_present && breakpoint)
|
||||
G_BREAKPOINT ();
|
||||
else
|
||||
g_abort ();
|
||||
}
|
||||
|
||||
static gboolean
|
||||
should_show_log_for_level (GLogLevelFlags log_level,
|
||||
int verbosity_level)
|
||||
{
|
||||
if (verbosity_level >= 5)
|
||||
return TRUE;
|
||||
|
||||
if (log_level & CC_LOG_LEVEL_TRACE)
|
||||
return verbosity_level >= 4;
|
||||
|
||||
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)
|
||||
{
|
||||
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++)
|
||||
{
|
||||
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");
|
||||
}
|
||||
|
||||
G_UNLOCK (channel_lock);
|
||||
static const char *
|
||||
get_log_level_prefix (GLogLevelFlags log_level,
|
||||
gboolean use_color)
|
||||
{
|
||||
/* Ignore custom flags set */
|
||||
log_level = log_level & ~CC_LOG_DETAILED;
|
||||
|
||||
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"));
|
||||
|
||||
g_setenv ("G_MESSAGES_DEBUG", "all", TRUE);
|
||||
if (domains && !*domains)
|
||||
g_clear_pointer (&domains, g_free);
|
||||
|
||||
g_log_set_default_handler (log_handler, NULL);
|
||||
if (!domains || g_str_equal (domains, "all"))
|
||||
any_domain = TRUE;
|
||||
|
||||
g_once_init_leave (&initialized, TRUE);
|
||||
if (domains && strstr (domains, "no-anonymize"))
|
||||
{
|
||||
any_domain = TRUE;
|
||||
no_anonymize = TRUE;
|
||||
g_clear_pointer (&domains, g_free);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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, '#');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
#include "cc-debug.h"
|
||||
#include "cc-log.h"
|
||||
#include "cc-panel-list.h"
|
||||
#include "cc-util.h"
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
#include <config.h>
|
||||
|
||||
#include "cc-debug.h"
|
||||
#include "cc-log.h"
|
||||
#include "cc-window.h"
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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',
|
||||
|
|
Loading…
Add table
Reference in a new issue