- Added component locks
[public/netxms.git] / src / server / core / log.cpp
CommitLineData
4385fa12
VK
1/*
2** Network Management System Core
3** Copyright (C) 2003 Victor Kirhenshtein
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
23#include "nms_core.h"
4385fa12
VK
24
25
26//
27// Static data
28//
29
30#ifdef _WIN32
31static HANDLE m_hEventLog = INVALID_HANDLE_VALUE;
32#endif
33static FILE *m_hLogFile = NULL;
34static MUTEX m_mutexLogAccess = INVALID_MUTEX_HANDLE;
35
36
37//
38// Initialize log
39//
40
41void InitLog(void)
42{
43#ifdef _WIN32
44 if (g_dwFlags & AF_USE_EVENT_LOG)
45 {
46 m_hEventLog = RegisterEventSource(NULL, CORE_EVENT_SOURCE);
47 }
48 else
49 {
50#endif
51 char szTimeBuf[32];
52 struct tm *loc;
53 time_t t;
54
55 m_hLogFile = fopen(g_szLogFile, "a");
56 t = time(NULL);
57 loc = localtime(&t);
58 strftime(szTimeBuf, 32, "%d-%b-%Y %H:%M:%S", loc);
59 fprintf(m_hLogFile, "**************************************************************\r\n[%s] Log file opened\r\n", szTimeBuf);
60
61 m_mutexLogAccess = MutexCreate();
62#ifdef _WIN32
63 }
64#endif
65}
66
67
68//
69// Close log
70//
71
72void CloseLog(void)
73{
74#ifdef _WIN32
75 if (g_dwFlags & AF_USE_EVENT_LOG)
76 {
77 DeregisterEventSource(m_hEventLog);
78 }
79 else
80 {
81#endif
82 if (m_hLogFile != NULL)
83 fclose(m_hLogFile);
84 if (m_mutexLogAccess != INVALID_MUTEX_HANDLE)
85 MutexDestroy(m_mutexLogAccess);
86#ifdef _WIN32
87 }
88#endif
89}
90
91
92//
93// Write record to log file
94//
95
96static void WriteLogToFile(char *szMessage)
97{
98 char szBuffer[64];
99 time_t t;
100 struct tm *loc;
101
102 // Prevent simultaneous write to log file
103 MutexLock(m_mutexLogAccess, INFINITE);
104
105 t = time(NULL);
106 loc = localtime(&t);
48b1c0ac 107 strftime(szBuffer, 32, "[%d-%b-%Y %H:%M:%S]", loc);
4385fa12
VK
108 fprintf(m_hLogFile, "%s %s", szBuffer, szMessage);
109 if (IsStandalone())
110 printf("%s %s", szBuffer, szMessage);
111
112 MutexUnlock(m_mutexLogAccess);
113}
114
115
116//
117// Write log record
118// Parameters:
119// msg - Message ID
120// wType - Message type (see ReportEvent() for details)
121// format - Parameter format string, each parameter represented by one character.
122// The following format characters can be used:
123// s - String
124// d - Decimal integer
125// x - Hex integer
126// e - System error code (will appear in log as textual description)
c7ca9142 127// a - IP address in network byte order
4385fa12
VK
128//
129
130void WriteLog(DWORD msg, WORD wType, char *format, ...)
131{
132 va_list args;
133 char *strings[16], *msgBuf;
134 int numStrings = 0;
135 DWORD error;
136
137 memset(strings, 0, sizeof(char *) * 16);
138
139 if (format != NULL)
140 {
141 va_start(args, format);
142
143 for(; (format[numStrings] != 0) && (numStrings < 16); numStrings++)
144 {
145 switch(format[numStrings])
146 {
147 case 's':
148 strings[numStrings] = strdup(va_arg(args, char *));
149 break;
150 case 'd':
151 strings[numStrings] = (char *)malloc(16);
152 sprintf(strings[numStrings], "%d", va_arg(args, LONG));
153 break;
154 case 'x':
155 strings[numStrings] = (char *)malloc(16);
156 sprintf(strings[numStrings], "0x%08X", va_arg(args, DWORD));
157 break;
c7ca9142
VK
158 case 'a':
159 strings[numStrings] = (char *)malloc(20);
160 IpToStr(va_arg(args, DWORD), strings[numStrings]);
161 break;
4385fa12
VK
162 case 'e':
163 error = va_arg(args, DWORD);
164#ifdef _WIN32
165 if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
166 FORMAT_MESSAGE_FROM_SYSTEM |
167 FORMAT_MESSAGE_IGNORE_INSERTS,
168 NULL, error,
169 MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT), // Default language
170 (LPSTR)&msgBuf,0,NULL)>0)
171 {
172 msgBuf[strcspn(msgBuf,"\r\n")] = 0;
173 strings[numStrings]=(char *)malloc(strlen(msgBuf) + 1);
174 strcpy(strings[numStrings], msgBuf);
175 LocalFree(msgBuf);
176 }
177 else
178 {
179 strings[numStrings] = (char *)malloc(64);
180 sprintf(strings[numStrings], "MSG 0x%08X - Unable to find message text", error);
181 }
182#else /* _WIN32 */
183 strings[numStrings] = strdup(strerror(error));
184#endif
185 break;
186 default:
187 strings[numStrings] = (char *)malloc(32);
188 sprintf(strings[numStrings], "BAD FORMAT (0x%08X)", va_arg(args, DWORD));
189 break;
190 }
191 }
192 va_end(args);
193 }
194
195#ifdef _WIN32
196 if (g_dwFlags & AF_USE_EVENT_LOG)
197 {
198 ReportEvent(m_hEventLog, wType, 0, msg, NULL, numStrings, 0, (const char **)strings, NULL);
199 }
200 else
201 {
202 LPVOID lpMsgBuf;
203
204 if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_ARGUMENT_ARRAY,
205 NULL, msg, 0, (LPTSTR)&lpMsgBuf, 0, strings)>0)
206 {
207 WriteLogToFile((char *)lpMsgBuf);
208 LocalFree(lpMsgBuf);
209 }
210 else
211 {
212 char message[64];
213
214 sprintf(message,"MSG 0x%08X - Unable to find message text\r\n",msg);
215 WriteLogToFile(message);
216 }
217 }
218#else /* _WIN32 */
219
3a2f672c 220 /* TODO: add event logging under UNIX */
4385fa12 221
3a2f672c 222#endif /* _WIN32 */
4385fa12
VK
223
224 while(--numStrings >= 0)
225 free(strings[numStrings]);
226}