Log and database functions moved from server core to libnxsrv
[public/netxms.git] / src / server / libnxsrv / log.cpp
CommitLineData
4385fa12 1/*
9cc9ea72
VK
2** NetXMS - Network Management System
3** Copyright (C) 2003, 2004 Victor Kirhenshtein
4385fa12
VK
4**
5** This program is free software; you can redistribute it and/or modify
6** it under the terms of the GNU General Public License as published by
7** the Free Software Foundation; either version 2 of the License, or
8** (at your option) any later version.
9**
10** This program is distributed in the hope that it will be useful,
11** but WITHOUT ANY WARRANTY; without even the implied warranty of
12** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13** GNU General Public License for more details.
14**
15** You should have received a copy of the GNU General Public License
16** along with this program; if not, write to the Free Software
17** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18**
19** $module: log.cpp
20**
21**/
22
9cc9ea72 23#include "libnxsrv.h"
4385fa12
VK
24
25
e40c3204
VK
26//
27// Messages generated by mc.pl (for UNIX version only)
28//
29
30#ifndef _WIN32
31extern DWORD g_dwNumMessages;
32extern char *g_szMessages[];
33#endif
34
35
4385fa12
VK
36//
37// Static data
38//
39
40#ifdef _WIN32
41static HANDLE m_hEventLog = INVALID_HANDLE_VALUE;
9cc9ea72 42static HMODULE m_hLibraryHandle = NULL;
4385fa12
VK
43#endif
44static FILE *m_hLogFile = NULL;
45static MUTEX m_mutexLogAccess = INVALID_MUTEX_HANDLE;
9cc9ea72
VK
46static BOOL m_bUseSystemLog = FALSE;
47static BOOL m_bPrintToScreen = FALSE;
4385fa12
VK
48
49
50//
51// Initialize log
52//
53
9cc9ea72 54void LIBNXSRV_EXPORTABLE InitLog(BOOL bUseSystemLog, char *pszLogFile, BOOL bPrintToScreen)
4385fa12 55{
9cc9ea72
VK
56 m_bUseSystemLog = bUseSystemLog;
57 m_bPrintToScreen = bPrintToScreen;
4385fa12 58#ifdef _WIN32
9cc9ea72
VK
59 m_hLibraryHandle = GetModuleHandle(_T("LIBNXSRV.DLL"));
60 if (m_bUseSystemLog)
4385fa12
VK
61 {
62 m_hEventLog = RegisterEventSource(NULL, CORE_EVENT_SOURCE);
63 }
64 else
65 {
66#endif
67 char szTimeBuf[32];
68 struct tm *loc;
69 time_t t;
70
9cc9ea72 71 m_hLogFile = fopen(pszLogFile, "a");
4385fa12
VK
72 t = time(NULL);
73 loc = localtime(&t);
74 strftime(szTimeBuf, 32, "%d-%b-%Y %H:%M:%S", loc);
b1dd534d 75 fprintf(m_hLogFile, "\n[%s] Log file opened\n", szTimeBuf);
03ef9555 76 fflush(m_hLogFile);
4385fa12
VK
77
78 m_mutexLogAccess = MutexCreate();
79#ifdef _WIN32
80 }
81#endif
82}
83
84
85//
86// Close log
87//
88
9cc9ea72 89void LIBNXSRV_EXPORTABLE CloseLog(void)
4385fa12
VK
90{
91#ifdef _WIN32
9cc9ea72 92 if (m_bUseSystemLog)
4385fa12
VK
93 {
94 DeregisterEventSource(m_hEventLog);
95 }
96 else
97 {
98#endif
99 if (m_hLogFile != NULL)
6e165a72
VK
100 {
101 char szTimeBuf[32];
102 struct tm *loc;
103 time_t t;
104
105 t = time(NULL);
106 loc = localtime(&t);
107 strftime(szTimeBuf, 32, "%d-%b-%Y %H:%M:%S", loc);
b1dd534d 108 fprintf(m_hLogFile, "[%s] Log file closed\n", szTimeBuf);
4385fa12 109 fclose(m_hLogFile);
6e165a72 110 }
4385fa12
VK
111 if (m_mutexLogAccess != INVALID_MUTEX_HANDLE)
112 MutexDestroy(m_mutexLogAccess);
113#ifdef _WIN32
114 }
115#endif
116}
117
118
119//
120// Write record to log file
121//
122
123static void WriteLogToFile(char *szMessage)
124{
125 char szBuffer[64];
126 time_t t;
127 struct tm *loc;
128
129 // Prevent simultaneous write to log file
130 MutexLock(m_mutexLogAccess, INFINITE);
131
132 t = time(NULL);
133 loc = localtime(&t);
48b1c0ac 134 strftime(szBuffer, 32, "[%d-%b-%Y %H:%M:%S]", loc);
4385fa12 135 fprintf(m_hLogFile, "%s %s", szBuffer, szMessage);
03ef9555 136 fflush(m_hLogFile);
9cc9ea72 137 if (m_bPrintToScreen)
4385fa12
VK
138 printf("%s %s", szBuffer, szMessage);
139
140 MutexUnlock(m_mutexLogAccess);
141}
142
143
e40c3204
VK
144//
145// Format message (UNIX version)
146//
147
148#ifndef _WIN32
149
9cc9ea72 150static char *FormatMessageUX(DWORD dwMsgId, char **ppStrings)
e40c3204
VK
151{
152 char *p, *pMsg;
153 int i, iSize, iLen;
154
155 if (dwMsgId >= g_dwNumMessages)
156 {
157 // No message with this ID
158 pMsg = (char *)malloc(128);
159 sprintf(pMsg, "MSG 0x%08X - Unable to find message text\n", dwMsgId);
160 }
161 else
162 {
163 iSize = strlen(g_szMessages[dwMsgId]) + 2;
164 pMsg = (char *)malloc(iSize);
165
166 for(i = 0, p = g_szMessages[dwMsgId]; *p != 0; p++)
167 if (*p == '%')
168 {
169 p++;
170 if ((*p >= '1') && (*p <= '9'))
171 {
172 iLen = strlen(ppStrings[*p - '1']);
173 iSize += iLen;
174 pMsg = (char *)realloc(pMsg, iSize);
175 strcpy(&pMsg[i], ppStrings[*p - '1']);
176 i += iLen;
177 }
178 else
179 {
180 if (*p == 0) // Handle single % character at the string end
181 break;
182 pMsg[i++] = *p;
183 }
184 }
185 else
186 {
187 pMsg[i++] = *p;
188 }
189 pMsg[i++] = '\n';
190 pMsg[i] = 0;
191 }
192
193 return pMsg;
194}
195
196#endif /* ! _WIN32 */
197
198
4385fa12
VK
199//
200// Write log record
201// Parameters:
202// msg - Message ID
203// wType - Message type (see ReportEvent() for details)
204// format - Parameter format string, each parameter represented by one character.
205// The following format characters can be used:
206// s - String
207// d - Decimal integer
208// x - Hex integer
209// e - System error code (will appear in log as textual description)
c7ca9142 210// a - IP address in network byte order
4385fa12
VK
211//
212
9cc9ea72 213void LIBNXSRV_EXPORTABLE WriteLog(DWORD msg, WORD wType, char *format, ...)
4385fa12
VK
214{
215 va_list args;
e40c3204 216 char *strings[16], *pMsg;
4385fa12
VK
217 int numStrings = 0;
218 DWORD error;
219
220 memset(strings, 0, sizeof(char *) * 16);
221
222 if (format != NULL)
223 {
224 va_start(args, format);
225
226 for(; (format[numStrings] != 0) && (numStrings < 16); numStrings++)
227 {
228 switch(format[numStrings])
229 {
230 case 's':
231 strings[numStrings] = strdup(va_arg(args, char *));
232 break;
233 case 'd':
234 strings[numStrings] = (char *)malloc(16);
235 sprintf(strings[numStrings], "%d", va_arg(args, LONG));
236 break;
237 case 'x':
238 strings[numStrings] = (char *)malloc(16);
239 sprintf(strings[numStrings], "0x%08X", va_arg(args, DWORD));
240 break;
c7ca9142
VK
241 case 'a':
242 strings[numStrings] = (char *)malloc(20);
243 IpToStr(va_arg(args, DWORD), strings[numStrings]);
244 break;
4385fa12
VK
245 case 'e':
246 error = va_arg(args, DWORD);
247#ifdef _WIN32
248 if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
249 FORMAT_MESSAGE_FROM_SYSTEM |
250 FORMAT_MESSAGE_IGNORE_INSERTS,
251 NULL, error,
252 MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT), // Default language
e40c3204 253 (LPSTR)&pMsg,0,NULL)>0)
4385fa12 254 {
fa1d3757 255 pMsg[strcspn(pMsg,"\r\n")] = 0;
e40c3204
VK
256 strings[numStrings]=(char *)malloc(strlen(pMsg) + 1);
257 strcpy(strings[numStrings], pMsg);
258 LocalFree(pMsg);
4385fa12
VK
259 }
260 else
261 {
262 strings[numStrings] = (char *)malloc(64);
263 sprintf(strings[numStrings], "MSG 0x%08X - Unable to find message text", error);
264 }
265#else /* _WIN32 */
266 strings[numStrings] = strdup(strerror(error));
267#endif
268 break;
269 default:
270 strings[numStrings] = (char *)malloc(32);
271 sprintf(strings[numStrings], "BAD FORMAT (0x%08X)", va_arg(args, DWORD));
272 break;
273 }
274 }
275 va_end(args);
276 }
277
278#ifdef _WIN32
9cc9ea72 279 if (m_bUseSystemLog)
4385fa12
VK
280 {
281 ReportEvent(m_hEventLog, wType, 0, msg, NULL, numStrings, 0, (const char **)strings, NULL);
282 }
283 else
284 {
285 LPVOID lpMsgBuf;
286
9cc9ea72
VK
287 if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
288 FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_ARGUMENT_ARRAY,
289 m_hLibraryHandle, msg, 0, (LPTSTR)&lpMsgBuf, 0, strings)>0)
4385fa12 290 {
b1dd534d
VK
291 char *pCR;
292
293 // Replace trailing CR/LF pair with LF
294 pCR = strchr((char *)lpMsgBuf, '\r');
295 if (pCR != NULL)
296 {
297 *pCR = '\n';
298 pCR++;
299 *pCR = 0;
300 }
4385fa12
VK
301 WriteLogToFile((char *)lpMsgBuf);
302 LocalFree(lpMsgBuf);
303 }
304 else
305 {
306 char message[64];
307
b1dd534d 308 sprintf(message,"MSG 0x%08X - Unable to find message text\n",msg);
4385fa12
VK
309 WriteLogToFile(message);
310 }
311 }
312#else /* _WIN32 */
e40c3204 313 pMsg = FormatMessageUX(msg, strings);
9cc9ea72 314 if (m_bUseSystemLog)
e40c3204
VK
315 {
316 }
317 else
318 {
319 WriteLogToFile(pMsg);
320 }
321 free(pMsg);
3a2f672c 322#endif /* _WIN32 */
4385fa12
VK
323
324 while(--numStrings >= 0)
325 free(strings[numStrings]);
326}