change log updated
[public/netxms.git] / include / nxlpapi.h
index 03a1fed..46c2fe3 100644 (file)
-/* \r
-** NetXMS - Network Management System\r
-** Log Parsing Library\r
-** Copyright (C) 2008, 2009 Victor Kirhenshtein\r
-**\r
-** This program is free software; you can redistribute it and/or modify\r
-** it under the terms of the GNU General Public License as published by\r
-** the Free Software Foundation; either version 2 of the License, or\r
-** (at your option) any later version.\r
-**\r
-** This program is distributed in the hope that it will be useful,\r
-** but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-** GNU General Public License for more details.\r
-**\r
-** You should have received a copy of the GNU General Public License\r
-** along with this program; if not, write to the Free Software\r
-** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\r
-**\r
-** File: nxlpapi.h\r
-**\r
-**/\r
-\r
-#ifndef _nxlpapi_h_\r
-#define _nxlpapi_h_\r
-\r
-#ifdef _WIN32\r
-#ifdef LIBNXLP_EXPORTS\r
-#define LIBNXLP_EXPORTABLE __declspec(dllexport)\r
-#else\r
-#define LIBNXLP_EXPORTABLE __declspec(dllimport)\r
-#endif\r
-#else    /* _WIN32 */\r
-#define LIBNXLP_EXPORTABLE\r
-#endif\r
-\r
-\r
-#ifdef _WIN32\r
-#include <netxms-regex.h>\r
-#else\r
-#include <regex.h>\r
-#endif\r
-\r
-\r
-//\r
-// Context actions\r
-//\r
-\r
-#define CONTEXT_SET_MANUAL    0\r
-#define CONTEXT_SET_AUTOMATIC 1\r
-#define CONTEXT_CLEAR         2\r
-\r
-\r
-//\r
-// Callback\r
-// Parameters:\r
-//    event id, original text, number of parameters, list of parameters,\r
-//    object id, user arg\r
-//\r
-\r
-typedef void (* LogParserCallback)(DWORD, const char *, int, char **, DWORD, void *);\r
-\r
-\r
-//\r
-// Log parser rule\r
-//\r
-\r
-class LIBNXLP_EXPORTABLE LogParser;\r
-\r
-class LIBNXLP_EXPORTABLE LogParserRule\r
-{\r
-private:\r
-       LogParser *m_parser;\r
-       regex_t m_preg;\r
-       DWORD m_event;\r
-       bool m_isValid;\r
-       int m_numParams;\r
-       regmatch_t *m_pmatch;\r
-       TCHAR *m_regexp;\r
-       TCHAR *m_source;\r
-       DWORD m_level;\r
-       DWORD m_idStart;\r
-       DWORD m_idEnd;\r
-       TCHAR *m_context;\r
-       int m_contextAction;\r
-       TCHAR *m_contextToChange;\r
-       bool m_isInverted;\r
-       bool m_breakOnMatch;\r
-       TCHAR *m_description;\r
-\r
-       void expandMacros(const char *regexp, String &out);\r
-\r
-public:\r
-       LogParserRule(LogParser *parser,\r
-                     const char *regexp, DWORD event = 0, int numParams = 0,\r
-                     const TCHAR *source = NULL, DWORD level = 0xFFFFFFFF,\r
-                                         DWORD idStart = 0, DWORD idEnd = 0xFFFFFFFF);\r
-       ~LogParserRule();\r
-\r
-       bool isValid() { return m_isValid; }\r
-       bool match(const char *line, LogParserCallback cb, DWORD objectId, void *userArg);\r
-       bool matchEx(const TCHAR *source, DWORD eventId, DWORD level,\r
-                    const char *line, LogParserCallback cb, DWORD objectId, void *userArg); \r
-       \r
-       void setContext(const TCHAR *context) { safe_free(m_context); m_context = (context != NULL) ? _tcsdup(context) : NULL; }\r
-       void setContextToChange(const TCHAR *context) { safe_free(m_contextToChange); m_contextToChange = (context != NULL) ? _tcsdup(context) : NULL; }\r
-       void setContextAction(int action) { m_contextAction = action; }\r
-\r
-       void setInverted(bool flag) { m_isInverted = flag; }\r
-       BOOL isInverted() { return m_isInverted; }\r
-\r
-       void setBreakFlag(bool flag) { m_breakOnMatch = flag; }\r
-       BOOL getBreakFlag() { return m_breakOnMatch; }\r
-\r
-       const TCHAR *getContext() { return m_context; }\r
-       const TCHAR *getContextToChange() { return m_contextToChange; }\r
-       int getContextAction() { return m_contextAction; }\r
-\r
-       void setDescription(const TCHAR *descr) { safe_free(m_description); m_description = (descr != NULL) ? _tcsdup(descr) : NULL; }\r
-       const TCHAR *getDescription() { return CHECK_NULL_EX(m_description); }\r
-\r
-       void setSource(const TCHAR *source) { safe_free(m_source); m_source = (source != NULL) ? _tcsdup(source) : NULL; }\r
-       const TCHAR *getSource() { return CHECK_NULL_EX(m_source); }\r
-\r
-       void setLevel(DWORD level) { m_level = level; }\r
-       DWORD getLevel() { return m_level; }\r
-\r
-       void setIdRange(DWORD start, DWORD end) { m_idStart = start; m_idEnd = end; }\r
-       QWORD getIdRange() { return ((QWORD)m_idStart << 32) | (QWORD)m_idEnd; }\r
-\r
-       const TCHAR *getRegexpSource() { return CHECK_NULL(m_regexp); }\r
-};\r
-\r
-\r
-//\r
-// Log parser class\r
-//\r
-\r
-class LIBNXLP_EXPORTABLE LogParser\r
-{\r
-       friend bool LogParserRule::match(const char *, LogParserCallback, DWORD, void *);\r
-       friend bool LogParserRule::matchEx(const TCHAR *, DWORD, DWORD, const char *, LogParserCallback, DWORD, void *);\r
-\r
-private:\r
-       int m_numRules;\r
-       LogParserRule **m_rules;\r
-       StringMap m_contexts;\r
-       StringMap m_macros;\r
-       LogParserCallback m_cb;\r
-       void *m_userArg;\r
-       TCHAR *m_fileName;\r
-       CODE_TO_TEXT *m_eventNameList;\r
-       bool (*m_eventResolver)(const TCHAR *, DWORD *);\r
-       THREAD m_thread;        // Associated thread\r
-       int m_recordsProcessed;\r
-       int m_recordsMatched;\r
-       bool m_processAllRules;\r
-       int m_traceLevel;\r
-       void (*m_traceCallback)(const TCHAR *, va_list);\r
-       \r
-       const TCHAR *checkContext(LogParserRule *rule);\r
-       void trace(int level, const TCHAR *format, ...);\r
-       bool matchLogRecord(bool hasAttributes, const char *source, DWORD eventId, DWORD level, const char *line, DWORD objectId);\r
-\r
-public:\r
-       LogParser();\r
-       ~LogParser();\r
-       \r
-       bool createFromXml(const char *xml, int xmlLen = -1, char *errorText = NULL, int errBufSize = 0);\r
-\r
-       void setFileName(const TCHAR *name);\r
-       const TCHAR *getFileName() { return m_fileName; }\r
-\r
-       void setThread(THREAD th) { m_thread = th; }\r
-       THREAD getThread() { return m_thread; }\r
-\r
-       void setProcessAllFlag(bool flag) { m_processAllRules = flag; }\r
-       bool getProcessAllFlag() { return m_processAllRules; }\r
-\r
-       bool addRule(const char *regexp, DWORD event = 0, int numParams = 0);\r
-       bool addRule(LogParserRule *rule);\r
-       void setCallback(LogParserCallback cb) { m_cb = cb; }\r
-       void setUserArg(void *arg) { m_userArg = arg; }\r
-       void setEventNameList(CODE_TO_TEXT *ctt) { m_eventNameList = ctt; }\r
-       void setEventNameResolver(bool (*cb)(const TCHAR *, DWORD *)) { m_eventResolver = cb; }\r
-       DWORD resolveEventName(const TCHAR *name, DWORD defVal = 0);\r
-\r
-       void addMacro(const TCHAR *name, const TCHAR *value);\r
-       const TCHAR *getMacro(const TCHAR *name);\r
-\r
-       bool matchLine(const char *line, DWORD objectId = 0);\r
-       bool matchEvent(const char *source, DWORD eventId, DWORD level, const char *line, DWORD objectId = 0);\r
-\r
-       int getProcessedRecordsCount() { return m_recordsProcessed; }\r
-       int getMatchedRecordsCount() { return m_recordsMatched; }\r
-\r
-       int getTraceLevel() { return m_traceLevel; }\r
-       void setTraceLevel(int level) { m_traceLevel = level; }\r
-       void setTraceCallback(void (*cb)(const TCHAR *, va_list)) { m_traceCallback = cb; }\r
-\r
-#ifdef _WIN32\r
-       bool monitorFile(HANDLE stopEvent, void (*logger)(int, const TCHAR *, ...));\r
-#else\r
-       bool monitorFile(CONDITION stopCondition, bool *stopFlag, void (*logger)(int, const TCHAR *, ...));\r
-#endif\r
-};\r
-\r
-#endif\r
+/*
+** NetXMS - Network Management System
+** Log Parsing Library
+** Copyright (C) 2003-2012 Victor Kirhenshtein
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as published by
+** the Free Software Foundation; either version 3 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+**
+** File: nxlpapi.h
+**
+**/
+
+#ifndef _nxlpapi_h_
+#define _nxlpapi_h_
+
+#ifdef _WIN32
+#ifdef LIBNXLP_EXPORTS
+#define LIBNXLP_EXPORTABLE __declspec(dllexport)
+#else
+#define LIBNXLP_EXPORTABLE __declspec(dllimport)
+#endif
+#else    /* _WIN32 */
+#define LIBNXLP_EXPORTABLE
+#endif
+
+#include <netxms-regex.h>
+#include <nms_util.h>
+
+/**
+ * Parser status
+ */
+enum LogParserStatus
+{
+   LPS_INIT                = 0,
+   LPS_RUNNING             = 1,
+   LPS_NO_FILE             = 2,
+   LPS_OPEN_ERROR          = 3,
+   LPS_SUSPENDED           = 4,
+   LPS_EVT_SUBSCRIBE_ERROR = 5,
+   LPS_EVT_READ_ERROR      = 6,
+   LPS_EVT_OPEN_ERROR      = 7,
+   LPS_VSS_FAILURE         = 8
+};
+
+/**
+ * Context actions
+ */
+enum LogParserContextAction
+{
+   CONTEXT_SET_MANUAL    = 0,
+   CONTEXT_SET_AUTOMATIC = 1,
+   CONTEXT_CLEAR         = 2
+};
+
+/**
+ * File encoding
+ */
+enum LogParserFileEncoding
+{
+   LP_FCP_AUTO    = -1,
+   LP_FCP_ACP     = 0,
+   LP_FCP_UTF8    = 1,
+   LP_FCP_UCS2    = 2,
+   LP_FCP_UCS2_LE = 3,
+   LP_FCP_UCS2_BE = 4,
+   LP_FCP_UCS4    = 5,
+   LP_FCP_UCS4_LE = 6,
+   LP_FCP_UCS4_BE = 7
+};
+
+/**
+ * Log parser callback
+ * Parameters:
+ *    NetXMS event code, NetXMS event name, original text, source,
+ *    original event ID (facility), original severity,
+ *    number of capture groups, list of capture groups,
+ *    object id, user arg
+ */
+typedef void (* LogParserCallback)(UINT32, const TCHAR *, const TCHAR *, const TCHAR *, UINT32, UINT32, int, TCHAR **, UINT32, int, void *);
+
+class LIBNXLP_EXPORTABLE LogParser;
+
+#ifdef _WIN32
+
+/**
+ * Snapshot handle
+ */
+struct FileSnapshot
+{
+   void *handle;
+   TCHAR *name;
+};
+
+#endif
+
+/**
+ * Per object rule statistics
+ */
+struct ObjectRuleStats
+{
+   int checkCount;
+   int matchCount;
+};
+
+/**
+ * Log parser rule
+ */
+class LIBNXLP_EXPORTABLE LogParserRule
+{
+   friend class LogParser;
+
+private:
+       LogParser *m_parser;
+       TCHAR *m_name;
+       regex_t m_preg;
+       UINT32 m_eventCode;
+       TCHAR *m_eventName;
+       bool m_isValid;
+       int m_numParams;
+       regmatch_t *m_pmatch;
+       TCHAR *m_regexp;
+       TCHAR *m_source;
+       UINT32 m_level;
+       UINT32 m_idStart;
+       UINT32 m_idEnd;
+       TCHAR *m_context;
+       int m_contextAction;
+       TCHAR *m_contextToChange;
+       bool m_isInverted;
+       bool m_breakOnMatch;
+       TCHAR *m_description;
+       int m_repeatInterval;
+       int m_repeatCount;
+   IntegerArray<time_t> *m_matchArray;
+       bool m_resetRepeat;
+       int m_checkCount;
+       int m_matchCount;
+       HashMap<UINT32, ObjectRuleStats> *m_objectCounters;
+
+       bool matchInternal(bool extMode, const TCHAR *source, UINT32 eventId, UINT32 level,
+                          const TCHAR *line, LogParserCallback cb, UINT32 objectId, void *userArg);
+       bool matchRepeatCount();
+   void expandMacros(const TCHAR *regexp, String &out);
+   void incCheckCount(UINT32 objectId);
+   void incMatchCount(UINT32 objectId);
+
+public:
+       LogParserRule(LogParser *parser, const TCHAR *name,
+                     const TCHAR *regexp, UINT32 eventCode = 0, const TCHAR *eventName = NULL,
+                                         int numParams = 0, int repeatInterval = 0, int repeatCount = 0,
+                                         bool resetRepeat = true, const TCHAR *source = NULL, UINT32 level = 0xFFFFFFFF,
+                                         UINT32 idStart = 0, UINT32 idEnd = 0xFFFFFFFF);
+       LogParserRule(LogParserRule *src, LogParser *parser);
+       ~LogParserRule();
+
+       const TCHAR *getName() const { return m_name; }
+       bool isValid() const { return m_isValid; }
+
+       bool match(const TCHAR *line, LogParserCallback cb, UINT32 objectId, void *userArg);
+       bool matchEx(const TCHAR *source, UINT32 eventId, UINT32 level,
+                    const TCHAR *line, LogParserCallback cb, UINT32 objectId, void *userArg);
+
+       void setContext(const TCHAR *context) { safe_free(m_context); m_context = (context != NULL) ? _tcsdup(context) : NULL; }
+       void setContextToChange(const TCHAR *context) { safe_free(m_contextToChange); m_contextToChange = (context != NULL) ? _tcsdup(context) : NULL; }
+       void setContextAction(int action) { m_contextAction = action; }
+
+       void setInverted(bool flag) { m_isInverted = flag; }
+       bool isInverted() const { return m_isInverted; }
+
+       void setBreakFlag(bool flag) { m_breakOnMatch = flag; }
+       bool getBreakFlag() const { return m_breakOnMatch; }
+
+       const TCHAR *getContext() const { return m_context; }
+       const TCHAR *getContextToChange() const { return m_contextToChange; }
+       int getContextAction() const { return m_contextAction; }
+
+       void setDescription(const TCHAR *descr) { safe_free(m_description); m_description = (descr != NULL) ? _tcsdup(descr) : NULL; }
+       const TCHAR *getDescription() const { return CHECK_NULL_EX(m_description); }
+
+       void setSource(const TCHAR *source) { safe_free(m_source); m_source = (source != NULL) ? _tcsdup(source) : NULL; }
+       const TCHAR *getSource() const { return CHECK_NULL_EX(m_source); }
+
+       void setLevel(UINT32 level) { m_level = level; }
+       UINT32 getLevel() const { return m_level; }
+
+       void setIdRange(UINT32 start, UINT32 end) { m_idStart = start; m_idEnd = end; }
+       QWORD getIdRange() const { return ((QWORD)m_idStart << 32) | (QWORD)m_idEnd; }
+
+   void setRepeatInterval(int repeatInterval) { m_repeatInterval = repeatInterval; }
+   int getRepeatInterval() const { return m_repeatInterval; }
+
+   void setRepeatCount(int repeatCount) { m_repeatCount = repeatCount; }
+   int getRepeatCount() const { return m_repeatCount; }
+
+   void setRepeatReset(bool resetRepeat) { m_resetRepeat = resetRepeat; }
+   bool isRepeatReset() const { return m_resetRepeat; }
+
+       const TCHAR *getRegexpSource() const { return CHECK_NULL(m_regexp); }
+
+   int getCheckCount(UINT32 objectId = 0) const;
+   int getMatchCount(UINT32 objectId = 0) const;
+
+   void restoreCounters(const LogParserRule *rule);
+};
+
+/**
+ * Log parser class
+ */
+class LIBNXLP_EXPORTABLE LogParser
+{
+       friend bool LogParserRule::matchInternal(bool, const TCHAR *, UINT32, UINT32, const TCHAR *, LogParserCallback, UINT32, void *);
+
+private:
+       ObjectArray<LogParserRule> *m_rules;
+       StringMap m_contexts;
+       StringMap m_macros;
+       LogParserCallback m_cb;
+       void *m_userArg;
+       TCHAR *m_fileName;
+       int m_fileEncoding;
+       bool m_preallocatedFile;
+       StringList m_exclusionSchedules;
+       TCHAR *m_name;
+       CODE_TO_TEXT *m_eventNameList;
+       bool (*m_eventResolver)(const TCHAR *, UINT32 *);
+       THREAD m_thread;        // Associated thread
+       int m_recordsProcessed;
+       int m_recordsMatched;
+       bool m_processAllRules;
+   bool m_suspended;
+       int m_traceLevel;
+       void (*m_traceCallback)(int, const TCHAR *, va_list);
+       LogParserStatus m_status;
+#ifdef _WIN32
+   TCHAR *m_marker;
+   bool m_useSnapshot;
+#endif
+
+       const TCHAR *checkContext(LogParserRule *rule);
+       void trace(int level, const TCHAR *format, ...);
+       bool matchLogRecord(bool hasAttributes, const TCHAR *source, UINT32 eventId, UINT32 level, const TCHAR *line, UINT32 objectId);
+
+       bool isExclusionPeriod();
+
+   const LogParserRule *findRuleByName(const TCHAR *name) const;
+
+   int getCharSize() const;
+
+   void setStatus(LogParserStatus status) { m_status = status; }
+
+#ifdef _WIN32
+   void parseEvent(EVENTLOGRECORD *rec);
+
+   bool monitorFileWithSnapshot(CONDITION stopCondition, bool readFromCurrPos);
+   bool monitorEventLogV6(CONDITION stopCondition);
+       bool monitorEventLogV4(CONDITION stopCondition);
+
+   time_t readLastProcessedRecordTimestamp();
+#endif
+
+public:
+       LogParser();
+       LogParser(const LogParser *src);
+       ~LogParser();
+
+       static ObjectArray<LogParser> *createFromXml(const char *xml, int xmlLen = -1,
+               TCHAR *errorText = NULL, int errBufSize = 0, bool (*eventResolver)(const TCHAR *, UINT32 *) = NULL);
+
+   const TCHAR *getName() const { return m_name; }
+       const TCHAR *getFileName() const { return m_fileName; }
+       int getFileEncoding() const { return m_fileEncoding; }
+   LogParserStatus getStatus() const { return m_status; }
+   const TCHAR *getStatusText() const;
+   bool isFilePreallocated() const { return m_preallocatedFile; }
+
+       void setName(const TCHAR *name);
+   void setFileName(const TCHAR *name);
+
+       void setThread(THREAD th) { m_thread = th; }
+       THREAD getThread() { return m_thread; }
+
+       void setProcessAllFlag(bool flag) { m_processAllRules = flag; }
+       bool getProcessAllFlag() { return m_processAllRules; }
+
+#ifdef _WIN32
+   void setSnapshotMode(bool enable) { m_useSnapshot = enable;  }
+   bool isSnapshotMode() const { return m_useSnapshot;  }
+#endif
+
+       bool addRule(const TCHAR *regexp, UINT32 eventCode = 0, const TCHAR *eventName = NULL, int numParams = 0, int repeatInterval = 0, int repeatCount = 0, bool resetRepeat = true);
+       bool addRule(LogParserRule *rule);
+       void setCallback(LogParserCallback cb) { m_cb = cb; }
+       void setUserArg(void *arg) { m_userArg = arg; }
+       void setEventNameList(CODE_TO_TEXT *ctt) { m_eventNameList = ctt; }
+       void setEventNameResolver(bool (*cb)(const TCHAR *, UINT32 *)) { m_eventResolver = cb; }
+       UINT32 resolveEventName(const TCHAR *name, UINT32 defVal = 0);
+
+   void addExclusionSchedule(const TCHAR *schedule) { m_exclusionSchedules.add(schedule); }
+
+       void addMacro(const TCHAR *name, const TCHAR *value);
+       const TCHAR *getMacro(const TCHAR *name);
+
+       bool matchLine(const TCHAR *line, UINT32 objectId = 0);
+       bool matchEvent(const TCHAR *source, UINT32 eventId, UINT32 level, const TCHAR *line, UINT32 objectId = 0);
+
+       int getProcessedRecordsCount() const { return m_recordsProcessed; }
+       int getMatchedRecordsCount() const { return m_recordsMatched; }
+
+       int getTraceLevel() const { return m_traceLevel; }
+       void setTraceLevel(int level) { m_traceLevel = level; }
+       void setTraceCallback(void (*cb)(int, const TCHAR *, va_list)) { m_traceCallback = cb; }
+
+       bool monitorFile(CONDITION stopCondition, bool readFromCurrPos = true);
+#ifdef _WIN32
+   bool monitorEventLog(CONDITION stopCondition, const TCHAR *markerPrefix);
+   void saveLastProcessedRecordTimestamp(time_t timestamp);
+#endif
+
+   int getRuleCheckCount(const TCHAR *ruleName, UINT32 objectId = 0) const { const LogParserRule *r = findRuleByName(ruleName); return (r != NULL) ? r->getCheckCount(objectId) : -1; }
+   int getRuleMatchCount(const TCHAR *ruleName, UINT32 objectId = 0) const { const LogParserRule *r = findRuleByName(ruleName); return (r != NULL) ? r->getMatchCount(objectId) : -1; }
+
+   void restoreCounters(const LogParser *parser);
+
+   void suspend();
+   void resume();
+};
+
+/**
+ * Init log parser library
+ */
+void LIBNXLP_EXPORTABLE InitLogParserLibrary();
+
+/**
+ * Cleanup event log parsig library
+ */
+void LIBNXLP_EXPORTABLE CleanupLogParserLibrary();
+
+/**
+ * Set trace callback for log parser library
+ */
+void LIBNXLP_EXPORTABLE SetLogParserTraceCallback(void (* traceCallback)(int, const TCHAR *, va_list));
+
+#ifdef _WIN32
+
+/**
+ * Create file snapshot
+ */
+FileSnapshot LIBNXLP_EXPORTABLE *CreateFileSnapshot(const TCHAR *path);
+
+/**
+* Destroy file snapshot
+*/
+void LIBNXLP_EXPORTABLE DestroyFileSnapshot(FileSnapshot *snapshot);
+
+#endif
+
+#endif