6 #include "mono-compiler.h"
7 #include "mono-logger-internals.h"
14 GLogLevelFlags mono_internal_current_level = INT_MAX;
15 MonoTraceMask mono_internal_current_mask = MONO_TRACE_ALL;
17 static GQueue *level_stack = NULL;
18 static const char *mono_log_domain = "Mono";
19 static MonoPrintCallback print_callback, printerr_callback;
24 * Initializes the mono tracer.
27 mono_trace_init (void)
29 if(level_stack == NULL) {
30 mono_internal_current_level = G_LOG_LEVEL_ERROR;
31 level_stack = g_queue_new();
33 mono_trace_set_mask_string(g_getenv("MONO_LOG_MASK"));
34 mono_trace_set_level_string(g_getenv("MONO_LOG_LEVEL"));
41 * Releases the mono tracer.
44 mono_trace_cleanup (void)
46 if(level_stack != NULL) {
47 while(!g_queue_is_empty (level_stack)) {
48 g_free (g_queue_pop_head (level_stack));
51 g_queue_free (level_stack);
59 * @level: Verbose level of the specified message
60 * @mask: Type of the specified message
62 * Traces a new message, depending on the current logging level
66 mono_tracev_inner (GLogLevelFlags level, MonoTraceMask mask, const char *format, va_list args)
68 if (level_stack == NULL) {
70 if(level > mono_internal_current_level || !(mask & mono_internal_current_mask))
74 g_logv (mono_log_domain, level, format, args);
78 * mono_trace_set_level:
80 * @level: Verbose level to set
82 * Sets the current logging level. Every subsequent call to
83 * mono_trace will check the visibility of a message against this
87 mono_trace_set_level (GLogLevelFlags level)
89 if(level_stack == NULL)
92 mono_internal_current_level = level;
96 * mono_trace_set_mask:
98 * @mask: Mask of visible message types.
100 * Sets the current logging level. Every subsequent call to
101 * mono_trace will check the visibility of a message against this
105 mono_trace_set_mask (MonoTraceMask mask)
107 if(level_stack == NULL)
110 mono_internal_current_mask = mask;
116 * @level: Verbose level to set
117 * @mask: Mask of visible message types.
119 * Saves the current values of level and mask then calls mono_trace_set
120 * with the specified new values.
123 mono_trace_push (GLogLevelFlags level, MonoTraceMask mask)
125 if(level_stack == NULL)
126 g_error("%s: cannot use mono_trace_push without calling mono_trace_init first.", __func__);
128 MonoLogLevelEntry *entry = (MonoLogLevelEntry *) g_malloc(sizeof(MonoLogLevelEntry));
129 entry->level = mono_internal_current_level;
130 entry->mask = mono_internal_current_mask;
132 g_queue_push_head (level_stack, (gpointer)entry);
134 /* Set the new level and mask
136 mono_internal_current_level = level;
137 mono_internal_current_mask = mask;
144 * Restores level and mask values saved from a previous call to mono_trace_push.
147 mono_trace_pop (void)
149 if(level_stack == NULL)
150 g_error("%s: cannot use mono_trace_pop without calling mono_trace_init first.", __func__);
152 if(!g_queue_is_empty (level_stack)) {
153 MonoLogLevelEntry *entry = (MonoLogLevelEntry*)g_queue_pop_head (level_stack);
155 /* Restore previous level and mask
157 mono_internal_current_level = entry->level;
158 mono_internal_current_mask = entry->mask;
167 mono_trace_set_level_string (const char *value)
170 const char *valid_vals[] = {"error", "critical", "warning", "message", "info", "debug", NULL};
171 const GLogLevelFlags valid_ids[] = {G_LOG_LEVEL_ERROR, G_LOG_LEVEL_CRITICAL, G_LOG_LEVEL_WARNING,
172 G_LOG_LEVEL_MESSAGE, G_LOG_LEVEL_INFO, G_LOG_LEVEL_DEBUG };
177 while(valid_vals[i]) {
178 if(!strcmp(valid_vals[i], value)){
179 mono_trace_set_level(valid_ids[i]);
186 g_print("Unknown trace loglevel: %s\n", value);
190 mono_trace_set_mask_string (const char *value)
196 const char *valid_flags[] = {"asm", "type", "dll", "gc", "cfg", "aot", "security", "threadpool", "io-threadpool", "io-layer", "all", NULL};
197 const MonoTraceMask valid_masks[] = {MONO_TRACE_ASSEMBLY, MONO_TRACE_TYPE, MONO_TRACE_DLLIMPORT,
198 MONO_TRACE_GC, MONO_TRACE_CONFIG, MONO_TRACE_AOT, MONO_TRACE_SECURITY,
199 MONO_TRACE_THREADPOOL, MONO_TRACE_IO_THREADPOOL, MONO_TRACE_IO_LAYER, MONO_TRACE_ALL };
211 for (i = 0; valid_flags[i]; i++) {
212 int len = strlen (valid_flags[i]);
213 if (strncmp (tok, valid_flags[i], len) == 0 && (tok[len] == 0 || tok[len] == ',')) {
214 flags |= valid_masks[i];
219 if (!valid_flags[i]) {
220 g_print("Unknown trace flag: %s\n", tok);
225 mono_trace_set_mask ((MonoTraceMask) flags);
229 * mono_trace_is_traced:
231 * Returns whenever a message with @level and @mask will be printed or not.
234 mono_trace_is_traced (GLogLevelFlags level, MonoTraceMask mask)
236 return (level <= mono_internal_current_level && mask & mono_internal_current_mask);
239 static MonoLogCallback log_callback;
242 log_level_get_name (GLogLevelFlags log_level)
244 switch (log_level & G_LOG_LEVEL_MASK) {
245 case G_LOG_LEVEL_ERROR: return "error";
246 case G_LOG_LEVEL_CRITICAL: return "critical";
247 case G_LOG_LEVEL_WARNING: return "warning";
248 case G_LOG_LEVEL_MESSAGE: return "message";
249 case G_LOG_LEVEL_INFO: return "info";
250 case G_LOG_LEVEL_DEBUG: return "debug";
251 default: return "unknown";
256 log_adapter (const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data)
258 log_callback (log_domain, log_level_get_name (log_level), message, log_level & G_LOG_LEVEL_ERROR, user_data);
262 * mono_trace_set_log_handler:
264 * @callback The callback that will replace the default logging handler
265 * @user_data Argument passed to @callback
267 * The log handler replaces the default runtime logger. All logging requests with be routed to it.
268 * If the fatal argument in the callback is true, the callback must abort the current process. The runtime expects that
269 * execution will not resume after a fatal error.
272 mono_trace_set_log_handler (MonoLogCallback callback, void *user_data)
275 log_callback = callback;
276 g_log_set_default_handler (log_adapter, user_data);
280 print_handler (const char *string)
282 print_callback (string, TRUE);
286 printerr_handler (const char *string)
288 printerr_callback (string, FALSE);
292 * mono_trace_set_print_handler:
294 * @callback The callback that will replace the default runtime behavior for stdout output.
296 * The print handler replaces the default runtime stdout output handler. This is used by free form output done by the runtime.
300 mono_trace_set_print_handler (MonoPrintCallback callback)
303 print_callback = callback;
304 g_set_print_handler (print_handler);
308 * mono_trace_set_printerr_handler:
310 * @callback The callback that will replace the default runtime behavior for stderr output.
312 * The print handler replaces the default runtime stderr output handler. This is used by free form output done by the runtime.
316 mono_trace_set_printerr_handler (MonoPrintCallback callback)
319 printerr_callback = callback;
320 g_set_printerr_handler (printerr_handler);