logger.cpp 4.1 KB

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