summaryrefslogtreecommitdiffstats
path: root/library/cpp/actors/core/log_buffer.cpp
diff options
context:
space:
mode:
authorandrew-rykov <[email protected]>2022-09-15 16:44:36 +0300
committerandrew-rykov <[email protected]>2022-09-15 16:44:36 +0300
commit67ddc7744f2c537a293745383c33e324fbf08928 (patch)
tree596c2c382226b2cdaf9913e32a4fe41e7f0f1dda /library/cpp/actors/core/log_buffer.cpp
parent343f348b324943ca4364be11cad7c9e69fec348c (diff)
add log buffer 3
Diffstat (limited to 'library/cpp/actors/core/log_buffer.cpp')
-rw-r--r--library/cpp/actors/core/log_buffer.cpp136
1 files changed, 73 insertions, 63 deletions
diff --git a/library/cpp/actors/core/log_buffer.cpp b/library/cpp/actors/core/log_buffer.cpp
index 4a05f9a8c25..8c80f1d054b 100644
--- a/library/cpp/actors/core/log_buffer.cpp
+++ b/library/cpp/actors/core/log_buffer.cpp
@@ -6,93 +6,103 @@
using namespace NActors::NLog;
namespace NActors {
-TLogBufferMessage::TLogBufferMessage(NLog::TEvLog::TPtr& ev)
- : Formatted(ev->Get()->Line)
- , Time(ev->Get()->Stamp)
- , Component(ev->Get()->Component)
- , Priority(ev->Get()->Level.ToPrio())
-{}
-
-TLogBuffer::TLogBuffer(ILoggerMetrics *metrics)
+TLogBuffer::TLogBuffer(ILoggerMetrics &metrics, const NLog::TSettings &settings)
: Metrics(metrics)
+ , Settings(settings)
{}
-bool TLogBuffer::TryAddMessage(TLogBufferMessage message) {
- Buffer.push_back(std::move(message));
- BufferSize += sizeof(message);
- PrioStats[message.Priority]++;
+size_t TLogBuffer::GetLogCostInBytes(NLog::TEvLog *log) const {
+ return LOG_STRUCTURE_BYTES + log->Line.length();
+}
- return true;
+ui16 TLogBuffer::GetPrioIndex(NLog::EPrio prio) {
+ return Min(ui16(prio), ui16(LOG_PRIORITIES_NUMBER - 1));
}
-TLogBufferMessage TLogBuffer::GetMessage() {
- auto message = Buffer.front();
+TIntrusiveList<NLog::TEvLog, NLog::TEvLogBufferLevelListTag> &TLogBuffer::GetPrioLogs(NLog::EPrio prio) {
+ return PrioLogsList[GetPrioIndex(prio)];
+}
- ui64 messageSize = sizeof(message);
- BufferSize -= messageSize;
- Buffer.pop_front();
- PrioStats[message.Priority]--;
+void TLogBuffer::AddLog(NLog::TEvLog *log) {
+ NLog::EPrio prio = log->Level.ToPrio();
+ if (!CheckSize(log) && prio > NLog::EPrio::Emerg) { // always keep logs with prio Emerg = 0
+ HandleIgnoredLog(log);
+ return;
+ }
- return message;
+ SizeBytes += GetLogCostInBytes(log);
+ Logs.PushBack(log);
+ GetPrioLogs(prio).PushBack(log);
}
-bool TLogBuffer::IsEmpty() const {
- return Buffer.empty();
+NLog::TEvLog* TLogBuffer::Pop() {
+ NLog::TEvLog* log = Logs.PopFront();
+ static_cast<TIntrusiveListItem<TEvLog, TEvLogBufferLevelListTag>&>(*log).Unlink();
+
+ SizeBytes -= GetLogCostInBytes(log);
+
+ return log;
}
-size_t TLogBuffer::GetLogsNumber() const {
- return Buffer.size();
+bool TLogBuffer::IsEmpty() const {
+ return Logs.Empty();
}
-ui64 TLogBuffer::GetSizeBytes() const {
- return BufferSize;
+bool TLogBuffer::CheckLogIgnoring() const {
+ return IgnoredCount > 0;
}
-void TLogBuffer::FilterByLogPriority(NLog::EPrio prio) {
- bool isFirstRemoving = true;
- auto it = Buffer.begin();
- while (it != Buffer.end())
- {
- if (it->Priority >= prio) {
- ui64 messageSize = sizeof(*it);
- BufferSize -= messageSize;
- Metrics->IncIgnoredMsgs();
- PrioStats[it->Priority]--;
+bool TLogBuffer::CheckSize(NLog::TEvLog *log) {
+ size_t startSizeBytes = SizeBytes;
- if (isFirstRemoving && prio > NLog::EPrio::Error) {
- it->Priority = NLog::EPrio::Error;
- it->Formatted = Sprintf("Ignored log records due to log buffer overflow! IgnoredCount# %" PRIu32 " ", PrioStats[prio]);
+ size_t logSize = GetLogCostInBytes(log);
+ if (SizeBytes + logSize <= Settings.BufferSizeLimitBytes) {
+ return true;
+ }
- PrioStats[NLog::EPrio::Error]++;
- BufferSize += sizeof(*it);
- it++;
- isFirstRemoving = false;
+ ui16 scanHighestPrio = Max((ui16)1, GetPrioIndex(log->Level.ToPrio())); // always keep logs with prio Emerg = 0
+ for (ui16 scanPrio = LOG_PRIORITIES_NUMBER - 1; scanPrio >= scanHighestPrio; scanPrio--) {
+ TIntrusiveList<NLog::TEvLog, NLog::TEvLogBufferLevelListTag> &scanLogs = PrioLogsList[scanPrio];
+ while (!scanLogs.Empty()) {
+ NLog::TEvLog* log = scanLogs.PopFront();
+ SizeBytes -= GetLogCostInBytes(log);
+ HandleIgnoredLog(log);
+
+ if (SizeBytes + logSize <= Settings.BufferSizeLimitBytes) {
+ return true;
}
- else {
- it = Buffer.erase(it);
- }
- }
- else {
- it++;
}
}
-}
-bool inline TLogBuffer::CheckMessagesNumberEnoughForClearing(ui32 number) {
- return number * 10 > Buffer.size();
+ if (startSizeBytes > SizeBytes) {
+ return true;
+ }
+
+ return false;
}
-bool TLogBuffer::TryReduceLogsNumber() {
- ui32 removeLogsNumber = 0;
- for (ui16 p = ui16(NLog::EPrio::Trace); p > ui16(NLog::EPrio::Alert); p--)
- {
- NLog::EPrio prio = static_cast<NLog::EPrio>(p);
- removeLogsNumber += PrioStats[prio];
- if (CheckMessagesNumberEnoughForClearing(removeLogsNumber)) {
- FilterByLogPriority(prio);
- return true;
- }
+void TLogBuffer::HandleIgnoredLog(NLog::TEvLog *log) {
+ ui16 logPrio = GetPrioIndex(log->Level.ToPrio());
+ Metrics.IncIgnoredMsgs();
+ if (IgnoredHighestPrio > logPrio) {
+ IgnoredHighestPrio = logPrio;
}
- return false;
+ IgnoredCount++;
+ delete log;
+}
+
+ui64 TLogBuffer::GetIgnoredCount() {
+ return IgnoredCount;
+}
+
+NLog::EPrio TLogBuffer::GetIgnoredHighestPrio() {
+ NLog::EPrio prio = static_cast<NLog::EPrio>(IgnoredHighestPrio);
+ return prio;
}
+
+void TLogBuffer::ClearIgnoredCount() {
+ IgnoredHighestPrio = LOG_PRIORITIES_NUMBER - 1;
+ IgnoredCount = 0;
+}
+
}