2323
2424#include < olp/core/logging/Configuration.h>
2525#include < olp/core/logging/FilterGroup.h>
26+ #include < olp/core/porting/optional.h>
2627#include < olp/core/thread/Atomic.h>
2728
2829#include < string>
2930#include < unordered_map>
3031
3132namespace olp {
3233namespace logging {
34+
35+ namespace {
36+
37+ constexpr auto kSecretMask = " *****" ;
38+ }
39+
40+ struct LogMessageExt : public LogMessage {
41+ olp::porting::optional<std::string> adjusted_message;
42+ };
43+
3344class LogImpl {
3445 public:
3546 friend class olp ::thread::Atomic<logging::LogImpl>;
@@ -67,14 +78,20 @@ class LogImpl {
6778 unsigned int line, const char * function,
6879 const char * fullFunction);
6980
81+ void censor (std::string msg);
82+
7083 private:
7184 LogImpl ();
7285 template <class LogItem >
7386 void appendLogItem (const LogItem& log_item);
7487
88+ template <class LogItem >
89+ void censorLogItem (LogItem& log_item, const std::string& original);
90+
7591 Configuration m_configuration;
7692 std::unordered_map<std::string, Level> m_logLevels;
7793 Level m_defaultLevel;
94+ std::vector<std::string> m_toCensor;
7895};
7996
8097LogImpl::LogImpl ()
@@ -120,7 +137,8 @@ void LogImpl::setLevel(Level level, const std::string& tag) {
120137}
121138
122139porting::optional<Level> LogImpl::getLevel (const std::string& tag) const {
123- if (tag.empty ()) return getLevel ();
140+ if (tag.empty ())
141+ return getLevel ();
124142
125143 auto foundIter = m_logLevels.find (tag);
126144 if (foundIter == m_logLevels.end ())
@@ -130,21 +148,24 @@ porting::optional<Level> LogImpl::getLevel(const std::string& tag) const {
130148}
131149
132150void LogImpl::clearLevel (const std::string& tag) {
133- if (tag.empty ()) return ;
151+ if (tag.empty ())
152+ return ;
134153
135154 m_logLevels.erase (tag);
136155}
137156
138157void LogImpl::clearLevels () { m_logLevels.clear (); }
139158
140159bool LogImpl::isEnabled (Level level) const {
141- if (level == Level::Off) return false ;
160+ if (level == Level::Off)
161+ return false ;
142162
143163 return static_cast <int >(level) >= static_cast <int >(m_defaultLevel);
144164}
145165
146166bool LogImpl::isEnabled (Level level, const std::string& tag) const {
147- if (level == Level::Off) return false ;
167+ if (level == Level::Off)
168+ return false ;
148169
149170 auto foundIter = m_logLevels.find (tag);
150171 Level targetLevel;
@@ -159,7 +180,7 @@ void LogImpl::logMessage(Level level, const std::string& tag,
159180 const std::string& message, const char * file,
160181 unsigned int line, const char * function,
161182 const char * fullFunction) {
162- LogMessage logMessage;
183+ LogMessageExt logMessage;
163184 logMessage.level = level;
164185 logMessage.tag = tag.c_str ();
165186 logMessage.message = message.c_str ();
@@ -170,6 +191,7 @@ void LogImpl::logMessage(Level level, const std::string& tag,
170191 logMessage.time = std::chrono::system_clock::now ();
171192 logMessage.threadId = getThreadId ();
172193
194+ censorLogItem (logMessage, message);
173195 appendLogItem (logMessage);
174196}
175197
@@ -181,95 +203,134 @@ void LogImpl::appendLogItem(const LogItem& log_item) {
181203 }
182204}
183205
206+ template <class LogItem >
207+ void LogImpl::censorLogItem (LogItem& log_item, const std::string& original) {
208+ bool has_copy = log_item.adjusted_message .has_value ();
209+ const std::string& src =
210+ has_copy ? log_item.adjusted_message .value () : original;
211+
212+ for (const std::string& secret : m_toCensor) {
213+ auto found_pos = src.find (secret);
214+ while (found_pos != std::string::npos) {
215+ if (!has_copy) {
216+ log_item.adjusted_message = original;
217+ has_copy = true ;
218+ log_item.message = log_item.adjusted_message .value ().c_str ();
219+ }
220+ log_item.adjusted_message .value ().replace (found_pos, secret.length (),
221+ kSecretMask );
222+ found_pos = log_item.adjusted_message .value ().find (secret, found_pos);
223+ }
224+ }
225+ }
226+
227+ void LogImpl::censor (std::string msg) {
228+ m_toCensor.emplace_back (std::move (msg));
229+ }
230+
184231// implementation of public static Log API
185232// --------------------------------------------------------
186233
187234bool Log::configure (Configuration configuration) {
188- if (!LogImpl::aliveStatus ()) return false ;
235+ if (!LogImpl::aliveStatus ())
236+ return false ;
189237
190238 return LogImpl::getInstance ().locked ([&configuration](LogImpl& log) {
191239 return log.configure (std::move (configuration));
192240 });
193241}
194242
195243Configuration Log::getConfiguration () {
196- if (!LogImpl::aliveStatus ()) return Configuration ();
244+ if (!LogImpl::aliveStatus ())
245+ return Configuration ();
197246
198247 return LogImpl::getInstance ().locked (
199248 [](const LogImpl& log) { return log.getConfiguration (); });
200249}
201250
202251void Log::setLevel (Level level) {
203- if (!LogImpl::aliveStatus ()) return ;
252+ if (!LogImpl::aliveStatus ())
253+ return ;
204254
205255 LogImpl::getInstance ().locked ([level](LogImpl& log) { log.setLevel (level); });
206256}
207257
208258Level Log::getLevel () {
209- if (!LogImpl::aliveStatus ()) return Level::Off;
259+ if (!LogImpl::aliveStatus ())
260+ return Level::Off;
210261
211262 return LogImpl::getInstance ().locked (
212263 [](const LogImpl& log) { return log.getLevel (); });
213264}
214265
215266void Log::setLevel (Level level, const std::string& tag) {
216- if (!LogImpl::aliveStatus ()) return ;
267+ if (!LogImpl::aliveStatus ())
268+ return ;
217269
218270 LogImpl::getInstance ().locked (
219271 [level, &tag](LogImpl& log) { log.setLevel (level, tag); });
220272}
221273
222274void Log::setLevel (const std::string& level, const std::string& tag) {
223275 auto log_level = FilterGroup::stringToLevel (level);
224- if (!log_level) return ;
276+ if (!log_level)
277+ return ;
225278
226- if (!LogImpl::aliveStatus ()) return ;
279+ if (!LogImpl::aliveStatus ())
280+ return ;
227281
228282 LogImpl::getInstance ().locked (
229283 [&log_level, &tag](LogImpl& log) { log.setLevel (*log_level, tag); });
230284}
231285
232286porting::optional<Level> Log::getLevel (const std::string& tag) {
233- if (!LogImpl::aliveStatus ()) return porting::none;
287+ if (!LogImpl::aliveStatus ())
288+ return porting::none;
234289
235290 return LogImpl::getInstance ().locked (
236291 [&tag](const LogImpl& log) { return log.getLevel (tag); });
237292}
238293
239294void Log::clearLevel (const std::string& tag) {
240- if (!LogImpl::aliveStatus ()) return ;
295+ if (!LogImpl::aliveStatus ())
296+ return ;
241297
242298 LogImpl::getInstance ().locked ([&tag](LogImpl& log) { log.clearLevel (tag); });
243299}
244300
245301void Log::clearLevels () {
246- if (!LogImpl::aliveStatus ()) return ;
302+ if (!LogImpl::aliveStatus ())
303+ return ;
247304
248305 LogImpl::getInstance ().locked ([](LogImpl& log) { log.clearLevels (); });
249306}
250307
251308void Log::applyFilterGroup (const FilterGroup& filters) {
252- if (!LogImpl::aliveStatus ()) return ;
309+ if (!LogImpl::aliveStatus ())
310+ return ;
253311
254312 LogImpl::getInstance ().locked ([&filters](LogImpl& log) {
255313 log.clearLevels ();
256314 log.clearLevels ();
257315 auto defaultLevel = filters.getLevel ();
258- if (defaultLevel) log.setLevel (*defaultLevel);
316+ if (defaultLevel)
317+ log.setLevel (*defaultLevel);
259318 for (const auto & tagLevel : filters.m_tagLevels )
260319 log.setLevel (tagLevel.second , tagLevel.first );
261320 });
262321}
263322
264323bool Log::isEnabled (Level level) {
265- if (!LogImpl::aliveStatus ()) return false ;
324+ if (!LogImpl::aliveStatus ())
325+ return false ;
266326
267327 return LogImpl::getInstance ().locked (
268328 [level](const LogImpl& log) { return log.isEnabled (level); });
269329}
270330
271331bool Log::isEnabled (Level level, const std::string& tag) {
272- if (!LogImpl::aliveStatus ()) return false ;
332+ if (!LogImpl::aliveStatus ())
333+ return false ;
273334
274335 return LogImpl::getInstance ().locked (
275336 [level, &tag](const LogImpl& log) { return log.isEnabled (level, tag); });
@@ -279,12 +340,20 @@ void Log::logMessage(Level level, const std::string& tag,
279340 const std::string& message, const char * file,
280341 unsigned int line, const char * function,
281342 const char * fullFunction) {
282- if (!LogImpl::aliveStatus ()) return ;
343+ if (!LogImpl::aliveStatus ())
344+ return ;
283345
284346 LogImpl::getInstance ().locked ([&](LogImpl& log) {
285347 log.logMessage (level, tag, message, file, line, function, fullFunction);
286348 });
287349}
288350
351+ void Log::censor (const std::string& message) {
352+ if (!LogImpl::aliveStatus ())
353+ return ;
354+
355+ LogImpl::getInstance ().locked ([&](LogImpl& log) { log.censor (message); });
356+ }
357+
289358} // namespace logging
290359} // namespace olp
0 commit comments