Merge pull request #4540 from kumpera/android-changes-part1
[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 #ifndef HOST_WIN32
111                 struct tm tod;
112                 time(&t);
113                 localtime_r(&t, &tod);
114                 pid = getpid();
115                 strftime(logTime, sizeof(logTime), "%Y-%m-%d %H:%M:%S", &tod);
116 #else
117                 struct tm *tod;
118                 time(&t);
119                 tod = localtime(&t);
120                 pid = mono_process_current_pid ();
121                 strftime(logTime, sizeof(logTime), "%F %T", tod);
122 #endif
123                 fprintf (logFile, "%s level[%c] mono[%d]: %s\n", logTime, mapLogFileLevel (level), pid, message);
124         } else {
125                 fprintf (logFile, "%s%s%s\n",
126                         log_domain != NULL ? log_domain : "",
127                         log_domain != NULL ? ": " : "",
128                         message);
129         }
130
131         fflush(logFile);
132
133         if (level & G_LOG_LEVEL_ERROR)
134                 abort();
135 }
136
137 /**
138  * mono_log_close_logfile:
139  * Close the log file
140  */
141 void
142 mono_log_close_logfile()
143 {
144         if (logFile) {
145                 if (logFile != stdout)
146                         fclose(logFile);
147                 logFile = NULL;
148         }
149 }