mirror of
https://github.com/scylladb/scylladb.git
synced 2026-04-23 01:50:35 +00:00
Merge 'audit: decrease allocations / instructions on will_log() fast path' from Marcin Maliszkiewicz
Audit::will_log() runs on every CQL/Alternator request. Since9646ee05bdit constructs three temporary sstrings per call to look up the audited keyspaces set / tables map with std::string_view keys, costing ~180 insns/op and 2 allocations if sstring misses SSO. This series switches the containers to std::less<> comparators to enable heterogeneous lookup, then drops the sstring temporaries from will_log(). perf-simple-query --smp 1 --duration 15 --audit "table" --audit-keyspaces "ks-non-existing" --audit-categories "DCL,DDL,AUTH,DML,QUERY" baseline3d0582d51e36777 insns/op regression9646ee05bd36952 (+175) this series 36768 (-184, fixed) Fixes https://scylladb.atlassian.net/browse/SCYLLADB-1616 Backport: no, offending commit is not backported Closes scylladb/scylladb#29565 * github.com:scylladb/scylladb: audit: drop sstring temporaries on the will_log() fast path audit: enable heterogeneous lookup on audited keyspaces/tables
This commit is contained in:
@@ -113,8 +113,8 @@ static category_set parse_audit_categories(const sstring& data) {
|
||||
return result;
|
||||
}
|
||||
|
||||
static std::map<sstring, std::set<sstring>> parse_audit_tables(const sstring& data) {
|
||||
std::map<sstring, std::set<sstring>> result;
|
||||
static audit::audited_tables_t parse_audit_tables(const sstring& data) {
|
||||
audit::audited_tables_t result;
|
||||
if (!data.empty()) {
|
||||
std::vector<sstring> tokens;
|
||||
boost::split(tokens, data, boost::is_any_of(","));
|
||||
@@ -139,8 +139,8 @@ static std::map<sstring, std::set<sstring>> parse_audit_tables(const sstring& da
|
||||
return result;
|
||||
}
|
||||
|
||||
static std::set<sstring> parse_audit_keyspaces(const sstring& data) {
|
||||
std::set<sstring> result;
|
||||
static audit::audited_keyspaces_t parse_audit_keyspaces(const sstring& data) {
|
||||
audit::audited_keyspaces_t result;
|
||||
if (!data.empty()) {
|
||||
std::vector<sstring> tokens;
|
||||
boost::split(tokens, data, boost::is_any_of(","));
|
||||
@@ -156,8 +156,8 @@ audit::audit(locator::shared_token_metadata& token_metadata,
|
||||
cql3::query_processor& qp,
|
||||
service::migration_manager& mm,
|
||||
std::set<sstring>&& audit_modes,
|
||||
std::set<sstring>&& audited_keyspaces,
|
||||
std::map<sstring, std::set<sstring>>&& audited_tables,
|
||||
audited_keyspaces_t&& audited_keyspaces,
|
||||
audited_tables_t&& audited_tables,
|
||||
category_set&& audited_categories,
|
||||
const db::config& cfg)
|
||||
: _token_metadata(token_metadata)
|
||||
@@ -165,8 +165,8 @@ audit::audit(locator::shared_token_metadata& token_metadata,
|
||||
, _audited_tables(std::move(audited_tables))
|
||||
, _audited_categories(std::move(audited_categories))
|
||||
, _cfg(cfg)
|
||||
, _cfg_keyspaces_observer(cfg.audit_keyspaces.observe([this] (sstring const& new_value){ update_config<std::set<sstring>>(new_value, parse_audit_keyspaces, _audited_keyspaces); }))
|
||||
, _cfg_tables_observer(cfg.audit_tables.observe([this] (sstring const& new_value){ update_config<std::map<sstring, std::set<sstring>>>(new_value, parse_audit_tables, _audited_tables); }))
|
||||
, _cfg_keyspaces_observer(cfg.audit_keyspaces.observe([this] (sstring const& new_value){ update_config<audited_keyspaces_t>(new_value, parse_audit_keyspaces, _audited_keyspaces); }))
|
||||
, _cfg_tables_observer(cfg.audit_tables.observe([this] (sstring const& new_value){ update_config<audited_tables_t>(new_value, parse_audit_tables, _audited_tables); }))
|
||||
, _cfg_categories_observer(cfg.audit_categories.observe([this] (sstring const& new_value){ update_config<category_set>(new_value, parse_audit_categories, _audited_categories); }))
|
||||
{
|
||||
_storage_helper_ptr = create_storage_helper(std::move(audit_modes), qp, mm);
|
||||
@@ -181,8 +181,8 @@ future<> audit::start_audit(const db::config& cfg, sharded<locator::shared_token
|
||||
return make_ready_future<>();
|
||||
}
|
||||
category_set audited_categories = parse_audit_categories(cfg.audit_categories());
|
||||
std::map<sstring, std::set<sstring>> audited_tables = parse_audit_tables(cfg.audit_tables());
|
||||
std::set<sstring> audited_keyspaces = parse_audit_keyspaces(cfg.audit_keyspaces());
|
||||
audit::audited_tables_t audited_tables = parse_audit_tables(cfg.audit_tables());
|
||||
audit::audited_keyspaces_t audited_keyspaces = parse_audit_keyspaces(cfg.audit_keyspaces());
|
||||
|
||||
logger.info("Audit is enabled. Auditing to: \"{}\", with the following categories: \"{}\", keyspaces: \"{}\", and tables: \"{}\"",
|
||||
cfg.audit(), cfg.audit_categories(), cfg.audit_keyspaces(), cfg.audit_tables());
|
||||
@@ -304,7 +304,7 @@ future<> inspect_login(const sstring& username, socket_address client_ip, bool e
|
||||
return audit::local_audit_instance().log_login(username, client_ip, error);
|
||||
}
|
||||
|
||||
bool audit::should_log_table(const sstring& keyspace, const sstring& name) const {
|
||||
bool audit::should_log_table(std::string_view keyspace, std::string_view name) const {
|
||||
auto keyspace_it = _audited_tables.find(keyspace);
|
||||
return keyspace_it != _audited_tables.cend() && keyspace_it->second.find(name) != keyspace_it->second.cend();
|
||||
}
|
||||
@@ -319,8 +319,8 @@ bool audit::will_log(statement_category cat, std::string_view keyspace, std::str
|
||||
// so it is logged whenever the category matches.
|
||||
return _audited_categories.contains(cat)
|
||||
&& (keyspace.empty()
|
||||
|| _audited_keyspaces.find(sstring(keyspace)) != _audited_keyspaces.cend()
|
||||
|| should_log_table(sstring(keyspace), sstring(table))
|
||||
|| _audited_keyspaces.find(keyspace) != _audited_keyspaces.cend()
|
||||
|| should_log_table(keyspace, table)
|
||||
|| cat == statement_category::AUTH
|
||||
|| cat == statement_category::ADMIN
|
||||
|| cat == statement_category::DCL);
|
||||
|
||||
@@ -129,10 +129,15 @@ public:
|
||||
class storage_helper;
|
||||
|
||||
class audit final : public seastar::async_sharded_service<audit> {
|
||||
public:
|
||||
// Transparent comparator (std::less<>) enables heterogeneous lookup with
|
||||
// string_view keys.
|
||||
using audited_keyspaces_t = std::set<sstring, std::less<>>;
|
||||
using audited_tables_t = std::map<sstring, std::set<sstring, std::less<>>, std::less<>>;
|
||||
private:
|
||||
locator::shared_token_metadata& _token_metadata;
|
||||
std::set<sstring> _audited_keyspaces;
|
||||
// Maps keyspace name to set of table names in that keyspace
|
||||
std::map<sstring, std::set<sstring>> _audited_tables;
|
||||
audited_keyspaces_t _audited_keyspaces;
|
||||
audited_tables_t _audited_tables;
|
||||
category_set _audited_categories;
|
||||
|
||||
std::unique_ptr<storage_helper> _storage_helper_ptr;
|
||||
@@ -145,7 +150,7 @@ class audit final : public seastar::async_sharded_service<audit> {
|
||||
template<class T>
|
||||
void update_config(const sstring & new_value, std::function<T(const sstring&)> parse_func, T& cfg_parameter);
|
||||
|
||||
bool should_log_table(const sstring& keyspace, const sstring& name) const;
|
||||
bool should_log_table(std::string_view keyspace, std::string_view name) const;
|
||||
public:
|
||||
static seastar::sharded<audit>& audit_instance() {
|
||||
// FIXME: leaked intentionally to avoid shutdown problems, see #293
|
||||
@@ -164,8 +169,8 @@ public:
|
||||
cql3::query_processor& qp,
|
||||
service::migration_manager& mm,
|
||||
std::set<sstring>&& audit_modes,
|
||||
std::set<sstring>&& audited_keyspaces,
|
||||
std::map<sstring, std::set<sstring>>&& audited_tables,
|
||||
audited_keyspaces_t&& audited_keyspaces,
|
||||
audited_tables_t&& audited_tables,
|
||||
category_set&& audited_categories,
|
||||
const db::config& cfg);
|
||||
~audit();
|
||||
|
||||
Reference in New Issue
Block a user