1 /* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  *  Copyright (C) 2012-2013  Kouhei Sutou <kou@clear-code.com>
4  *
5  *  This library is free software: you can redistribute it and/or modify
6  *  it under the terms of the GNU Lesser 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.
9  *
10  *  This library 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 Lesser General Public License for more details.
14  *
15  *  You should have received a copy of the GNU Lesser General Public License
16  *  along with this library.  If not, see <http://www.gnu.org/licenses/>.
17  *
18  */
19 
20 #ifndef __CUT_LOGGER_H__
21 #define __CUT_LOGGER_H__
22 
23 #include <glib-object.h>
24 
25 G_BEGIN_DECLS
26 
27 #define cut_log(level, format, ...)                             \
28 do {                                                            \
29     if (cut_need_log(level)) {                                  \
30         (cut_logger_log(cut_logger(),                           \
31                         CUT_LOG_DOMAIN,                         \
32                         (level),                                \
33                         __FILE__,                               \
34                         __LINE__,                               \
35                         G_STRFUNC,                              \
36                         format, ## __VA_ARGS__));               \
37     }                                                           \
38 } while (0)
39 
40 #define cut_log_critical(format, ...)                           \
41     cut_log(CUT_LOG_LEVEL_CRITICAL, format, ## __VA_ARGS__)
42 #define cut_log_error(format, ...)                              \
43     cut_log(CUT_LOG_LEVEL_ERROR, format, ## __VA_ARGS__)
44 #define cut_log_warning(format, ...)                            \
45     cut_log(CUT_LOG_LEVEL_WARNING, format, ## __VA_ARGS__)
46 #define cut_log_message(format, ...)                            \
47     cut_log(CUT_LOG_LEVEL_MESSAGE, format, ## __VA_ARGS__)
48 #define cut_log_info(format, ...)                       \
49     cut_log(CUT_LOG_LEVEL_INFO, format, ## __VA_ARGS__)
50 #define cut_log_debug(format, ...)                              \
51     cut_log(CUT_LOG_LEVEL_DEBUG, format, ## __VA_ARGS__)
52 #define cut_log_trace(format, ...)                              \
53     cut_log(CUT_LOG_LEVEL_TRACE, format, ## __VA_ARGS__)
54 
55 #define cut_set_log_level(level)                        \
56     cut_logger_set_target_level(cut_logger(), (level))
57 #define cut_get_log_level()                             \
58     cut_logger_get_resolved_target_level(cut_logger())
59 #define cut_get_interesting_log_level()                 \
60     cut_logger_get_interesting_level(cut_logger())
61 
62 #define cut_need_log(level)                     \
63     (cut_get_interesting_log_level() & (level))
64 #define cut_need_critical_log()                 \
65     (cut_need_log(CUT_LOG_LEVEL_CRITICAL))
66 #define cut_need_error_log()                    \
67     (cut_need_log(CUT_LOG_LEVEL_ERROR))
68 #define cut_need_warning_log()                  \
69     (cut_need_log(CUT_LOG_LEVEL_WARNING))
70 #define cut_need_message_log()                  \
71     (cut_need_log(CUT_LOG_LEVEL_MESSAGE))
72 #define cut_need_info_log()                     \
73     (cut_need_log(CUT_LOG_LEVEL_INFO))
74 #define cut_need_debug_log()                    \
75     (cut_need_log(CUT_LOG_LEVEL_DEBUG))
76 #define cut_need_trace_log()                    \
77     (cut_need_log(CUT_LOG_LEVEL_TRACE))
78 
79 #define CUT_TYPE_LOGGER            (cut_logger_get_type())
80 #define CUT_LOGGER(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), CUT_TYPE_LOGGER, CutLogger))
81 #define CUT_LOGGER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), CUT_TYPE_LOGGER, CutLoggerClass))
82 #define CUT_IS_LOGGER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), CUT_TYPE_LOGGER))
83 #define CUT_IS_LOGGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), CUT_TYPE_LOGGER))
84 #define CUT_LOGGER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), CUT_TYPE_LOGGER, CutLoggerClass))
85 
86 typedef enum
87 {
88     CUT_LOG_LEVEL_DEFAULT    = 0,
89     CUT_LOG_LEVEL_NONE       = 1 << 0,
90     CUT_LOG_LEVEL_CRITICAL   = 1 << 1,
91     CUT_LOG_LEVEL_ERROR      = 1 << 2,
92     CUT_LOG_LEVEL_WARNING    = 1 << 3,
93     CUT_LOG_LEVEL_MESSAGE    = 1 << 4,
94     CUT_LOG_LEVEL_INFO       = 1 << 5,
95     CUT_LOG_LEVEL_DEBUG      = 1 << 6,
96     CUT_LOG_LEVEL_TRACE      = 1 << 7
97 } CutLogLevelFlags;
98 
99 #define CUT_LOG_LEVEL_ALL (CUT_LOG_LEVEL_CRITICAL |          \
100                            CUT_LOG_LEVEL_ERROR |             \
101                            CUT_LOG_LEVEL_WARNING |           \
102                            CUT_LOG_LEVEL_MESSAGE |           \
103                            CUT_LOG_LEVEL_INFO |              \
104                            CUT_LOG_LEVEL_DEBUG |             \
105                            CUT_LOG_LEVEL_TRACE)
106 
107 #define CUT_LOG_NULL_SAFE_STRING(string) ((string) ? (string) : "(null)")
108 
109 typedef enum
110 {
111     CUT_LOG_ITEM_DEFAULT     = 0,
112     CUT_LOG_ITEM_NONE        = 1 << 0,
113     CUT_LOG_ITEM_DOMAIN      = 1 << 1,
114     CUT_LOG_ITEM_LEVEL       = 1 << 2,
115     CUT_LOG_ITEM_LOCATION    = 1 << 3,
116     CUT_LOG_ITEM_TIME        = 1 << 4,
117     CUT_LOG_ITEM_NAME        = 1 << 5,
118     CUT_LOG_ITEM_PID         = 1 << 6
119 } CutLogItemFlags;
120 
121 #define CUT_LOG_ITEM_ALL (CUT_LOG_ITEM_DOMAIN |      \
122                           CUT_LOG_ITEM_LEVEL |       \
123                           CUT_LOG_ITEM_LOCATION |    \
124                           CUT_LOG_ITEM_TIME |        \
125                           CUT_LOG_ITEM_NAME |        \
126                           CUT_LOG_ITEM_PID)
127 
128 typedef enum
129 {
130     CUT_LOG_COLORIZE_DEFAULT,
131     CUT_LOG_COLORIZE_NONE,
132     CUT_LOG_COLORIZE_CONSOLE
133 } CutLogColorize;
134 
135 #define CUT_ENUM_ERROR           (cut_enum_error_quark())
136 #define CUT_FLAGS_ERROR          (cut_flags_error_quark())
137 
138 typedef enum
139 {
140     CUT_ENUM_ERROR_NULL_NAME,
141     CUT_ENUM_ERROR_UNKNOWN_NAME
142 } CutEnumError;
143 
144 typedef enum
145 {
146     CUT_FLAGS_ERROR_NULL_NAME,
147     CUT_FLAGS_ERROR_UNKNOWN_NAMES
148 } CutFlagsError;
149 
150 GQuark           cut_enum_error_quark       (void);
151 GQuark           cut_flags_error_quark      (void);
152 
153 typedef struct _CutLogger         CutLogger;
154 typedef struct _CutLoggerClass    CutLoggerClass;
155 
156 struct _CutLogger
157 {
158     GObject object;
159 };
160 
161 struct _CutLoggerClass
162 {
163     GObjectClass parent_class;
164 
165     void (*log) (CutLogger        *logger,
166                  const gchar      *domain,
167                  CutLogLevelFlags  level,
168                  const gchar      *file,
169                  guint             line,
170                  const gchar      *function,
171                  GTimeVal         *time_value,
172                  const gchar      *message);
173 };
174 
175 GQuark           cut_logger_error_quark    (void);
176 
177 GType            cut_logger_get_type       (void) G_GNUC_CONST;
178 
179 CutLogLevelFlags cut_log_level_flags_from_string (const gchar *level_name,
180                                                   CutLogLevelFlags base_flags,
181                                                   GError     **error);
182 CutLogItemFlags  cut_log_item_flags_from_string  (const gchar *item_name,
183                                                   CutLogItemFlags base_flags,
184                                                   GError     **error);
185 
186 CutLogger       *cut_logger                (void);
187 void             cut_logger_default_log_handler
188                                            (CutLogger        *logger,
189                                             const gchar      *domain,
190                                             CutLogLevelFlags  level,
191                                             const gchar      *file,
192                                             guint             line,
193                                             const gchar      *function,
194                                             GTimeVal         *time_value,
195                                             const gchar      *message,
196                                             gpointer          user_data);
197 CutLogger       *cut_logger_new            (void);
198 void             cut_logger_log            (CutLogger        *logger,
199                                             const gchar      *domain,
200                                             CutLogLevelFlags  level,
201                                             const gchar      *file,
202                                             guint             line,
203                                             const gchar      *function,
204                                             const gchar      *format,
205                                             ...) G_GNUC_PRINTF(7, 8);
206 void             cut_logger_log_va_list    (CutLogger        *logger,
207                                             const gchar      *domain,
208                                             CutLogLevelFlags  level,
209                                             const gchar      *file,
210                                             guint             line,
211                                             const gchar      *function,
212                                             const gchar      *format,
213                                             va_list           args);
214 CutLogLevelFlags cut_logger_get_target_level
215                                            (CutLogger        *logger);
216 CutLogLevelFlags cut_logger_get_resolved_target_level
217                                            (CutLogger        *logger);
218 void             cut_logger_set_target_level
219                                            (CutLogger        *logger,
220                                             CutLogLevelFlags  level);
221 gboolean         cut_logger_set_target_level_by_string
222                                            (CutLogger        *logger,
223                                             const gchar      *level_name,
224                                             GError          **error);
225 void             cut_logger_set_interesting_level
226                                            (CutLogger        *logger,
227                                             const gchar      *key,
228                                             CutLogLevelFlags  level);
229 CutLogLevelFlags cut_logger_get_interesting_level
230                                            (CutLogger        *logger);
231 CutLogItemFlags  cut_logger_get_target_item(CutLogger        *logger);
232 void             cut_logger_set_target_item(CutLogger        *logger,
233                                             CutLogItemFlags   item);
234 gboolean         cut_logger_set_target_item_by_string
235                                            (CutLogger        *logger,
236                                             const gchar      *item_name,
237                                             GError          **error);
238 
239 void             cut_logger_connect_default_handler
240                                            (CutLogger        *logger);
241 void             cut_logger_disconnect_default_handler
242                                            (CutLogger        *logger);
243 
244 #define CUT_GLIB_LOG_DELEGATE(domain)           \
245     g_log_set_handler(domain,                   \
246                       G_LOG_LEVEL_MASK |        \
247                       G_LOG_FLAG_RECURSION |    \
248                       G_LOG_FLAG_FATAL,         \
249                       cut_glib_log_handler,     \
250                       NULL)
251 
252 void             cut_glib_log_handler      (const gchar         *log_domain,
253                                             GLogLevelFlags       log_level,
254                                             const gchar         *message,
255                                             gpointer             user_data);
256 
257 G_END_DECLS
258 
259 #endif /* __CUT_LOGGER_H__ */
260 
261 /*
262 vi:ts=4:nowrap:ai:expandtab:sw=4
263 */
264