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