1 //
2 // Copyright 2022 The Abseil Authors.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // https://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15
16 #include "absl/log/internal/flags.h"
17
18 #include <stddef.h>
19
20 #include <algorithm>
21 #include <cstdlib>
22 #include <string>
23
24 #include "absl/base/attributes.h"
25 #include "absl/base/config.h"
26 #include "absl/base/log_severity.h"
27 #include "absl/flags/flag.h"
28 #include "absl/flags/marshalling.h"
29 #include "absl/log/globals.h"
30 #include "absl/log/internal/config.h"
31 #include "absl/strings/numbers.h"
32 #include "absl/strings/string_view.h"
33
34 namespace absl {
35 ABSL_NAMESPACE_BEGIN
36 namespace log_internal {
37 namespace {
38
SyncLoggingFlags()39 void SyncLoggingFlags() {
40 absl::SetFlag(&FLAGS_minloglevel, static_cast<int>(absl::MinLogLevel()));
41 absl::SetFlag(&FLAGS_log_prefix, absl::ShouldPrependLogPrefix());
42 }
43
RegisterSyncLoggingFlags()44 bool RegisterSyncLoggingFlags() {
45 log_internal::SetLoggingGlobalsListener(&SyncLoggingFlags);
46 return true;
47 }
48
49 ABSL_ATTRIBUTE_UNUSED const bool unused = RegisterSyncLoggingFlags();
50
51 template <typename T>
GetFromEnv(const char * varname,T dflt)52 T GetFromEnv(const char* varname, T dflt) {
53 const char* val = ::getenv(varname);
54 if (val != nullptr) {
55 std::string err;
56 ABSL_INTERNAL_CHECK(absl::ParseFlag(val, &dflt, &err), err.c_str());
57 }
58 return dflt;
59 }
60
StderrThresholdDefault()61 constexpr absl::LogSeverityAtLeast StderrThresholdDefault() {
62 return absl::LogSeverityAtLeast::kError;
63 }
64
65 } // namespace
66 } // namespace log_internal
67 ABSL_NAMESPACE_END
68 } // namespace absl
69
70 ABSL_FLAG(int, stderrthreshold,
71 static_cast<int>(absl::log_internal::StderrThresholdDefault()),
72 "Log messages at or above this threshold level are copied to stderr.")
__anon092b2c7b0202null73 .OnUpdate([] {
74 absl::log_internal::RawSetStderrThreshold(
75 static_cast<absl::LogSeverityAtLeast>(
76 absl::GetFlag(FLAGS_stderrthreshold)));
77 });
78
79 ABSL_FLAG(int, minloglevel, static_cast<int>(absl::LogSeverityAtLeast::kInfo),
80 "Messages logged at a lower level than this don't actually "
81 "get logged anywhere")
__anon092b2c7b0302null82 .OnUpdate([] {
83 absl::log_internal::RawSetMinLogLevel(
84 static_cast<absl::LogSeverityAtLeast>(
85 absl::GetFlag(FLAGS_minloglevel)));
86 });
87
88 ABSL_FLAG(std::string, log_backtrace_at, "",
89 "Emit a backtrace when logging at file:linenum.")
__anon092b2c7b0402null90 .OnUpdate([] {
91 const std::string log_backtrace_at =
92 absl::GetFlag(FLAGS_log_backtrace_at);
93 if (log_backtrace_at.empty()) {
94 absl::ClearLogBacktraceLocation();
95 return;
96 }
97
98 const size_t last_colon = log_backtrace_at.rfind(':');
99 if (last_colon == log_backtrace_at.npos) {
100 absl::ClearLogBacktraceLocation();
101 return;
102 }
103
104 const absl::string_view file =
105 absl::string_view(log_backtrace_at).substr(0, last_colon);
106 int line;
107 if (!absl::SimpleAtoi(
108 absl::string_view(log_backtrace_at).substr(last_colon + 1),
109 &line)) {
110 absl::ClearLogBacktraceLocation();
111 return;
112 }
113 absl::SetLogBacktraceLocation(file, line);
114 });
115
116 ABSL_FLAG(bool, log_prefix, true,
117 "Prepend the log prefix to the start of each log line")
__anon092b2c7b0502null118 .OnUpdate([] {
119 absl::log_internal::RawEnableLogPrefix(absl::GetFlag(FLAGS_log_prefix));
120 });
121