mirror of
https://github.com/openappsec/openappsec.git
synced 2025-09-29 19:24:26 +03:00
First release of open-appsec source code
This commit is contained in:
3
core/memory_consumption/CMakeLists.txt
Executable file
3
core/memory_consumption/CMakeLists.txt
Executable file
@@ -0,0 +1,3 @@
|
||||
add_library(memory_consumption memory_consumption.cc)
|
||||
|
||||
add_subdirectory(memory_consumption_ut)
|
163
core/memory_consumption/memory_consumption.cc
Executable file
163
core/memory_consumption/memory_consumption.cc
Executable file
@@ -0,0 +1,163 @@
|
||||
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "memory_consumption.h"
|
||||
#include "memory_metric.h"
|
||||
#include <unistd.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
USE_DEBUG_FLAG(D_MONITORING);
|
||||
|
||||
class MemoryCalculator::Impl
|
||||
{
|
||||
public:
|
||||
void
|
||||
init()
|
||||
{
|
||||
I_MainLoop *i_mainloop = Singleton::Consume<I_MainLoop>::by<MemoryCalculator>();
|
||||
|
||||
memory_metric.init(
|
||||
"Memory usage",
|
||||
ReportIS::AudienceTeam::AGENT_CORE,
|
||||
ReportIS::IssuingEngine::AGENT_CORE,
|
||||
chrono::seconds(600),
|
||||
true
|
||||
);
|
||||
memory_metric.registerListener();
|
||||
|
||||
i_mainloop->addRecurringRoutine(
|
||||
I_MainLoop::RoutineType::Timer,
|
||||
chrono::seconds(60),
|
||||
[this] () { getCurrentMemoryUsage(); },
|
||||
"Memory consumption getter",
|
||||
false
|
||||
);
|
||||
|
||||
memory_values.insert(make_pair(virtual_process_memory_key, 0));
|
||||
memory_values.insert(make_pair(rss_process_key, 0));
|
||||
memory_values.insert(make_pair(general_total_memory_key, 0));
|
||||
}
|
||||
|
||||
void
|
||||
getCurrentMemoryUsage()
|
||||
{
|
||||
getCurrentProcessMemoryUsage();
|
||||
if (Singleton::exists<I_Environment>()) {
|
||||
auto name = Singleton::Consume<I_Environment>::by<MemoryCalculator>()->get<string>("Service Name");
|
||||
string orch_service_name = getConfigurationWithDefault<string>(
|
||||
"Orchestration",
|
||||
"orchestration",
|
||||
"Service name"
|
||||
);
|
||||
if (name.ok() && *name == orch_service_name) {
|
||||
getCurrentGeneralTotalMemoryUsage();
|
||||
} else {
|
||||
memory_values[general_total_memory_key] = 0;
|
||||
}
|
||||
} else {
|
||||
memory_values[general_total_memory_key] = 0;
|
||||
}
|
||||
|
||||
memory_event.setMemoryValues(memory_values);
|
||||
memory_event.notify();
|
||||
}
|
||||
|
||||
private:
|
||||
void
|
||||
getCurrentProcessMemoryUsage()
|
||||
{
|
||||
unsigned long vsize;
|
||||
long rss;
|
||||
{
|
||||
string ignore;
|
||||
ifstream ifs("/proc/self/stat", ios_base::in);
|
||||
for (uint ignored_stat_data = 0; ignored_stat_data < 22; ignored_stat_data++) {
|
||||
ifs >> ignore;
|
||||
}
|
||||
ifs >> vsize >> rss;
|
||||
}
|
||||
|
||||
long page_size_kb = sysconf(_SC_PAGE_SIZE) / 1024;
|
||||
memory_values[virtual_process_memory_key] = vsize / 1024;
|
||||
memory_values[rss_process_key] = rss * page_size_kb;
|
||||
}
|
||||
|
||||
void
|
||||
getCurrentGeneralTotalMemoryUsage()
|
||||
{
|
||||
static const string general_total_mem_file = "/proc/meminfo";
|
||||
ifstream ifs(general_total_mem_file, ios_base::in);
|
||||
double mem_general_total = 0;
|
||||
double mem_free = 0;
|
||||
string word, value, ignore;
|
||||
|
||||
static const int max_words_to_read = 150;
|
||||
int words_count = 0;
|
||||
while (words_count < max_words_to_read && ifs >> word) {
|
||||
words_count++;
|
||||
if (word != "") {
|
||||
//Reduce last letter which is ':' in order to get clean memory string.
|
||||
word = word.substr(0, word.size()-1);
|
||||
}
|
||||
static const string mem_general_total_str = "MemTotal";
|
||||
static const set<string> mem_free_strings = { "MemFree", "Buffers", "Cached" };
|
||||
if (word == mem_general_total_str) {
|
||||
ifs >> value;
|
||||
mem_general_total = atof(value.c_str());
|
||||
} else if (mem_free_strings.find(word) != mem_free_strings.end()) {
|
||||
ifs >> value;
|
||||
mem_free += atof(word.c_str());
|
||||
} else {
|
||||
ifs >> ignore;
|
||||
}
|
||||
ifs >> ignore;
|
||||
}
|
||||
|
||||
dbgTrace(D_MONITORING) << "General total value of memory in use: " << mem_general_total;
|
||||
dbgTrace(D_MONITORING) << "General total value of free memory: " << mem_free;
|
||||
memory_values[general_total_memory_key] = (mem_general_total - mem_free);
|
||||
}
|
||||
|
||||
map<string, double> memory_values;
|
||||
MemoryConsumptionEvent memory_event;
|
||||
MemoryMetric memory_metric;
|
||||
};
|
||||
|
||||
MemoryCalculator::MemoryCalculator() : Component("MemoryCalculator"), pimpl(make_unique<Impl>()) {}
|
||||
|
||||
MemoryCalculator::~MemoryCalculator() {}
|
||||
|
||||
void
|
||||
MemoryCalculator::preload()
|
||||
{
|
||||
registerExpectedConfiguration<string>("orchestration", "Service name");
|
||||
}
|
||||
|
||||
void MemoryCalculator::init() { pimpl->init(); }
|
||||
|
||||
void
|
||||
MemoryMetric::upon(const MemoryConsumptionEvent &event)
|
||||
{
|
||||
virtual_process_memory_max.report(event.getMemoryValue(memory_type_metric::VM_PROC_MAX));
|
||||
virtual_process_memory_min.report(event.getMemoryValue(memory_type_metric::VM_PROC_MIN));
|
||||
virtual_process_memory_average.report(event.getMemoryValue(memory_type_metric::VM_PROC_AVERAGE));
|
||||
|
||||
rss_process_max.report(event.getMemoryValue(memory_type_metric::RSS_PROC_MAX));
|
||||
rss_process_min.report(event.getMemoryValue(memory_type_metric::RSS_PROC_MIN));
|
||||
rss_process_average.report(event.getMemoryValue(memory_type_metric::RSS_PROC_AVERAGE));
|
||||
|
||||
general_total_memory_max.report(event.getMemoryValue(memory_type_metric::GENERAL_TOTAL_MAX));
|
||||
general_total_memory_min.report(event.getMemoryValue(memory_type_metric::GENERAL_TOTAL_MIN));
|
||||
general_total_memory_average.report(event.getMemoryValue(memory_type_metric::GENERAL_TOTAL_AVERAGE));
|
||||
}
|
7
core/memory_consumption/memory_consumption_ut/CMakeLists.txt
Executable file
7
core/memory_consumption/memory_consumption_ut/CMakeLists.txt
Executable file
@@ -0,0 +1,7 @@
|
||||
link_directories(${BOOST_ROOT}/lib)
|
||||
|
||||
add_unit_test(
|
||||
memory_consumption_ut
|
||||
"memory_consumption_ut.cc"
|
||||
"memory_consumption;event_is;metric;-lboost_regex;"
|
||||
)
|
76
core/memory_consumption/memory_consumption_ut/memory_consumption_ut.cc
Executable file
76
core/memory_consumption/memory_consumption_ut/memory_consumption_ut.cc
Executable file
@@ -0,0 +1,76 @@
|
||||
#include "memory_consumption.h"
|
||||
#include "../memory_metric.h"
|
||||
|
||||
#include "cptest.h"
|
||||
#include "cptest.h"
|
||||
#include "config_component.h"
|
||||
#include "environment.h"
|
||||
#include "mock/mock_mainloop.h"
|
||||
#include "mock/mock_time_get.h"
|
||||
#include "config_component.h"
|
||||
#include "debug.h"
|
||||
#include <boost/regex.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace testing;
|
||||
|
||||
USE_DEBUG_FLAG(D_MONITORING);
|
||||
|
||||
class MemoryConsumptionTest : public Test
|
||||
{
|
||||
public:
|
||||
MemoryConsumptionTest()
|
||||
{
|
||||
env.preload();
|
||||
env.init();
|
||||
Singleton::Consume<I_Environment>::from(env)->registerValue<string>("Service Name", "Orchestration");
|
||||
|
||||
EXPECT_CALL(mock_ml, addRecurringRoutine(_, _, _, _, _)).WillRepeatedly(Return(0));
|
||||
|
||||
EXPECT_CALL(mock_ml, addRecurringRoutine(I_MainLoop::RoutineType::Timer, _, _, _, _))
|
||||
.WillRepeatedly(DoAll(SaveArg<2>(&memory_routine), Return(1)));
|
||||
|
||||
memory_consumption.preload();
|
||||
memory_consumption.init();
|
||||
}
|
||||
|
||||
StrictMock<MockMainLoop> mock_ml;
|
||||
StrictMock<MockTimeGet> mock_time;
|
||||
MemoryCalculator memory_consumption;
|
||||
I_MainLoop::Routine memory_routine = nullptr;
|
||||
|
||||
private:
|
||||
ConfigComponent conf;
|
||||
::Environment env;
|
||||
};
|
||||
|
||||
TEST_F(MemoryConsumptionTest, initializeMemoryConsumption)
|
||||
{
|
||||
memory_routine();
|
||||
}
|
||||
|
||||
TEST_F(MemoryConsumptionTest, memoryConsumptionMetricTest)
|
||||
{
|
||||
memory_routine();
|
||||
|
||||
AllMetricEvent all_mt_event;
|
||||
all_mt_event.setReset(false);
|
||||
all_mt_event.notify();
|
||||
EXPECT_NE(all_mt_event.performNamedQuery().begin()->second, "");
|
||||
|
||||
boost::regex expected_reg(
|
||||
"{\\n\\s*\\\"Metric\\\":\\s*\\\"Memory usage\\\",\\n"
|
||||
"\\s*\\\"Reporting interval\\\":\\s*600,\\n"
|
||||
"\\s*\\\"serviceVirtualMemorySizeMaxSample\\\":\\s*\\d*\\.\\d*,\\n"
|
||||
"\\s*\\\"serviceVirtualMemorySizeMinSample\\\":\\s*\\d*\\.\\d*,\\n"
|
||||
"\\s*\\\"serviceVirtualMemorySizeAvgSample\\\":\\s*\\d*\\.\\d*,\\n"
|
||||
"\\s*\\\"serviceRssMemorySizeMaxSample\\\":\\s*\\d*\\.\\d*,\\n"
|
||||
"\\s*\\\"serviceRssMemorySizeMinSample\\\":\\s*\\d*\\.\\d*,\\n"
|
||||
"\\s*\\\"serviceRssMemorySizeAvgSample\\\":\\s*\\d*\\.\\d*,\\n"
|
||||
"\\s*\\\"generalTotalMemorySizeMaxSample\\\":\\s*\\d*\\.\\d*,\\n"
|
||||
"\\s*\\\"generalTotalMemorySizeMinSample\\\":\\s*\\d*\\.\\d*,\\n"
|
||||
"\\s*\\\"generalTotalMemorySizeAvgSample\\\":\\s*\\d*\\.\\d*\\n}"
|
||||
);
|
||||
|
||||
EXPECT_TRUE(boost::regex_search(all_mt_event.query()[0], expected_reg));
|
||||
}
|
120
core/memory_consumption/memory_metric.h
Executable file
120
core/memory_consumption/memory_metric.h
Executable file
@@ -0,0 +1,120 @@
|
||||
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef __MEMORY_METRIC_H__
|
||||
#define __MEMORY_METRIC_H__
|
||||
|
||||
#include "log_generator.h"
|
||||
#include "generic_metric.h"
|
||||
#include "event.h"
|
||||
|
||||
enum class memory_type_metric {
|
||||
VM_PROC_MAX,
|
||||
VM_PROC_MIN,
|
||||
VM_PROC_AVERAGE,
|
||||
RSS_PROC_MAX,
|
||||
RSS_PROC_MIN,
|
||||
RSS_PROC_AVERAGE,
|
||||
GENERAL_TOTAL_MAX,
|
||||
GENERAL_TOTAL_MIN,
|
||||
GENERAL_TOTAL_AVERAGE
|
||||
};
|
||||
|
||||
static const std::string virtual_process_memory_key = "virtual_process_memory";
|
||||
static const std::string rss_process_key = "rss_process";
|
||||
static const std::string general_total_memory_key = "general_total_memory";
|
||||
|
||||
USE_DEBUG_FLAG(D_MONITORING);
|
||||
|
||||
class MemoryConsumptionEvent : public Event<MemoryConsumptionEvent>
|
||||
{
|
||||
public:
|
||||
void
|
||||
setMemoryValues(std::map<std::string, double> new_values)
|
||||
{
|
||||
virtual_process_memory_max = new_values[virtual_process_memory_key];
|
||||
virtual_process_memory_min = new_values[virtual_process_memory_key];
|
||||
virtual_process_memory_average = new_values[virtual_process_memory_key];
|
||||
|
||||
rss_process_max = new_values[rss_process_key];
|
||||
rss_process_min = new_values[rss_process_key];
|
||||
rss_process_average = new_values[rss_process_key];
|
||||
|
||||
general_total_memory_max = new_values[general_total_memory_key];
|
||||
general_total_memory_min = new_values[general_total_memory_key];
|
||||
general_total_memory_average = new_values[general_total_memory_key];
|
||||
}
|
||||
|
||||
double
|
||||
getMemoryValue(const memory_type_metric memory_type) const
|
||||
{
|
||||
switch (memory_type) {
|
||||
case memory_type_metric::VM_PROC_MAX:
|
||||
return virtual_process_memory_max;
|
||||
case memory_type_metric::VM_PROC_MIN:
|
||||
return virtual_process_memory_min;
|
||||
case memory_type_metric::VM_PROC_AVERAGE:
|
||||
return virtual_process_memory_average;
|
||||
case memory_type_metric::RSS_PROC_MAX:
|
||||
return rss_process_max;
|
||||
case memory_type_metric::RSS_PROC_MIN:
|
||||
return rss_process_min;
|
||||
case memory_type_metric::RSS_PROC_AVERAGE:
|
||||
return rss_process_average;
|
||||
case memory_type_metric::GENERAL_TOTAL_MAX:
|
||||
return general_total_memory_max;
|
||||
case memory_type_metric::GENERAL_TOTAL_MIN:
|
||||
return general_total_memory_min;
|
||||
case memory_type_metric::GENERAL_TOTAL_AVERAGE:
|
||||
return general_total_memory_average;
|
||||
default:
|
||||
dbgWarning(D_MONITORING) << "Unsupported memory metric type.";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
double virtual_process_memory_max = 0;
|
||||
double virtual_process_memory_min = 0;
|
||||
double virtual_process_memory_average = 0;
|
||||
double rss_process_max = 0;
|
||||
double rss_process_min = 0;
|
||||
double rss_process_average = 0;
|
||||
double general_total_memory_max = 0;
|
||||
double general_total_memory_min = 0;
|
||||
double general_total_memory_average = 0;
|
||||
};
|
||||
|
||||
class MemoryMetric
|
||||
:
|
||||
public GenericMetric,
|
||||
public Listener<MemoryConsumptionEvent>
|
||||
{
|
||||
public:
|
||||
void upon(const MemoryConsumptionEvent &event) override;
|
||||
|
||||
private:
|
||||
MetricCalculations::Max<double> virtual_process_memory_max{this, "serviceVirtualMemorySizeMaxSample", 0};
|
||||
MetricCalculations::Min<double> virtual_process_memory_min{this, "serviceVirtualMemorySizeMinSample"};
|
||||
MetricCalculations::Average<double> virtual_process_memory_average{this, "serviceVirtualMemorySizeAvgSample"};
|
||||
|
||||
MetricCalculations::Max<double> rss_process_max{this, "serviceRssMemorySizeMaxSample", 0};
|
||||
MetricCalculations::Min<double> rss_process_min{this, "serviceRssMemorySizeMinSample"};
|
||||
MetricCalculations::Average<double> rss_process_average{this, "serviceRssMemorySizeAvgSample"};
|
||||
|
||||
MetricCalculations::Max<double> general_total_memory_max{this, "generalTotalMemorySizeMaxSample", 0};
|
||||
MetricCalculations::Min<double> general_total_memory_min{this, "generalTotalMemorySizeMinSample"};
|
||||
MetricCalculations::Average<double> general_total_memory_average{this, "generalTotalMemorySizeAvgSample"};
|
||||
};
|
||||
|
||||
#endif // __MEMORY_METRIC_H__
|
Reference in New Issue
Block a user