Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions olp-cpp-sdk-core/include/olp/core/logging/Log.h
Original file line number Diff line number Diff line change
Expand Up @@ -562,6 +562,26 @@ class CORE_API Log {
const std::string& message, const char* file,
unsigned int line, const char* function,
const char* fullFunction);

/**
* @brief Adds a line to be censored out from the log.
*
* Censoring out is a replacement with a predefiend mask with length not
* correlated with the original line length.
*
* @param message The line to be censored out from the log.
*/
static void addCensor(const std::string& message);

/**
* @brief Removes a line from censoring out from the log.
*
* Censoring out is a replacement with a predefiend mask with length not
* correlated with the original line length.
*
* @param message The line to be excluded from censoring out from the log.
*/
static void removeCensor(const std::string& message);
};
} // namespace logging
} // namespace olp
127 changes: 107 additions & 20 deletions olp-cpp-sdk-core/src/logging/Log.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,25 @@

#include <olp/core/logging/Configuration.h>
#include <olp/core/logging/FilterGroup.h>
#include <olp/core/porting/optional.h>
#include <olp/core/thread/Atomic.h>

#include <algorithm>
#include <string>
#include <unordered_map>

namespace olp {
namespace logging {

namespace {
constexpr auto kSecretMask = "*****";
const auto kSecretMaskLength = std::strlen(kSecretMask);
} // namespace

struct LogMessageExt : public LogMessage {
olp::porting::optional<std::string> adjusted_message;
};

class LogImpl {
public:
friend class olp::thread::Atomic<logging::LogImpl>;
Expand Down Expand Up @@ -67,14 +79,21 @@ class LogImpl {
unsigned int line, const char* function,
const char* fullFunction);

void addCensor(std::string msg);
void removeCensor(const std::string& msg);

private:
LogImpl();
template <class LogItem>
void appendLogItem(const LogItem& log_item);

template <class LogItem>
void censorLogItem(LogItem& log_item, const std::string& original);

Configuration m_configuration;
std::unordered_map<std::string, Level> m_logLevels;
Level m_defaultLevel;
std::vector<std::string> m_toCensor;
};

LogImpl::LogImpl()
Expand Down Expand Up @@ -120,7 +139,8 @@ void LogImpl::setLevel(Level level, const std::string& tag) {
}

porting::optional<Level> LogImpl::getLevel(const std::string& tag) const {
if (tag.empty()) return getLevel();
if (tag.empty())
return getLevel();

auto foundIter = m_logLevels.find(tag);
if (foundIter == m_logLevels.end())
Expand All @@ -130,21 +150,24 @@ porting::optional<Level> LogImpl::getLevel(const std::string& tag) const {
}

void LogImpl::clearLevel(const std::string& tag) {
if (tag.empty()) return;
if (tag.empty())
return;

m_logLevels.erase(tag);
}

void LogImpl::clearLevels() { m_logLevels.clear(); }

bool LogImpl::isEnabled(Level level) const {
if (level == Level::Off) return false;
if (level == Level::Off)
return false;

return static_cast<int>(level) >= static_cast<int>(m_defaultLevel);
}

bool LogImpl::isEnabled(Level level, const std::string& tag) const {
if (level == Level::Off) return false;
if (level == Level::Off)
return false;

auto foundIter = m_logLevels.find(tag);
Level targetLevel;
Expand All @@ -159,7 +182,7 @@ void LogImpl::logMessage(Level level, const std::string& tag,
const std::string& message, const char* file,
unsigned int line, const char* function,
const char* fullFunction) {
LogMessage logMessage;
LogMessageExt logMessage;
logMessage.level = level;
logMessage.tag = tag.c_str();
logMessage.message = message.c_str();
Expand All @@ -170,6 +193,7 @@ void LogImpl::logMessage(Level level, const std::string& tag,
logMessage.time = std::chrono::system_clock::now();
logMessage.threadId = getThreadId();

censorLogItem(logMessage, message);
appendLogItem(logMessage);
}

Expand All @@ -181,95 +205,142 @@ void LogImpl::appendLogItem(const LogItem& log_item) {
}
}

template <class LogItem>
void LogImpl::censorLogItem(LogItem& log_item, const std::string& original) {
bool has_copy = log_item.adjusted_message.has_value();
const std::string& src =
has_copy ? log_item.adjusted_message.value() : original;

for (const std::string& secret : m_toCensor) {
auto found_pos = src.find(secret);
while (found_pos != std::string::npos) {
if (!has_copy) {
log_item.adjusted_message = original;
has_copy = true;
log_item.message = log_item.adjusted_message.value().c_str();
}
log_item.adjusted_message.value().replace(found_pos, secret.length(),
kSecretMask);
found_pos = log_item.adjusted_message.value().find(
secret, found_pos + kSecretMaskLength);
}
}
}

void LogImpl::addCensor(std::string msg) {
m_toCensor.emplace_back(std::move(msg));
}

void LogImpl::removeCensor(const std::string& msg) {
auto it = std::find(m_toCensor.begin(), m_toCensor.end(), msg);
if (it != m_toCensor.end()) {
m_toCensor.erase(it);
}
}

// implementation of public static Log API
//--------------------------------------------------------

bool Log::configure(Configuration configuration) {
if (!LogImpl::aliveStatus()) return false;
if (!LogImpl::aliveStatus())
return false;

return LogImpl::getInstance().locked([&configuration](LogImpl& log) {
return log.configure(std::move(configuration));
});
}

Configuration Log::getConfiguration() {
if (!LogImpl::aliveStatus()) return Configuration();
if (!LogImpl::aliveStatus())
return Configuration();

return LogImpl::getInstance().locked(
[](const LogImpl& log) { return log.getConfiguration(); });
}

void Log::setLevel(Level level) {
if (!LogImpl::aliveStatus()) return;
if (!LogImpl::aliveStatus())
return;

LogImpl::getInstance().locked([level](LogImpl& log) { log.setLevel(level); });
}

Level Log::getLevel() {
if (!LogImpl::aliveStatus()) return Level::Off;
if (!LogImpl::aliveStatus())
return Level::Off;

return LogImpl::getInstance().locked(
[](const LogImpl& log) { return log.getLevel(); });
}

void Log::setLevel(Level level, const std::string& tag) {
if (!LogImpl::aliveStatus()) return;
if (!LogImpl::aliveStatus())
return;

LogImpl::getInstance().locked(
[level, &tag](LogImpl& log) { log.setLevel(level, tag); });
}

void Log::setLevel(const std::string& level, const std::string& tag) {
auto log_level = FilterGroup::stringToLevel(level);
if (!log_level) return;
if (!log_level)
return;

if (!LogImpl::aliveStatus()) return;
if (!LogImpl::aliveStatus())
return;

LogImpl::getInstance().locked(
[&log_level, &tag](LogImpl& log) { log.setLevel(*log_level, tag); });
}

porting::optional<Level> Log::getLevel(const std::string& tag) {
if (!LogImpl::aliveStatus()) return porting::none;
if (!LogImpl::aliveStatus())
return porting::none;

return LogImpl::getInstance().locked(
[&tag](const LogImpl& log) { return log.getLevel(tag); });
}

void Log::clearLevel(const std::string& tag) {
if (!LogImpl::aliveStatus()) return;
if (!LogImpl::aliveStatus())
return;

LogImpl::getInstance().locked([&tag](LogImpl& log) { log.clearLevel(tag); });
}

void Log::clearLevels() {
if (!LogImpl::aliveStatus()) return;
if (!LogImpl::aliveStatus())
return;

LogImpl::getInstance().locked([](LogImpl& log) { log.clearLevels(); });
}

void Log::applyFilterGroup(const FilterGroup& filters) {
if (!LogImpl::aliveStatus()) return;
if (!LogImpl::aliveStatus())
return;

LogImpl::getInstance().locked([&filters](LogImpl& log) {
log.clearLevels();
log.clearLevels();
auto defaultLevel = filters.getLevel();
if (defaultLevel) log.setLevel(*defaultLevel);
if (defaultLevel)
log.setLevel(*defaultLevel);
for (const auto& tagLevel : filters.m_tagLevels)
log.setLevel(tagLevel.second, tagLevel.first);
});
}

bool Log::isEnabled(Level level) {
if (!LogImpl::aliveStatus()) return false;
if (!LogImpl::aliveStatus())
return false;

return LogImpl::getInstance().locked(
[level](const LogImpl& log) { return log.isEnabled(level); });
}

bool Log::isEnabled(Level level, const std::string& tag) {
if (!LogImpl::aliveStatus()) return false;
if (!LogImpl::aliveStatus())
return false;

return LogImpl::getInstance().locked(
[level, &tag](const LogImpl& log) { return log.isEnabled(level, tag); });
Expand All @@ -279,12 +350,28 @@ void Log::logMessage(Level level, const std::string& tag,
const std::string& message, const char* file,
unsigned int line, const char* function,
const char* fullFunction) {
if (!LogImpl::aliveStatus()) return;
if (!LogImpl::aliveStatus())
return;

LogImpl::getInstance().locked([&](LogImpl& log) {
log.logMessage(level, tag, message, file, line, function, fullFunction);
});
}

void Log::addCensor(const std::string& message) {
if (!LogImpl::aliveStatus())
return;

LogImpl::getInstance().locked([&](LogImpl& log) { log.addCensor(message); });
}

void Log::removeCensor(const std::string& message) {
if (!LogImpl::aliveStatus())
return;

LogImpl::getInstance().locked(
[&](LogImpl& log) { log.removeCensor(message); });
}

} // namespace logging
} // namespace olp
Loading
Loading