/root/doris/be/src/common/logconfig.cpp
| Line | Count | Source (jump to first uncovered line) | 
| 1 |  | // Licensed to the Apache Software Foundation (ASF) under one | 
| 2 |  | // or more contributor license agreements.  See the NOTICE file | 
| 3 |  | // distributed with this work for additional information | 
| 4 |  | // regarding copyright ownership.  The ASF licenses this file | 
| 5 |  | // to you under the Apache License, Version 2.0 (the | 
| 6 |  | // "License"); you may not use this file except in compliance | 
| 7 |  | // with the License.  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, | 
| 12 |  | // software distributed under the License is distributed on an | 
| 13 |  | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | 
| 14 |  | // KIND, either express or implied.  See the License for the | 
| 15 |  | // specific language governing permissions and limitations | 
| 16 |  | // under the License. | 
| 17 |  |  | 
| 18 |  | #include <ctype.h> | 
| 19 |  | #include <stdint.h> | 
| 20 |  |  | 
| 21 |  | #include <cerrno> | 
| 22 |  | #include <cstdlib> | 
| 23 |  | #include <cstring> | 
| 24 |  | #include <iomanip> | 
| 25 |  | #include <iostream> | 
| 26 |  | #include <mutex> | 
| 27 |  | #include <string> | 
| 28 |  | #include <vector> | 
| 29 |  |  | 
| 30 |  | #include "common/config.h" | 
| 31 |  | #include "common/logging.h" | 
| 32 |  |  | 
| 33 |  | namespace doris { | 
| 34 |  |  | 
| 35 |  | static bool logging_initialized = false; | 
| 36 |  |  | 
| 37 |  | static std::mutex logging_mutex; | 
| 38 |  |  | 
| 39 |  | // Implement the custom log format: I20250118 10:53:06.239614 1318521 timezone_utils.cpp:115] Preloaded653 timezones. | 
| 40 |  | struct StdoutLogSink : google::LogSink { | 
| 41 |  |     void send(google::LogSeverity severity, const char* /*full_filename*/, | 
| 42 |  |               const char* base_filename, int line, const google::LogMessageTime& time, | 
| 43 | 0 |               const char* message, std::size_t message_len) override { | 
| 44 |  |         // 1.  Convert log severity to corresponding character (I/W/E/F) | 
| 45 | 0 |         char severity_char; | 
| 46 | 0 |         switch (severity) { | 
| 47 | 0 |         case google::GLOG_INFO: | 
| 48 | 0 |             severity_char = 'I'; | 
| 49 | 0 |             break; | 
| 50 | 0 |         case google::GLOG_WARNING: | 
| 51 | 0 |             severity_char = 'W'; | 
| 52 | 0 |             break; | 
| 53 | 0 |         case google::GLOG_ERROR: | 
| 54 | 0 |             severity_char = 'E'; | 
| 55 | 0 |             break; | 
| 56 | 0 |         case google::GLOG_FATAL: | 
| 57 | 0 |             severity_char = 'F'; | 
| 58 | 0 |             break; | 
| 59 | 0 |         default: | 
| 60 | 0 |             severity_char = '?'; | 
| 61 | 0 |             break; | 
| 62 | 0 |         } | 
| 63 |  |         // Set output formatting flags | 
| 64 | 0 |         std::cout << std::setfill('0'); | 
| 65 |  |  | 
| 66 |  |         // 1. Log severity (I/W/E/F) | 
| 67 | 0 |         std::cout << severity_char; | 
| 68 |  |  | 
| 69 |  |         // 2. Date (YYYYMMDD) | 
| 70 |  |         // Note: tm_year is years since 1900, tm_mon is 0-based (0-11) | 
| 71 | 0 |         std::cout << std::setw(4) << (time.year() + 1900) << std::setw(2) << std::setfill('0') | 
| 72 | 0 |                   << (time.month() + 1) << std::setw(2) << std::setfill('0') << time.day(); | 
| 73 |  |  | 
| 74 |  |         // 3. Time (HH:MM:SS.ffffff) | 
| 75 | 0 |         std::cout << " " << std::setw(2) << std::setfill('0') << time.hour() << ":" << std::setw(2) | 
| 76 | 0 |                   << std::setfill('0') << time.min() << ":" << std::setw(2) << std::setfill('0') | 
| 77 | 0 |                   << time.sec() << "." << std::setw(6) << std::setfill('0') << time.usec(); | 
| 78 |  |  | 
| 79 |  |         // 4. Process ID | 
| 80 | 0 |         std::cout << " " << getpid(); | 
| 81 |  |  | 
| 82 |  |         // 5. Filename and line number | 
| 83 | 0 |         std::cout << " " << base_filename << ":" << line << "] "; | 
| 84 |  |  | 
| 85 |  |         // 6. Log message | 
| 86 | 0 |         std::cout.write(message, message_len); | 
| 87 |  |  | 
| 88 |  |         // Add newline and flush | 
| 89 | 0 |         std::cout << std::endl; | 
| 90 | 0 |     } | 
| 91 |  | }; | 
| 92 |  |  | 
| 93 |  | static StdoutLogSink stdout_log_sink; | 
| 94 |  |  | 
| 95 | 18 | static bool iequals(const std::string& a, const std::string& b) { | 
| 96 | 18 |     unsigned int sz = a.size(); | 
| 97 | 18 |     if (b.size() != sz) { | 
| 98 | 4 |         return false; | 
| 99 | 4 |     } | 
| 100 | 58 |     for (unsigned int i = 0; i < sz; ++i) { | 
| 101 | 44 |         if (tolower(a[i]) != tolower(b[i])) { | 
| 102 | 0 |             return false; | 
| 103 | 0 |         } | 
| 104 | 44 |     } | 
| 105 | 14 |     return true; | 
| 106 | 14 | } | 
| 107 |  |  | 
| 108 |  | // if custom_date_time_format = false, same format as in be.log | 
| 109 |  | // The following is same as default log format. eg: | 
| 110 |  | // I20240605 15:25:15.677153 1763151 wal_manager.cpp:481] msg... | 
| 111 |  | template <bool add_runtime_logger_prefix = false, bool custom_date_time_format = false> | 
| 112 | 0 | void custom_prefix(std::ostream& s, const google::LogMessageInfo& l, void* arg) { | 
| 113 | 0 |     if constexpr (add_runtime_logger_prefix) { | 
| 114 |  |         // Add prefix "RuntimeLogger ". | 
| 115 | 0 |         s << "RuntimeLogger "; | 
| 116 | 0 |     } | 
| 117 | 0 |     s << l.severity[0]; | 
| 118 |  |  | 
| 119 |  |     // Add a space if custom_date_time_format. | 
| 120 | 0 |     if constexpr (custom_date_time_format) { | 
| 121 | 0 |         s << ' '; | 
| 122 | 0 |     } | 
| 123 |  | 
 | 
| 124 | 0 |     std::tm tm_time = {}; | 
| 125 | 0 |     tm_time.tm_year = l.time.year(); | 
| 126 | 0 |     tm_time.tm_mon = l.time.month(); | 
| 127 | 0 |     tm_time.tm_mday = l.time.day(); | 
| 128 | 0 |     tm_time.tm_hour = l.time.hour(); | 
| 129 | 0 |     tm_time.tm_min = l.time.min(); | 
| 130 | 0 |     tm_time.tm_sec = l.time.sec(); | 
| 131 |  | 
 | 
| 132 | 0 |     if constexpr (custom_date_time_format) { | 
| 133 | 0 |         s << std::put_time(&tm_time, config::sys_log_custom_date_time_format.c_str()); | 
| 134 | 0 |         if (!config::sys_log_custom_date_time_ms_format.empty()) { | 
| 135 | 0 |             s << fmt::format(config::sys_log_custom_date_time_ms_format, l.time.usec() / 1000); | 
| 136 | 0 |         } | 
| 137 | 0 |     } else { | 
| 138 | 0 |         s << std::put_time(&tm_time, "%Y%m%d %H:%M:%S"); | 
| 139 | 0 |         s << "." << std::setw(6) << l.time.usec(); | 
| 140 | 0 |     } | 
| 141 |  | 
 | 
| 142 | 0 |     s << ' '; | 
| 143 | 0 |     s << std::setfill(' ') << std::setw(5); | 
| 144 | 0 |     s << l.thread_id << std::setfill('0'); | 
| 145 | 0 |     s << ' '; | 
| 146 | 0 |     s << l.filename << ':' << l.line_number << "]"; | 
| 147 | 0 | } Unexecuted instantiation: _ZN5doris13custom_prefixILb1ELb1EEEvRSoRKN6google14LogMessageInfoEPvUnexecuted instantiation: _ZN5doris13custom_prefixILb1ELb0EEEvRSoRKN6google14LogMessageInfoEPvUnexecuted instantiation: _ZN5doris13custom_prefixILb0ELb1EEEvRSoRKN6google14LogMessageInfoEPv | 
| 148 |  |  | 
| 149 | 8 | bool init_glog(const char* basename) { | 
| 150 | 8 |     std::lock_guard<std::mutex> logging_lock(logging_mutex); | 
| 151 |  |  | 
| 152 | 8 |     if (logging_initialized) { | 
| 153 | 0 |         return true; | 
| 154 | 0 |     } | 
| 155 |  |  | 
| 156 | 8 |     bool log_to_console = (getenv("DORIS_LOG_TO_STDERR") != nullptr); | 
| 157 | 8 |     if (log_to_console) { | 
| 158 | 0 |         if (doris::config::enable_file_logger) { | 
| 159 |  |             // will output log to be.info and output log to stdout | 
| 160 | 0 |             google::AddLogSink(&stdout_log_sink); | 
| 161 | 0 |         } else { | 
| 162 |  |             // enable_file_logger is false, will only output log to stdout | 
| 163 |  |             // Not output to stderr because be.out will output log to stderr | 
| 164 | 0 |             FLAGS_logtostdout = true; | 
| 165 | 0 |         } | 
| 166 | 0 |     } | 
| 167 |  |  | 
| 168 |  |     // don't log to stderr except fatal level | 
| 169 |  |     // so fatal log can output to be.out . | 
| 170 | 8 |     FLAGS_stderrthreshold = google::FATAL; | 
| 171 |  |     // set glog log dir | 
| 172 |  |     // ATTN: sys_log_dir is deprecated, this is just for compatibility | 
| 173 | 8 |     std::string log_dir = config::sys_log_dir; | 
| 174 | 8 |     if (log_dir == "") { | 
| 175 | 8 |         log_dir = getenv("LOG_DIR"); | 
| 176 | 8 |     } | 
| 177 | 8 |     FLAGS_log_dir = log_dir; | 
| 178 |  |     // 0 means buffer INFO only | 
| 179 | 8 |     FLAGS_logbuflevel = 0; | 
| 180 |  |     // buffer log messages for at most this many seconds | 
| 181 | 8 |     FLAGS_logbufsecs = 30; | 
| 182 |  |     // set roll num | 
| 183 | 8 |     FLAGS_log_filenum_quota = config::sys_log_roll_num; | 
| 184 |  |  | 
| 185 |  |     // set log level | 
| 186 | 8 |     std::string& loglevel = config::sys_log_level; | 
| 187 | 8 |     if (iequals(loglevel, "INFO")) { | 
| 188 | 8 |         FLAGS_minloglevel = 0; | 
| 189 | 8 |     } else if (iequals(loglevel, "WARNING")) { | 
| 190 | 0 |         FLAGS_minloglevel = 1; | 
| 191 | 0 |     } else if (iequals(loglevel, "ERROR")) { | 
| 192 | 0 |         FLAGS_minloglevel = 2; | 
| 193 | 0 |     } else if (iequals(loglevel, "FATAL")) { | 
| 194 | 0 |         FLAGS_minloglevel = 3; | 
| 195 | 0 |     } else { | 
| 196 | 0 |         std::cerr << "sys_log_level needs to be INFO, WARNING, ERROR, FATAL" << std::endl; | 
| 197 | 0 |         return false; | 
| 198 | 0 |     } | 
| 199 |  |  | 
| 200 |  |     // set log buffer level | 
| 201 |  |     // default is 0 | 
| 202 | 8 |     std::string& logbuflevel = config::log_buffer_level; | 
| 203 | 8 |     if (iequals(logbuflevel, "-1")) { | 
| 204 | 6 |         FLAGS_logbuflevel = -1; | 
| 205 | 6 |     } else if (iequals(logbuflevel, "0")) { | 
| 206 | 0 |         FLAGS_logbuflevel = 0; | 
| 207 | 0 |     } | 
| 208 |  |  | 
| 209 |  |     // set log roll mode | 
| 210 | 8 |     std::string& rollmode = config::sys_log_roll_mode; | 
| 211 | 8 |     std::string sizeflag = "SIZE-MB-"; | 
| 212 | 8 |     bool ok = false; | 
| 213 | 8 |     if (rollmode.compare("TIME-DAY") == 0) { | 
| 214 | 0 |         FLAGS_log_split_method = "day"; | 
| 215 | 0 |         ok = true; | 
| 216 | 8 |     } else if (rollmode.compare("TIME-HOUR") == 0) { | 
| 217 | 0 |         FLAGS_log_split_method = "hour"; | 
| 218 | 0 |         ok = true; | 
| 219 | 8 |     } else if (rollmode.substr(0, sizeflag.length()).compare(sizeflag) == 0) { | 
| 220 | 8 |         FLAGS_log_split_method = "size"; | 
| 221 | 8 |         std::string sizestr = rollmode.substr(sizeflag.size(), rollmode.size() - sizeflag.size()); | 
| 222 | 8 |         if (sizestr.size() != 0) { | 
| 223 | 8 |             char* end = nullptr; | 
| 224 | 8 |             errno = 0; | 
| 225 | 8 |             const char* sizecstr = sizestr.c_str(); | 
| 226 | 8 |             int64_t ret64 = strtoll(sizecstr, &end, 10); | 
| 227 | 8 |             if ((errno == 0) && (end == sizecstr + strlen(sizecstr))) { | 
| 228 | 8 |                 int32_t retval = static_cast<int32_t>(ret64); | 
| 229 | 8 |                 if (retval == ret64) { | 
| 230 | 8 |                     FLAGS_max_log_size = retval; | 
| 231 | 8 |                     ok = true; | 
| 232 | 8 |                 } | 
| 233 | 8 |             } | 
| 234 | 8 |         } | 
| 235 | 8 |     } else { | 
| 236 | 0 |         ok = false; | 
| 237 | 0 |     } | 
| 238 | 8 |     if (!ok) { | 
| 239 | 0 |         std::cerr << "sys_log_roll_mode needs to be TIME-DAY, TIME-HOUR, SIZE-MB-nnn" << std::endl; | 
| 240 | 0 |         return false; | 
| 241 | 0 |     } | 
| 242 |  |  | 
| 243 |  |     // set verbose modules. | 
| 244 | 8 |     FLAGS_v = config::sys_log_verbose_flags_v; | 
| 245 | 8 |     std::vector<std::string>& verbose_modules = config::sys_log_verbose_modules; | 
| 246 | 8 |     int32_t vlog_level = config::sys_log_verbose_level; | 
| 247 | 18 |     for (size_t i = 0; i < verbose_modules.size(); i++) { | 
| 248 | 10 |         if (verbose_modules[i].size() != 0) { | 
| 249 | 10 |             google::SetVLOGLevel(verbose_modules[i].c_str(), vlog_level); | 
| 250 | 10 |         } | 
| 251 | 10 |     } | 
| 252 |  |  | 
| 253 | 8 |     if (log_to_console) { | 
| 254 |  |         // Add prefix if log output to stderr | 
| 255 | 0 |         if (config::sys_log_enable_custom_date_time_format) { | 
| 256 | 0 |             google::InitGoogleLogging(basename, &custom_prefix<true, true>); | 
| 257 | 0 |         } else { | 
| 258 | 0 |             google::InitGoogleLogging(basename, &custom_prefix<true, false>); | 
| 259 | 0 |         } | 
| 260 | 8 |     } else { | 
| 261 | 8 |         if (config::sys_log_enable_custom_date_time_format) { | 
| 262 | 0 |             google::InitGoogleLogging(basename, &custom_prefix<false, true>); | 
| 263 | 8 |         } else { | 
| 264 | 8 |             google::InitGoogleLogging(basename); | 
| 265 | 8 |         } | 
| 266 | 8 |     } | 
| 267 |  |  | 
| 268 | 8 |     logging_initialized = true; | 
| 269 |  |  | 
| 270 | 8 |     return true; | 
| 271 | 8 | } | 
| 272 |  |  | 
| 273 | 0 | void shutdown_logging() { | 
| 274 | 0 |     std::lock_guard<std::mutex> logging_lock(logging_mutex); | 
| 275 | 0 |     google::RemoveLogSink(&stdout_log_sink); | 
| 276 | 0 |     google::ShutdownGoogleLogging(); | 
| 277 | 0 | } | 
| 278 |  |  | 
| 279 | 0 | void update_logging(const std::string& name, const std::string& value) { | 
| 280 | 0 |     if ("sys_log_level" == name) { | 
| 281 | 0 |         if (iequals(value, "INFO")) { | 
| 282 | 0 |             FLAGS_minloglevel = 0; | 
| 283 | 0 |         } else if (iequals(value, "WARNING")) { | 
| 284 | 0 |             FLAGS_minloglevel = 1; | 
| 285 | 0 |         } else if (iequals(value, "ERROR")) { | 
| 286 | 0 |             FLAGS_minloglevel = 2; | 
| 287 | 0 |         } else if (iequals(value, "FATAL")) { | 
| 288 | 0 |             FLAGS_minloglevel = 3; | 
| 289 | 0 |         } else { | 
| 290 | 0 |             LOG(WARNING) << "update sys_log_level failed, need to be INFO, WARNING, ERROR, FATAL"; | 
| 291 | 0 |         } | 
| 292 | 0 |     } | 
| 293 | 0 | } | 
| 294 |  |  | 
| 295 |  | } // namespace doris |