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;
19 static MonoPrintCallback print_callback, printerr_callback;
24 * Initializes the mono tracer.
27 mono_trace_init (void)
29 if(level_stack == NULL) {
30 level_stack = g_queue_new();
32 mono_trace_set_mask_string(g_getenv("MONO_LOG_MASK"));
33 mono_trace_set_level_string(g_getenv("MONO_LOG_LEVEL"));
40 * Releases the mono tracer.
43 mono_trace_cleanup (void)
45 if(level_stack != NULL) {
46 while(!g_queue_is_empty (level_stack)) {
47 g_free (g_queue_pop_head (level_stack));
50 g_queue_free (level_stack);
58 * @level: Verbose level of the specified message
59 * @mask: Type of the specified message
61 * Traces a new message, depending on the current logging level
65 mono_trace(GLogLevelFlags level, MonoTraceMask mask, const char *format, ...)
67 if(level_stack == NULL)
70 if(level <= current_level && mask & current_mask) {
72 va_start (args, format);
73 g_logv (mono_log_domain, level, format, args);
81 * @level: Verbose level of the specified message
82 * @mask: Type of the specified message
84 * Traces a new message, depending on the current logging level
88 mono_tracev (GLogLevelFlags level, MonoTraceMask mask, const char *format, va_list args)
90 if (level_stack == NULL)
93 if(level <= current_level && mask & current_mask)
94 g_logv (mono_log_domain, level, format, args);
98 * mono_trace_set_level:
100 * @level: Verbose level to set
102 * Sets the current logging level. Every subsequent call to
103 * mono_trace will check the visibility of a message against this
107 mono_trace_set_level (GLogLevelFlags level)
109 if(level_stack == NULL)
112 current_level = level;
116 * mono_trace_set_mask:
118 * @mask: Mask of visible message types.
120 * Sets the current logging level. Every subsequent call to
121 * mono_trace will check the visibility of a message against this
125 mono_trace_set_mask (MonoTraceMask mask)
127 if(level_stack == NULL)
136 * @level: Verbose level to set
137 * @mask: Mask of visible message types.
139 * Saves the current values of level and mask then calls mono_trace_set
140 * with the specified new values.
143 mono_trace_push (GLogLevelFlags level, MonoTraceMask mask)
145 if(level_stack == NULL)
146 g_error("%s: cannot use mono_trace_push without calling mono_trace_init first.", __func__);
148 MonoLogLevelEntry *entry = g_malloc(sizeof(MonoLogLevelEntry));
149 entry->level = current_level;
150 entry->mask = current_mask;
152 g_queue_push_head (level_stack, (gpointer)entry);
154 /* Set the new level and mask
156 current_level = level;
164 * Restores level and mask values saved from a previous call to mono_trace_push.
167 mono_trace_pop (void)
169 if(level_stack == NULL)
170 g_error("%s: cannot use mono_trace_pop without calling mono_trace_init first.", __func__);
172 if(!g_queue_is_empty (level_stack)) {
173 MonoLogLevelEntry *entry = (MonoLogLevelEntry*)g_queue_pop_head (level_stack);
175 /* Restore previous level and mask
177 current_level = entry->level;
178 current_mask = entry->mask;
187 mono_trace_set_level_string (const char *value)
190 const char *valid_vals[] = {"error", "critical", "warning", "message", "info", "debug", NULL};
191 const GLogLevelFlags valid_ids[] = {G_LOG_LEVEL_ERROR, G_LOG_LEVEL_CRITICAL, G_LOG_LEVEL_WARNING,
192 G_LOG_LEVEL_MESSAGE, G_LOG_LEVEL_INFO, G_LOG_LEVEL_DEBUG };
197 while(valid_vals[i]) {
198 if(!strcmp(valid_vals[i], value)){
199 mono_trace_set_level(valid_ids[i]);
206 g_print("Unknown trace loglevel: %s\n", value);
210 mono_trace_set_mask_string (const char *value)
216 const char *valid_flags[] = {"asm", "type", "dll", "gc", "cfg", "aot", "security", "all", NULL};
217 const MonoTraceMask valid_masks[] = {MONO_TRACE_ASSEMBLY, MONO_TRACE_TYPE, MONO_TRACE_DLLIMPORT,
218 MONO_TRACE_GC, MONO_TRACE_CONFIG, MONO_TRACE_AOT, MONO_TRACE_SECURITY,
231 for (i = 0; valid_flags[i]; i++) {
232 int len = strlen (valid_flags[i]);
233 if (strncmp (tok, valid_flags[i], len) == 0 && (tok[len] == 0 || tok[len] == ',')) {
234 flags |= valid_masks[i];
239 if (!valid_flags[i]) {
240 g_print("Unknown trace flag: %s\n", tok);
245 mono_trace_set_mask (flags);
249 * mono_trace_is_traced:
251 * Returns whenever a message with @level and @mask will be printed or not.
254 mono_trace_is_traced (GLogLevelFlags level, MonoTraceMask mask)
256 return (level <= current_level && mask & current_mask);
259 static MonoLogCallback log_callback;
262 log_level_get_name (GLogLevelFlags log_level)
264 switch (log_level & G_LOG_LEVEL_MASK) {
265 case G_LOG_LEVEL_ERROR: return "error";
266 case G_LOG_LEVEL_CRITICAL: return "critical";
267 case G_LOG_LEVEL_WARNING: return "warning";
268 case G_LOG_LEVEL_MESSAGE: return "message";
269 case G_LOG_LEVEL_INFO: return "info";
270 case G_LOG_LEVEL_DEBUG: return "debug";
271 default: return "unknown";
276 log_adapter (const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data)
278 log_callback (log_domain, log_level_get_name (log_level), message, log_level & G_LOG_LEVEL_ERROR, user_data);
282 * mono_trace_set_log_handler:
284 * @callback The callback that will replace the default logging handler
285 * @user_data Argument passed to @callback
287 * The log handler replaces the default runtime logger. All logging requests with be routed to it.
288 * If the fatal argument in the callback is true, the callback must abort the current process. The runtime expects that
289 * execution will not resume after a fatal error.
292 mono_trace_set_log_handler (MonoLogCallback callback, void *user_data)
295 log_callback = callback;
296 g_log_set_default_handler (log_adapter, user_data);
300 print_handler (const char *string)
302 print_callback (string, TRUE);
306 printerr_handler (const char *string)
308 printerr_callback (string, FALSE);
312 * mono_trace_set_print_handler:
314 * @callback The callback that will replace the default runtime behavior for stdout output.
316 * The print handler replaces the default runtime stdout output handler. This is used by free form output done by the runtime.
320 mono_trace_set_print_handler (MonoPrintCallback callback)
323 print_callback = callback;
324 g_set_print_handler (print_handler);
328 * mono_trace_set_printerr_handler:
330 * @callback The callback that will replace the default runtime behavior for stderr output.
332 * The print handler replaces the default runtime stderr output handler. This is used by free form output done by the runtime.
336 mono_trace_set_printerr_handler (MonoPrintCallback callback)
339 printerr_callback = callback;
340 g_set_print_handler (printerr_handler);