Dimension.h 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  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->state->query_ops) { }
  11. RRDDIM *getRD() const { return RD; }
  12. time_t latestTime() { return Ops->latest_time(RD); }
  13. time_t oldestTime() { return Ops->oldest_time(RD); }
  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. void setAnomalyRateRD(RRDDIM *ARRD) { AnomalyRateRD = ARRD; }
  22. RRDDIM *getAnomalyRateRD() const { return AnomalyRateRD; }
  23. void setAnomalyRateRDName(const char *Name) const {
  24. rrddim_set_name(AnomalyRateRD->rrdset, AnomalyRateRD, Name);
  25. }
  26. virtual ~RrdDimension() {
  27. rrddim_free_custom(AnomalyRateRD->rrdset, AnomalyRateRD, 0);
  28. }
  29. private:
  30. RRDDIM *RD;
  31. RRDDIM *AnomalyRateRD;
  32. struct rrddim_volatile::rrddim_query_ops *Ops;
  33. std::string ID;
  34. };
  35. enum class MLResult {
  36. Success = 0,
  37. MissingData,
  38. NaN,
  39. };
  40. class TrainableDimension : public RrdDimension {
  41. public:
  42. TrainableDimension(RRDDIM *RD) :
  43. RrdDimension(RD), TrainEvery(Cfg.TrainEvery * updateEvery()) {}
  44. MLResult trainModel();
  45. CalculatedNumber computeAnomalyScore(SamplesBuffer &SB) {
  46. return Trained ? KM.anomalyScore(SB) : 0.0;
  47. }
  48. bool shouldTrain(const TimePoint &TP) const {
  49. if (ConstantModel)
  50. return false;
  51. return (LastTrainedAt + TrainEvery) < TP;
  52. }
  53. bool isTrained() const { return Trained; }
  54. private:
  55. std::pair<CalculatedNumber *, size_t> getCalculatedNumbers();
  56. public:
  57. TimePoint LastTrainedAt{Seconds{0}};
  58. protected:
  59. std::atomic<bool> ConstantModel{false};
  60. private:
  61. Seconds TrainEvery;
  62. KMeans KM;
  63. std::atomic<bool> Trained{false};
  64. };
  65. class PredictableDimension : public TrainableDimension {
  66. public:
  67. PredictableDimension(RRDDIM *RD) : TrainableDimension(RD) {}
  68. std::pair<MLResult, bool> predict();
  69. void addValue(CalculatedNumber Value, bool Exists);
  70. bool isAnomalous() { return AnomalyBit; }
  71. void updateAnomalyBitCounter(RRDSET *RS, unsigned Elapsed, bool IsAnomalous) {
  72. AnomalyBitCounter += IsAnomalous;
  73. if (Elapsed == Cfg.DBEngineAnomalyRateEvery) {
  74. double AR = static_cast<double>(AnomalyBitCounter) / Cfg.DBEngineAnomalyRateEvery;
  75. rrddim_set_by_pointer(RS, getAnomalyRateRD(), AR * 1000);
  76. AnomalyBitCounter = 0;
  77. }
  78. }
  79. private:
  80. CalculatedNumber AnomalyScore{0.0};
  81. std::atomic<bool> AnomalyBit{false};
  82. unsigned AnomalyBitCounter{0};
  83. std::vector<CalculatedNumber> CNs;
  84. };
  85. class DetectableDimension : public PredictableDimension {
  86. public:
  87. DetectableDimension(RRDDIM *RD) : PredictableDimension(RD) {}
  88. std::pair<bool, double> detect(size_t WindowLength, bool Reset) {
  89. bool AnomalyBit = isAnomalous();
  90. if (Reset)
  91. NumSetBits = BBC.numSetBits();
  92. NumSetBits += AnomalyBit;
  93. BBC.insert(AnomalyBit);
  94. double AnomalyRate = static_cast<double>(NumSetBits) / WindowLength;
  95. return { AnomalyBit, AnomalyRate };
  96. }
  97. private:
  98. BitBufferCounter BBC{static_cast<size_t>(Cfg.ADMinWindowSize)};
  99. size_t NumSetBits{0};
  100. };
  101. using Dimension = DetectableDimension;
  102. } // namespace ml
  103. #endif /* ML_DIMENSION_H */