3
* Copyright (C) 2015 Christian Hergert <christian@hergert.me>
5
* This program is free software: you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation, either version 3 of the License, or
8
* (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program. If not, see <http://www.gnu.org/licenses/>.
24
# include <sys/types.h>
25
# include <sys/syscall.h>
33
#include "ide-debug.h"
36
typedef const gchar *(*IdeLogLevelStrFunc) (GLogLevelFlags log_level);
38
static GPtrArray *channels;
39
static GLogFunc last_handler;
40
static int log_verbosity;
41
static IdeLogLevelStrFunc log_level_str_func;
43
G_LOCK_DEFINE (channels_lock);
48
* Retrieves task id for the current thread. This is only supported on Linux.
49
* On other platforms, the current current thread pointer is retrieved.
51
* Returns: The task id.
54
ide_log_get_thread (void)
57
return (gint) syscall (SYS_gettid);
59
return GPOINTER_TO_INT (g_thread_self ());
60
#endif /* __linux__ */
65
* @log_level: A #GLogLevelFlags.
67
* Retrieves the log level as a string.
69
* Returns: A string which shouldn't be modified or freed.
73
ide_log_level_str (GLogLevelFlags log_level)
75
switch (((gulong)log_level & G_LOG_LEVEL_MASK))
77
case G_LOG_LEVEL_ERROR: return " ERROR";
78
case G_LOG_LEVEL_CRITICAL: return "CRITICAL";
79
case G_LOG_LEVEL_WARNING: return " WARNING";
80
case G_LOG_LEVEL_MESSAGE: return " MESSAGE";
81
case G_LOG_LEVEL_INFO: return " INFO";
82
case G_LOG_LEVEL_DEBUG: return " DEBUG";
83
case G_LOG_LEVEL_TRACE: return " TRACE";
91
ide_log_level_str_with_color (GLogLevelFlags log_level)
93
switch (((gulong)log_level & G_LOG_LEVEL_MASK))
95
case G_LOG_LEVEL_ERROR: return " \033[1;31mERROR\033[0m";
96
case G_LOG_LEVEL_CRITICAL: return "\033[1;35mCRITICAL\033[0m";
97
case G_LOG_LEVEL_WARNING: return " \033[1;33mWARNING\033[0m";
98
case G_LOG_LEVEL_MESSAGE: return " \033[1;32mMESSAGE\033[0m";
99
case G_LOG_LEVEL_INFO: return " \033[1;32mINFO\033[0m";
100
case G_LOG_LEVEL_DEBUG: return " \033[1;32mDEBUG\033[0m";
101
case G_LOG_LEVEL_TRACE: return " \033[1;36mTRACE\033[0m";
109
* ide_log_write_to_channel:
110
* @channel: A #GIOChannel.
111
* @message: A string log message.
113
* Writes @message to @channel and flushes the channel.
116
ide_log_write_to_channel (GIOChannel *channel,
117
const gchar *message)
119
g_io_channel_write_chars (channel, message, -1, NULL, NULL);
120
g_io_channel_flush (channel, NULL);
125
* @log_domain: A string containing the log section.
126
* @log_level: A #GLogLevelFlags.
127
* @message: The string message.
128
* @user_data: User data supplied to g_log_set_default_handler().
130
* Default log handler that will dispatch log messages to configured logging
134
* Side effects: None.
137
ide_log_handler (const gchar *log_domain,
138
GLogLevelFlags log_level,
139
const gchar *message,
149
if (G_LIKELY (channels->len))
151
switch ((int)log_level)
153
case G_LOG_LEVEL_MESSAGE:
154
if (log_verbosity < 1)
158
case G_LOG_LEVEL_INFO:
159
if (log_verbosity < 2)
163
case G_LOG_LEVEL_DEBUG:
164
if (log_verbosity < 3)
168
case G_LOG_LEVEL_TRACE:
169
if (log_verbosity < 4)
177
level = log_level_str_func (log_level);
178
clock_gettime (CLOCK_REALTIME, &ts);
179
t = (time_t) ts.tv_sec;
180
tt = *localtime (&t);
181
strftime (ftime, sizeof (ftime), "%H:%M:%S", &tt);
182
buffer = g_strdup_printf ("%s.%04ld %30s[%d]: %s: %s\n",
186
ide_log_get_thread (),
189
G_LOCK (channels_lock);
190
g_ptr_array_foreach (channels, (GFunc) ide_log_write_to_channel, buffer);
191
G_UNLOCK (channels_lock);
198
* @stdout_: Indicates logging should be written to stdout.
199
* @filename: An optional file in which to store logs.
201
* Initializes the logging subsystem.
204
ide_log_init (gboolean stdout_,
205
const gchar *filename)
207
static gsize initialized = FALSE;
210
if (g_once_init_enter (&initialized))
212
log_level_str_func = ide_log_level_str;
213
channels = g_ptr_array_new ();
216
channel = g_io_channel_new_file (filename, "a", NULL);
217
g_ptr_array_add (channels, channel);
221
channel = g_io_channel_unix_new (STDOUT_FILENO);
222
g_ptr_array_add (channels, channel);
223
if ((filename == NULL) && isatty (STDOUT_FILENO))
224
log_level_str_func = ide_log_level_str_with_color;
227
g_log_set_default_handler (ide_log_handler, NULL);
228
g_once_init_leave (&initialized, TRUE);
235
* Cleans up after the logging subsystem.
238
ide_log_shutdown (void)
242
g_log_set_default_handler (last_handler, NULL);
248
* ide_log_increase_verbosity:
250
* Increases the amount of logging that will occur. By default, only
251
* warning and above will be displayed.
253
* Calling this once will cause G_LOG_LEVEL_MESSAGE to be displayed.
254
* Calling this twice will cause G_LOG_LEVEL_INFO to be displayed.
255
* Calling this thrice will cause G_LOG_LEVEL_DEBUG to be displayed.
256
* Calling this four times will cause G_LOG_LEVEL_TRACE to be displayed.
258
* Note that many DEBUG and TRACE level log messages are only compiled into
259
* debug builds, and therefore will not be available in release builds.
261
* This method is meant to be called for every -v provided on the command
264
* Calling this method more than four times is acceptable.
267
ide_log_increase_verbosity (void)