7bdf350c94aae3d66aa8ac79b77f9696a1f0de1d
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
;
62 LogParserRule::LogParserRule(LogParserRule
*src
, LogParser
*parser
)
65 m_regexp
= _tcsdup(src
->m_regexp
);
66 m_isValid
= (_tregcomp(&m_preg
, m_regexp
, REG_EXTENDED
| REG_ICASE
) == 0);
67 m_eventCode
= src
->m_eventCode
;
68 m_eventName
= (src
->m_eventName
!= NULL
) ? _tcsdup(src
->m_eventName
) : NULL
;
69 m_numParams
= src
->m_numParams
;
70 m_pmatch
= (m_numParams
> 0) ? (regmatch_t
*)malloc(sizeof(regmatch_t
) * (m_numParams
+ 1)) : NULL
;
71 m_source
= (src
->m_source
!= NULL
) ? _tcsdup(src
->m_source
) : NULL
;
72 m_level
= src
->m_level
;
73 m_idStart
= src
->m_idStart
;
74 m_idEnd
= src
->m_idEnd
;
75 m_context
= (src
->m_context
!= NULL
) ? _tcsdup(src
->m_context
) : NULL
;
76 m_contextAction
= src
->m_contextAction
;
77 m_contextToChange
= (src
->m_contextToChange
!= NULL
) ? _tcsdup(src
->m_contextToChange
) : NULL
;
78 m_isInverted
= src
->m_isInverted
;
79 m_breakOnMatch
= src
->m_breakOnMatch
;
80 m_description
= (src
->m_description
!= NULL
) ? _tcsdup(src
->m_description
) : NULL
;
81 m_repeatInterval
= src
->m_repeatInterval
;
82 m_repeatCount
= src
->m_repeatCount
;
83 m_resetRepeat
= src
->m_resetRepeat
;
84 if (src
->m_matchArray
!= NULL
)
86 m_matchArray
= new IntegerArray
<time_t>(src
->m_matchArray
->size(), 16);
87 for(int i
= 0; i
< src
->m_matchArray
->size(); i
++)
88 m_matchArray
->add(src
->m_matchArray
->get(i
));
92 m_matchArray
= new IntegerArray
<time_t>();
99 LogParserRule::~LogParserRule()
104 safe_free(m_description
);
107 safe_free(m_eventName
);
108 safe_free(m_context
);
109 safe_free(m_contextToChange
);
116 bool LogParserRule::matchInternal(bool extMode
, const TCHAR
*source
, UINT32 eventId
, UINT32 level
,
117 const TCHAR
*line
, LogParserCallback cb
, UINT32 objectId
, void *userArg
)
121 if (m_source
!= NULL
)
123 m_parser
->trace(6, _T(" matching source \"%s\" against pattern \"%s\""), source
, m_source
);
124 if (!MatchString(m_source
, source
, FALSE
))
126 m_parser
->trace(6, _T(" source: no match"));
131 if ((eventId
< m_idStart
) || (eventId
> m_idEnd
))
133 m_parser
->trace(6, _T(" event id 0x%08x not in range 0x%08x - 0x%08x"), eventId
, m_idStart
, m_idEnd
);
137 if (!(m_level
& level
))
139 m_parser
->trace(6, _T(" severity level 0x%04x not match mask 0x%04x"), level
, m_level
);
146 m_parser
->trace(6, _T(" regexp is invalid: %s"), m_regexp
);
152 m_parser
->trace(6, _T(" negated matching against regexp %s"), m_regexp
);
153 if ((_tregexec(&m_preg
, line
, 0, NULL
, 0) != 0) && matchRepeatCount())
155 m_parser
->trace(6, _T(" matched"));
156 if ((cb
!= NULL
) && ((m_eventCode
!= 0) || (m_eventName
!= NULL
)))
157 cb(m_eventCode
, m_eventName
, line
, source
, eventId
, level
, 0, NULL
, objectId
,
158 ((m_repeatCount
> 0) && (m_repeatInterval
> 0)) ? m_matchArray
->size() : 1, userArg
);
164 m_parser
->trace(6, _T(" matching against regexp %s"), m_regexp
);
165 if ((_tregexec(&m_preg
, line
, (m_numParams
> 0) ? m_numParams
+ 1 : 0, m_pmatch
, 0) == 0) && matchRepeatCount())
167 m_parser
->trace(6, _T(" matched"));
168 if ((cb
!= NULL
) && ((m_eventCode
!= 0) || (m_eventName
!= NULL
)))
170 TCHAR
**params
= NULL
;
176 params
= (TCHAR
**)alloca(sizeof(TCHAR
*) * m_numParams
);
178 params
= (TCHAR
**)malloc(sizeof(TCHAR
*) * m_numParams
);
180 for(i
= 0; i
< m_numParams
; i
++)
182 if (m_pmatch
[i
+ 1].rm_so
!= -1)
184 len
= m_pmatch
[i
+ 1].rm_eo
- m_pmatch
[i
+ 1].rm_so
;
185 params
[i
] = (TCHAR
*)malloc((len
+ 1) * sizeof(TCHAR
));
186 memcpy(params
[i
], &line
[m_pmatch
[i
+ 1].rm_so
], len
* sizeof(TCHAR
));
191 params
[i
] = _tcsdup(_T(""));
196 cb(m_eventCode
, m_eventName
, line
, source
, eventId
, level
, m_numParams
, params
, objectId
,
197 ((m_repeatCount
> 0) && (m_repeatInterval
> 0)) ? m_matchArray
->size() : 1, userArg
);
199 for(i
= 0; i
< m_numParams
; i
++)
209 m_parser
->trace(6, _T(" no match"));
210 return false; // no match
216 bool LogParserRule::match(const TCHAR
*line
, LogParserCallback cb
, UINT32 objectId
, void *userArg
)
218 return matchInternal(false, NULL
, 0, 0, line
, cb
, objectId
, userArg
);
224 bool LogParserRule::matchEx(const TCHAR
*source
, UINT32 eventId
, UINT32 level
,
225 const TCHAR
*line
, LogParserCallback cb
, UINT32 objectId
, void *userArg
)
227 return matchInternal(true, source
, eventId
, level
, line
, cb
, objectId
, userArg
);
231 * Expand macros in regexp
233 void LogParserRule::expandMacros(const TCHAR
*regexp
, String
&out
)
235 const TCHAR
*curr
, *prev
;
238 for(curr
= prev
= regexp
; *curr
!= 0; curr
++)
240 if (*curr
== _T('@'))
243 if ((curr
!= regexp
) && (*(curr
- 1) == _T('\\')))
245 out
.append(prev
, (size_t)(curr
- prev
- 1));
251 if (*(curr
+ 1) == _T('{'))
255 out
.append(prev
, (size_t)(curr
- prev
));
257 for(i
= 0; (*curr
!= 0) && (*curr
!= '}'); i
++)
260 out
+= m_parser
->getMacro(name
);
264 out
.append(prev
, (size_t)(curr
- prev
+ 1));
270 out
.append(prev
, (size_t)(curr
- prev
));
276 bool LogParserRule::matchRepeatCount()
278 if ((m_repeatCount
== 0) || (m_repeatInterval
== 0))
281 // remove expired matches
282 time_t now
= time(NULL
);
283 for(int i
= 0; i
< m_matchArray
->size(); i
++)
285 if (m_matchArray
->get(i
) >= (now
- m_repeatInterval
))
287 m_matchArray
->remove(i
);
291 m_matchArray
->add(now
);
292 bool match
= m_matchArray
->size() >= m_repeatCount
;
293 if (m_resetRepeat
&& match
)
294 m_matchArray
->clear();