2 ** NetXMS - Network Management System
4 ** Copyright (C) 2003-2016 Raden Solutions
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.
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.
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.
29 LogParserRule::LogParserRule(LogParser
*parser
, const TCHAR
*regexp
, UINT32 eventCode
, const TCHAR
*eventName
,
30 int numParams
, int repeatInterval
, int repeatCount
, bool resetRepeat
, const TCHAR
*source
,
31 UINT32 level
, UINT32 idStart
, UINT32 idEnd
)
33 String expandedRegexp
;
36 expandMacros(regexp
, expandedRegexp
);
37 m_regexp
= _tcsdup(expandedRegexp
);
38 m_isValid
= (_tregcomp(&m_preg
, expandedRegexp
, REG_EXTENDED
| REG_ICASE
) == 0);
39 m_eventCode
= eventCode
;
40 m_eventName
= (eventName
!= NULL
) ? _tcsdup(eventName
) : NULL
;
41 m_numParams
= numParams
;
42 m_pmatch
= (numParams
> 0) ? (regmatch_t
*)malloc(sizeof(regmatch_t
) * (numParams
+ 1)) : NULL
;
43 m_source
= (source
!= NULL
) ? _tcsdup(source
) : NULL
;
49 m_contextToChange
= NULL
;
51 m_breakOnMatch
= FALSE
;
53 m_repeatInterval
= repeatInterval
;
54 m_repeatCount
= repeatCount
;
55 m_matchArray
= new IntegerArray
<time_t>();
56 m_resetRepeat
= resetRepeat
;
64 LogParserRule::LogParserRule(LogParserRule
*src
, LogParser
*parser
)
67 m_regexp
= _tcsdup(src
->m_regexp
);
68 m_isValid
= (_tregcomp(&m_preg
, m_regexp
, REG_EXTENDED
| REG_ICASE
) == 0);
69 m_eventCode
= src
->m_eventCode
;
70 m_eventName
= (src
->m_eventName
!= NULL
) ? _tcsdup(src
->m_eventName
) : NULL
;
71 m_numParams
= src
->m_numParams
;
72 m_pmatch
= (m_numParams
> 0) ? (regmatch_t
*)malloc(sizeof(regmatch_t
) * (m_numParams
+ 1)) : NULL
;
73 m_source
= (src
->m_source
!= NULL
) ? _tcsdup(src
->m_source
) : NULL
;
74 m_level
= src
->m_level
;
75 m_idStart
= src
->m_idStart
;
76 m_idEnd
= src
->m_idEnd
;
77 m_context
= (src
->m_context
!= NULL
) ? _tcsdup(src
->m_context
) : NULL
;
78 m_contextAction
= src
->m_contextAction
;
79 m_contextToChange
= (src
->m_contextToChange
!= NULL
) ? _tcsdup(src
->m_contextToChange
) : NULL
;
80 m_isInverted
= src
->m_isInverted
;
81 m_breakOnMatch
= src
->m_breakOnMatch
;
82 m_description
= (src
->m_description
!= NULL
) ? _tcsdup(src
->m_description
) : NULL
;
83 m_repeatInterval
= src
->m_repeatInterval
;
84 m_repeatCount
= src
->m_repeatCount
;
85 m_resetRepeat
= src
->m_resetRepeat
;
86 if (src
->m_matchArray
!= NULL
)
88 m_matchArray
= new IntegerArray
<time_t>(src
->m_matchArray
->size(), 16);
89 for(int i
= 0; i
< src
->m_matchArray
->size(); i
++)
90 m_matchArray
->add(src
->m_matchArray
->get(i
));
94 m_matchArray
= new IntegerArray
<time_t>();
96 m_checkCount
= src
->m_checkCount
;
97 m_matchCount
= src
->m_matchCount
;
103 LogParserRule::~LogParserRule()
108 safe_free(m_description
);
111 safe_free(m_eventName
);
112 safe_free(m_context
);
113 safe_free(m_contextToChange
);
120 bool LogParserRule::matchInternal(bool extMode
, const TCHAR
*source
, UINT32 eventId
, UINT32 level
,
121 const TCHAR
*line
, LogParserCallback cb
, UINT32 objectId
, void *userArg
)
126 if (m_source
!= NULL
)
128 m_parser
->trace(6, _T(" matching source \"%s\" against pattern \"%s\""), source
, m_source
);
129 if (!MatchString(m_source
, source
, FALSE
))
131 m_parser
->trace(6, _T(" source: no match"));
136 if ((eventId
< m_idStart
) || (eventId
> m_idEnd
))
138 m_parser
->trace(6, _T(" event id 0x%08x not in range 0x%08x - 0x%08x"), eventId
, m_idStart
, m_idEnd
);
142 if (!(m_level
& level
))
144 m_parser
->trace(6, _T(" severity level 0x%04x not match mask 0x%04x"), level
, m_level
);
151 m_parser
->trace(6, _T(" regexp is invalid: %s"), m_regexp
);
157 m_parser
->trace(6, _T(" negated matching against regexp %s"), m_regexp
);
158 if ((_tregexec(&m_preg
, line
, 0, NULL
, 0) != 0) && matchRepeatCount())
160 m_parser
->trace(6, _T(" matched"));
161 if ((cb
!= NULL
) && ((m_eventCode
!= 0) || (m_eventName
!= NULL
)))
162 cb(m_eventCode
, m_eventName
, line
, source
, eventId
, level
, 0, NULL
, objectId
,
163 ((m_repeatCount
> 0) && (m_repeatInterval
> 0)) ? m_matchArray
->size() : 1, userArg
);
170 m_parser
->trace(6, _T(" matching against regexp %s"), m_regexp
);
171 if ((_tregexec(&m_preg
, line
, (m_numParams
> 0) ? m_numParams
+ 1 : 0, m_pmatch
, 0) == 0) && matchRepeatCount())
173 m_parser
->trace(6, _T(" matched"));
174 if ((cb
!= NULL
) && ((m_eventCode
!= 0) || (m_eventName
!= NULL
)))
176 TCHAR
**params
= NULL
;
182 params
= (TCHAR
**)alloca(sizeof(TCHAR
*) * m_numParams
);
184 params
= (TCHAR
**)malloc(sizeof(TCHAR
*) * m_numParams
);
186 for(i
= 0; i
< m_numParams
; i
++)
188 if (m_pmatch
[i
+ 1].rm_so
!= -1)
190 len
= m_pmatch
[i
+ 1].rm_eo
- m_pmatch
[i
+ 1].rm_so
;
191 params
[i
] = (TCHAR
*)malloc((len
+ 1) * sizeof(TCHAR
));
192 memcpy(params
[i
], &line
[m_pmatch
[i
+ 1].rm_so
], len
* sizeof(TCHAR
));
197 params
[i
] = _tcsdup(_T(""));
202 cb(m_eventCode
, m_eventName
, line
, source
, eventId
, level
, m_numParams
, params
, objectId
,
203 ((m_repeatCount
> 0) && (m_repeatInterval
> 0)) ? m_matchArray
->size() : 1, userArg
);
205 for(i
= 0; i
< m_numParams
; i
++)
217 m_parser
->trace(6, _T(" no match"));
218 return false; // no match
224 bool LogParserRule::match(const TCHAR
*line
, LogParserCallback cb
, UINT32 objectId
, void *userArg
)
226 return matchInternal(false, NULL
, 0, 0, line
, cb
, objectId
, userArg
);
232 bool LogParserRule::matchEx(const TCHAR
*source
, UINT32 eventId
, UINT32 level
,
233 const TCHAR
*line
, LogParserCallback cb
, UINT32 objectId
, void *userArg
)
235 return matchInternal(true, source
, eventId
, level
, line
, cb
, objectId
, userArg
);
239 * Expand macros in regexp
241 void LogParserRule::expandMacros(const TCHAR
*regexp
, String
&out
)
243 const TCHAR
*curr
, *prev
;
246 for(curr
= prev
= regexp
; *curr
!= 0; curr
++)
248 if (*curr
== _T('@'))
251 if ((curr
!= regexp
) && (*(curr
- 1) == _T('\\')))
253 out
.append(prev
, (size_t)(curr
- prev
- 1));
259 if (*(curr
+ 1) == _T('{'))
263 out
.append(prev
, (size_t)(curr
- prev
));
265 for(i
= 0; (*curr
!= 0) && (*curr
!= '}'); i
++)
268 out
+= m_parser
->getMacro(name
);
272 out
.append(prev
, (size_t)(curr
- prev
+ 1));
278 out
.append(prev
, (size_t)(curr
- prev
));
284 bool LogParserRule::matchRepeatCount()
286 if ((m_repeatCount
== 0) || (m_repeatInterval
== 0))
289 // remove expired matches
290 time_t now
= time(NULL
);
291 for(int i
= 0; i
< m_matchArray
->size(); i
++)
293 if (m_matchArray
->get(i
) >= (now
- m_repeatInterval
))
295 m_matchArray
->remove(i
);
299 m_matchArray
->add(now
);
300 bool match
= m_matchArray
->size() >= m_repeatCount
;
301 if (m_resetRepeat
&& match
)
302 m_matchArray
->clear();