/src/abseil-cpp/absl/log/globals.cc
Line  | Count  | Source  | 
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  |  |  | 
15  |  | #include "absl/log/globals.h"  | 
16  |  |  | 
17  |  | #include <atomic>  | 
18  |  | #include <cstddef>  | 
19  |  | #include <cstdint>  | 
20  |  | #include <cstdlib>  | 
21  |  | #include <cstring>  | 
22  |  | #include <string>  | 
23  |  |  | 
24  |  | #include "absl/base/attributes.h"  | 
25  |  | #include "absl/base/config.h"  | 
26  |  | #include "absl/base/internal/atomic_hook.h"  | 
27  |  | #include "absl/base/internal/raw_logging.h"  | 
28  |  | #include "absl/base/log_severity.h"  | 
29  |  | #include "absl/hash/hash.h"  | 
30  |  | #include "absl/strings/string_view.h"  | 
31  |  |  | 
32  |  | namespace absl { | 
33  |  | ABSL_NAMESPACE_BEGIN  | 
34  |  | namespace { | 
35  |  |  | 
36  |  | // These atomics represent logging library configuration.  | 
37  |  | // Integer types are used instead of absl::LogSeverity to ensure that a  | 
38  |  | // lock-free std::atomic is used when possible.  | 
39  |  | ABSL_CONST_INIT std::atomic<int> min_log_level{ | 
40  |  |     static_cast<int>(absl::LogSeverityAtLeast::kInfo)};  | 
41  |  | ABSL_CONST_INIT std::atomic<int> stderrthreshold{ | 
42  |  |     static_cast<int>(absl::LogSeverityAtLeast::kError)};  | 
43  |  | // We evaluate this value as a hash comparison to avoid having to  | 
44  |  | // hold a mutex or make a copy (to access the value of a string-typed flag) in  | 
45  |  | // very hot codepath.  | 
46  |  | ABSL_CONST_INIT std::atomic<size_t> log_backtrace_at_hash{0}; | 
47  |  | ABSL_CONST_INIT std::atomic<bool> prepend_log_prefix{true}; | 
48  |  |  | 
49  |  | constexpr char kDefaultAndroidTag[] = "native";  | 
50  |  | ABSL_CONST_INIT std::atomic<const char*> android_log_tag{kDefaultAndroidTag}; | 
51  |  |  | 
52  |  | ABSL_INTERNAL_ATOMIC_HOOK_ATTRIBUTES  | 
53  |  | absl::base_internal::AtomicHook<log_internal::LoggingGlobalsListener>  | 
54  |  |     logging_globals_listener;  | 
55  |  |  | 
56  | 0  | size_t HashSiteForLogBacktraceAt(absl::string_view file, int line) { | 
57  | 0  |   return absl::HashOf(file, line);  | 
58  | 0  | }  | 
59  |  |  | 
60  | 0  | void TriggerLoggingGlobalsListener() { | 
61  | 0  |   auto* listener = logging_globals_listener.Load();  | 
62  | 0  |   if (listener != nullptr) listener();  | 
63  | 0  | }  | 
64  |  |  | 
65  |  | }  // namespace  | 
66  |  |  | 
67  |  | namespace log_internal { | 
68  |  |  | 
69  | 0  | void RawSetMinLogLevel(absl::LogSeverityAtLeast severity) { | 
70  | 0  |   min_log_level.store(static_cast<int>(severity), std::memory_order_release);  | 
71  | 0  | }  | 
72  |  |  | 
73  | 0  | void RawSetStderrThreshold(absl::LogSeverityAtLeast severity) { | 
74  | 0  |   stderrthreshold.store(static_cast<int>(severity), std::memory_order_release);  | 
75  | 0  | }  | 
76  |  |  | 
77  | 0  | void RawEnableLogPrefix(bool on_off) { | 
78  | 0  |   prepend_log_prefix.store(on_off, std::memory_order_release);  | 
79  | 0  | }  | 
80  |  |  | 
81  | 0  | void SetLoggingGlobalsListener(LoggingGlobalsListener l) { | 
82  | 0  |   logging_globals_listener.Store(l);  | 
83  | 0  | }  | 
84  |  |  | 
85  |  | }  // namespace log_internal  | 
86  |  |  | 
87  | 4.12M  | absl::LogSeverityAtLeast MinLogLevel() { | 
88  | 4.12M  |   return static_cast<absl::LogSeverityAtLeast>(  | 
89  | 4.12M  |       min_log_level.load(std::memory_order_acquire));  | 
90  | 4.12M  | }  | 
91  |  |  | 
92  | 0  | void SetMinLogLevel(absl::LogSeverityAtLeast severity) { | 
93  | 0  |   log_internal::RawSetMinLogLevel(severity);  | 
94  | 0  |   TriggerLoggingGlobalsListener();  | 
95  | 0  | }  | 
96  |  |  | 
97  |  | namespace log_internal { | 
98  |  |  | 
99  |  | ScopedMinLogLevel::ScopedMinLogLevel(absl::LogSeverityAtLeast severity)  | 
100  | 0  |     : saved_severity_(absl::MinLogLevel()) { | 
101  | 0  |   absl::SetMinLogLevel(severity);  | 
102  | 0  | }  | 
103  | 0  | ScopedMinLogLevel::~ScopedMinLogLevel() { | 
104  | 0  |   absl::SetMinLogLevel(saved_severity_);  | 
105  | 0  | }  | 
106  |  |  | 
107  |  | }  // namespace log_internal  | 
108  |  |  | 
109  | 4.12M  | absl::LogSeverityAtLeast StderrThreshold() { | 
110  | 4.12M  |   return static_cast<absl::LogSeverityAtLeast>(  | 
111  | 4.12M  |       stderrthreshold.load(std::memory_order_acquire));  | 
112  | 4.12M  | }  | 
113  |  |  | 
114  | 0  | void SetStderrThreshold(absl::LogSeverityAtLeast severity) { | 
115  | 0  |   log_internal::RawSetStderrThreshold(severity);  | 
116  | 0  |   TriggerLoggingGlobalsListener();  | 
117  | 0  | }  | 
118  |  |  | 
119  |  | ScopedStderrThreshold::ScopedStderrThreshold(absl::LogSeverityAtLeast severity)  | 
120  | 0  |     : saved_severity_(absl::StderrThreshold()) { | 
121  | 0  |   absl::SetStderrThreshold(severity);  | 
122  | 0  | }  | 
123  |  |  | 
124  | 0  | ScopedStderrThreshold::~ScopedStderrThreshold() { | 
125  | 0  |   absl::SetStderrThreshold(saved_severity_);  | 
126  | 0  | }  | 
127  |  |  | 
128  |  | namespace log_internal { | 
129  |  |  | 
130  | 0  | const char* GetAndroidNativeTag() { | 
131  | 0  |   return android_log_tag.load(std::memory_order_acquire);  | 
132  | 0  | }  | 
133  |  |  | 
134  |  | }  // namespace log_internal  | 
135  |  |  | 
136  | 0  | void SetAndroidNativeTag(const char* tag) { | 
137  | 0  |   ABSL_CONST_INIT static std::atomic<const std::string*> user_log_tag(nullptr);  | 
138  | 0  |   ABSL_INTERNAL_CHECK(tag, "tag must be non-null.");  | 
139  |  |  | 
140  | 0  |   const std::string* tag_str = new std::string(tag);  | 
141  | 0  |   ABSL_INTERNAL_CHECK(  | 
142  | 0  |       android_log_tag.exchange(tag_str->c_str(), std::memory_order_acq_rel) ==  | 
143  | 0  |           kDefaultAndroidTag,  | 
144  | 0  |       "SetAndroidNativeTag() must only be called once per process!");  | 
145  | 0  |   user_log_tag.store(tag_str, std::memory_order_relaxed);  | 
146  | 0  | }  | 
147  |  |  | 
148  |  | namespace log_internal { | 
149  |  |  | 
150  | 0  | bool ShouldLogBacktraceAt(absl::string_view file, int line) { | 
151  | 0  |   const size_t flag_hash =  | 
152  | 0  |       log_backtrace_at_hash.load(std::memory_order_relaxed);  | 
153  |  | 
  | 
154  | 0  |   return flag_hash != 0 && flag_hash == HashSiteForLogBacktraceAt(file, line);  | 
155  | 0  | }  | 
156  |  |  | 
157  |  | }  // namespace log_internal  | 
158  |  |  | 
159  | 0  | void SetLogBacktraceLocation(absl::string_view file, int line) { | 
160  | 0  |   log_backtrace_at_hash.store(HashSiteForLogBacktraceAt(file, line),  | 
161  | 0  |                               std::memory_order_relaxed);  | 
162  | 0  | }  | 
163  |  |  | 
164  | 0  | void ClearLogBacktraceLocation() { | 
165  | 0  |   log_backtrace_at_hash.store(0, std::memory_order_relaxed);  | 
166  | 0  | }  | 
167  |  |  | 
168  | 4.12M  | bool ShouldPrependLogPrefix() { | 
169  | 4.12M  |   return prepend_log_prefix.load(std::memory_order_acquire);  | 
170  | 4.12M  | }  | 
171  |  |  | 
172  | 0  | void EnableLogPrefix(bool on_off) { | 
173  | 0  |   log_internal::RawEnableLogPrefix(on_off);  | 
174  | 0  |   TriggerLoggingGlobalsListener();  | 
175  | 0  | }  | 
176  |  |  | 
177  |  | ABSL_NAMESPACE_END  | 
178  |  | }  // namespace absl  |