Dimension.h 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. // SPDX-License-Identifier: GPL-3.0-or-later
  2. #ifndef ML_DIMENSION_H
  3. #define ML_DIMENSION_H
  4. #include "BitBufferCounter.h"
  5. #include "Config.h"
  6. #include "ml-private.h"
  7. namespace ml {
  8. class RrdDimension {
  9. public:
  10. RrdDimension(RRDDIM *RD) : RD(RD), Ops(&RD->tiers[0]->query_ops) { }
  11. RRDDIM *getRD() const { return RD; }
  12. time_t latestTime() { return Ops->latest_time(RD->tiers[0]->db_metric_handle); }
  13. time_t oldestTime() { return Ops->oldest_time(RD->tiers[0]->db_metric_handle); }
  14. unsigned updateEvery() const { return RD->update_every; }
  15. const std::string getID() const {
  16. RRDSET *RS = RD->rrdset;
  17. std::stringstream SS;
  18. SS << RS->context << "|" << RS->id << "|" << RD->name;
  19. return SS.str();
  20. }
  21. bool isActive() const {
  22. if (rrdset_flag_check(RD->rrdset, RRDSET_FLAG_OBSOLETE))
  23. return false;
  24. if (rrddim_flag_check(RD, RRDDIM_FLAG_OBSOLETE))
  25. return false;
  26. return true;
  27. }
  28. void setAnomalyRateRD(RRDDIM *ARRD) { AnomalyRateRD = ARRD; }
  29. RRDDIM *getAnomalyRateRD() const { return AnomalyRateRD; }
  30. void setAnomalyRateRDName(const char *Name) const {
  31. rrddim_set_name(AnomalyRateRD->rrdset, AnomalyRateRD, Name);
  32. }
  33. virtual ~RrdDimension() {
  34. rrddim_free(AnomalyRateRD->rrdset, AnomalyRateRD);
  35. }
  36. private:
  37. RRDDIM *RD;
  38. RRDDIM *AnomalyRateRD;
  39. struct rrddim_query_ops *Ops;
  40. std::string ID;
  41. };
  42. enum class MLResult {
  43. Success = 0,
  44. MissingData,
  45. NaN,
  46. };
  47. class TrainableDimension : public RrdDimension {
  48. public:
  49. TrainableDimension(RRDDIM *RD) :
  50. RrdDimension(RD), TrainEvery(Cfg.TrainEvery * updateEvery()) {}
  51. MLResult trainModel();
  52. CalculatedNumber computeAnomalyScore(SamplesBuffer &SB) {
  53. return Trained ? KM.anomalyScore(SB) : 0.0;
  54. }
  55. bool shouldTrain(const TimePoint &TP) const {
  56. if (ConstantModel)
  57. return false;
  58. return (LastTrainedAt + TrainEvery) < TP;
  59. }
  60. bool isTrained() const { return Trained; }
  61. private:
  62. std::pair<CalculatedNumber *, size_t> getCalculatedNumbers();
  63. public:
  64. TimePoint LastTrainedAt{Seconds{0}};
  65. protected:
  66. std::atomic<bool> ConstantModel{false};
  67. private:
  68. Seconds TrainEvery;
  69. KMeans KM;
  70. std::atomic<bool> Trained{false};
  71. };
  72. class PredictableDimension : public TrainableDimension {
  73. public:
  74. PredictableDimension(RRDDIM *RD) : TrainableDimension(RD) {}
  75. std::pair<MLResult, bool> predict();
  76. void addValue(CalculatedNumber Value, bool Exists);
  77. bool isAnomalous() { return AnomalyBit; }
  78. void updateAnomalyBitCounter(RRDSET *RS, unsigned Elapsed, bool IsAnomalous) {
  79. AnomalyBitCounter += IsAnomalous;
  80. if (Elapsed == Cfg.DBEngineAnomalyRateEvery) {
  81. double AR = static_cast<double>(AnomalyBitCounter) / Cfg.DBEngineAnomalyRateEvery;
  82. rrddim_set_by_pointer(RS, getAnomalyRateRD(), AR * 1000);
  83. AnomalyBitCounter = 0;
  84. }
  85. }
  86. private:
  87. CalculatedNumber AnomalyScore{0.0};
  88. std::atomic<bool> AnomalyBit{false};
  89. unsigned AnomalyBitCounter{0};
  90. std::vector<CalculatedNumber> CNs;
  91. };
  92. class DetectableDimension : public PredictableDimension {
  93. public:
  94. DetectableDimension(RRDDIM *RD) : PredictableDimension(RD) {}
  95. std::pair<bool, double> detect(size_t WindowLength, bool Reset) {
  96. bool AnomalyBit = isAnomalous();
  97. if (Reset)
  98. NumSetBits = BBC.numSetBits();
  99. NumSetBits += AnomalyBit;
  100. BBC.insert(AnomalyBit);
  101. double AnomalyRate = static_cast<double>(NumSetBits) / WindowLength;
  102. return { AnomalyBit, AnomalyRate };
  103. }
  104. private:
  105. BitBufferCounter BBC{static_cast<size_t>(Cfg.ADMinWindowSize)};
  106. size_t NumSetBits{0};
  107. };
  108. using Dimension = DetectableDimension;
  109. } // namespace ml
  110. #endif /* ML_DIMENSION_H */