common.h 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. #pragma once
  2. #include <util/datetime/base.h>
  3. #include <util/folder/path.h>
  4. #include <util/generic/singleton.h>
  5. #include <util/generic/string.h>
  6. #include <util/generic/ptr.h>
  7. #include <util/generic/yexception.h>
  8. #include <util/string/printf.h>
  9. #include <util/system/src_location.h>
  10. #include <library/cpp/logger/log.h>
  11. namespace NLoggingImpl {
  12. const size_t SingletonPriority = 500;
  13. }
  14. template <class T>
  15. T* CreateDefaultLogger() {
  16. return nullptr;
  17. }
  18. namespace NLoggingImpl {
  19. template<class T, class TTraits>
  20. class TOperatorBase {
  21. struct TPtr {
  22. TPtr()
  23. : Instance(TTraits::CreateDefault())
  24. {
  25. }
  26. THolder<T> Instance;
  27. };
  28. public:
  29. inline static bool Usage() {
  30. return SingletonWithPriority<TPtr, SingletonPriority>()->Instance.Get();
  31. }
  32. inline static T* Get() {
  33. return SingletonWithPriority<TPtr, SingletonPriority>()->Instance.Get();
  34. }
  35. inline static void Set(T* v) {
  36. SingletonWithPriority<TPtr, SingletonPriority>()->Instance.Reset(v);
  37. }
  38. };
  39. template<class T>
  40. struct TLoggerTraits {
  41. static T* CreateDefault() {
  42. return CreateDefaultLogger<T>();
  43. }
  44. };
  45. }
  46. template <class T>
  47. class TLoggerOperator : public NLoggingImpl::TOperatorBase<T, NLoggingImpl::TLoggerTraits<T>> {
  48. public:
  49. inline static TLog& Log() {
  50. Y_ASSERT(TLoggerOperator::Usage());
  51. return *TLoggerOperator::Get();
  52. }
  53. };
  54. namespace NLoggingImpl {
  55. TString GetLocalTimeSSimple();
  56. // Returns correct log type to use
  57. TString PrepareToOpenLog(TString logType, int logLevel, bool rotation, bool startAsDaemon);
  58. template <class TLoggerType>
  59. void InitLogImpl(TString logType, const int logLevel, const bool rotation, const bool startAsDaemon) {
  60. TLoggerOperator<TLoggerType>::Set(new TLoggerType(PrepareToOpenLog(logType, logLevel, rotation, startAsDaemon), (ELogPriority)logLevel));
  61. }
  62. }
  63. struct TLogRecordContext {
  64. constexpr TLogRecordContext(const TSourceLocation& sourceLocation, TStringBuf customMessage, ELogPriority priority)
  65. : SourceLocation(sourceLocation)
  66. , CustomMessage(customMessage)
  67. , Priority(priority)
  68. {}
  69. TSourceLocation SourceLocation;
  70. TStringBuf CustomMessage;
  71. ELogPriority Priority;
  72. };
  73. template <class... R>
  74. struct TLogRecordPreprocessor;
  75. template <>
  76. struct TLogRecordPreprocessor<> {
  77. inline static bool CheckLoggingContext(TLog& /*log*/, const TLogRecordContext& /*context*/) {
  78. return true;
  79. }
  80. inline static TSimpleSharedPtr<TLogElement> StartRecord(TLog& log, const TLogRecordContext& context, TSimpleSharedPtr<TLogElement> earlier) {
  81. if (earlier)
  82. return earlier;
  83. TSimpleSharedPtr<TLogElement> result(new TLogElement(&log));
  84. *result << context.Priority;
  85. return result;
  86. }
  87. };
  88. template <class H, class... R>
  89. struct TLogRecordPreprocessor<H, R...> {
  90. inline static bool CheckLoggingContext(TLog& log, const TLogRecordContext& context) {
  91. return H::CheckLoggingContext(log, context) && TLogRecordPreprocessor<R...>::CheckLoggingContext(log, context);
  92. }
  93. inline static TSimpleSharedPtr<TLogElement> StartRecord(TLog& log, const TLogRecordContext& context, TSimpleSharedPtr<TLogElement> earlier) {
  94. TSimpleSharedPtr<TLogElement> first = H::StartRecord(log, context, earlier);
  95. return TLogRecordPreprocessor<R...>::StartRecord(log, context, first);
  96. }
  97. };
  98. struct TLogFilter {
  99. static bool CheckLoggingContext(TLog& log, const TLogRecordContext& context);
  100. static TSimpleSharedPtr<TLogElement> StartRecord(TLog& log, const TLogRecordContext& context, TSimpleSharedPtr<TLogElement> earlier);
  101. };
  102. class TNullLog;
  103. template <class TPreprocessor>
  104. TSimpleSharedPtr<TLogElement> GetLoggerForce(TLog& log, const TLogRecordContext& context) {
  105. if (TSimpleSharedPtr<TLogElement> result = TPreprocessor::StartRecord(log, context, nullptr))
  106. return result;
  107. return new TLogElement(&TLoggerOperator<TNullLog>::Log());
  108. }
  109. namespace NPrivateGlobalLogger {
  110. struct TEatStream {
  111. Y_FORCE_INLINE bool operator|(const IOutputStream&) const {
  112. return true;
  113. }
  114. };
  115. }
  116. #define LOGGER_GENERIC_LOG_CHECKED(logger, preprocessor, level, message) (*GetLoggerForce<preprocessor>(logger, TLogRecordContext(__LOCATION__, message, level)))
  117. #define LOGGER_CHECKED_GENERIC_LOG(logger, preprocessor, level, message) \
  118. (preprocessor::CheckLoggingContext(logger, TLogRecordContext(__LOCATION__, message, level))) && NPrivateGlobalLogger::TEatStream() | (*(preprocessor::StartRecord(logger, TLogRecordContext(__LOCATION__, message, level), nullptr)))
  119. #define SINGLETON_GENERIC_LOG_CHECKED(type, preprocessor, level, message) LOGGER_GENERIC_LOG_CHECKED(TLoggerOperator<type>::Log(), preprocessor, level, message)
  120. #define SINGLETON_CHECKED_GENERIC_LOG(type, preprocessor, level, message) LOGGER_CHECKED_GENERIC_LOG(TLoggerOperator<type>::Log(), preprocessor, level, message)