06addaeee28476afc366922a1ab7af80ac4e827a
[public/netxms.git] / include / nxlpapi.h
1 /*
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
73 /**
74 * Log parser callback
75 * Parameters:
76 * NetXMS event code, NetXMS event name, original text, source,
77 * original event ID (facility), original severity,
78 * number of capture groups, list of capture groups,
79 * object id, user arg
80 */
81 typedef void (* LogParserCallback)(UINT32, const TCHAR *, const TCHAR *, const TCHAR *, UINT32, UINT32, int, TCHAR **, UINT32, void *, int matchRepeatCount);
82
83 class LIBNXLP_EXPORTABLE LogParser;
84
85 /**
86 * Log parser rule
87 */
88 class LIBNXLP_EXPORTABLE LogParserRule
89 {
90 friend class LogParser;
91
92 private:
93 LogParser *m_parser;
94 regex_t m_preg;
95 UINT32 m_eventCode;
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;
102 UINT32 m_level;
103 UINT32 m_idStart;
104 UINT32 m_idEnd;
105 TCHAR *m_context;
106 int m_contextAction;
107 TCHAR *m_contextToChange;
108 bool m_isInverted;
109 bool m_breakOnMatch;
110 TCHAR *m_description;
111 int m_repeatInterval;
112 int m_repeatCount;
113 IntegerArray<time_t> *m_matchArray;
114 bool m_resetRepeat;
115
116 bool matchInternal(bool extMode, const TCHAR *source, UINT32 eventId, UINT32 level,
117 const TCHAR *line, LogParserCallback cb, UINT32 objectId, void *userArg);
118 void expandMacros(const TCHAR *regexp, String &out);
119
120 public:
121 LogParserRule(LogParser *parser,
122 const TCHAR *regexp, UINT32 eventCode = 0, const TCHAR *eventName = NULL,
123 int numParams = 0, int repeatInterval = 0, int repeatCount = 0,
124 bool resetRepeat = true, const TCHAR *source = NULL, UINT32 level = 0xFFFFFFFF,
125 UINT32 idStart = 0, UINT32 idEnd = 0xFFFFFFFF);
126 LogParserRule(LogParserRule *src, LogParser *parser);
127 ~LogParserRule();
128
129 bool isValid() { return m_isValid; }
130 bool match(const TCHAR *line, LogParserCallback cb, UINT32 objectId, void *userArg);
131 bool matchEx(const TCHAR *source, UINT32 eventId, UINT32 level,
132 const TCHAR *line, LogParserCallback cb, UINT32 objectId, void *userArg);
133
134 void setContext(const TCHAR *context) { safe_free(m_context); m_context = (context != NULL) ? _tcsdup(context) : NULL; }
135 void setContextToChange(const TCHAR *context) { safe_free(m_contextToChange); m_contextToChange = (context != NULL) ? _tcsdup(context) : NULL; }
136 void setContextAction(int action) { m_contextAction = action; }
137
138 void setInverted(bool flag) { m_isInverted = flag; }
139 BOOL isInverted() { return m_isInverted; }
140
141 void setBreakFlag(bool flag) { m_breakOnMatch = flag; }
142 BOOL getBreakFlag() { return m_breakOnMatch; }
143
144 const TCHAR *getContext() { return m_context; }
145 const TCHAR *getContextToChange() { return m_contextToChange; }
146 int getContextAction() { return m_contextAction; }
147
148 void setDescription(const TCHAR *descr) { safe_free(m_description); m_description = (descr != NULL) ? _tcsdup(descr) : NULL; }
149 const TCHAR *getDescription() { return CHECK_NULL_EX(m_description); }
150
151 void setSource(const TCHAR *source) { safe_free(m_source); m_source = (source != NULL) ? _tcsdup(source) : NULL; }
152 const TCHAR *getSource() { return CHECK_NULL_EX(m_source); }
153
154 void setLevel(UINT32 level) { m_level = level; }
155 UINT32 getLevel() { return m_level; }
156
157 void setIdRange(UINT32 start, UINT32 end) { m_idStart = start; m_idEnd = end; }
158 QWORD getIdRange() { return ((QWORD)m_idStart << 32) | (QWORD)m_idEnd; }
159
160 void setRepeatInterval(int repeatInterval) { m_repeatInterval = repeatInterval; }
161 int getRepeatInterval() { return m_repeatInterval; }
162
163 void setRepeatCount(int repeatCount) { m_repeatCount = repeatCount; }
164 int getRepeatCount() { return m_repeatCount; }
165
166 void setRepeatReset(bool resetRepeat) { m_resetRepeat = resetRepeat; }
167 bool isRepeatReset() { return m_resetRepeat; }
168
169 int getAppearanceCount() { return m_matchArray->size(); }
170 const TCHAR *getRegexpSource() { return CHECK_NULL(m_regexp); }
171 void matchArrayHousekeeper();
172 bool processMatch();
173 };
174
175 /**
176 * Log parser class
177 */
178 class LIBNXLP_EXPORTABLE LogParser
179 {
180 friend bool LogParserRule::matchInternal(bool, const TCHAR *, UINT32, UINT32, const TCHAR *, LogParserCallback, UINT32, void *);
181
182 private:
183 int m_numRules;
184 LogParserRule **m_rules;
185 StringMap m_contexts;
186 StringMap m_macros;
187 LogParserCallback m_cb;
188 void *m_userArg;
189 TCHAR *m_fileName;
190 int m_fileEncoding;
191 TCHAR *m_name;
192 CODE_TO_TEXT *m_eventNameList;
193 bool (*m_eventResolver)(const TCHAR *, UINT32 *);
194 THREAD m_thread; // Associated thread
195 int m_recordsProcessed;
196 int m_recordsMatched;
197 bool m_processAllRules;
198 int m_traceLevel;
199 void (*m_traceCallback)(const TCHAR *, va_list);
200 TCHAR m_status[MAX_PARSER_STATUS_LEN];
201 #ifdef _WIN32
202 TCHAR *m_marker;
203 #endif
204
205 const TCHAR *checkContext(LogParserRule *rule);
206 void trace(int level, const TCHAR *format, ...);
207 bool matchLogRecord(bool hasAttributes, const TCHAR *source, UINT32 eventId, UINT32 level, const TCHAR *line, UINT32 objectId);
208
209 #ifdef _WIN32
210 void parseEvent(EVENTLOGRECORD *rec);
211
212 bool monitorEventLogV6(CONDITION stopCondition);
213 bool monitorEventLogV4(CONDITION stopCondition);
214
215 time_t readLastProcessedRecordTimestamp();
216 #endif
217
218 public:
219 LogParser();
220 LogParser(LogParser *src);
221 ~LogParser();
222
223 static ObjectArray<LogParser> *createFromXml(const char *xml, int xmlLen = -1,
224 TCHAR *errorText = NULL, int errBufSize = 0, bool (*eventResolver)(const TCHAR *, UINT32 *) = NULL);
225
226 void setFileName(const TCHAR *name);
227 const TCHAR *getFileName() { return m_fileName; }
228
229 void setFileEncoding(int encoding) { m_fileEncoding = encoding; }
230 int getFileEncoding() { return m_fileEncoding; }
231
232 void setName(const TCHAR *name);
233 const TCHAR *getName() { return m_name; }
234
235 void setStatus(const TCHAR *status) { nx_strncpy(m_status, status, MAX_PARSER_STATUS_LEN); }
236 const TCHAR *getStatus() { return m_status; }
237
238 void setThread(THREAD th) { m_thread = th; }
239 THREAD getThread() { return m_thread; }
240
241 void setProcessAllFlag(bool flag) { m_processAllRules = flag; }
242 bool getProcessAllFlag() { return m_processAllRules; }
243
244 bool addRule(const TCHAR *regexp, UINT32 eventCode = 0, const TCHAR *eventName = NULL, int numParams = 0, int repeatInterval = 0, int repeatCount = 0, bool resetRepeat = true);
245 bool addRule(LogParserRule *rule);
246 void setCallback(LogParserCallback cb) { m_cb = cb; }
247 void setUserArg(void *arg) { m_userArg = arg; }
248 void setEventNameList(CODE_TO_TEXT *ctt) { m_eventNameList = ctt; }
249 void setEventNameResolver(bool (*cb)(const TCHAR *, UINT32 *)) { m_eventResolver = cb; }
250 UINT32 resolveEventName(const TCHAR *name, UINT32 defVal = 0);
251
252 void addMacro(const TCHAR *name, const TCHAR *value);
253 const TCHAR *getMacro(const TCHAR *name);
254
255 bool matchLine(const TCHAR *line, UINT32 objectId = 0);
256 bool matchEvent(const TCHAR *source, UINT32 eventId, UINT32 level, const TCHAR *line, UINT32 objectId = 0);
257
258 int getProcessedRecordsCount() { return m_recordsProcessed; }
259 int getMatchedRecordsCount() { return m_recordsMatched; }
260
261 int getTraceLevel() { return m_traceLevel; }
262 void setTraceLevel(int level) { m_traceLevel = level; }
263 void setTraceCallback(void (*cb)(const TCHAR *, va_list)) { m_traceCallback = cb; }
264
265 bool monitorFile(CONDITION stopCondition, bool readFromCurrPos = true);
266 #ifdef _WIN32
267 bool monitorEventLog(CONDITION stopCondition, const TCHAR *markerPrefix);
268 void saveLastProcessedRecordTimestamp(time_t timestamp);
269 #endif
270 };
271
272 /**
273 * Init log parser library
274 */
275 void LIBNXLP_EXPORTABLE InitLogParserLibrary();
276
277 /**
278 * Cleanup event log parsig library
279 */
280 void LIBNXLP_EXPORTABLE CleanupLogParserLibrary();
281
282 /**
283 * Set trace callback for log parser library
284 */
285 void LIBNXLP_EXPORTABLE SetLogParserTraceCallback(void (* traceCallback)(int, const TCHAR *, va_list));
286
287 #endif