Commit | Line | Data |
---|---|---|
659bf814 | 1 | /* |
8b1de1cc AK |
2 | ** NetXMS - Network Management System |
3 | ** Log Parsing Library | |
4 | ** Copyright (C) 2003-2012 Victor Kirhenshtein | |
5 | ** | |
6 | ** This program is free software; you can redistribute it and/or modify | |
7 | ** it under the terms of the GNU Lesser General Public License as published by | |
8 | ** the Free Software Foundation; either version 3 of the License, or | |
9 | ** (at your option) any later version. | |
10 | ** | |
11 | ** This program is distributed in the hope that it will be useful, | |
12 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | ** GNU General Public License for more details. | |
15 | ** | |
16 | ** You should have received a copy of the GNU Lesser General Public License | |
17 | ** along with this program; if not, write to the Free Software | |
18 | ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
19 | ** | |
20 | ** File: nxlpapi.h | |
21 | ** | |
22 | **/ | |
23 | ||
24 | #ifndef _nxlpapi_h_ | |
25 | #define _nxlpapi_h_ | |
26 | ||
27 | #ifdef _WIN32 | |
28 | #ifdef LIBNXLP_EXPORTS | |
29 | #define LIBNXLP_EXPORTABLE __declspec(dllexport) | |
30 | #else | |
31 | #define LIBNXLP_EXPORTABLE __declspec(dllimport) | |
32 | #endif | |
33 | #else /* _WIN32 */ | |
34 | #define LIBNXLP_EXPORTABLE | |
35 | #endif | |
36 | ||
37 | #include <netxms-regex.h> | |
38 | #include <nms_util.h> | |
39 | ||
40 | ||
41 | // | |
42 | // Parser status | |
43 | // | |
44 | ||
45 | #define MAX_PARSER_STATUS_LEN 64 | |
46 | ||
47 | #define LPS_INIT _T("INIT") | |
48 | #define LPS_RUNNING _T("RUNNING") | |
49 | #define LPS_NO_FILE _T("FILE MISSING") | |
50 | #define LPS_OPEN_ERROR _T("FILE OPEN ERROR") | |
51 | ||
52 | ||
53 | // | |
54 | // Context actions | |
55 | // | |
56 | ||
57 | #define CONTEXT_SET_MANUAL 0 | |
58 | #define CONTEXT_SET_AUTOMATIC 1 | |
59 | #define CONTEXT_CLEAR 2 | |
60 | ||
61 | ||
62 | // | |
63 | // File encoding | |
64 | // | |
65 | ||
66 | #define LP_FCP_ACP 0 | |
67 | #define LP_FCP_UTF8 1 | |
68 | #define LP_FCP_UCS2 2 | |
69 | #define LP_FCP_UCS2_LE 3 | |
70 | #define LP_FCP_UCS4 4 | |
71 | #define LP_FCP_UCS4_LE 5 | |
72 | ||
da623f8b VK |
73 | /** |
74 | * Log parser callback | |
75 | * Parameters: | |
659bf814 | 76 | * NetXMS event code, NetXMS event name, original text, source, |
da623f8b VK |
77 | * original event ID (facility), original severity, |
78 | * number of capture groups, list of capture groups, | |
79 | * object id, user arg | |
80 | */ | |
d930bfc9 | 81 | typedef void (* LogParserCallback)(UINT32, const TCHAR *, const TCHAR *, const TCHAR *, UINT32, UINT32, int, TCHAR **, UINT32, int, void *); |
8b1de1cc AK |
82 | |
83 | class LIBNXLP_EXPORTABLE LogParser; | |
84 | ||
da623f8b VK |
85 | /** |
86 | * Log parser rule | |
87 | */ | |
8b1de1cc AK |
88 | class LIBNXLP_EXPORTABLE LogParserRule |
89 | { | |
da623f8b VK |
90 | friend class LogParser; |
91 | ||
8b1de1cc AK |
92 | private: |
93 | LogParser *m_parser; | |
94 | regex_t m_preg; | |
da623f8b | 95 | UINT32 m_eventCode; |
8b1de1cc AK |
96 | TCHAR *m_eventName; |
97 | bool m_isValid; | |
98 | int m_numParams; | |
99 | regmatch_t *m_pmatch; | |
100 | TCHAR *m_regexp; | |
101 | TCHAR *m_source; | |
da623f8b VK |
102 | UINT32 m_level; |
103 | UINT32 m_idStart; | |
104 | UINT32 m_idEnd; | |
8b1de1cc AK |
105 | TCHAR *m_context; |
106 | int m_contextAction; | |
107 | TCHAR *m_contextToChange; | |
108 | bool m_isInverted; | |
109 | bool m_breakOnMatch; | |
110 | TCHAR *m_description; | |
659bf814 | 111 | int m_repeatInterval; |
112 | int m_repeatCount; | |
113 | IntegerArray<time_t> *m_matchArray; | |
114 | bool m_resetRepeat; | |
aa07a370 VK |
115 | UINT32 m_checkCount; |
116 | UINT32 m_matchCount; | |
8b1de1cc | 117 | |
da623f8b | 118 | bool matchInternal(bool extMode, const TCHAR *source, UINT32 eventId, UINT32 level, |
659bf814 | 119 | const TCHAR *line, LogParserCallback cb, UINT32 objectId, void *userArg); |
d930bfc9 | 120 | bool matchRepeatCount(); |
da623f8b | 121 | void expandMacros(const TCHAR *regexp, String &out); |
8b1de1cc AK |
122 | |
123 | public: | |
124 | LogParserRule(LogParser *parser, | |
da623f8b | 125 | const TCHAR *regexp, UINT32 eventCode = 0, const TCHAR *eventName = NULL, |
659bf814 | 126 | int numParams = 0, int repeatInterval = 0, int repeatCount = 0, |
127 | bool resetRepeat = true, const TCHAR *source = NULL, UINT32 level = 0xFFFFFFFF, | |
da623f8b | 128 | UINT32 idStart = 0, UINT32 idEnd = 0xFFFFFFFF); |
8b1de1cc AK |
129 | LogParserRule(LogParserRule *src, LogParser *parser); |
130 | ~LogParserRule(); | |
131 | ||
aa07a370 | 132 | bool isValid() const { return m_isValid; } |
da623f8b VK |
133 | bool match(const TCHAR *line, LogParserCallback cb, UINT32 objectId, void *userArg); |
134 | bool matchEx(const TCHAR *source, UINT32 eventId, UINT32 level, | |
659bf814 | 135 | const TCHAR *line, LogParserCallback cb, UINT32 objectId, void *userArg); |
136 | ||
8b1de1cc AK |
137 | void setContext(const TCHAR *context) { safe_free(m_context); m_context = (context != NULL) ? _tcsdup(context) : NULL; } |
138 | void setContextToChange(const TCHAR *context) { safe_free(m_contextToChange); m_contextToChange = (context != NULL) ? _tcsdup(context) : NULL; } | |
139 | void setContextAction(int action) { m_contextAction = action; } | |
140 | ||
141 | void setInverted(bool flag) { m_isInverted = flag; } | |
aa07a370 | 142 | BOOL isInverted() const { return m_isInverted; } |
8b1de1cc AK |
143 | |
144 | void setBreakFlag(bool flag) { m_breakOnMatch = flag; } | |
aa07a370 | 145 | BOOL getBreakFlag() const { return m_breakOnMatch; } |
8b1de1cc | 146 | |
aa07a370 VK |
147 | const TCHAR *getContext() const { return m_context; } |
148 | const TCHAR *getContextToChange() const { return m_contextToChange; } | |
149 | int getContextAction() const { return m_contextAction; } | |
8b1de1cc AK |
150 | |
151 | void setDescription(const TCHAR *descr) { safe_free(m_description); m_description = (descr != NULL) ? _tcsdup(descr) : NULL; } | |
aa07a370 | 152 | const TCHAR *getDescription() const { return CHECK_NULL_EX(m_description); } |
8b1de1cc AK |
153 | |
154 | void setSource(const TCHAR *source) { safe_free(m_source); m_source = (source != NULL) ? _tcsdup(source) : NULL; } | |
aa07a370 | 155 | const TCHAR *getSource() const { return CHECK_NULL_EX(m_source); } |
8b1de1cc | 156 | |
da623f8b | 157 | void setLevel(UINT32 level) { m_level = level; } |
aa07a370 | 158 | UINT32 getLevel() const { return m_level; } |
8b1de1cc | 159 | |
da623f8b | 160 | void setIdRange(UINT32 start, UINT32 end) { m_idStart = start; m_idEnd = end; } |
aa07a370 | 161 | QWORD getIdRange() const { return ((QWORD)m_idStart << 32) | (QWORD)m_idEnd; } |
8b1de1cc | 162 | |
659bf814 | 163 | void setRepeatInterval(int repeatInterval) { m_repeatInterval = repeatInterval; } |
aa07a370 | 164 | int getRepeatInterval() const { return m_repeatInterval; } |
659bf814 | 165 | |
166 | void setRepeatCount(int repeatCount) { m_repeatCount = repeatCount; } | |
aa07a370 | 167 | int getRepeatCount() const { return m_repeatCount; } |
659bf814 | 168 | |
169 | void setRepeatReset(bool resetRepeat) { m_resetRepeat = resetRepeat; } | |
aa07a370 | 170 | bool isRepeatReset() const { return m_resetRepeat; } |
659bf814 | 171 | |
aa07a370 VK |
172 | const TCHAR *getRegexpSource() const { return CHECK_NULL(m_regexp); } |
173 | ||
174 | UINT32 getCheckCount() const { return m_checkCount; } | |
175 | UINT32 getMatchCount() const { return m_matchCount; } | |
8b1de1cc AK |
176 | }; |
177 | ||
da623f8b VK |
178 | /** |
179 | * Log parser class | |
180 | */ | |
8b1de1cc AK |
181 | class LIBNXLP_EXPORTABLE LogParser |
182 | { | |
da623f8b | 183 | friend bool LogParserRule::matchInternal(bool, const TCHAR *, UINT32, UINT32, const TCHAR *, LogParserCallback, UINT32, void *); |
8b1de1cc AK |
184 | |
185 | private: | |
186 | int m_numRules; | |
187 | LogParserRule **m_rules; | |
188 | StringMap m_contexts; | |
189 | StringMap m_macros; | |
190 | LogParserCallback m_cb; | |
191 | void *m_userArg; | |
192 | TCHAR *m_fileName; | |
193 | int m_fileEncoding; | |
194 | TCHAR *m_name; | |
195 | CODE_TO_TEXT *m_eventNameList; | |
da623f8b | 196 | bool (*m_eventResolver)(const TCHAR *, UINT32 *); |
8b1de1cc AK |
197 | THREAD m_thread; // Associated thread |
198 | int m_recordsProcessed; | |
199 | int m_recordsMatched; | |
200 | bool m_processAllRules; | |
201 | int m_traceLevel; | |
202 | void (*m_traceCallback)(const TCHAR *, va_list); | |
203 | TCHAR m_status[MAX_PARSER_STATUS_LEN]; | |
18b96a67 VK |
204 | #ifdef _WIN32 |
205 | TCHAR *m_marker; | |
206 | #endif | |
659bf814 | 207 | |
8b1de1cc AK |
208 | const TCHAR *checkContext(LogParserRule *rule); |
209 | void trace(int level, const TCHAR *format, ...); | |
da623f8b | 210 | bool matchLogRecord(bool hasAttributes, const TCHAR *source, UINT32 eventId, UINT32 level, const TCHAR *line, UINT32 objectId); |
8b1de1cc | 211 | |
07a1156a VK |
212 | #ifdef _WIN32 |
213 | void parseEvent(EVENTLOGRECORD *rec); | |
214 | ||
215 | bool monitorEventLogV6(CONDITION stopCondition); | |
216 | bool monitorEventLogV4(CONDITION stopCondition); | |
18b96a67 VK |
217 | |
218 | time_t readLastProcessedRecordTimestamp(); | |
07a1156a VK |
219 | #endif |
220 | ||
8b1de1cc AK |
221 | public: |
222 | LogParser(); | |
223 | LogParser(LogParser *src); | |
224 | ~LogParser(); | |
659bf814 | 225 | |
226 | static ObjectArray<LogParser> *createFromXml(const char *xml, int xmlLen = -1, | |
da623f8b | 227 | TCHAR *errorText = NULL, int errBufSize = 0, bool (*eventResolver)(const TCHAR *, UINT32 *) = NULL); |
8b1de1cc AK |
228 | |
229 | void setFileName(const TCHAR *name); | |
230 | const TCHAR *getFileName() { return m_fileName; } | |
231 | ||
232 | void setFileEncoding(int encoding) { m_fileEncoding = encoding; } | |
233 | int getFileEncoding() { return m_fileEncoding; } | |
234 | ||
235 | void setName(const TCHAR *name); | |
236 | const TCHAR *getName() { return m_name; } | |
237 | ||
238 | void setStatus(const TCHAR *status) { nx_strncpy(m_status, status, MAX_PARSER_STATUS_LEN); } | |
239 | const TCHAR *getStatus() { return m_status; } | |
240 | ||
241 | void setThread(THREAD th) { m_thread = th; } | |
242 | THREAD getThread() { return m_thread; } | |
243 | ||
244 | void setProcessAllFlag(bool flag) { m_processAllRules = flag; } | |
245 | bool getProcessAllFlag() { return m_processAllRules; } | |
246 | ||
659bf814 | 247 | bool addRule(const TCHAR *regexp, UINT32 eventCode = 0, const TCHAR *eventName = NULL, int numParams = 0, int repeatInterval = 0, int repeatCount = 0, bool resetRepeat = true); |
8b1de1cc AK |
248 | bool addRule(LogParserRule *rule); |
249 | void setCallback(LogParserCallback cb) { m_cb = cb; } | |
250 | void setUserArg(void *arg) { m_userArg = arg; } | |
251 | void setEventNameList(CODE_TO_TEXT *ctt) { m_eventNameList = ctt; } | |
da623f8b VK |
252 | void setEventNameResolver(bool (*cb)(const TCHAR *, UINT32 *)) { m_eventResolver = cb; } |
253 | UINT32 resolveEventName(const TCHAR *name, UINT32 defVal = 0); | |
8b1de1cc AK |
254 | |
255 | void addMacro(const TCHAR *name, const TCHAR *value); | |
256 | const TCHAR *getMacro(const TCHAR *name); | |
257 | ||
da623f8b VK |
258 | bool matchLine(const TCHAR *line, UINT32 objectId = 0); |
259 | bool matchEvent(const TCHAR *source, UINT32 eventId, UINT32 level, const TCHAR *line, UINT32 objectId = 0); | |
8b1de1cc AK |
260 | |
261 | int getProcessedRecordsCount() { return m_recordsProcessed; } | |
262 | int getMatchedRecordsCount() { return m_recordsMatched; } | |
263 | ||
264 | int getTraceLevel() { return m_traceLevel; } | |
265 | void setTraceLevel(int level) { m_traceLevel = level; } | |
266 | void setTraceCallback(void (*cb)(const TCHAR *, va_list)) { m_traceCallback = cb; } | |
267 | ||
07a1156a VK |
268 | bool monitorFile(CONDITION stopCondition, bool readFromCurrPos = true); |
269 | #ifdef _WIN32 | |
18b96a67 VK |
270 | bool monitorEventLog(CONDITION stopCondition, const TCHAR *markerPrefix); |
271 | void saveLastProcessedRecordTimestamp(time_t timestamp); | |
07a1156a | 272 | #endif |
8b1de1cc AK |
273 | }; |
274 | ||
07a1156a VK |
275 | /** |
276 | * Init log parser library | |
277 | */ | |
278 | void LIBNXLP_EXPORTABLE InitLogParserLibrary(); | |
279 | ||
280 | /** | |
281 | * Cleanup event log parsig library | |
282 | */ | |
283 | void LIBNXLP_EXPORTABLE CleanupLogParserLibrary(); | |
284 | ||
285 | /** | |
286 | * Set trace callback for log parser library | |
287 | */ | |
288 | void LIBNXLP_EXPORTABLE SetLogParserTraceCallback(void (* traceCallback)(int, const TCHAR *, va_list)); | |
289 | ||
8b1de1cc | 290 | #endif |