First release of open-appsec source code

This commit is contained in:
roybarda
2022-10-26 19:33:19 +03:00
parent 3883109caf
commit a883352f79
1353 changed files with 276290 additions and 1 deletions

View File

@@ -0,0 +1,3 @@
add_library(memory_consumption memory_consumption.cc)
add_subdirectory(memory_consumption_ut)

View 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));
}

View 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;"
)

View 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));
}

View 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__