2 ** NetXMS - Network Management System
3 ** Copyright (C) 2003-2014 Victor Kirhenshtein
5 ** This program is free software; you can redistribute it and/or modify
6 ** it under the terms of the GNU General Public License as published by
7 ** the Free Software Foundation; either version 2 of the License, or
8 ** (at your option) any later version.
10 ** This program is distributed in the hope that it will be useful,
11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ** GNU General Public License for more details.
15 ** You should have received a copy of the GNU General Public License
16 ** along with this program; if not, write to the Free Software
17 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 ** File: dcithreshold.cpp
26 * Create new threshold for given DCI
28 Threshold::Threshold(DCItem
*pRelatedItem
)
31 m_itemId
= pRelatedItem
->getId();
32 m_targetId
= pRelatedItem
->getOwnerId();
33 m_eventCode
= EVENT_THRESHOLD_REACHED
;
34 m_rearmEventCode
= EVENT_THRESHOLD_REARMED
;
37 m_dataType
= pRelatedItem
->getDataType();
39 m_scriptSource
= NULL
;
42 m_currentSeverity
= SEVERITY_NORMAL
;
43 m_repeatInterval
= -1;
44 m_lastEventTimestamp
= 0;
49 * Constructor for NXMP parser
51 Threshold::Threshold()
56 m_eventCode
= EVENT_THRESHOLD_REACHED
;
57 m_rearmEventCode
= EVENT_THRESHOLD_REARMED
;
62 m_scriptSource
= NULL
;
65 m_currentSeverity
= SEVERITY_NORMAL
;
66 m_repeatInterval
= -1;
67 m_lastEventTimestamp
= 0;
72 * Create from another threshold object
74 Threshold::Threshold(Threshold
*src
)
77 m_itemId
= src
->m_itemId
;
78 m_targetId
= src
->m_targetId
;
79 m_eventCode
= src
->m_eventCode
;
80 m_rearmEventCode
= src
->m_rearmEventCode
;
81 m_value
= src
->m_value
;
82 m_function
= src
->m_function
;
83 m_operation
= src
->m_operation
;
84 m_dataType
= src
->m_dataType
;
85 m_sampleCount
= src
->m_sampleCount
;
86 m_scriptSource
= NULL
;
88 setScript((src
->m_scriptSource
!= NULL
) ? _tcsdup(src
->m_scriptSource
) : NULL
);
90 m_currentSeverity
= SEVERITY_NORMAL
;
91 m_repeatInterval
= src
->m_repeatInterval
;
92 m_lastEventTimestamp
= 0;
97 * Constructor for creating object from database
98 * This constructor assumes that SELECT query look as following:
99 * SELECT threshold_id,fire_value,rearm_value,check_function,check_operation,
100 * sample_count,script,event_code,current_state,rearm_event_code,
101 * repeat_interval,current_severity,last_event_timestamp,match_count FROM thresholds
103 Threshold::Threshold(DB_RESULT hResult
, int iRow
, DCItem
*pRelatedItem
)
105 TCHAR szBuffer
[MAX_DB_STRING
];
107 m_id
= DBGetFieldULong(hResult
, iRow
, 0);
108 m_itemId
= pRelatedItem
->getId();
109 m_targetId
= pRelatedItem
->getOwnerId();
110 m_eventCode
= DBGetFieldULong(hResult
, iRow
, 7);
111 m_rearmEventCode
= DBGetFieldULong(hResult
, iRow
, 9);
112 DBGetField(hResult
, iRow
, 1, szBuffer
, MAX_DB_STRING
);
114 m_function
= (BYTE
)DBGetFieldLong(hResult
, iRow
, 3);
115 m_operation
= (BYTE
)DBGetFieldLong(hResult
, iRow
, 4);
116 m_dataType
= pRelatedItem
->getDataType();
117 m_sampleCount
= DBGetFieldLong(hResult
, iRow
, 5);
118 if ((m_function
== F_LAST
) && (m_sampleCount
< 1))
120 m_scriptSource
= NULL
;
122 setScript(DBGetField(hResult
, iRow
, 6, NULL
, 0));
123 m_isReached
= DBGetFieldLong(hResult
, iRow
, 8);
124 m_repeatInterval
= DBGetFieldLong(hResult
, iRow
, 10);
125 m_currentSeverity
= (BYTE
)DBGetFieldLong(hResult
, iRow
, 11);
126 m_lastEventTimestamp
= (time_t)DBGetFieldULong(hResult
, iRow
, 12);
127 m_numMatches
= DBGetFieldLong(hResult
, iRow
, 13);
131 * Create threshold from import file
133 Threshold::Threshold(ConfigEntry
*config
, DCItem
*parentItem
)
136 m_itemId
= parentItem
->getId();
137 m_targetId
= parentItem
->getOwnerId();
138 m_eventCode
= EventCodeFromName(config
->getSubEntryValue(_T("activationEvent"), 0, _T("SYS_THRESHOLD_REACHED")));
139 m_rearmEventCode
= EventCodeFromName(config
->getSubEntryValue(_T("deactivationEvent"), 0, _T("SYS_THRESHOLD_REARMED")));
140 m_function
= (BYTE
)config
->getSubEntryValueAsInt(_T("function"), 0, F_LAST
);
141 m_operation
= (BYTE
)config
->getSubEntryValueAsInt(_T("condition"), 0, OP_EQ
);
142 m_dataType
= parentItem
->getDataType();
143 m_value
= config
->getSubEntryValue(_T("value"), 0, _T(""));
144 m_sampleCount
= (config
->getSubEntryValue(_T("sampleCount")) != NULL
) ? config
->getSubEntryValueAsInt(_T("sampleCount"), 0, 1) : config
->getSubEntryValueAsInt(_T("param1"), 0, 1);
145 m_scriptSource
= NULL
;
147 const TCHAR
*script
= config
->getSubEntryValue(_T("script"));
148 setScript(_tcsdup_ex(script
));
150 m_currentSeverity
= SEVERITY_NORMAL
;
151 m_repeatInterval
= config
->getSubEntryValueAsInt(_T("repeatInterval"), 0, -1);
152 m_lastEventTimestamp
= 0;
159 Threshold::~Threshold()
161 safe_free(m_scriptSource
);
166 * Create new unique id for object
168 void Threshold::createId()
170 m_id
= CreateUniqueId(IDG_THRESHOLD
);
174 * Save threshold to database
176 BOOL
Threshold::saveToDB(DB_HANDLE hdb
, UINT32 dwIndex
)
178 // Prepare and execute query
180 if (!IsDatabaseRecordExist(hdb
, _T("thresholds"), _T("threshold_id"), m_id
))
182 hStmt
= DBPrepare(hdb
,
183 _T("INSERT INTO thresholds (item_id,fire_value,rearm_value,")
184 _T("check_function,check_operation,sample_count,script,event_code,")
185 _T("sequence_number,current_state,rearm_event_code,repeat_interval,")
186 _T("current_severity,last_event_timestamp,match_count,threshold_id) ")
187 _T("VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"));
191 hStmt
= DBPrepare(hdb
,
192 _T("UPDATE thresholds SET item_id=?,fire_value=?,rearm_value=?,check_function=?,")
193 _T("check_operation=?,sample_count=?,script=?,event_code=?,")
194 _T("sequence_number=?,current_state=?,rearm_event_code=?,")
195 _T("repeat_interval=?,current_severity=?,last_event_timestamp=?,")
196 _T("match_count=? WHERE threshold_id=?"));
201 DBBind(hStmt
, 1, DB_SQLTYPE_INTEGER
, m_itemId
);
202 DBBind(hStmt
, 2, DB_SQLTYPE_VARCHAR
, m_value
.getString(), DB_BIND_STATIC
);
203 DBBind(hStmt
, 3, DB_SQLTYPE_VARCHAR
, NULL
, DB_BIND_STATIC
);
204 DBBind(hStmt
, 4, DB_SQLTYPE_INTEGER
, (INT32
)m_function
);
205 DBBind(hStmt
, 5, DB_SQLTYPE_INTEGER
, (INT32
)m_operation
);
206 DBBind(hStmt
, 6, DB_SQLTYPE_INTEGER
, (INT32
)m_sampleCount
);
207 DBBind(hStmt
, 7, DB_SQLTYPE_VARCHAR
, m_scriptSource
, DB_BIND_STATIC
);
208 DBBind(hStmt
, 8, DB_SQLTYPE_INTEGER
, m_eventCode
);
209 DBBind(hStmt
, 9, DB_SQLTYPE_INTEGER
, dwIndex
);
210 DBBind(hStmt
, 10, DB_SQLTYPE_INTEGER
, (INT32
)(m_isReached
? 1 : 0));
211 DBBind(hStmt
, 11, DB_SQLTYPE_INTEGER
, m_rearmEventCode
);
212 DBBind(hStmt
, 12, DB_SQLTYPE_INTEGER
, (INT32
)m_repeatInterval
);
213 DBBind(hStmt
, 13, DB_SQLTYPE_INTEGER
, (INT32
)m_currentSeverity
);
214 DBBind(hStmt
, 14, DB_SQLTYPE_INTEGER
, (INT32
)m_lastEventTimestamp
);
215 DBBind(hStmt
, 15, DB_SQLTYPE_INTEGER
, (INT32
)m_numMatches
);
216 DBBind(hStmt
, 16, DB_SQLTYPE_INTEGER
, (INT32
)m_id
);
218 BOOL success
= DBExecute(hStmt
);
219 DBFreeStatement(hStmt
);
225 * Method will return the following codes:
226 * THRESHOLD_REACHED - when item's value match the threshold condition while previous check doesn't
227 * THRESHOLD_REARMED - when item's value doesn't match the threshold condition while previous check do
228 * NO_ACTION - when there are no changes in item's value match to threshold's condition
230 ThresholdCheckResult
Threshold::check(ItemValue
&value
, ItemValue
**ppPrevValues
, ItemValue
&fvalue
, NetObj
*target
, DCItem
*dci
)
232 // check if there is enough cached data
236 if (ppPrevValues
[0]->getTimeStamp() == 1) // Timestamp 1 means placeholder value inserted by cache loader
237 return m_isReached
? ALREADY_ACTIVE
: ALREADY_INACTIVE
;
242 for(int i
= 0; i
< m_sampleCount
- 1; i
++)
243 if (ppPrevValues
[i
]->getTimeStamp() == 1) // Timestamp 1 means placeholder value inserted by cache loader
244 return m_isReached
? ALREADY_ACTIVE
: ALREADY_INACTIVE
;
251 int iDataType
= m_dataType
;
253 // Execute function on value
256 case F_LAST
: // Check last value only
260 case F_AVERAGE
: // Check average value for last n polls
261 calculateAverageValue(&fvalue
, value
, ppPrevValues
);
264 calculateSumValue(&fvalue
, value
, ppPrevValues
);
266 case F_DEVIATION
: // Check mean absolute deviation
267 calculateMDValue(&fvalue
, value
, ppPrevValues
);
270 calculateDiff(&fvalue
, value
, ppPrevValues
);
271 if (m_dataType
== DCI_DT_STRING
)
272 iDataType
= DCI_DT_INT
; // diff() for strings is an integer
274 case F_ERROR
: // Check for collection error
281 // Run comparision operation on function result and threshold value
282 if (m_function
== F_ERROR
)
284 // Threshold::Check() can be called only for valid values, which
285 // means that error thresholds cannot be active
288 else if (m_function
== F_SCRIPT
)
290 if (m_script
!= NULL
)
292 NXSL_VM
*vm
= new NXSL_VM(new NXSL_ServerEnv());
293 if (vm
->load(m_script
))
295 NXSL_Value
*parameters
[2];
296 parameters
[0] = new NXSL_Value(value
.getString());
297 parameters
[1] = new NXSL_Value(m_value
.getString());
298 vm
->setGlobalVariable(_T("$object"), target
->createNXSLObject());
299 if (target
->getObjectClass() == OBJECT_NODE
)
301 vm
->setGlobalVariable(_T("$node"), new NXSL_Value(new NXSL_Object(&g_nxslNodeClass
, target
)));
303 vm
->setGlobalVariable(_T("$dci"), dci
->createNXSLObject());
304 vm
->setGlobalVariable(_T("$isCluster"), new NXSL_Value((target
->getObjectClass() == OBJECT_CLUSTER
) ? 1 : 0));
305 if (vm
->run(2, parameters
))
307 NXSL_Value
*result
= vm
->getResult();
310 bMatch
= (result
->getValueAsInt32() != 0);
316 _sntprintf(buffer
, 1024, _T("DCI::%s::%d::%d::ThresholdScript"), target
->getName(), dci
->getId(), m_id
);
317 PostDciEvent(EVENT_SCRIPT_ERROR
, g_dwMgmtNode
, dci
->getId(), "ssd", buffer
, vm
->getErrorText(), dci
->getId());
318 nxlog_write(MSG_THRESHOLD_SCRIPT_EXECUTION_ERROR
, NXLOG_WARNING
, "sdds", target
->getName(), dci
->getId(), m_id
, vm
->getErrorText());
324 _sntprintf(buffer
, 1024, _T("DCI::%s::%d::%d::ThresholdScript"), target
->getName(), dci
->getId(), m_id
);
325 PostDciEvent(EVENT_SCRIPT_ERROR
, g_dwMgmtNode
, dci
->getId(), "ssd", buffer
, vm
->getErrorText(), dci
->getId());
326 nxlog_write(MSG_THRESHOLD_SCRIPT_EXECUTION_ERROR
, NXLOG_WARNING
, "sdds", target
->getName(), dci
->getId(), m_id
, vm
->getErrorText());
332 DbgPrintf(7, _T("Script not compiled for threshold %d of DCI %d of data collection target %s [%d]"),
333 m_id
, dci
->getId(), target
->getName(), target
->getId());
344 bMatch
= ((INT32
)fvalue
< (INT32
)m_value
);
347 bMatch
= ((UINT32
)fvalue
< (UINT32
)m_value
);
350 bMatch
= ((INT64
)fvalue
< (INT64
)m_value
);
353 bMatch
= ((UINT64
)fvalue
< (UINT64
)m_value
);
356 bMatch
= ((double)fvalue
< (double)m_value
);
360 case OP_LE_EQ
: // Less or equal
364 bMatch
= ((INT32
)fvalue
<= (INT32
)m_value
);
367 bMatch
= ((UINT32
)fvalue
<= (UINT32
)m_value
);
370 bMatch
= ((INT64
)fvalue
<= (INT64
)m_value
);
373 bMatch
= ((UINT64
)fvalue
<= (UINT64
)m_value
);
376 bMatch
= ((double)fvalue
<= (double)m_value
);
384 bMatch
= ((INT32
)fvalue
== (INT32
)m_value
);
387 bMatch
= ((UINT32
)fvalue
== (UINT32
)m_value
);
390 bMatch
= ((INT64
)fvalue
== (INT64
)m_value
);
393 bMatch
= ((UINT64
)fvalue
== (UINT64
)m_value
);
396 bMatch
= ((double)fvalue
== (double)m_value
);
399 bMatch
= !_tcscmp(fvalue
.getString(), m_value
.getString());
403 case OP_GT_EQ
: // Greater or equal
407 bMatch
= ((INT32
)fvalue
>= (INT32
)m_value
);
410 bMatch
= ((UINT32
)fvalue
>= (UINT32
)m_value
);
413 bMatch
= ((INT64
)fvalue
>= (INT64
)m_value
);
416 bMatch
= ((UINT64
)fvalue
>= (UINT64
)m_value
);
419 bMatch
= ((double)fvalue
>= (double)m_value
);
423 case OP_GT
: // Greater
427 bMatch
= ((INT32
)fvalue
> (INT32
)m_value
);
430 bMatch
= ((UINT32
)fvalue
> (UINT32
)m_value
);
433 bMatch
= ((INT64
)fvalue
> (INT64
)m_value
);
436 bMatch
= ((UINT64
)fvalue
> (UINT64
)m_value
);
439 bMatch
= ((double)fvalue
> (double)m_value
);
443 case OP_NE
: // Not equal
447 bMatch
= ((INT32
)fvalue
!= (INT32
)m_value
);
450 bMatch
= ((UINT32
)fvalue
!= (UINT32
)m_value
);
453 bMatch
= ((INT64
)fvalue
!= (INT64
)m_value
);
456 bMatch
= ((UINT64
)fvalue
!= (UINT64
)m_value
);
459 bMatch
= ((double)fvalue
!= (double)m_value
);
462 bMatch
= _tcscmp(fvalue
.getString(), m_value
.getString());
467 // This operation can be performed only on strings
468 if (m_dataType
== DCI_DT_STRING
)
469 bMatch
= MatchString(m_value
.getString(), fvalue
.getString(), true);
472 // This operation can be performed only on strings
473 if (m_dataType
== DCI_DT_STRING
)
474 bMatch
= !MatchString(m_value
.getString(), fvalue
.getString(), true);
481 // Check for number of consecutive matches
482 if ((m_function
== F_LAST
) || (m_function
== F_SCRIPT
))
487 if (m_numMatches
< m_sampleCount
)
496 ThresholdCheckResult result
= (bMatch
& !m_isReached
) ? ACTIVATED
: ((!bMatch
& m_isReached
) ? DEACTIVATED
: (m_isReached
? ALREADY_ACTIVE
: ALREADY_INACTIVE
));
497 m_isReached
= bMatch
;
498 if (result
== ACTIVATED
|| result
== DEACTIVATED
)
500 // Update threshold status in database
502 _sntprintf(szQuery
, 256, _T("UPDATE thresholds SET current_state=%d WHERE threshold_id=%d"), (int)m_isReached
, (int)m_id
);
503 QueueSQLRequest(szQuery
);
509 * Mark last activation event
511 void Threshold::markLastEvent(int severity
)
513 m_lastEventTimestamp
= time(NULL
);
514 m_currentSeverity
= (BYTE
)severity
;
516 // Update threshold in database
518 _sntprintf(query
, 256,
519 _T("UPDATE thresholds SET current_severity=%d,last_event_timestamp=%d WHERE threshold_id=%d"),
520 (int)m_currentSeverity
, (int)m_lastEventTimestamp
, (int)m_id
);
521 QueueSQLRequest(query
);
525 * Check for collection error thresholds
526 * Return same values as Check()
528 ThresholdCheckResult
Threshold::checkError(UINT32 dwErrorCount
)
530 if (m_function
!= F_ERROR
)
531 return m_isReached
? ALREADY_ACTIVE
: ALREADY_INACTIVE
;
533 BOOL bMatch
= ((UINT32
)m_sampleCount
<= dwErrorCount
);
534 ThresholdCheckResult result
= (bMatch
& !m_isReached
) ? ACTIVATED
: ((!bMatch
& m_isReached
) ? DEACTIVATED
: (m_isReached
? ALREADY_ACTIVE
: ALREADY_INACTIVE
));
535 m_isReached
= bMatch
;
536 if (result
== ACTIVATED
|| result
== DEACTIVATED
)
538 // Update threshold status in database
540 _sntprintf(szQuery
, 256, _T("UPDATE thresholds SET current_state=%d WHERE threshold_id=%d"), m_isReached
, m_id
);
541 QueueSQLRequest(szQuery
);
547 * Fill DCI_THRESHOLD with object's data ready to send over the network
549 void Threshold::createMessage(NXCPMessage
*msg
, UINT32 baseId
)
551 UINT32 varId
= baseId
;
553 msg
->setField(varId
++, m_id
);
554 msg
->setField(varId
++, m_eventCode
);
555 msg
->setField(varId
++, m_rearmEventCode
);
556 msg
->setField(varId
++, (WORD
)m_function
);
557 msg
->setField(varId
++, (WORD
)m_operation
);
558 msg
->setField(varId
++, (UINT32
)m_sampleCount
);
559 msg
->setField(varId
++, CHECK_NULL_EX(m_scriptSource
));
560 msg
->setField(varId
++, (UINT32
)m_repeatInterval
);
561 msg
->setField(varId
++, m_value
.getString());
562 msg
->setField(varId
++, (WORD
)m_isReached
);
563 msg
->setField(varId
++, (WORD
)m_currentSeverity
);
564 msg
->setField(varId
++, (UINT32
)m_lastEventTimestamp
);
568 * Update threshold object from NXCP message
570 void Threshold::updateFromMessage(NXCPMessage
*msg
, UINT32 baseId
)
572 TCHAR buffer
[MAX_DCI_STRING_VALUE
];
573 UINT32 varId
= baseId
+ 1; // Skip ID field
575 m_eventCode
= msg
->getFieldAsUInt32(varId
++);
576 m_rearmEventCode
= msg
->getFieldAsUInt32(varId
++);
577 m_function
= (BYTE
)msg
->getFieldAsUInt16(varId
++);
578 m_operation
= (BYTE
)msg
->getFieldAsUInt16(varId
++);
579 m_sampleCount
= (int)msg
->getFieldAsUInt32(varId
++);
580 setScript(msg
->getFieldAsString(varId
++));
581 m_repeatInterval
= (int)msg
->getFieldAsUInt32(varId
++);
582 m_value
= msg
->getFieldAsString(varId
++, buffer
, MAX_DCI_STRING_VALUE
);
586 * Calculate average value for parameter
588 #define CALC_AVG_VALUE(vtype) \
591 var = (vtype)lastValue; \
592 for(int i = 1; i < m_sampleCount; i++) \
594 var += (vtype)(*ppPrevValues[i - 1]); \
596 *pResult = var / (vtype)m_sampleCount; \
599 void Threshold::calculateAverageValue(ItemValue
*pResult
, ItemValue
&lastValue
, ItemValue
**ppPrevValues
)
604 CALC_AVG_VALUE(INT32
);
607 CALC_AVG_VALUE(UINT32
);
610 CALC_AVG_VALUE(INT64
);
613 CALC_AVG_VALUE(UINT64
);
616 CALC_AVG_VALUE(double);
619 *pResult
= _T(""); // Average value for string is meaningless
627 * Calculate sum value for values of given type
629 #define CALC_SUM_VALUE(vtype) \
632 var = (vtype)lastValue; \
633 for(int i = 1; i < m_sampleCount; i++) \
635 var += (vtype)(*ppPrevValues[i - 1]); \
641 * Calculate sum value for parameter
643 void Threshold::calculateSumValue(ItemValue
*pResult
, ItemValue
&lastValue
, ItemValue
**ppPrevValues
)
648 CALC_SUM_VALUE(INT32
);
651 CALC_SUM_VALUE(UINT32
);
654 CALC_SUM_VALUE(INT64
);
657 CALC_SUM_VALUE(UINT64
);
660 CALC_SUM_VALUE(double);
663 *pResult
= _T(""); // Sum value for string is meaningless
671 * Calculate mean absolute deviation for values of given type
673 #define CALC_MD_VALUE(vtype) \
676 mean = (vtype)lastValue; \
677 for(i = 1; i < m_sampleCount; i++) \
679 mean += (vtype)(*ppPrevValues[i - 1]); \
681 mean /= (vtype)m_sampleCount; \
682 dev = ABS((vtype)lastValue - mean); \
683 for(i = 1; i < m_sampleCount; i++) \
685 dev += ABS((vtype)(*ppPrevValues[i - 1]) - mean); \
687 *pResult = dev / (vtype)m_sampleCount; \
691 * Calculate mean absolute deviation for parameter
693 void Threshold::calculateMDValue(ItemValue
*pResult
, ItemValue
&lastValue
, ItemValue
**ppPrevValues
)
700 #define ABS(x) ((x) < 0 ? -(x) : (x))
701 CALC_MD_VALUE(INT32
);
704 CALC_MD_VALUE(INT64
);
707 CALC_MD_VALUE(double);
712 CALC_MD_VALUE(UINT32
);
715 CALC_MD_VALUE(UINT64
);
718 *pResult
= _T(""); // Mean deviation for string is meaningless
728 * Calculate difference between last and previous value
730 void Threshold::calculateDiff(ItemValue
*pResult
, ItemValue
&lastValue
, ItemValue
**ppPrevValues
)
732 CalculateItemValueDiff(*pResult
, m_dataType
, lastValue
, *ppPrevValues
[0]);
736 * Compare to another threshold
738 BOOL
Threshold::compare(Threshold
*pThr
)
745 bMatch
= ((INT32
)pThr
->m_value
== (INT32
)m_value
);
748 bMatch
= ((UINT32
)pThr
->m_value
== (UINT32
)m_value
);
751 bMatch
= ((INT64
)pThr
->m_value
== (INT64
)m_value
);
754 bMatch
= ((UINT64
)pThr
->m_value
== (UINT64
)m_value
);
757 bMatch
= ((double)pThr
->m_value
== (double)m_value
);
760 bMatch
= !_tcscmp(pThr
->m_value
.getString(), m_value
.getString());
767 (pThr
->m_eventCode
== m_eventCode
) &&
768 (pThr
->m_rearmEventCode
== m_rearmEventCode
) &&
769 (pThr
->m_dataType
== m_dataType
) &&
770 (pThr
->m_function
== m_function
) &&
771 (pThr
->m_operation
== m_operation
) &&
772 (pThr
->m_sampleCount
== m_sampleCount
) &&
773 !_tcscmp(CHECK_NULL_EX(pThr
->m_scriptSource
), CHECK_NULL_EX(m_scriptSource
)) &&
774 (pThr
->m_repeatInterval
== m_repeatInterval
);
778 * Create management pack record
780 void Threshold::createNXMPRecord(String
&str
, int index
)
782 TCHAR activationEvent
[MAX_EVENT_NAME
], deactivationEvent
[MAX_EVENT_NAME
];
784 EventNameFromCode(m_eventCode
, activationEvent
);
785 EventNameFromCode(m_rearmEventCode
, deactivationEvent
);
786 str
.appendFormattedString(_T("\t\t\t\t\t\t<threshold id=\"%d\">\n")
787 _T("\t\t\t\t\t\t\t<function>%d</function>\n")
788 _T("\t\t\t\t\t\t\t<condition>%d</condition>\n")
789 _T("\t\t\t\t\t\t\t<value>%s</value>\n")
790 _T("\t\t\t\t\t\t\t<activationEvent>%s</activationEvent>\n")
791 _T("\t\t\t\t\t\t\t<deactivationEvent>%s</deactivationEvent>\n")
792 _T("\t\t\t\t\t\t\t<sampleCount>%d</sampleCount>\n")
793 _T("\t\t\t\t\t\t\t<repeatInterval>%d</repeatInterval>\n"),
794 index
, m_function
, m_operation
,
795 (const TCHAR
*)EscapeStringForXML2(m_value
.getString()),
796 (const TCHAR
*)EscapeStringForXML2(activationEvent
),
797 (const TCHAR
*)EscapeStringForXML2(deactivationEvent
),
798 m_sampleCount
, m_repeatInterval
);
799 if (m_scriptSource
!= NULL
)
801 str
.append(_T("\t\t\t\t\t\t\t<script>"));
802 str
.append(EscapeStringForXML2(m_scriptSource
));
803 str
.append(_T("</script>\n"));
805 str
.append(_T("\t\t\t\t\t\t</threshold>\n"));
809 * Make an association with DCI (used by management pack parser)
811 void Threshold::associate(DCItem
*pItem
)
813 m_itemId
= pItem
->getId();
814 m_targetId
= pItem
->getOwnerId();
815 m_dataType
= pItem
->getDataType();
819 * Set new script. Script source must be dynamically allocated
820 * and will be deallocated by threshold object
822 void Threshold::setScript(TCHAR
*script
)
824 safe_free(m_scriptSource
);
828 m_scriptSource
= script
;
829 StrStrip(m_scriptSource
);
830 if (m_scriptSource
[0] != 0)
832 TCHAR errorText
[1024];
833 m_script
= NXSLCompile(m_scriptSource
, errorText
, 1024, NULL
);
834 if (m_script
== NULL
)
836 TCHAR buffer
[1024], defaultName
[32];
837 _sntprintf(defaultName
, 32, _T("[%d]"), m_targetId
);
838 _sntprintf(buffer
, 1024, _T("DCI::%s::%d::%d::ThresholdScript"), GetObjectName(m_targetId
, defaultName
), m_itemId
, m_id
);
839 PostDciEvent(EVENT_SCRIPT_ERROR
, g_dwMgmtNode
, m_itemId
, "ssd", buffer
, errorText
, m_itemId
);
840 nxlog_write(MSG_THRESHOLD_SCRIPT_COMPILATION_ERROR
, NXLOG_WARNING
, "sdds", GetObjectName(m_targetId
, defaultName
), m_itemId
, m_id
, errorText
);
850 m_scriptSource
= NULL
;