logger.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. #include "logger.h"
  2. #include <library/cpp/unified_agent_client/clock.h>
  3. #include <library/cpp/logger/log.h>
  4. #include <util/datetime/base.h>
  5. #include <util/stream/str.h>
  6. #include <util/system/getpid.h>
  7. #include <util/system/thread.h>
  8. namespace NUnifiedAgent {
  9. namespace {
  10. TString FormatLogLine(ELogPriority logLevel, const TStringBuf message, const TString& scope) {
  11. TString result;
  12. {
  13. TStringOutput output(result);
  14. output << FormatIsoLocal(TClock::Now())
  15. << " " << GetPID()
  16. << " " << TThread::CurrentThreadId()
  17. << " " << logLevel;
  18. if (!scope.Empty()) {
  19. output << " " << scope;
  20. }
  21. output << " " << message << "\n";
  22. }
  23. return result;
  24. }
  25. }
  26. TLogger::TThrottlerWithLock::TThrottlerWithLock(size_t rateLimitBytes)
  27. : Throttler(rateLimitBytes, rateLimitBytes / 2)
  28. , Lock()
  29. {
  30. }
  31. bool TLogger::TThrottlerWithLock::TryConsume(double tokens) {
  32. with_lock(Lock) {
  33. return Throttler.TryConsume(tokens);
  34. }
  35. }
  36. TLogger::TLogger(TLog& log, TFMaybe<size_t> rateLimitBytes)
  37. : DefaultLogContext{log, log.IsNullLog() ? ELogPriority::TLOG_EMERG : log.FiltrationLevel()}
  38. , TracingLogContexts()
  39. , CurrentLogContext_()
  40. , Errors(nullptr)
  41. , DroppedBytes(nullptr)
  42. , Throttler(rateLimitBytes.Defined() ? MakeHolder<TThrottlerWithLock>(*rateLimitBytes) : nullptr)
  43. , Lock()
  44. {
  45. SetCurrentLogContext(DefaultLogContext);
  46. }
  47. void TLogger::SetCurrentLogContext(TLogContext& logContext) {
  48. CurrentLogContext_.store(logContext.Log.IsNullLog() ? nullptr : &logContext, std::memory_order_release);
  49. }
  50. void TLogger::Log(TLog& log, ELogPriority logPriority, const TStringBuf message, const TString& scope) const {
  51. try {
  52. const auto logLine = FormatLogLine(logPriority, message, scope);
  53. if (Throttler && &log == &DefaultLogContext.Log && !Throttler->TryConsume(logLine.size())) {
  54. if (DroppedBytes) {
  55. DroppedBytes->Add(logLine.size());
  56. }
  57. return;
  58. }
  59. log.Write(logPriority, logLine);
  60. } catch (...) {
  61. }
  62. }
  63. void TLogger::StartTracing(ELogPriority logPriority) noexcept {
  64. with_lock(Lock) {
  65. auto& logContext = GetOrCreateTracingLogContext(logPriority);
  66. SetTracing(logContext, "started");
  67. }
  68. }
  69. void TLogger::FinishTracing() noexcept {
  70. with_lock(Lock) {
  71. SetTracing(DefaultLogContext, "finished");
  72. }
  73. }
  74. void TLogger::SetTracing(TLogContext& logContext, const char* action) {
  75. // Lock must be held
  76. SetCurrentLogContext(logContext);
  77. Log(logContext.Log,
  78. TLOG_INFO,
  79. Sprintf("tracing %s, log priority is set to [%s]",
  80. action, ToString(logContext.Priority).c_str()),
  81. "");
  82. }
  83. auto TLogger::GetOrCreateTracingLogContext(ELogPriority logPriority) -> TLogContext& {
  84. // Lock must be held
  85. for (const auto& c: TracingLogContexts) {
  86. if (c->Priority == logPriority) {
  87. return *c;
  88. }
  89. }
  90. auto newLogContext = MakeHolder<TLogContext>();
  91. newLogContext->Log = TLog("cerr", logPriority);
  92. newLogContext->Priority = logPriority;
  93. auto* result = newLogContext.Get();
  94. TracingLogContexts.push_back(std::move(newLogContext));
  95. return *result;
  96. }
  97. TScopeLogger::TScopeLogger()
  98. : Logger(nullptr)
  99. , Scope()
  100. , Errors(nullptr)
  101. {
  102. }
  103. TScopeLogger::TScopeLogger(TLogger* logger,
  104. const TString& scope,
  105. NMonitoring::TDeprecatedCounter* errors)
  106. : Logger(logger)
  107. , Scope(scope)
  108. , Errors(errors)
  109. {
  110. }
  111. }