globals.cc 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. // Copyright 2022 The Abseil Authors.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // https://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #include "absl/log/globals.h"
  15. #include <stddef.h>
  16. #include <stdint.h>
  17. #include <atomic>
  18. #include "absl/base/attributes.h"
  19. #include "absl/base/config.h"
  20. #include "absl/base/internal/atomic_hook.h"
  21. #include "absl/base/log_severity.h"
  22. #include "absl/hash/hash.h"
  23. #include "absl/strings/string_view.h"
  24. namespace absl {
  25. ABSL_NAMESPACE_BEGIN
  26. namespace {
  27. // These atomics represent logging library configuration.
  28. // Integer types are used instead of absl::LogSeverity to ensure that a
  29. // lock-free std::atomic is used when possible.
  30. ABSL_CONST_INIT std::atomic<int> min_log_level{
  31. static_cast<int>(absl::LogSeverityAtLeast::kInfo)};
  32. ABSL_CONST_INIT std::atomic<int> stderrthreshold{
  33. static_cast<int>(absl::LogSeverityAtLeast::kError)};
  34. // We evaluate this value as a hash comparison to avoid having to
  35. // hold a mutex or make a copy (to access the value of a string-typed flag) in
  36. // very hot codepath.
  37. ABSL_CONST_INIT std::atomic<size_t> log_backtrace_at_hash{0};
  38. ABSL_CONST_INIT std::atomic<bool> prepend_log_prefix{true};
  39. ABSL_INTERNAL_ATOMIC_HOOK_ATTRIBUTES
  40. absl::base_internal::AtomicHook<log_internal::LoggingGlobalsListener>
  41. logging_globals_listener;
  42. size_t HashSiteForLogBacktraceAt(absl::string_view file, int line) {
  43. return absl::HashOf(file, line);
  44. }
  45. void TriggerLoggingGlobalsListener() {
  46. auto* listener = logging_globals_listener.Load();
  47. if (listener != nullptr) listener();
  48. }
  49. } // namespace
  50. namespace log_internal {
  51. void RawSetMinLogLevel(absl::LogSeverityAtLeast severity) {
  52. min_log_level.store(static_cast<int>(severity), std::memory_order_release);
  53. }
  54. void RawSetStderrThreshold(absl::LogSeverityAtLeast severity) {
  55. stderrthreshold.store(static_cast<int>(severity), std::memory_order_release);
  56. }
  57. void RawEnableLogPrefix(bool on_off) {
  58. prepend_log_prefix.store(on_off, std::memory_order_release);
  59. }
  60. void SetLoggingGlobalsListener(LoggingGlobalsListener l) {
  61. logging_globals_listener.Store(l);
  62. }
  63. } // namespace log_internal
  64. absl::LogSeverityAtLeast MinLogLevel() {
  65. return static_cast<absl::LogSeverityAtLeast>(
  66. min_log_level.load(std::memory_order_acquire));
  67. }
  68. void SetMinLogLevel(absl::LogSeverityAtLeast severity) {
  69. log_internal::RawSetMinLogLevel(severity);
  70. TriggerLoggingGlobalsListener();
  71. }
  72. namespace log_internal {
  73. ScopedMinLogLevel::ScopedMinLogLevel(absl::LogSeverityAtLeast severity)
  74. : saved_severity_(absl::MinLogLevel()) {
  75. absl::SetMinLogLevel(severity);
  76. }
  77. ScopedMinLogLevel::~ScopedMinLogLevel() {
  78. absl::SetMinLogLevel(saved_severity_);
  79. }
  80. } // namespace log_internal
  81. absl::LogSeverityAtLeast StderrThreshold() {
  82. return static_cast<absl::LogSeverityAtLeast>(
  83. stderrthreshold.load(std::memory_order_acquire));
  84. }
  85. void SetStderrThreshold(absl::LogSeverityAtLeast severity) {
  86. log_internal::RawSetStderrThreshold(severity);
  87. TriggerLoggingGlobalsListener();
  88. }
  89. ScopedStderrThreshold::ScopedStderrThreshold(absl::LogSeverityAtLeast severity)
  90. : saved_severity_(absl::StderrThreshold()) {
  91. absl::SetStderrThreshold(severity);
  92. }
  93. ScopedStderrThreshold::~ScopedStderrThreshold() {
  94. absl::SetStderrThreshold(saved_severity_);
  95. }
  96. namespace log_internal {
  97. bool ShouldLogBacktraceAt(absl::string_view file, int line) {
  98. const size_t flag_hash =
  99. log_backtrace_at_hash.load(std::memory_order_acquire);
  100. return flag_hash != 0 && flag_hash == HashSiteForLogBacktraceAt(file, line);
  101. }
  102. } // namespace log_internal
  103. void SetLogBacktraceLocation(absl::string_view file, int line) {
  104. log_backtrace_at_hash.store(HashSiteForLogBacktraceAt(file, line),
  105. std::memory_order_release);
  106. }
  107. bool ShouldPrependLogPrefix() {
  108. return prepend_log_prefix.load(std::memory_order_acquire);
  109. }
  110. void EnableLogPrefix(bool on_off) {
  111. log_internal::RawEnableLogPrefix(on_off);
  112. TriggerLoggingGlobalsListener();
  113. }
  114. ABSL_NAMESPACE_END
  115. } // namespace absl