e31625167b8d57e39812cfeae3c1ce1200fc8204
[public/netxms.git] / src / server / include / nms_dcoll.h
1 /*
2 ** NetXMS - Network Management System
3 ** Copyright (C) 2003-2012 Victor Kirhenshtein
4 **
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.
9 **
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.
14 **
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.
18 **
19 ** File: nms_dcoll.h
20 **
21 **/
22
23 #ifndef _nms_dcoll_h_
24 #define _nms_dcoll_h_
25
26
27 //
28 // Data collection errors
29 //
30
31 #define DCE_SUCCESS 0
32 #define DCE_COMM_ERROR 1
33 #define DCE_NOT_SUPPORTED 2
34
35 /**
36 * Threshold check results
37 */
38 #define THRESHOLD_REACHED 0
39 #define THRESHOLD_REARMED 1
40 #define NO_ACTION 2
41
42 /**
43 * DCI value
44 */
45 class NXCORE_EXPORTABLE ItemValue
46 {
47 private:
48 double m_dFloat;
49 LONG m_iInt32;
50 INT64 m_iInt64;
51 DWORD m_dwInt32;
52 QWORD m_qwInt64;
53 TCHAR m_szString[MAX_DB_STRING];
54 DWORD m_dwTimeStamp;
55
56 public:
57 ItemValue();
58 ItemValue(const TCHAR *pszValue, DWORD dwTimeStamp);
59 ItemValue(const ItemValue *pValue);
60 ~ItemValue();
61
62 void setTimeStamp(DWORD dwTime) { m_dwTimeStamp = dwTime; }
63 DWORD getTimeStamp() { return m_dwTimeStamp; }
64
65 const TCHAR *getString() { return m_szString; }
66
67 operator double() { return m_dFloat; }
68 operator DWORD() { return m_dwInt32; }
69 operator QWORD() { return m_qwInt64; }
70 operator LONG() { return m_iInt32; }
71 operator INT64() { return m_iInt64; }
72 operator const TCHAR*() const { return m_szString; }
73
74 const ItemValue& operator=(const ItemValue &src);
75 const ItemValue& operator=(const TCHAR *pszStr);
76 const ItemValue& operator=(double dFloat);
77 const ItemValue& operator=(LONG iInt32);
78 const ItemValue& operator=(INT64 iInt64);
79 const ItemValue& operator=(DWORD dwInt32);
80 const ItemValue& operator=(QWORD qwInt64);
81 };
82
83
84 class DCItem;
85
86 /**
87 * Threshold definition class
88 */
89 class NXCORE_EXPORTABLE Threshold
90 {
91 private:
92 DWORD m_id; // Unique threshold id
93 DWORD m_itemId; // Related item id
94 DWORD m_eventCode; // Event code to be generated
95 DWORD m_rearmEventCode;
96 ItemValue m_value;
97 BYTE m_function; // Function code
98 BYTE m_operation; // Comparision operation code
99 BYTE m_dataType; // Related item data type
100 BYTE m_currentSeverity; // Current everity (NORMAL if threshold is inactive)
101 int m_param1; // Function's parameter #1
102 int m_param2; // Function's parameter #2
103 BOOL m_isReached;
104 int m_numMatches; // Number of consecutive matches
105 int m_repeatInterval; // -1 = default, 0 = off, >0 = seconds between repeats
106 time_t m_lastEventTimestamp;
107
108 const ItemValue& value() { return m_value; }
109 void calculateAverageValue(ItemValue *pResult, ItemValue &lastValue, ItemValue **ppPrevValues);
110 void calculateSumValue(ItemValue *pResult, ItemValue &lastValue, ItemValue **ppPrevValues);
111 void calculateMDValue(ItemValue *pResult, ItemValue &lastValue, ItemValue **ppPrevValues);
112 void calculateDiff(ItemValue *pResult, ItemValue &lastValue, ItemValue **ppPrevValues);
113
114 public:
115 Threshold();
116 Threshold(DCItem *pRelatedItem);
117 Threshold(Threshold *pSrc);
118 Threshold(DB_RESULT hResult, int iRow, DCItem *pRelatedItem);
119 Threshold(ConfigEntry *config, DCItem *parentItem);
120 ~Threshold();
121
122 void bindToItem(DWORD dwItemId) { m_itemId = dwItemId; }
123
124 DWORD getId() { return m_id; }
125 DWORD getEventCode() { return m_eventCode; }
126 DWORD getRearmEventCode() { return m_rearmEventCode; }
127 int getFunction() { return m_function; }
128 int getOperation() { return m_operation; }
129 int getParam1() { return m_param1; }
130 int getParam2() { return m_param2; }
131 const TCHAR *getStringValue() { return m_value.getString(); }
132 BOOL isReached() { return m_isReached; }
133
134 int getRepeatInterval() { return m_repeatInterval; }
135 time_t getLastEventTimestamp() { return m_lastEventTimestamp; }
136 int getCurrentSeverity() { return m_currentSeverity; }
137 void markLastEvent(int severity);
138
139 BOOL saveToDB(DB_HANDLE hdb, DWORD dwIndex);
140 int check(ItemValue &value, ItemValue **ppPrevValues, ItemValue &fvalue);
141 int checkError(DWORD dwErrorCount);
142
143 void createMessage(CSCPMessage *msg, DWORD baseId);
144 void updateFromMessage(CSCPMessage *msg, DWORD baseId);
145
146 void createId();
147 DWORD getRequiredCacheSize() { return ((m_function == F_LAST) || (m_function == F_ERROR)) ? 0 : m_param1; }
148
149 BOOL compare(Threshold *pThr);
150
151 void createNXMPRecord(String &str, int index);
152
153 void associate(DCItem *pItem);
154 void setFunction(int nFunc) { m_function = nFunc; }
155 void setOperation(int nOp) { m_operation = nOp; }
156 void setEvent(DWORD dwEvent) { m_eventCode = dwEvent; }
157 void setRearmEvent(DWORD dwEvent) { m_rearmEventCode = dwEvent; }
158 void setParam1(int nVal) { m_param1 = nVal; }
159 void setParam2(int nVal) { m_param2 = nVal; }
160 void setValue(const TCHAR *value) { m_value = value; }
161 };
162
163 class Template;
164
165 /**
166 * Generic data collection object
167 */
168 class NXCORE_EXPORTABLE DCObject
169 {
170 protected:
171 DWORD m_dwId;
172 TCHAR m_szName[MAX_ITEM_NAME];
173 TCHAR m_szDescription[MAX_DB_STRING];
174 TCHAR m_systemTag[MAX_DB_STRING];
175 time_t m_tLastPoll; // Last poll time
176 int m_iPollingInterval; // Polling interval in seconds
177 int m_iRetentionTime; // Retention time in seconds
178 BYTE m_source; // origin: SNMP, agent, etc.
179 BYTE m_status; // Item status: active, disabled or not supported
180 BYTE m_busy; // 1 when item is queued for polling, 0 if not
181 BYTE m_scheduledForDeletion; // 1 when item is scheduled for deletion, 0 if not
182 WORD m_flags;
183 DWORD m_dwTemplateId; // Related template's id
184 DWORD m_dwTemplateItemId; // Related template item's id
185 Template *m_pNode; // Pointer to node or template object this item related to
186 MUTEX m_hMutex;
187 DWORD m_dwNumSchedules;
188 TCHAR **m_ppScheduleList;
189 time_t m_tLastCheck; // Last schedule checking time
190 DWORD m_dwErrorCount; // Consequtive collection error count
191 DWORD m_dwResourceId; // Associated cluster resource ID
192 DWORD m_dwProxyNode; // Proxy node ID or 0 to disable
193 WORD m_snmpPort; // Custom SNMP port or 0 for node default
194 TCHAR *m_pszPerfTabSettings;
195
196 void lock() { MutexLock(m_hMutex); }
197 void unlock() { MutexUnlock(m_hMutex); }
198
199 BOOL loadCustomSchedules();
200
201 bool matchClusterResource();
202
203 void expandMacros(const TCHAR *src, TCHAR *dst, size_t dstLen);
204
205 virtual bool isCacheLoaded();
206
207 // --- constructors ---
208 DCObject();
209 DCObject(const DCObject *src);
210 DCObject(DWORD dwId, const TCHAR *szName, int iSource, int iPollingInterval, int iRetentionTime, Template *pNode,
211 const TCHAR *pszDescription = NULL, const TCHAR *systemTag = NULL);
212 DCObject(ConfigEntry *config, Template *owner);
213
214 public:
215 virtual ~DCObject();
216
217 virtual int getType() const { return DCO_TYPE_GENERIC; }
218
219 virtual void updateFromTemplate(DCObject *dcObject);
220
221 virtual BOOL saveToDB(DB_HANDLE hdb);
222 virtual void deleteFromDB();
223 virtual bool loadThresholdsFromDB();
224
225 virtual void processNewValue(time_t nTimeStamp, void *value);
226 virtual void processNewError();
227
228 virtual bool hasValue();
229
230 DWORD getId() { return m_dwId; }
231 int getDataSource() { return m_source; }
232 int getStatus() { return m_status; }
233 const TCHAR *getName() { return m_szName; }
234 const TCHAR *getDescription() { return m_szDescription; }
235 const TCHAR *getSystemTag() { return m_systemTag; }
236 const TCHAR *getPerfTabSettings() { return m_pszPerfTabSettings; }
237 Template *getTarget() { return m_pNode; }
238 DWORD getTemplateId() { return m_dwTemplateId; }
239 DWORD getTemplateItemId() { return m_dwTemplateItemId; }
240 DWORD getResourceId() { return m_dwResourceId; }
241 DWORD getProxyNode() { return m_dwProxyNode; }
242 time_t getLastPollTime() { return m_tLastPoll; }
243 DWORD getErrorCount() { return m_dwErrorCount; }
244 WORD getSnmpPort() { return m_snmpPort; }
245
246 bool isReadyForPolling(time_t currTime);
247 bool isScheduledForDeletion() { return m_scheduledForDeletion ? true : false; }
248 void setLastPollTime(time_t tLastPoll) { m_tLastPoll = tLastPoll; }
249 void setStatus(int status, bool generateEvent);
250 void setBusyFlag(BOOL busy) { m_busy = (BYTE)busy; }
251 void setTemplateId(DWORD dwTemplateId, DWORD dwItemId)
252 { m_dwTemplateId = dwTemplateId; m_dwTemplateItemId = dwItemId; }
253
254 virtual void createMessage(CSCPMessage *pMsg);
255 virtual void updateFromMessage(CSCPMessage *pMsg);
256
257 virtual void changeBinding(DWORD dwNewId, Template *pNode, BOOL doMacroExpansion);
258
259 virtual void deleteExpiredData();
260 virtual bool deleteAllData();
261
262 virtual void getEventList(DWORD **ppdwList, DWORD *pdwSize);
263 virtual void createNXMPRecord(String &str);
264
265 void setName(const TCHAR *pszName) { nx_strncpy(m_szName, pszName, MAX_ITEM_NAME); }
266 void setDescription(const TCHAR *pszDescr) { nx_strncpy(m_szDescription, pszDescr, MAX_DB_STRING); }
267 void setOrigin(int origin) { m_source = origin; }
268 void setRetentionTime(int nTime) { m_iRetentionTime = nTime; }
269 void setInterval(int nInt) { m_iPollingInterval = nInt; }
270 void setAdvScheduleFlag(BOOL bFlag) { if (bFlag) m_flags |= DCF_ADVANCED_SCHEDULE; else m_flags &= ~DCF_ADVANCED_SCHEDULE; }
271 void addSchedule(const TCHAR *pszSchedule);
272
273 bool prepareForDeletion();
274
275 private:
276 BOOL matchSchedule(struct tm *pCurrTime, TCHAR *pszSchedule, BOOL *bWithSeconds, time_t currTimestamp);
277 };
278
279 /**
280 * Data collection item class
281 */
282 class NXCORE_EXPORTABLE DCItem : public DCObject
283 {
284 protected:
285 TCHAR m_instance[MAX_DB_STRING];
286 BYTE m_deltaCalculation; // Delta calculation method
287 BYTE m_dataType;
288 ObjectArray<Threshold> *m_thresholds;
289 TCHAR *m_transformerSource; // Transformation script (source code)
290 NXSL_Program *m_transformer; // Compiled transformation script
291 DWORD m_dwCacheSize; // Number of items in cache
292 ItemValue **m_ppValueCache;
293 ItemValue m_prevRawValue; // Previous raw value (used for delta calculation)
294 time_t m_tPrevValueTimeStamp;
295 bool m_bCacheLoaded;
296 int m_nBaseUnits;
297 int m_nMultiplier;
298 TCHAR *m_customUnitName;
299 WORD m_snmpRawValueType; // Actual SNMP raw value type for input transformation
300 WORD m_instanceDiscoveryMethod;
301 TCHAR *m_instanceDiscoveryData;
302 TCHAR *m_instanceFilterSource;
303 NXSL_Program *m_instanceFilter;
304
305 void transform(ItemValue &value, time_t nElapsedTime);
306 void checkThresholds(ItemValue &value);
307 void clearCache();
308
309 virtual bool isCacheLoaded();
310
311 public:
312 DCItem();
313 DCItem(const DCItem *pItem);
314 DCItem(DB_RESULT hResult, int iRow, Template *pNode);
315 DCItem(DWORD dwId, const TCHAR *szName, int iSource, int iDataType,
316 int iPollingInterval, int iRetentionTime, Template *pNode,
317 const TCHAR *pszDescription = NULL, const TCHAR *systemTag = NULL);
318 DCItem(ConfigEntry *config, Template *owner);
319 virtual ~DCItem();
320
321 virtual int getType() const { return DCO_TYPE_ITEM; }
322
323 virtual void updateFromTemplate(DCObject *dcObject);
324
325 virtual BOOL saveToDB(DB_HANDLE hdb);
326 virtual void deleteFromDB();
327 virtual bool loadThresholdsFromDB();
328
329 void updateCacheSize(DWORD dwCondId = 0);
330
331 int getDataType() { return m_dataType; }
332 bool isInterpretSnmpRawValue() { return (m_flags & DCF_RAW_VALUE_OCTET_STRING) ? true : false; }
333 WORD getSnmpRawValueType() { return m_snmpRawValueType; }
334 bool hasActiveThreshold();
335 WORD getInstanceDiscoveryMethod() { return m_instanceDiscoveryMethod; }
336 const TCHAR *getInstanceDiscoveryData() { return m_instanceDiscoveryData; }
337 NXSL_Program *getInstanceFilter() { return m_instanceFilter; }
338 const TCHAR *getInstance() { return m_instance; }
339
340 void filterInstanceList(StringList *instances);
341 void expandInstance();
342
343 void processNewValue(time_t nTimeStamp, void *value);
344 void processNewError();
345
346 virtual bool hasValue();
347
348 void getLastValue(CSCPMessage *pMsg, DWORD dwId);
349 NXSL_Value *getValueForNXSL(int nFunction, int nPolls);
350
351 virtual void createMessage(CSCPMessage *pMsg);
352 void updateFromMessage(CSCPMessage *pMsg, DWORD *pdwNumMaps, DWORD **ppdwMapIndex, DWORD **ppdwMapId);
353 void fillMessageWithThresholds(CSCPMessage *msg);
354
355 virtual void changeBinding(DWORD dwNewId, Template *pNode, BOOL doMacroExpansion);
356
357 virtual void deleteExpiredData();
358 virtual bool deleteAllData();
359
360 virtual void getEventList(DWORD **ppdwList, DWORD *pdwSize);
361 virtual void createNXMPRecord(String &str);
362
363 int getThresholdCount() const { return (m_thresholds != NULL) ? m_thresholds->size() : 0; }
364 BOOL enumThresholds(BOOL (* pfCallback)(Threshold *, DWORD, void *), void *pArg);
365
366 void setInstance(const TCHAR *instance) { nx_strncpy(m_instance, instance, MAX_DB_STRING); }
367 void setDataType(int dataType) { m_dataType = dataType; }
368 void setDeltaCalcMethod(int method) { m_deltaCalculation = method; }
369 void setAllThresholdsFlag(BOOL bFlag) { if (bFlag) m_flags |= DCF_ALL_THRESHOLDS; else m_flags &= ~DCF_ALL_THRESHOLDS; }
370 void addThreshold(Threshold *pThreshold);
371 void deleteAllThresholds();
372 void setTransformationScript(const TCHAR *pszScript);
373 void setInstanceDiscoveryMethod(WORD method) { m_instanceDiscoveryMethod = method; }
374 void setInstanceDiscoveryData(const TCHAR *data) { safe_free(m_instanceDiscoveryData); m_instanceDiscoveryData = (data != NULL) ? _tcsdup(data) : NULL; }
375 void setInstanceFilter(const TCHAR *pszScript);
376
377 BOOL testTransformation(const TCHAR *script, const TCHAR *value, TCHAR *buffer, size_t bufSize);
378 };
379
380 /**
381 * Table column definition
382 */
383 class NXCORE_EXPORTABLE DCTableColumn
384 {
385 private:
386 TCHAR m_name[MAX_COLUMN_NAME];
387 int m_dataType;
388 SNMP_ObjectId *m_snmpOid;
389 TCHAR *m_scriptSource;
390 NXSL_Program *m_script;
391
392 public:
393 DCTableColumn(const DCTableColumn *src);
394 DCTableColumn(CSCPMessage *msg, DWORD baseId);
395 DCTableColumn(DB_RESULT hResult, int row);
396 ~DCTableColumn();
397
398 void setTransformationScript(const TCHAR *script);
399
400 const TCHAR *getName() { return m_name; }
401 int getDataType() { return m_dataType; }
402 SNMP_ObjectId *getSnmpOid() { return m_snmpOid; }
403 const TCHAR *getScriptSource() { return m_scriptSource; }
404 };
405
406
407 //
408 // Table column ID hash entry
409 //
410
411 struct TC_ID_MAP_ENTRY
412 {
413 LONG id;
414 TCHAR name[MAX_COLUMN_NAME];
415 };
416
417
418 //
419 // Tabular data collection object
420 //
421
422 class NXCORE_EXPORTABLE DCTable : public DCObject
423 {
424 protected:
425 TCHAR m_instanceColumn[MAX_COLUMN_NAME];
426 ObjectArray<DCTableColumn> *m_columns;
427 Table *m_lastValue;
428
429 static TC_ID_MAP_ENTRY *m_cache;
430 static int m_cacheSize;
431 static int m_cacheAllocated;
432 static MUTEX m_cacheMutex;
433
434 public:
435 DCTable();
436 DCTable(const DCTable *src);
437 DCTable(DWORD id, const TCHAR *name, int source, int pollingInterval, int retentionTime,
438 Template *node, const TCHAR *instanceColumn = NULL, const TCHAR *description = NULL, const TCHAR *systemTag = NULL);
439 DCTable(DB_RESULT hResult, int iRow, Template *pNode);
440 virtual ~DCTable();
441
442 virtual int getType() const { return DCO_TYPE_TABLE; }
443
444 virtual BOOL saveToDB(DB_HANDLE hdb);
445 virtual void deleteFromDB();
446
447 virtual void processNewValue(time_t nTimeStamp, void *value);
448 virtual void processNewError();
449
450 virtual void createMessage(CSCPMessage *pMsg);
451 virtual void updateFromMessage(CSCPMessage *pMsg);
452
453 virtual void deleteExpiredData();
454 virtual bool deleteAllData();
455
456 void getLastValue(CSCPMessage *msg);
457 void getLastValueSummary(CSCPMessage *pMsg, DWORD dwId);
458
459 LONG getInstanceColumnId();
460
461 static LONG columnIdFromName(const TCHAR *name);
462 };
463
464
465 //
466 // Functions
467 //
468
469 BOOL InitDataCollector();
470 void DeleteAllItemsForNode(DWORD dwNodeId);
471 void WriteFullParamListToMessage(CSCPMessage *pMsg, WORD flags);
472
473 void CalculateItemValueDiff(ItemValue &result, int nDataType,
474 ItemValue &value1, ItemValue &value2);
475 void CalculateItemValueAverage(ItemValue &result, int nDataType,
476 int nNumValues, ItemValue **ppValueList);
477 void CalculateItemValueMD(ItemValue &result, int nDataType,
478 int nNumValues, ItemValue **ppValueList);
479
480
481 //
482 // Variables
483 //
484
485 extern double g_dAvgPollerQueueSize;
486 extern double g_dAvgDBWriterQueueSize;
487 extern double g_dAvgIDataWriterQueueSize;
488 extern double g_dAvgDBAndIDataWriterQueueSize;
489 extern double g_dAvgStatusPollerQueueSize;
490 extern double g_dAvgConfigPollerQueueSize;
491 extern DWORD g_dwAvgDCIQueuingTime;
492
493
494 #endif /* _nms_dcoll_h_ */