Add read and write locks to fix race condition in OwnFilterinChannel

This commit is contained in:
Peter Nguyen 2024-10-18 16:48:15 -07:00
parent d08a1b313e
commit 70215dbd9b
2 changed files with 39 additions and 28 deletions

View File

@ -1,3 +1,4 @@
#include <shared_mutex>
#include <Loggers/OwnFilteringChannel.h>
#include <Poco/RegularExpression.h>
@ -7,9 +8,19 @@ namespace DB
void OwnFilteringChannel::log(const Poco::Message & msg)
{
std::string formatted_text;
if (regexpFilteredOut(msg))
return;
if (!positive_pattern.empty() || !negative_pattern.empty())
pChannel->log(msg);
}
bool OwnFilteringChannel::regexpFilteredOut(const Poco::Message & msg)
{
std::string formatted_text;
auto [pos_pattern, neg_pattern] = safeGetPatterns();
// Skip checks if both patterns are empty
if (!pos_pattern.empty() || !neg_pattern.empty())
{
// Apply formatting to the text
if (pFormatter)
@ -20,33 +31,28 @@ void OwnFilteringChannel::log(const Poco::Message & msg)
{
formatted_text = msg.getText();
}
if (regexpFilteredOut(formatted_text))
return;
}
pChannel->log(msg);
}
// Check for patterns in formatted text
Poco::RegularExpression positive_regexp(pos_pattern);
if (!pos_pattern.empty() && !positive_regexp.match(formatted_text))
{
return true;
}
bool OwnFilteringChannel::regexpFilteredOut(const std::string & text) const
{
if (!positive_pattern.empty())
{
Poco::RegularExpression positive_regexp(positive_pattern);
if (!positive_regexp.match(text))
Poco::RegularExpression negative_regexp(neg_pattern);
if (!neg_pattern.empty() && negative_regexp.match(formatted_text))
{
return true;
}
}
if (!negative_pattern.empty())
{
Poco::RegularExpression negative_regexp(negative_pattern);
if (negative_regexp.match(text))
{
return true;
}
}
return false;
}
std::pair<std::string, std::string> OwnFilteringChannel::safeGetPatterns()
{
std::shared_lock<std::shared_mutex> read_lock(pattern_mutex);
return std::make_pair(positive_pattern, negative_pattern);
}
}

View File

@ -4,6 +4,7 @@
#include <Poco/Message.h>
#include <Poco/Util/AbstractConfiguration.h>
#include <Loggers/OwnPatternFormatter.h>
#include <shared_mutex>
namespace DB
@ -30,13 +31,14 @@ public:
void log(const Poco::Message & msg) override;
// Sets the regex patterns to use for filtering. Specifying an empty string pattern "" indicates no filtering
void setRegexpPatterns(const std::string & positive_pattern_, const std::string & negative_pattern_)
void setRegexpPatterns(const std::string & new_pos_pattern, const std::string & new_neg_pattern)
{
if (positive_pattern_ != positive_pattern || negative_pattern_ != negative_pattern)
auto [old_pos_pattern, old_neg_pattern] = safeGetPatterns();
if (old_pos_pattern != new_pos_pattern || old_neg_pattern != new_neg_pattern)
{
std::lock_guard<std::mutex> lock(pattern_mutex);
positive_pattern = positive_pattern_;
negative_pattern = negative_pattern_;
std::unique_lock<std::shared_mutex> write_lock(pattern_mutex);
positive_pattern = new_pos_pattern;
negative_pattern = new_neg_pattern;
}
}
@ -71,14 +73,17 @@ public:
}
private:
bool regexpFilteredOut(const std::string & text) const;
bool regexpFilteredOut(const Poco::Message & msg);
// Create copy safely, so we don't have to worry about race conditions from reading and writing at the same time
std::pair<std::string, std::string> safeGetPatterns();
const std::string logger_name;
std::string positive_pattern;
std::string negative_pattern;
Poco::AutoPtr<Poco::Channel> pChannel;
Poco::AutoPtr<OwnPatternFormatter> pFormatter;
std::mutex pattern_mutex;
std::shared_mutex pattern_mutex;
};
}