using namespace snort;
-const char* table_header = "AppId Performance Statistics (all)\n========================================================================================================================\n";
-const char* columns = " AppId App Name Microsecs Packets Avg/Packet Sessions Avg/Session \n";
-const char* partition = "------------------------------------------------------------------------------------------------------------------------\n";
+static const char* table_header = "AppId Performance Statistics (all)\n========================================================================================================================\n";
+static const char* columns = " AppId App Name Microsecs Packets Avg/Packet Sessions Avg/Session \n";
+static const char* partition = "------------------------------------------------------------------------------------------------------------------------\n";
-std::string FormatWithCommas(uint64_t value)
+static std::string FormatWithCommas(uint64_t value)
{
std::string numStr = std::to_string(value);
int insertPosition = numStr.length() - 3;
// Comparator for priority queue based on avg_processing_time/session
struct CompareByAvgProcessingTime {
bool operator()(const std::pair<AppId, AppidCPUProfilerStats>& a, const std::pair<AppId, AppidCPUProfilerStats>& b) const {
- if (a.second.processed_packets == 0 or b.second.processed_packets == 0) {
+ if (a.second.per_appid_sessions == 0 or b.second.per_appid_sessions == 0)
return false;
- }
- return a.second.processing_time/a.second.per_appid_sessions < b.second.processing_time/b.second.per_appid_sessions ;
+
+ return a.second.processing_time/a.second.per_appid_sessions < b.second.processing_time/b.second.per_appid_sessions;
}
};
-void AppidCPUProfilingManager::display_appid_cpu_profiler_table(AppId appid)
+AppidCpuTableDisplayStatus AppidCPUProfilingManager::display_appid_cpu_profiler_table(AppId appid, OdpContext& odp_ctxt)
{
- if (appid_cpu_profiling_table.empty())
- {
- appid_log(nullptr, TRACE_INFO_LEVEL,"Appid CPU Profiler Table is empty\n", appid);
- return;
- }
+ if (odp_ctxt.is_appid_cpu_profiler_running())
+ return DISPLAY_ERROR_APPID_PROFILER_RUNNING;
+ else if (appid_cpu_profiling_table.empty())
+ return DISPLAY_ERROR_TABLE_EMPTY;
+
auto bucket = appid_cpu_profiling_table.find(appid);
if (bucket != appid_cpu_profiling_table.end())
{
appid_log(nullptr, TRACE_INFO_LEVEL,"Appid %d not found in the table\n", appid);
}
+ return DISPLAY_SUCCESS;
}
-void AppidCPUProfilingManager::display_appid_cpu_profiler_table()
+AppidCpuTableDisplayStatus AppidCPUProfilingManager::display_appid_cpu_profiler_table(OdpContext& odp_ctxt, bool override_running_flag)
{
- if (appid_cpu_profiling_table.empty())
- {
- appid_log(nullptr, TRACE_INFO_LEVEL,"Appid CPU Profiler Table is empty\n");
- return;
- }
+ if (odp_ctxt.is_appid_cpu_profiler_running() and !override_running_flag)
+ return DISPLAY_ERROR_APPID_PROFILER_RUNNING;
+ else if (appid_cpu_profiling_table.empty())
+ return DISPLAY_ERROR_TABLE_EMPTY;
std::priority_queue<std::pair<AppId, AppidCPUProfilerStats>, std::vector<std::pair<AppId, AppidCPUProfilerStats>>, CompareByAvgProcessingTime> sorted_appid_cpu_profiler_table;
for (const auto& entry : appid_cpu_profiling_table)
- {
- sorted_appid_cpu_profiler_table.push(entry); // Push the pair (AppId, AppidCPUProfilerStats)
- }
+ sorted_appid_cpu_profiler_table.push(entry);
appid_log(nullptr, TRACE_INFO_LEVEL, table_header);
appid_log(nullptr, TRACE_INFO_LEVEL, columns);
{
auto entry = sorted_appid_cpu_profiler_table.top();
sorted_appid_cpu_profiler_table.pop();
- if (!entry.second.processed_packets)
+ if (!entry.second.processed_packets or !entry.second.per_appid_sessions)
continue;
appid_log(nullptr, TRACE_INFO_LEVEL, " %5d %-25.25s %18s %12s %15s %12s %12s\n",
entry.first, entry.second.app_name.c_str(), FormatWithCommas(entry.second.processing_time).c_str(), FormatWithCommas(entry.second.processed_packets).c_str(), FormatWithCommas(entry.second.processing_time/entry.second.processed_packets).c_str(),
FormatWithCommas(entry.second.per_appid_sessions).c_str(), FormatWithCommas(entry.second.processing_time/entry.second.per_appid_sessions).c_str());
}
-}
-
-AppidCPUProfilingManager::AppidCPUProfilingManager()
-{
- appid_cpu_profiling_table.clear();
+ return DISPLAY_SUCCESS;
}
void AppidCPUProfilingManager::cleanup_appid_cpu_profiler_table()
{
+ std::lock_guard<std::mutex> lock(appid_cpu_profiler_mutex);
appid_cpu_profiling_table.clear();
}
void AppidCPUProfilingManager::insert_appid_cpu_profiler_record(AppId appId, const AppidCPUProfilerStats& stats)
{
+ std::lock_guard<std::mutex> lock(appid_cpu_profiler_mutex);
+
auto it = appid_cpu_profiling_table.find(appId);
if (it == appid_cpu_profiling_table.end())
{
#include <unordered_map>
#include <vector>
+#include <mutex>
#include "main/thread.h"
#include "utils/util.h"
class AppIdSession;
class OdpContext;
+enum AppidCpuTableDisplayStatus {
+ DISPLAY_SUCCESS = 0,
+ DISPLAY_ERROR_TABLE_EMPTY,
+ DISPLAY_ERROR_APPID_PROFILER_RUNNING
+};
+
struct AppidCPUProfilerStats {
std::string app_name;
uint64_t processing_time = 0;
class AppidCPUProfilingManager {
private:
- typedef std::unordered_map<AppId, AppidCPUProfilerStats> AppidCPUProfilingTable;
+ using AppidCPUProfilingTable = std::unordered_map<AppId, AppidCPUProfilerStats>;
AppidCPUProfilingTable appid_cpu_profiling_table;
+ std::mutex appid_cpu_profiler_mutex;
public:
- AppidCPUProfilingManager();
+ AppidCPUProfilingManager() = default;
void stats_bucket_insert(AppId appid, const char* app_name, uint64_t processing_time, uint64_t processed_packets);
void insert_appid_cpu_profiler_record(AppId appId, const AppidCPUProfilerStats& stats);
void check_appid_cpu_profiler_table_entry(const AppIdSession* asd, AppId service_id, AppId client_id, AppId payload_id, AppId misc_id);
void check_appid_cpu_profiler_table_entry(const AppIdSession* asd, AppId payload_id);
- void display_appid_cpu_profiler_table();
- void display_appid_cpu_profiler_table(AppId appid);
+ AppidCpuTableDisplayStatus display_appid_cpu_profiler_table(OdpContext&, bool override_running_flag = false);
+ AppidCpuTableDisplayStatus display_appid_cpu_profiler_table(AppId, OdpContext&);
void cleanup_appid_cpu_profiler_table();
};
{
odp_ctxt.appid_cpu_profiler = false;
}
- else if (!(strcasecmp(conf_val, "enabled")))
- {
- odp_ctxt.appid_cpu_profiler = true;
- }
}
else
ParseWarning(WARN_CONF, "appid: unsupported configuration: %s\n", conf_key);
if (odp_ctxt)
{
odp_ctxt->get_app_info_mgr().cleanup_appid_info_table();
- if (odp_ctxt->is_appid_cpu_profiler_running())
- odp_ctxt->get_appid_cpu_profiler_mgr().display_appid_cpu_profiler_table();
+ if (odp_ctxt->is_appid_cpu_profiler_enabled())
+ odp_ctxt->get_appid_cpu_profiler_mgr().display_appid_cpu_profiler_table(*odp_ctxt, true);
odp_ctxt->get_appid_cpu_profiler_mgr().cleanup_appid_cpu_profiler_table();
delete odp_ctxt;
uint16_t max_packet_service_fail_ignore_bytes = DEFAULT_MAX_PKT_BEFORE_SERVICE_FAIL_IGNORE_BYTES;
FirstPktAppIdDiscovered first_pkt_appid_prefix = NO_APPID_FOUND;
bool eve_http_client = true;
- bool appid_cpu_profiler = false;
+ bool appid_cpu_profiler = true;
OdpContext(const AppIdConfig&, snort::SnortConfig*);
void initialize(AppIdInspector& inspector);
#include "appid_inspector.h"
#include "appid_peg_counts.h"
#include "service_state.h"
+#include "app_cpu_profile_table.h"
using namespace snort;
using namespace std;
}
}
-
static int show_cpu_profiler_stats(lua_State* L)
{
int appid = luaL_optint(L, 1, 0);
return 0;
}
const AppIdContext& ctxt = inspector->get_ctxt();
- OdpContext& odp_ctxt = ctxt.get_odp_ctxt();
+ OdpContext& odp_ctxt = ctxt.get_odp_ctxt();
+
if (odp_ctxt.is_appid_cpu_profiler_enabled())
{
+ AppidCpuTableDisplayStatus displayed = DISPLAY_SUCCESS;
ctrlcon->respond("== showing appid cpu profiler table\n");
if (!appid)
- odp_ctxt.get_appid_cpu_profiler_mgr().display_appid_cpu_profiler_table();
+ displayed = odp_ctxt.get_appid_cpu_profiler_mgr().display_appid_cpu_profiler_table(odp_ctxt);
else
- odp_ctxt.get_appid_cpu_profiler_mgr().display_appid_cpu_profiler_table(appid);
+ displayed = odp_ctxt.get_appid_cpu_profiler_mgr().display_appid_cpu_profiler_table(appid, odp_ctxt);
+
+ switch (displayed){
+ case DISPLAY_ERROR_TABLE_EMPTY:
+ ctrlcon->respond("== appid cpu profiler table is empty\n");
+ break;
+ case DISPLAY_ERROR_APPID_PROFILER_RUNNING:
+ ctrlcon->respond("== appid cpu profiler is still running\n");
+ break;
+ case DISPLAY_SUCCESS:
+ break;
+ }
}
else
ctrlcon->respond("appid cpu profiler is disabled\n");
return nullptr;
}
-
-AppidCPUProfilingManager::AppidCPUProfilingManager() { }
-
bool AppIdReloadTuner::tinit() { return false; }
bool AppIdReloadTuner::tune_resources(unsigned int)
{
return nullptr;
}
-AppidCPUProfilingManager::AppidCPUProfilingManager() { }
void ServiceDiscoveryState::set_service_id_valid(ServiceDetector*) { }
AppIdConfig::~AppIdConfig() = default;
OdpContext::OdpContext(const AppIdConfig&, snort::SnortConfig*) { }
-AppidCPUProfilingManager::AppidCPUProfilingManager() {}
AppIdConfig stub_config;
AppIdContext stub_ctxt(stub_config);
void Profiler::show_stats() { }
OdpContext::OdpContext(const AppIdConfig&, snort::SnortConfig*) { }
-AppidCPUProfilingManager::AppidCPUProfilingManager() { }
AppIdConfig::~AppIdConfig() = default;
return true;
}
-AppidCPUProfilingManager::AppidCPUProfilingManager() { }
-
#endif
void ClientAppDescriptor::update_user(AppId, const char*, AppidChangeBits&){}
AppIdConfig::~AppIdConfig() = default;
OdpContext::OdpContext(const AppIdConfig&, snort::SnortConfig*) { }
-AppidCPUProfilingManager::AppidCPUProfilingManager() {}
AppIdConfig stub_config;
AppIdContext stub_ctxt(stub_config);
OdpContext stub_odp_ctxt(stub_config, nullptr);
AlpnPatternMatchers::~AlpnPatternMatchers() = default;
CipPatternMatchers::~CipPatternMatchers() = default;
AppIdConfig::~AppIdConfig() = default;
-AppidCPUProfilingManager::AppidCPUProfilingManager() = default;
OdpContext::OdpContext(const AppIdConfig&, snort::SnortConfig*) { }
void ServiceDiscovery::initialize(AppIdInspector&) { }
void ServiceDiscovery::reload() { }