[runtime] Fix DISABLE_REFLECTION_EMIT build.
[mono.git] / mono / utils / mono-log-common.c
1 /**
2  * \file
3  * Platform-independent interface to the logger
4  *
5  * This module contains the POSIX syslog logger interface
6  *
7  * Author:
8  *    Neale Ferguson <neale@sinenomine.net>
9  *
10  */
11 #include <config.h>
12
13 #ifdef HAVE_UNISTD_H
14 #include <unistd.h>
15 #endif
16
17 #include <stdlib.h>
18 #include <stdio.h>
19 #include <ctype.h>
20 #include <string.h>
21 #include <glib.h>
22 #include <errno.h>
23 #include <time.h>
24 #ifndef HOST_WIN32
25 #include <sys/time.h>
26 #else
27 #include <process.h>
28 #endif
29 #include "mono-logger-internals.h"
30 #include "mono-proclib.h"
31
32 static FILE *logFile = NULL;
33 static void *logUserData = NULL;
34
35 /**
36  * mapSyslogLevel:
37  *      
38  *      @level - GLogLevelFlags value
39  *      @returns The equivalent character identifier
40  */
41 static inline char 
42 mapLogFileLevel(GLogLevelFlags level) 
43 {
44         if (level & G_LOG_LEVEL_ERROR)
45                 return ('E');
46         if (level & G_LOG_LEVEL_CRITICAL)
47                 return ('C');
48         if (level & G_LOG_LEVEL_WARNING)
49                 return ('W');
50         if (level & G_LOG_LEVEL_MESSAGE)
51                 return ('N');
52         if (level & G_LOG_LEVEL_INFO)
53                 return ('I');
54         if (level & G_LOG_LEVEL_DEBUG)
55                 return ('D');
56         return ('I');
57 }
58
59 /**
60  * mono_log_open_logfile:
61  * \param path Path for log file
62  * \param userData Not used
63  * Open the logfile. If the path is not specified default to stdout. If the
64  * open fails issue a warning and use stdout as the log file destination.
65  */
66 void
67 mono_log_open_logfile(const char *path, void *userData)
68 {
69         if (path == NULL) {
70                 logFile = stdout;
71         } else {
72 #ifndef HOST_WIN32
73                 logFile = fopen(path, "w");
74 #else
75                 gunichar2 *wPath = g_utf8_to_utf16(path, -1, 0, 0, 0);
76                 if (wPath != NULL) {
77                         logFile = _wfopen((wchar_t *) wPath, L"w");
78                         g_free (wPath);
79                 }
80 #endif
81                 if (logFile == NULL) {
82                         g_warning("opening of log file %s failed with %s - defaulting to stdout", 
83                                   path, strerror(errno));
84                         logFile = stdout;
85                 }
86         }
87         logUserData = userData;
88 }
89
90 /**
91  * mono_log_write_logfile:
92  * \param domain Identifier string
93  * \param level Logging level flags
94  * \param format \c printf format string
95  * \param vargs Variable argument list
96  * Write data to the log file.
97  */
98 void
99 mono_log_write_logfile (const char *log_domain, GLogLevelFlags level, mono_bool hdr, const char *message)
100 {
101         time_t t;
102
103         if (logFile == NULL)
104                 logFile = stdout;
105
106         if (hdr) {
107                 pid_t pid;
108                 char logTime [80];
109
110 #ifdef HAVE_LOCALTIME_R
111                 struct tm tod;
112                 time(&t);
113                 localtime_r(&t, &tod);
114                 strftime(logTime, sizeof(logTime), "%Y-%m-%d %H:%M:%S", &tod);
115 #else
116                 struct tm *tod;
117                 time(&t);
118                 tod = localtime(&t);
119                 strftime(logTime, sizeof(logTime), "%F %T", tod);
120 #endif
121
122                 pid = mono_process_current_pid ();
123
124                 fprintf (logFile, "%s level[%c] mono[%d]: %s\n", logTime, mapLogFileLevel (level), pid, message);
125         } else {
126                 fprintf (logFile, "%s%s%s\n",
127                         log_domain != NULL ? log_domain : "",
128                         log_domain != NULL ? ": " : "",
129                         message);
130         }
131
132         fflush(logFile);
133
134         if (level & G_LOG_LEVEL_ERROR)
135                 abort();
136 }
137
138 /**
139  * mono_log_close_logfile:
140  * Close the log file
141  */
142 void
143 mono_log_close_logfile()
144 {
145         if (logFile) {
146                 if (logFile != stdout)
147                         fclose(logFile);
148                 logFile = NULL;
149         }
150 }