6 #include "mono-compiler.h"
7 #include "mono-logger-internal.h"
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;
23 * Initializes the mono tracer.
26 mono_trace_init (void)
28 if(level_stack == NULL) {
29 level_stack = g_queue_new();
31 mono_trace_set_mask_string(g_getenv("MONO_LOG_MASK"));
32 mono_trace_set_level_string(g_getenv("MONO_LOG_LEVEL"));
39 * Releases the mono tracer.
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);
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
64 mono_trace(GLogLevelFlags level, MonoTraceMask mask, const char *format, ...)
66 if(level_stack == NULL)
69 if(level <= current_level && mask & current_mask) {
71 va_start (args, format);
72 g_logv (mono_log_domain, level, format, args);
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
87 mono_tracev (GLogLevelFlags level, MonoTraceMask mask, const char *format, va_list args)
89 if (level_stack == NULL)
92 if(level <= current_level && mask & current_mask)
93 g_logv (mono_log_domain, level, format, args);
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
106 mono_trace_set_level (GLogLevelFlags level)
108 if(level_stack == NULL)
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
124 mono_trace_set_mask (MonoTraceMask mask)
126 if(level_stack == NULL)
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.
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__);
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;
163 * Restores level and mask values saved from a previous call to mono_trace_push.
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__);
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;
186 mono_trace_set_level_string (const char *value)
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 };
196 while(valid_vals[i]) {
197 if(!strcmp(valid_vals[i], value)){
198 mono_trace_set_level(valid_ids[i]);
205 g_print("Unknown trace loglevel: %s\n", value);
209 mono_trace_set_mask_string (const char *value)
215 const char *valid_flags[] = {"asm", "type", "dll", "gc", "cfg", "aot", "security", "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_SECURITY,
230 for (i = 0; valid_flags[i]; i++) {
231 int len = strlen (valid_flags[i]);
232 if (strncmp (tok, valid_flags[i], len) == 0 && (tok[len] == 0 || tok[len] == ',')) {
233 flags |= valid_masks[i];
238 if (!valid_flags[i]) {
239 g_print("Unknown trace flag: %s\n", tok);
244 mono_trace_set_mask (flags);
248 * mono_trace_is_traced:
250 * Returns whenever a message with @level and @mask will be printed or not.
253 mono_trace_is_traced (GLogLevelFlags level, MonoTraceMask mask)
255 return (level <= current_level && mask & current_mask);
258 static MonoLogCallback log_callback;
261 log_level_get_name (GLogLevelFlags log_level)
263 switch (log_level & G_LOG_LEVEL_MASK) {
264 case G_LOG_LEVEL_ERROR: return "error";
265 case G_LOG_LEVEL_CRITICAL: return "critical";
266 case G_LOG_LEVEL_WARNING: return "warning";
267 case G_LOG_LEVEL_MESSAGE: return "message";
268 case G_LOG_LEVEL_INFO: return "info";
269 case G_LOG_LEVEL_DEBUG: return "debug";
270 default: return "unknown";
275 log_adapter (const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data)
277 log_callback (log_domain, log_level_get_name (log_level), message, log_level & G_LOG_LEVEL_ERROR, user_data);
281 * mono_trace_set_log_handler:
283 * @callback The callback that will replace the default logging handler
284 * @user_data Argument passed to @callback
286 * The log handler replaces the default runtime logger. All logging requests with be routed to it.
287 * If the fatal argument in the callback is true, the callback must abort the current process. The runtime expects that
288 * execution will not resume after a fatal error.
291 mono_trace_set_log_handler (MonoLogCallback callback, void *user_data)
294 log_callback = callback;
295 g_log_set_default_handler (log_adapter, user_data);
300 * mono_trace_set_print_handler:
302 * @callback The callback that will replace the default runtime behavior for stdout output.
304 * The print handler replaces the default runtime stdout output handler. This is used by free form output done by the runtime.
308 mono_trace_set_print_handler (MonoPrintCallback callback)
311 g_set_print_handler (callback);
315 * mono_trace_set_printerr_handler:
317 * @callback The callback that will replace the default runtime behavior for stderr output.
319 * The print handler replaces the default runtime stderr output handler. This is used by free form output done by the runtime.
323 mono_trace_set_printerr_handler (MonoPrintCallback callback)
326 g_set_printerr_handler (callback);