2009-12-30 Rodrigo Kumpera <rkumpera@novell.com>
[mono.git] / mono / utils / mono-logger.c
blob1fdc26b82894d60944b7a44e6de1bd0261a5ce10
1 #include <string.h>
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include <glib.h>
6 #include "mono-compiler.h"
7 #include "mono-logger.h"
9 typedef struct {
10 GLogLevelFlags level;
11 MonoTraceMask mask;
12 } MonoLogLevelEntry;
14 static GLogLevelFlags current_level = G_LOG_LEVEL_ERROR;
15 static MonoTraceMask current_mask = MONO_TRACE_ALL;
17 static const char *mono_log_domain = "Mono";
18 static GQueue *level_stack = NULL;
20 /**
21 * mono_trace_init:
23 * Initializes the mono tracer.
25 static void
26 mono_trace_init (void)
28 if(level_stack == NULL) {
29 level_stack = g_queue_new();
31 mono_trace_set_mask_string(getenv("MONO_LOG_MASK"));
32 mono_trace_set_level_string(getenv("MONO_LOG_LEVEL"));
36 /**
37 * mono_trace_cleanup:
39 * Releases the mono tracer.
41 void
42 mono_trace_cleanup (void)
44 if(level_stack != NULL) {
45 while(!g_queue_is_empty (level_stack)) {
46 g_free (g_queue_pop_head (level_stack));
49 g_queue_free (level_stack);
50 level_stack = NULL;
54 /**
55 * mono_trace:
57 * @level: Verbose level of the specified message
58 * @mask: Type of the specified message
60 * Traces a new message, depending on the current logging level
61 * and trace mask.
63 void
64 mono_trace(GLogLevelFlags level, MonoTraceMask mask, const char *format, ...)
66 if(level_stack == NULL)
67 mono_trace_init();
69 if(level <= current_level && mask & current_mask) {
70 va_list args;
71 va_start (args, format);
72 g_logv (mono_log_domain, level, format, args);
73 va_end (args);
77 /**
78 * mono_tracev:
80 * @level: Verbose level of the specified message
81 * @mask: Type of the specified message
83 * Traces a new message, depending on the current logging level
84 * and trace mask.
86 void
87 mono_tracev (GLogLevelFlags level, MonoTraceMask mask, const char *format, va_list args)
89 if (level_stack == NULL)
90 mono_trace_init ();
92 if(level <= current_level && mask & current_mask)
93 g_logv (mono_log_domain, level, format, args);
96 /**
97 * mono_trace_set_level:
99 * @level: Verbose level to set
101 * Sets the current logging level. Every subsequent call to
102 * mono_trace will check the visibility of a message against this
103 * value.
105 void
106 mono_trace_set_level (GLogLevelFlags level)
108 if(level_stack == NULL)
109 mono_trace_init();
111 current_level = level;
115 * mono_trace_set_mask:
117 * @mask: Mask of visible message types.
119 * Sets the current logging level. Every subsequent call to
120 * mono_trace will check the visibility of a message against this
121 * value.
123 void
124 mono_trace_set_mask (MonoTraceMask mask)
126 if(level_stack == NULL)
127 mono_trace_init();
129 current_mask = mask;
133 * mono_trace_push:
135 * @level: Verbose level to set
136 * @mask: Mask of visible message types.
138 * Saves the current values of level and mask then calls mono_trace_set
139 * with the specified new values.
141 void
142 mono_trace_push (GLogLevelFlags level, MonoTraceMask mask)
144 if(level_stack == NULL)
145 g_error("%s: cannot use mono_trace_push without calling mono_trace_init first.", __func__);
146 else {
147 MonoLogLevelEntry *entry = g_malloc(sizeof(MonoLogLevelEntry));
148 entry->level = current_level;
149 entry->mask = current_mask;
151 g_queue_push_head (level_stack, (gpointer)entry);
153 /* Set the new level and mask
155 current_level = level;
156 current_mask = mask;
161 * mono_trace_pop:
163 * Restores level and mask values saved from a previous call to mono_trace_push.
165 void
166 mono_trace_pop (void)
168 if(level_stack == NULL)
169 g_error("%s: cannot use mono_trace_pop without calling mono_trace_init first.", __func__);
170 else {
171 if(!g_queue_is_empty (level_stack)) {
172 MonoLogLevelEntry *entry = (MonoLogLevelEntry*)g_queue_pop_head (level_stack);
174 /* Restore previous level and mask
176 current_level = entry->level;
177 current_mask = entry->mask;
179 g_free (entry);
185 void
186 mono_trace_set_level_string (const char *value)
188 int i = 0;
189 const char *valid_vals[] = {"error", "critical", "warning", "message", "info", "debug", NULL};
190 const GLogLevelFlags valid_ids[] = {G_LOG_LEVEL_ERROR, G_LOG_LEVEL_CRITICAL, G_LOG_LEVEL_WARNING,
191 G_LOG_LEVEL_MESSAGE, G_LOG_LEVEL_INFO, G_LOG_LEVEL_DEBUG };
193 if(!value)
194 return;
196 while(valid_vals[i]) {
197 if(!strcmp(valid_vals[i], value)){
198 mono_trace_set_level(valid_ids[i]);
199 return;
201 i++;
204 if(*value)
205 g_print("Unknown trace loglevel: %s\n", value);
208 void
209 mono_trace_set_mask_string (char *value)
211 int i;
212 char *tok;
213 guint32 flags = 0;
215 const char *valid_flags[] = {"asm", "type", "dll", "gc", "cfg", "aot", "all", NULL};
216 const MonoTraceMask valid_masks[] = {MONO_TRACE_ASSEMBLY, MONO_TRACE_TYPE, MONO_TRACE_DLLIMPORT,
217 MONO_TRACE_GC, MONO_TRACE_CONFIG, MONO_TRACE_AOT, MONO_TRACE_ALL };
219 if(!value)
220 return;
222 tok = strtok (value, ",");
224 if(!tok)
225 tok = value;
227 while (tok) {
228 for (i = 0; valid_flags[i]; i++) {
229 if (strcmp (tok, valid_flags[i]) == 0) {
230 flags |= valid_masks[i];
231 break;
234 if (!valid_flags[i])
235 g_print("Unknown trace flag: %s\n", tok);
237 tok = strtok (NULL, ",");
240 if(flags)
241 mono_trace_set_mask (flags);
245 * mono_trace_is_traced:
247 * Returns whenever a message with @level and @mask will be printed or not.
249 gboolean
250 mono_trace_is_traced (GLogLevelFlags level, MonoTraceMask mask)
252 return (level <= current_level && mask & current_mask);