1 //
2 //
3 // Copyright 2015 gRPC authors.
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17 //
18
19 #include <grpc/support/port_platform.h>
20
21 #include "absl/log/log.h"
22
23 #include <stdio.h>
24 #include <string.h>
25
26 #include "absl/strings/match.h"
27 #include "absl/strings/str_cat.h"
28
29 #include <grpc/support/alloc.h>
30 #include <grpc/support/atm.h>
31 #include <grpc/support/log.h>
32
33 #include "src/core/lib/config/config_vars.h"
34 #include "src/core/lib/gpr/string.h"
35 #include "src/core/lib/gprpp/crash.h"
36
37 #ifndef GPR_DEFAULT_LOG_VERBOSITY_STRING
38 #define GPR_DEFAULT_LOG_VERBOSITY_STRING "ERROR"
39 #endif // !GPR_DEFAULT_LOG_VERBOSITY_STRING
40
41 static constexpr gpr_atm GPR_LOG_SEVERITY_UNSET = GPR_LOG_SEVERITY_ERROR + 10;
42 static constexpr gpr_atm GPR_LOG_SEVERITY_NONE = GPR_LOG_SEVERITY_ERROR + 11;
43
44 void gpr_default_log(gpr_log_func_args* args);
45 void gpr_platform_log(gpr_log_func_args* args);
46 static gpr_atm g_log_func = reinterpret_cast<gpr_atm>(gpr_default_log);
47 static gpr_atm g_min_severity_to_print = GPR_LOG_SEVERITY_UNSET;
48 static gpr_atm g_min_severity_to_print_stacktrace = GPR_LOG_SEVERITY_UNSET;
49
gpr_unreachable_code(const char * reason,const char * file,int line)50 void gpr_unreachable_code(const char* reason, const char* file, int line) {
51 grpc_core::Crash(absl::StrCat("UNREACHABLE CODE: ", reason),
52 grpc_core::SourceLocation(file, line));
53 }
54
gpr_assertion_failed(const char * filename,int line,const char * message)55 void gpr_assertion_failed(const char* filename, int line, const char* message) {
56 grpc_core::Crash(absl::StrCat("ASSERTION FAILED: ", message),
57 grpc_core::SourceLocation(filename, line));
58 }
59
gpr_log_severity_string(gpr_log_severity severity)60 const char* gpr_log_severity_string(gpr_log_severity severity) {
61 switch (severity) {
62 case GPR_LOG_SEVERITY_DEBUG:
63 return "D";
64 case GPR_LOG_SEVERITY_INFO:
65 return "I";
66 case GPR_LOG_SEVERITY_ERROR:
67 return "E";
68 }
69 GPR_UNREACHABLE_CODE(return "UNKNOWN");
70 }
71
gpr_should_log(gpr_log_severity severity)72 int gpr_should_log(gpr_log_severity severity) {
73 return static_cast<gpr_atm>(severity) >=
74 gpr_atm_no_barrier_load(&g_min_severity_to_print)
75 ? 1
76 : 0;
77 }
78
gpr_default_log(gpr_log_func_args * args)79 void gpr_default_log(gpr_log_func_args* args) {
80 if (!grpc_core::ConfigVars::Get().AbslLogging()) {
81 gpr_platform_log(args);
82 return;
83 }
84 switch (args->severity) {
85 case GPR_LOG_SEVERITY_DEBUG:
86 // Log DEBUG messages as VLOG(2).
87 VLOG(2).AtLocation(args->file, args->line) << args->message;
88 return;
89 case GPR_LOG_SEVERITY_INFO:
90 LOG(INFO).AtLocation(args->file, args->line) << args->message;
91 return;
92 case GPR_LOG_SEVERITY_ERROR:
93 LOG(ERROR).AtLocation(args->file, args->line) << args->message;
94 return;
95 default:
96 LOG(ERROR) << __func__ << ": unknown gpr log severity(" << args->severity
97 << "), using ERROR";
98 LOG(ERROR).AtLocation(args->file, args->line) << args->message;
99 }
100 }
101
gpr_should_log_stacktrace(gpr_log_severity severity)102 int gpr_should_log_stacktrace(gpr_log_severity severity) {
103 return static_cast<gpr_atm>(severity) >=
104 gpr_atm_no_barrier_load(&g_min_severity_to_print_stacktrace)
105 ? 1
106 : 0;
107 }
108
gpr_log_message(const char * file,int line,gpr_log_severity severity,const char * message)109 void gpr_log_message(const char* file, int line, gpr_log_severity severity,
110 const char* message) {
111 if (gpr_should_log(severity) == 0) {
112 return;
113 }
114
115 gpr_log_func_args lfargs;
116 memset(&lfargs, 0, sizeof(lfargs));
117 lfargs.file = file;
118 lfargs.line = line;
119 lfargs.severity = severity;
120 lfargs.message = message;
121 reinterpret_cast<gpr_log_func>(gpr_atm_no_barrier_load(&g_log_func))(&lfargs);
122 }
123
gpr_set_log_verbosity(gpr_log_severity min_severity_to_print)124 void gpr_set_log_verbosity(gpr_log_severity min_severity_to_print) {
125 gpr_atm_no_barrier_store(&g_min_severity_to_print,
126 (gpr_atm)min_severity_to_print);
127 }
128
parse_log_severity(absl::string_view str,gpr_atm error_value)129 static gpr_atm parse_log_severity(absl::string_view str, gpr_atm error_value) {
130 if (absl::EqualsIgnoreCase(str, "DEBUG")) return GPR_LOG_SEVERITY_DEBUG;
131 if (absl::EqualsIgnoreCase(str, "INFO")) return GPR_LOG_SEVERITY_INFO;
132 if (absl::EqualsIgnoreCase(str, "ERROR")) return GPR_LOG_SEVERITY_ERROR;
133 if (absl::EqualsIgnoreCase(str, "NONE")) return GPR_LOG_SEVERITY_NONE;
134 return error_value;
135 }
136
gpr_log_verbosity_init()137 void gpr_log_verbosity_init() {
138 // init verbosity when it hasn't been set
139 if ((gpr_atm_no_barrier_load(&g_min_severity_to_print)) ==
140 GPR_LOG_SEVERITY_UNSET) {
141 auto verbosity = grpc_core::ConfigVars::Get().Verbosity();
142 gpr_atm min_severity_to_print = GPR_LOG_SEVERITY_ERROR;
143 if (!verbosity.empty()) {
144 min_severity_to_print =
145 parse_log_severity(verbosity, min_severity_to_print);
146 }
147 gpr_atm_no_barrier_store(&g_min_severity_to_print, min_severity_to_print);
148 }
149 // init stacktrace_minloglevel when it hasn't been set
150 if ((gpr_atm_no_barrier_load(&g_min_severity_to_print_stacktrace)) ==
151 GPR_LOG_SEVERITY_UNSET) {
152 auto stacktrace_minloglevel =
153 grpc_core::ConfigVars::Get().StacktraceMinloglevel();
154 gpr_atm min_severity_to_print_stacktrace = GPR_LOG_SEVERITY_NONE;
155 if (!stacktrace_minloglevel.empty()) {
156 min_severity_to_print_stacktrace = parse_log_severity(
157 stacktrace_minloglevel, min_severity_to_print_stacktrace);
158 }
159 gpr_atm_no_barrier_store(&g_min_severity_to_print_stacktrace,
160 min_severity_to_print_stacktrace);
161 }
162 }
163
gpr_set_log_function(gpr_log_func f)164 void gpr_set_log_function(gpr_log_func f) {
165 gpr_atm_no_barrier_store(&g_log_func, (gpr_atm)(f ? f : gpr_default_log));
166 }
167