optimizations and fixes in log watcher repeat count processing
authorVictor Kirhenshtein <victor@netxms.org>
Thu, 16 Jun 2016 07:34:47 +0000 (10:34 +0300)
committerVictor Kirhenshtein <victor@netxms.org>
Thu, 16 Jun 2016 07:34:47 +0000 (10:34 +0300)
include/nxlpapi.h
src/agent/subagents/logwatch/logwatch.cpp
src/libnxlp/parser.cpp
src/libnxlp/rule.cpp
src/server/core/syslogd.cpp

index 06addae..5c5a98a 100644 (file)
@@ -78,7 +78,7 @@
  *    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, void *, int matchRepeatCount);
+typedef void (* LogParserCallback)(UINT32, const TCHAR *, const TCHAR *, const TCHAR *, UINT32, UINT32, int, TCHAR **, UINT32, int, void *);
 
 class LIBNXLP_EXPORTABLE LogParser;
 
@@ -115,6 +115,7 @@ private:
 
        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);
 
 public:
@@ -166,10 +167,7 @@ public:
    void setRepeatReset(bool resetRepeat) { m_resetRepeat = resetRepeat; }
    bool isRepeatReset() { return m_resetRepeat; }
 
-   int getAppearanceCount() { return m_matchArray->size(); }
        const TCHAR *getRegexpSource() { return CHECK_NULL(m_regexp); }
