imported svn:keywords properties
[public/netxms.git] / src / server / core / dcithreshold.cpp
1 /* $Id$ */
2 /*
3 ** NetXMS - Network Management System
4 ** Copyright (C) 2003, 2004, 2005, 2006, 2007 Victor Kirhenshtein
5 **
6 ** This program is free software; you can redistribute it and/or modify
7 ** it under the terms of the GNU General Public License as published by
8 ** the Free Software Foundation; either version 2 of the License, or
9 ** (at your option) any later version.
10 **
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.
15 **
16 ** You should have received a copy of the GNU 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.
19 **
20 ** File: dcithreshold.cpp
21 **
22 **/
23
24 #include "nxcore.h"
25
26
27 //
28 // Default constructor
29 //
30
31 Threshold::Threshold(DCItem *pRelatedItem)
32 {
33 m_dwId = 0;
34 m_dwItemId = pRelatedItem->Id();
35 m_dwEventCode = EVENT_THRESHOLD_REACHED;
36 m_dwRearmEventCode = EVENT_THRESHOLD_REARMED;
37 m_iFunction = F_LAST;
38 m_iOperation = OP_EQ;
39 m_iDataType = pRelatedItem->DataType();
40 m_iParam1 = 0;
41 m_iParam2 = 0;
42 m_bIsReached = FALSE;
43 m_nRepeatInterval = -1;
44 m_tmLastEventTimestamp = 0;
45 }
46
47
48 //
49 // Constructor for NXMP parser
50 //
51
52 Threshold::Threshold()
53 {
54 m_dwId = 0;
55 m_dwItemId = 0;
56 m_dwEventCode = EVENT_THRESHOLD_REACHED;
57 m_dwRearmEventCode = EVENT_THRESHOLD_REARMED;
58 m_iFunction = F_LAST;
59 m_iOperation = OP_EQ;
60 m_iDataType = 0;
61 m_iParam1 = 0;
62 m_iParam2 = 0;
63 m_bIsReached = FALSE;
64 m_nRepeatInterval = -1;
65 m_tmLastEventTimestamp = 0;
66 }
67
68
69 //
70 // Create from another threshold object
71 //
72
73 Threshold::Threshold(Threshold *pSrc)
74 {
75 m_dwId = pSrc->m_dwId;
76 m_dwItemId = pSrc->m_dwItemId;
77 m_dwEventCode = pSrc->m_dwEventCode;
78 m_dwRearmEventCode = pSrc->m_dwRearmEventCode;
79 m_value = pSrc->Value();
80 m_iFunction = pSrc->m_iFunction;
81 m_iOperation = pSrc->m_iOperation;
82 m_iDataType = pSrc->m_iDataType;
83 m_iParam1 = pSrc->m_iParam1;
84 m_iParam2 = pSrc->m_iParam2;
85 m_bIsReached = FALSE;
86 m_nRepeatInterval = pSrc->m_nRepeatInterval;
87 m_tmLastEventTimestamp = 0;
88 }
89
90
91 //
92 // Constructor for creating object from database
93 // This constructor assumes that SELECT query look as following:
94 // SELECT threshold_id,fire_value,rearm_value,check_function,check_operation,
95 // parameter_1,parameter_2,event_code,current_state,
96 // rearm_event_code,repeat_interval FROM thresholds
97 //
98
99 Threshold::Threshold(DB_RESULT hResult, int iRow, DCItem *pRelatedItem)
100 {
101 TCHAR szBuffer[MAX_DB_STRING];
102
103 m_dwId = DBGetFieldULong(hResult, iRow, 0);
104 m_dwItemId = pRelatedItem->Id();
105 m_dwEventCode = DBGetFieldULong(hResult, iRow, 7);
106 m_dwRearmEventCode = DBGetFieldULong(hResult, iRow, 9);
107 DBGetField(hResult, iRow, 1, szBuffer, MAX_DB_STRING);
108 DecodeSQLString(szBuffer);
109 m_value = szBuffer;
110 m_iFunction = (BYTE)DBGetFieldLong(hResult, iRow, 3);
111 m_iOperation = (BYTE)DBGetFieldLong(hResult, iRow, 4);
112 m_iDataType = pRelatedItem->DataType();
113 m_iParam1 = DBGetFieldLong(hResult, iRow, 5);
114 m_iParam2 = DBGetFieldLong(hResult, iRow, 6);
115 m_bIsReached = DBGetFieldLong(hResult, iRow, 8);
116 m_nRepeatInterval = DBGetFieldLong(hResult, iRow, 10);
117 m_tmLastEventTimestamp = 0;
118 }
119
120
121 //
122 // Destructor
123 //
124
125 Threshold::~Threshold()
126 {
127 }
128
129
130 //
131 // Create new unique id for object
132 //
133
134 void Threshold::CreateId(void)
135 {
136 m_dwId = CreateUniqueId(IDG_THRESHOLD);
137 }
138
139
140 //
141 // Save threshold to database
142 //
143
144 BOOL Threshold::SaveToDB(DB_HANDLE hdb, DWORD dwIndex)
145 {
146 TCHAR *pszEscValue, szQuery[512];
147 DB_RESULT hResult;
148 BOOL bNewObject = TRUE;
149
150 // Check for object's existence in database
151 _stprintf(szQuery, _T("SELECT threshold_id FROM thresholds WHERE threshold_id=%d"), m_dwId);
152 hResult = DBSelect(hdb, szQuery);
153 if (hResult != 0)
154 {
155 if (DBGetNumRows(hResult) > 0)
156 bNewObject = FALSE;
157 DBFreeResult(hResult);
158 }
159
160 // Prepare and execute query
161 pszEscValue = EncodeSQLString(m_value.String());
162 if (bNewObject)
163 sprintf(szQuery, "INSERT INTO thresholds (threshold_id,item_id,fire_value,rearm_value,"
164 "check_function,check_operation,parameter_1,parameter_2,event_code,"
165 "sequence_number,current_state,rearm_event_code,repeat_interval) VALUES "
166 "(%d,%d,'%s','#00',%d,%d,%d,%d,%d,%d,%d,%d,%d)",
167 m_dwId, m_dwItemId, pszEscValue, m_iFunction, m_iOperation, m_iParam1,
168 m_iParam2, m_dwEventCode, dwIndex, m_bIsReached, m_dwRearmEventCode,
169 m_nRepeatInterval);
170 else
171 sprintf(szQuery, "UPDATE thresholds SET item_id=%d,fire_value='%s',check_function=%d,"
172 "check_operation=%d,parameter_1=%d,parameter_2=%d,event_code=%d,"
173 "sequence_number=%d,current_state=%d,"
174 "rearm_event_code=%d,repeat_interval=%d WHERE threshold_id=%d",
175 m_dwItemId, pszEscValue, m_iFunction, m_iOperation, m_iParam1,
176 m_iParam2, m_dwEventCode, dwIndex, m_bIsReached,
177 m_dwRearmEventCode, m_nRepeatInterval, m_dwId);
178 free(pszEscValue);
179 return DBQuery(hdb, szQuery);
180 }
181
182
183 //
184 // Check threshold
185 // Function will return the following codes:
186 // THRESHOLD_REACHED - when item's value match the threshold condition while previous check doesn't
187 // THRESHOLD_REARMED - when item's value doesn't match the threshold condition while previous check do
188 // NO_ACTION - when there are no changes in item's value match to threshold's condition
189 //
190
191 int Threshold::Check(ItemValue &value, ItemValue **ppPrevValues, ItemValue &fvalue)
192 {
193 BOOL bMatch = FALSE;
194 int iResult, iDataType = m_iDataType;
195
196 // Execute function on value
197 switch(m_iFunction)
198 {
199 case F_LAST: // Check last value only
200 fvalue = value;
201 break;
202 case F_AVERAGE: // Check average value for last n polls
203 CalculateAverageValue(&fvalue, value, ppPrevValues);
204 break;
205 case F_DEVIATION: // Check mean absolute deviation
206 CalculateMDValue(&fvalue, value, ppPrevValues);
207 break;
208 case F_DIFF:
209 CalculateDiff(&fvalue, value, ppPrevValues);
210 if (m_iDataType == DCI_DT_STRING)
211 iDataType = DCI_DT_INT; // diff() for strings is an integer
212 break;
213 case F_ERROR: // Check for collection error
214 fvalue = (DWORD)0;
215 break;
216 default:
217 break;
218 }
219
220 // Run comparision operation on function result and threshold value
221 if (m_iFunction == F_ERROR)
222 {
223 // Threshold::Check() can be called only for valid values, which
224 // means that error thresholds cannot be active
225 bMatch = FALSE;
226 }
227 else
228 {
229 switch(m_iOperation)
230 {
231 case OP_LE: // Less
232 switch(iDataType)
233 {
234 case DCI_DT_INT:
235 bMatch = ((LONG)fvalue < (LONG)m_value);
236 break;
237 case DCI_DT_UINT:
238 bMatch = ((DWORD)fvalue < (DWORD)m_value);
239 break;
240 case DCI_DT_INT64:
241 bMatch = ((INT64)fvalue < (INT64)m_value);
242 break;
243 case DCI_DT_UINT64:
244 bMatch = ((QWORD)fvalue < (QWORD)m_value);
245 break;
246 case DCI_DT_FLOAT:
247 bMatch = ((double)fvalue < (double)m_value);
248 break;
249 }
250 break;
251 case OP_LE_EQ: // Less or equal
252 switch(iDataType)
253 {
254 case DCI_DT_INT:
255 bMatch = ((LONG)fvalue <= (LONG)m_value);
256 break;
257 case DCI_DT_UINT:
258 bMatch = ((DWORD)fvalue <= (DWORD)m_value);
259 break;
260 case DCI_DT_INT64:
261 bMatch = ((INT64)fvalue <= (INT64)m_value);
262 break;
263 case DCI_DT_UINT64:
264 bMatch = ((QWORD)fvalue <= (QWORD)m_value);
265 break;
266 case DCI_DT_FLOAT:
267 bMatch = ((double)fvalue <= (double)m_value);
268 break;
269 }
270 break;
271 case OP_EQ: // Equal
272 switch(iDataType)
273 {
274 case DCI_DT_INT:
275 bMatch = ((LONG)fvalue == (LONG)m_value);
276 break;
277 case DCI_DT_UINT:
278 bMatch = ((DWORD)fvalue == (DWORD)m_value);
279 break;
280 case DCI_DT_INT64:
281 bMatch = ((INT64)fvalue == (INT64)m_value);
282 break;
283 case DCI_DT_UINT64:
284 bMatch = ((QWORD)fvalue == (QWORD)m_value);
285 break;
286 case DCI_DT_FLOAT:
287 bMatch = ((double)fvalue == (double)m_value);
288 break;
289 case DCI_DT_STRING:
290 bMatch = !strcmp(fvalue.String(), m_value.String());
291 break;
292 }
293 break;
294 case OP_GT_EQ: // Greater or equal
295 switch(iDataType)
296 {
297 case DCI_DT_INT:
298 bMatch = ((LONG)fvalue >= (LONG)m_value);
299 break;
300 case DCI_DT_UINT:
301 bMatch = ((DWORD)fvalue >= (DWORD)m_value);
302 break;
303 case DCI_DT_INT64:
304 bMatch = ((INT64)fvalue >= (INT64)m_value);
305 break;
306 case DCI_DT_UINT64:
307 bMatch = ((QWORD)fvalue >= (QWORD)m_value);
308 break;
309 case DCI_DT_FLOAT:
310 bMatch = ((double)fvalue >= (double)m_value);
311 break;
312 }
313 break;
314 case OP_GT: // Greater
315 switch(iDataType)
316 {
317 case DCI_DT_INT:
318 bMatch = ((LONG)fvalue > (LONG)m_value);
319 break;
320 case DCI_DT_UINT:
321 bMatch = ((DWORD)fvalue > (DWORD)m_value);
322 break;
323 case DCI_DT_INT64:
324 bMatch = ((INT64)fvalue > (INT64)m_value);
325 break;
326 case DCI_DT_UINT64:
327 bMatch = ((QWORD)fvalue > (QWORD)m_value);
328 break;
329 case DCI_DT_FLOAT:
330 bMatch = ((double)fvalue > (double)m_value);
331 break;
332 }
333 break;
334 case OP_NE: // Not equal
335 switch(iDataType)
336 {
337 case DCI_DT_INT:
338 bMatch = ((LONG)fvalue != (LONG)m_value);
339 break;
340 case DCI_DT_UINT:
341 bMatch = ((DWORD)fvalue != (DWORD)m_value);
342 break;
343 case DCI_DT_INT64:
344 bMatch = ((INT64)fvalue != (INT64)m_value);
345 break;
346 case DCI_DT_UINT64:
347 bMatch = ((QWORD)fvalue != (QWORD)m_value);
348 break;
349 case DCI_DT_FLOAT:
350 bMatch = ((double)fvalue != (double)m_value);
351 break;
352 case DCI_DT_STRING:
353 bMatch = strcmp(fvalue.String(), m_value.String());
354 break;
355 }
356 break;
357 case OP_LIKE:
358 // This operation can be performed only on strings
359 if (m_iDataType == DCI_DT_STRING)
360 bMatch = MatchString(m_value.String(), fvalue.String(), TRUE);
361 break;
362 case OP_NOTLIKE:
363 // This operation can be performed only on strings
364 if (m_iDataType == DCI_DT_STRING)
365 bMatch = !MatchString(m_value.String(), fvalue.String(), TRUE);
366 break;
367 default:
368 break;
369 }
370 }
371
372 iResult = (bMatch & !m_bIsReached) ? THRESHOLD_REACHED :
373 ((!bMatch & m_bIsReached) ? THRESHOLD_REARMED : NO_ACTION);
374 m_bIsReached = bMatch;
375 if (iResult != NO_ACTION)
376 {
377 TCHAR szQuery[256];
378
379 // Update threshold status in database
380 _sntprintf(szQuery, 256,
381 _T("UPDATE thresholds SET current_state=%d WHERE threshold_id=%d"),
382 m_bIsReached, m_dwId);
383 QueueSQLRequest(szQuery);
384 }
385 return iResult;
386 }
387
388
389 //
390 // Check for collection error thresholds
391 // Return same values as Check()
392 //
393
394 int Threshold::CheckError(DWORD dwErrorCount)
395 {
396 int nResult;
397 BOOL bMatch;
398
399 if (m_iFunction != F_ERROR)
400 return NO_ACTION;
401
402 bMatch = ((DWORD)m_iParam1 <= dwErrorCount);
403 nResult = (bMatch & !m_bIsReached) ? THRESHOLD_REACHED :
404 ((!bMatch & m_bIsReached) ? THRESHOLD_REARMED : NO_ACTION);
405 m_bIsReached = bMatch;
406 if (nResult != NO_ACTION)
407 {
408 TCHAR szQuery[256];
409
410 // Update threshold status in database
411 _sntprintf(szQuery, 256,
412 _T("UPDATE thresholds SET current_state=%d WHERE threshold_id=%d"),
413 m_bIsReached, m_dwId);
414 QueueSQLRequest(szQuery);
415 }
416 return nResult;
417 }
418
419
420 //
421 // Fill DCI_THRESHOLD with object's data ready to send over the network
422 //
423
424 void Threshold::CreateMessage(DCI_THRESHOLD *pData)
425 {
426 pData->dwId = htonl(m_dwId);
427 pData->dwEvent = htonl(m_dwEventCode);
428 pData->dwRearmEvent = htonl(m_dwRearmEventCode);
429 pData->wFunction = htons((WORD)m_iFunction);
430 pData->wOperation = htons((WORD)m_iOperation);
431 pData->dwArg1 = htonl(m_iParam1);
432 pData->dwArg2 = htonl(m_iParam2);
433 pData->nRepeatInterval = htonl(m_nRepeatInterval);
434 switch(m_iDataType)
435 {
436 case DCI_DT_INT:
437 pData->value.dwInt32 = htonl((LONG)m_value);
438 break;
439 case DCI_DT_UINT:
440 pData->value.dwInt32 = htonl((DWORD)m_value);
441 break;
442 case DCI_DT_INT64:
443 pData->value.qwInt64 = htonq((INT64)m_value);
444 break;
445 case DCI_DT_UINT64:
446 pData->value.qwInt64 = htonq((QWORD)m_value);
447 break;
448 case DCI_DT_FLOAT:
449 pData->value.dFloat = htond((double)m_value);
450 break;
451 case DCI_DT_STRING:
452 #ifdef UNICODE
453 #ifdef UNICODE_UCS4
454 ucs4_to_ucs2(m_value.String(), -1, pData->value.szString, MAX_DCI_STRING_VALUE);
455 #else
456 wcscpy(pData->value.szString, m_value.String());
457 #endif
458 #else
459 mb_to_ucs2(m_value.String(), -1, pData->value.szString, MAX_DCI_STRING_VALUE);
460 #endif
461 SwapWideString(pData->value.szString);
462 break;
463 default:
464 break;
465 }
466 }
467
468
469 //
470 // Update threshold object from DCI_THRESHOLD structure
471 //
472
473 void Threshold::UpdateFromMessage(DCI_THRESHOLD *pData)
474 {
475 #ifndef UNICODE_UCS2
476 TCHAR szBuffer[MAX_DCI_STRING_VALUE];
477 #endif
478
479 m_dwEventCode = ntohl(pData->dwEvent);
480 m_dwRearmEventCode = ntohl(pData->dwRearmEvent);
481 m_iFunction = (BYTE)ntohs(pData->wFunction);
482 m_iOperation = (BYTE)ntohs(pData->wOperation);
483 m_iParam1 = ntohl(pData->dwArg1);
484 m_iParam2 = ntohl(pData->dwArg2);
485 m_nRepeatInterval = ntohl(pData->nRepeatInterval);
486 switch(m_iDataType)
487 {
488 case DCI_DT_INT:
489 m_value = (LONG)ntohl(pData->value.dwInt32);
490 break;
491 case DCI_DT_UINT:
492 m_value = (DWORD)ntohl(pData->value.dwInt32);
493 break;
494 case DCI_DT_INT64:
495 m_value = (INT64)ntohq(pData->value.qwInt64);
496 break;
497 case DCI_DT_UINT64:
498 m_value = (QWORD)ntohq(pData->value.qwInt64);
499 break;
500 case DCI_DT_FLOAT:
501 m_value = ntohd(pData->value.dFloat);
502 break;
503 case DCI_DT_STRING:
504 SwapWideString(pData->value.szString);
505 #ifdef UNICODE
506 #ifdef UNICODE_UCS4
507 ucs2_to_ucs4(pData->value.szString, -1, szBuffer, MAX_DCI_STRING_VALUE);
508 m_value = szBuffer;
509 #else
510 m_value = pData->value.szString;
511 #endif
512 #else
513 ucs2_to_mb(pData->value.szString, -1, szBuffer, MAX_DCI_STRING_VALUE);
514 m_value = szBuffer;
515 #endif
516 break;
517 default:
518 DbgPrintf(3, "WARNING: Invalid datatype %d in threshold object %d", m_iDataType, m_dwId);
519 break;
520 }
521 }
522
523
524 //
525 // Calculate average value for parameter
526 //
527
528 #define CALC_AVG_VALUE(vtype) \
529 { \
530 vtype var; \
531 var = (vtype)lastValue; \
532 for(i = 1, nValueCount = 1; i < m_iParam1; i++) \
533 { \
534 if (ppPrevValues[i - 1]->GetTimeStamp() != 1) \
535 { \
536 var += (vtype)(*ppPrevValues[i - 1]); \
537 nValueCount++; \
538 } \
539 } \
540 *pResult = var / (vtype)nValueCount; \
541 }
542
543 void Threshold::CalculateAverageValue(ItemValue *pResult, ItemValue &lastValue, ItemValue **ppPrevValues)
544 {
545 int i, nValueCount;
546
547 switch(m_iDataType)
548 {
549 case DCI_DT_INT:
550 CALC_AVG_VALUE(LONG);
551 break;
552 case DCI_DT_UINT:
553 CALC_AVG_VALUE(DWORD);
554 break;
555 case DCI_DT_INT64:
556 CALC_AVG_VALUE(INT64);
557 break;
558 case DCI_DT_UINT64:
559 CALC_AVG_VALUE(QWORD);
560 break;
561 case DCI_DT_FLOAT:
562 CALC_AVG_VALUE(double);
563 break;
564 case DCI_DT_STRING:
565 *pResult = _T(""); // Average value for string is meaningless
566 break;
567 default:
568 break;
569 }
570 }
571
572
573 //
574 // Calculate mean absolute deviation for parameter
575 //
576
577 #define CALC_MD_VALUE(vtype) \
578 { \
579 vtype mean, dev; \
580 mean = (vtype)lastValue; \
581 for(i = 1, nValueCount = 1; i < m_iParam1; i++) \
582 { \
583 if (ppPrevValues[i - 1]->GetTimeStamp() != 1) \
584 { \
585 mean += (vtype)(*ppPrevValues[i - 1]); \
586 nValueCount++; \
587 } \
588 } \
589 mean /= (vtype)nValueCount; \
590 dev = ABS((vtype)lastValue - mean); \
591 for(i = 1, nValueCount = 1; i < m_iParam1; i++) \
592 { \
593 if (ppPrevValues[i - 1]->GetTimeStamp() != 1) \
594 { \
595 dev += ABS((vtype)(*ppPrevValues[i - 1]) - mean); \
596 nValueCount++; \
597 } \
598 } \
599 *pResult = dev / (vtype)nValueCount; \
600 }
601
602 void Threshold::CalculateMDValue(ItemValue *pResult, ItemValue &lastValue, ItemValue **ppPrevValues)
603 {
604 int i, nValueCount;
605
606 switch(m_iDataType)
607 {
608 case DCI_DT_INT:
609 #define ABS(x) ((x) < 0 ? -(x) : (x))
610 CALC_MD_VALUE(LONG);
611 break;
612 case DCI_DT_INT64:
613 CALC_MD_VALUE(INT64);
614 break;
615 case DCI_DT_FLOAT:
616 CALC_MD_VALUE(double);
617 break;
618 case DCI_DT_UINT:
619 #undef ABS
620 #define ABS(x) (x)
621 CALC_MD_VALUE(DWORD);
622 break;
623 case DCI_DT_UINT64:
624 CALC_MD_VALUE(QWORD);
625 break;
626 case DCI_DT_STRING:
627 *pResult = _T(""); // Mean deviation for string is meaningless
628 break;
629 default:
630 break;
631 }
632 }
633
634 #undef ABS
635
636
637 //
638 // Calculate difference between last and previous value
639 //
640
641 void Threshold::CalculateDiff(ItemValue *pResult, ItemValue &lastValue, ItemValue **ppPrevValues)
642 {
643 CalculateItemValueDiff(*pResult, m_iDataType, lastValue, *ppPrevValues[0]);
644 }
645
646
647 //
648 // Compare to another threshold
649 //
650
651 BOOL Threshold::Compare(Threshold *pThr)
652 {
653 BOOL bMatch;
654
655 switch(m_iDataType)
656 {
657 case DCI_DT_INT:
658 bMatch = ((LONG)pThr->m_value == (LONG)m_value);
659 break;
660 case DCI_DT_UINT:
661 bMatch = ((DWORD)pThr->m_value == (DWORD)m_value);
662 break;
663 case DCI_DT_INT64:
664 bMatch = ((INT64)pThr->m_value == (INT64)m_value);
665 break;
666 case DCI_DT_UINT64:
667 bMatch = ((QWORD)pThr->m_value == (QWORD)m_value);
668 break;
669 case DCI_DT_FLOAT:
670 bMatch = ((double)pThr->m_value == (double)m_value);
671 break;
672 case DCI_DT_STRING:
673 bMatch = !strcmp(pThr->m_value.String(), m_value.String());
674 break;
675 default:
676 bMatch = TRUE;
677 break;
678 }
679 return bMatch &&
680 (pThr->m_dwEventCode == m_dwEventCode) &&
681 (pThr->m_dwRearmEventCode == m_dwRearmEventCode) &&
682 (pThr->m_iDataType == m_iDataType) &&
683 (pThr->m_iFunction == m_iFunction) &&
684 (pThr->m_iOperation == m_iOperation) &&
685 (pThr->m_iParam1 == m_iParam1) &&
686 (pThr->m_iParam2 == m_iParam2) &&
687 (pThr->m_nRepeatInterval == m_nRepeatInterval);
688 }
689
690
691 //
692 // Create management pack record
693 //
694
695 void Threshold::CreateNXMPRecord(String &str)
696 {
697 TCHAR szEvent1[MAX_EVENT_NAME], szEvent2[MAX_EVENT_NAME];
698 String strValue;
699
700 strValue = (TCHAR *)m_value.String();
701 ResolveEventName(m_dwEventCode, szEvent1);
702 ResolveEventName(m_dwRearmEventCode, szEvent2);
703 str.AddFormattedString(_T("\t\t\t\t\t@THRESHOLD\n\t\t\t\t\t{\n")
704 _T("\t\t\t\t\t\tFUNCTION=%d;\n")
705 _T("\t\t\t\t\t\tCONDITION=%d;\n")
706 _T("\t\t\t\t\t\tVALUE=\"%s\";\n")
707 _T("\t\t\t\t\t\tACTIVATION_EVENT=\"%s\";\n")
708 _T("\t\t\t\t\t\tDEACTIVATION_EVENT=\"%s\";\n")
709 _T("\t\t\t\t\t\tPARAM1=%d;\n")
710 _T("\t\t\t\t\t\tPARAM2=%d;\n")
711 _T("\t\t\t\t\t\tREPEAT_INTERVAL=%d;\n")
712 _T("\t\t\t\t\t}\n"),
713 m_iFunction, m_iOperation, (TCHAR *)strValue,
714 szEvent1, szEvent2, m_iParam1, m_iParam2,
715 m_nRepeatInterval);
716 }
717
718
719 //
720 // Made an association with DCI (used by management pack parser)
721 //
722
723 void Threshold::Associate(DCItem *pItem)
724 {
725 m_dwItemId = pItem->Id();
726 m_iDataType = pItem->DataType();
727 }