log_settings.h 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. #pragma once
  2. #include "actor.h"
  3. #include "log_iface.h"
  4. #include <util/generic/vector.h>
  5. #include <util/digest/murmur.h>
  6. #include <util/random/easy.h>
  7. namespace NActors {
  8. namespace NLog {
  9. inline const char* PriorityToString(EPrio priority) {
  10. switch (priority) {
  11. case EPrio::Emerg:
  12. return "EMERG";
  13. case EPrio::Alert:
  14. return "ALERT";
  15. case EPrio::Crit:
  16. return "CRIT";
  17. case EPrio::Error:
  18. return "ERROR";
  19. case EPrio::Warn:
  20. return "WARN";
  21. case EPrio::Notice:
  22. return "NOTICE";
  23. case EPrio::Info:
  24. return "INFO";
  25. case EPrio::Debug:
  26. return "DEBUG";
  27. case EPrio::Trace:
  28. return "TRACE";
  29. default:
  30. return "UNKNOWN";
  31. }
  32. }
  33. // You can structure your program to have multiple logical components.
  34. // In this case you can set different log priorities for different
  35. // components. And you can change component's priority while system
  36. // is running. Suspect a component has a bug? Turn DEBUG priority level on
  37. // for this component.
  38. static const int InvalidComponent = -1;
  39. // Functions converts EComponent id to string
  40. using EComponentToStringFunc = std::function<const TString&(EComponent)>;
  41. ;
  42. // Log settings
  43. struct TComponentSettings {
  44. union {
  45. struct {
  46. ui32 SamplingRate;
  47. ui8 SamplingLevel;
  48. ui8 Level;
  49. } X;
  50. ui64 Data;
  51. } Raw;
  52. TComponentSettings(TAtomicBase data) {
  53. Raw.Data = (ui64)data;
  54. }
  55. TComponentSettings(ui8 level, ui8 samplingLevel, ui32 samplingRate) {
  56. Raw.X.Level = level;
  57. Raw.X.SamplingLevel = samplingLevel;
  58. Raw.X.SamplingRate = samplingRate;
  59. }
  60. };
  61. struct TSettings: public TThrRefBase {
  62. public:
  63. TActorId LoggerActorId;
  64. EComponent LoggerComponent;
  65. ui64 TimeThresholdMs;
  66. bool AllowDrop;
  67. TDuration ThrottleDelay;
  68. TArrayHolder<TAtomic> ComponentInfo;
  69. TVector<TString> ComponentNames;
  70. EComponent MinVal;
  71. EComponent MaxVal;
  72. EComponent Mask;
  73. EPriority DefPriority;
  74. EPriority DefSamplingPriority;
  75. ui32 DefSamplingRate;
  76. bool UseLocalTimestamps;
  77. enum ELogFormat {
  78. PLAIN_FULL_FORMAT,
  79. PLAIN_SHORT_FORMAT,
  80. JSON_FORMAT
  81. };
  82. ELogFormat Format;
  83. TString ShortHostName;
  84. TString ClusterName;
  85. TString MessagePrefix;
  86. // The best way to provide minVal, maxVal and func is to have
  87. // protobuf enumeration of components. In this case protoc
  88. // automatically generates YOURTYPE_MIN, YOURTYPE_MAX and
  89. // YOURTYPE_Name for you.
  90. TSettings(const TActorId& loggerActorId, const EComponent loggerComponent,
  91. EComponent minVal, EComponent maxVal, EComponentToStringFunc func,
  92. EPriority defPriority, EPriority defSamplingPriority = PRI_DEBUG,
  93. ui32 defSamplingRate = 0, ui64 timeThresholdMs = 1000);
  94. TSettings(const TActorId& loggerActorId, const EComponent loggerComponent,
  95. EPriority defPriority, EPriority defSamplingPriority = PRI_DEBUG,
  96. ui32 defSamplingRate = 0, ui64 timeThresholdMs = 1000);
  97. void Append(EComponent minVal, EComponent maxVal, EComponentToStringFunc func);
  98. template <typename T>
  99. void Append(T minVal, T maxVal, const TString& (*func)(T)) {
  100. Append(
  101. static_cast<EComponent>(minVal),
  102. static_cast<EComponent>(maxVal),
  103. [func](EComponent c) -> const TString& {
  104. return func(static_cast<T>(c));
  105. }
  106. );
  107. }
  108. inline bool Satisfies(EPriority priority, EComponent component, ui64 sampleBy = 0) const {
  109. // by using Mask we don't get outside of array boundaries
  110. TComponentSettings settings = GetComponentSettings(component);
  111. if (priority > settings.Raw.X.Level) {
  112. if (priority > settings.Raw.X.SamplingLevel) {
  113. return false; // priority > both levels ==> do not log
  114. }
  115. // priority <= sampling level ==> apply sampling
  116. ui32 samplingRate = settings.Raw.X.SamplingRate;
  117. if (samplingRate) {
  118. ui32 samplingValue = sampleBy ? MurmurHash<ui32>((const char*)&sampleBy, sizeof(sampleBy))
  119. : samplingRate != 1 ? RandomNumber<ui32>() : 0;
  120. return (samplingValue % samplingRate == 0);
  121. } else {
  122. // sampling rate not set ==> do not log
  123. return false;
  124. }
  125. } else {
  126. // priority <= log level ==> log
  127. return true;
  128. }
  129. }
  130. inline TComponentSettings GetComponentSettings(EComponent component) const {
  131. Y_VERIFY_DEBUG((component & Mask) == component);
  132. // by using Mask we don't get outside of array boundaries
  133. return TComponentSettings(AtomicGet(ComponentInfo[component & Mask]));
  134. }
  135. const char* ComponentName(EComponent component) const {
  136. Y_VERIFY_DEBUG((component & Mask) == component);
  137. return ComponentNames[component & Mask].data();
  138. }
  139. int SetLevel(EPriority priority, EComponent component, TString& explanation);
  140. int SetSamplingLevel(EPriority priority, EComponent component, TString& explanation);
  141. int SetSamplingRate(ui32 sampling, EComponent component, TString& explanation);
  142. EComponent FindComponent(const TStringBuf& componentName) const;
  143. static int PowerOf2Mask(int val);
  144. static bool IsValidPriority(EPriority priority);
  145. bool IsValidComponent(EComponent component);
  146. void SetAllowDrop(bool val);
  147. void SetThrottleDelay(TDuration value);
  148. void SetUseLocalTimestamps(bool value);
  149. private:
  150. int SetLevelImpl(
  151. const TString& name, bool isSampling,
  152. EPriority priority, EComponent component, TString& explanation);
  153. };
  154. }
  155. }