-       void matchArrayHousekeeper();
-       bool processMatch();
 };
 
 /**
index f67b766..b0805c8 100644 (file)
@@ -134,12 +134,12 @@ static void SubagentShutdown()
  */
 static void LogParserMatch(UINT32 eventCode, const TCHAR *eventName, const TCHAR *text,
                            const TCHAR *source, UINT32 eventId, UINT32 severity,
-                           int cgCount, TCHAR **cgList, UINT32 objectId, void *userArg,
-                           int matchRepeatCount)
+                           int cgCount, TCHAR **cgList, UINT32 objectId, int repeatCount,
+                           void *userArg)
 {
    int count = cgCount + 1;
-   TCHAR eventIdText[16], severityText[16], repeatCount[16];
-   _sntprintf(repeatCount, 16, _T("%d"), matchRepeatCount);
+   TCHAR eventIdText[16], severityText[16], repeatCountText[16];
+   _sntprintf(repeatCountText, 16, _T("%d"), repeatCount);
    if (source != NULL)
    {
       _sntprintf(eventIdText, 16, _T("%u"), eventId);
@@ -158,7 +158,7 @@ static void LogParserMatch(UINT32 eventCode, const TCHAR *eventName, const TCHAR
       list[i++] = eventIdText;
       list[i++] = severityText;
    }
-   list[i++] = repeatCount;
+   list[i++] = repeatCountText;
 
    AgentSendTrap2(eventCode, eventName, count, list);
    free(list);
index 0422ae9..7a44a4a 100644 (file)
@@ -1,7 +1,7 @@
 /*
 ** NetXMS - Network Management System
 ** Log Parsing Library
-** Copyright (C) 2003-2013 Victor Kirhenshtein
+** Copyright (C) 2003-2016 Raden Solutions
 **
 ** 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
index c1c8b18..7bdf350 100644 (file)
@@ -1,7 +1,7 @@
 /*
 ** NetXMS - Network Management System
 ** Log Parsing Library
-** Copyright (C) 2003-2013 Victor Kirhenshtein
+** Copyright (C) 2003-2016 Raden Solutions
 **
 ** 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
@@ -116,7 +116,6 @@ LogParserRule::~LogParserRule()
 bool LogParserRule::matchInternal(bool extMode, const TCHAR *source, UINT32 eventId, UINT32 level,
                                                                          const TCHAR *line, LogParserCallback cb, UINT32 objectId, void *userArg)
 {
-   matchArrayHousekeeper();
    if (extMode)
    {
           if (m_source != NULL)
@@ -151,18 +150,19 @@ bool LogParserRule::matchInternal(bool extMode, const TCHAR *source, UINT32 even
        if (m_isInverted)
        {
                m_parser->trace(6, _T("  negated matching against regexp %s"), m_regexp);
-               if (_tregexec(&m_preg, line, 0, NULL, 0) != 0 && processMatch())
+               if ((_tregexec(&m_preg, line, 0, NULL, 0) != 0) && matchRepeatCount())
                {
                        m_parser->trace(6, _T("  matched"));
                        if ((cb != NULL) && ((m_eventCode != 0) || (m_eventName != NULL)))
-                               cb(m_eventCode, m_eventName, line, source, eventId, level, 0, NULL, objectId, userArg, getAppearanceCount());
+                               cb(m_eventCode, m_eventName, line, source, eventId, level, 0, NULL, objectId, 
+               ((m_repeatCount > 0) && (m_repeatInterval > 0)) ? m_matchArray->size() : 1, userArg);
                        return true;
                }
        }
        else
        {
                m_parser->trace(6, _T("  matching against regexp %s"), m_regexp);
-               if (_tregexec(&m_preg, line, (m_numParams > 0) ? m_numParams + 1 : 0, m_pmatch, 0) == 0 && processMatch())
+               if ((_tregexec(&m_preg, line, (m_numParams > 0) ? m_numParams + 1 : 0, m_pmatch, 0) == 0) && matchRepeatCount())
                {
                        m_parser->trace(6, _T("  matched"));
                        if ((cb != NULL) && ((m_eventCode != 0) || (m_eventName != NULL)))
@@ -193,7 +193,8 @@ bool LogParserRule::matchInternal(bool extMode, const TCHAR *source, UINT32 even
                                        }
                                }
 
-                               cb(m_eventCode, m_eventName, line, source, eventId, level, m_numParams, params, objectId, userArg, getAppearanceCount());
+                               cb(m_eventCode, m_eventName, line, source, eventId, level, m_numParams, params, objectId, 
+               ((m_repeatCount > 0) && (m_repeatInterval > 0)) ? m_matchArray->size() : 1, userArg);
 
                                for(i = 0; i < m_numParams; i++)
                                        free(params[i]);
@@ -269,28 +270,27 @@ void LogParserRule::expandMacros(const TCHAR *regexp, String &out)
        out.append(prev, (size_t)(curr - prev));
 }
 
-void LogParserRule::matchArrayHousekeeper()
+/**
+ * Match repeat count
+ */
+bool LogParserRule::matchRepeatCount()
 {
-   if(m_matchArray->size() == 0 || m_repeatCount == 0 || m_repeatInterval == 0)
-      return;
+   if ((m_repeatCount == 0) || (m_repeatInterval == 0))
+      return true;
 
+   // remove expired matches
    time_t now = time(NULL);
    for(int i = 0; i < m_matchArray->size(); i++)
    {
-      if(m_matchArray->get(i) < (now - m_repeatInterval))
-         m_matchArray->remove(i);
-      else
+      if (m_matchArray->get(i) >= (now - m_repeatInterval))
          break;
+      m_matchArray->remove(i);
+      i--;
    }
-}
-
-bool LogParserRule::processMatch()
-{
-   if(m_repeatCount == 0 || m_repeatInterval == 0)
-      return true;
 
-   m_matchArray->add(time(NULL));
+   m_matchArray->add(now);
    bool match = m_matchArray->size() >= m_repeatCount;
-   if(m_resetRepeat && match) m_matchArray->clear();
+   if (m_resetRepeat && match)
+      m_matchArray->clear();
    return match;
 }
index 4f273a0..7923fc2 100644 (file)
@@ -481,24 +481,19 @@ static void QueueSyslogMessage(char *msg, int msgLen, const InetAddress& sourceA
  */
 static void SyslogParserCallback(UINT32 eventCode, const TCHAR *eventName, const TCHAR *line,
                                  const TCHAR *source, UINT32 facility, UINT32 severity,
-                                 int paramCount, TCHAR **params, UINT32 objectId, void *userArg,
-                                 int matchRepeatCount)
+                                 int paramCount, TCHAR **params, UINT32 objectId, int repeatCount,
+                                 void *userArg)
 {
-       char format[] = "ssssssssssssssssssssssssssssssss";
-       TCHAR *plist[32];
-       int i, count;
-       TCHAR repeatCount[16];
-
-       count = min(paramCount, 32);
-       format[count] = 0;
-       for(i = 0; i < count; i++)
+       char format[] = "sssssssssssssssssssssssssssssssss";
+       TCHAR *plist[33];
+       TCHAR repeatCountText[16];
+
+       int count = min(paramCount, 32);
+       format[count + 1] = 0;
+       for(int i = 0; i < count; i++)
                plist[i] = params[i];
-   if(count < 32)
-   {
-      _sntprintf(repeatCount, 16, _T("%d"), matchRepeatCount);
-      plist[count] = repeatCount;
-      count++;
-   }
+   _sntprintf(repeatCountText, 16, _T("%d"), repeatCount);
+   plist[count] = repeatCountText;
        PostEvent(eventCode, objectId, format,
                  plist[0], plist[1], plist[2], plist[3],
                  plist[4], plist[5], plist[6], plist[7],