This is an automated email from the ASF dual-hosted git repository.

yiguolei pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/master by this push:
     new 88b62c34042 [bugfix](k8s) using stdout to output  (#54129)
88b62c34042 is described below

commit 88b62c34042c8a8371c9facd7edac3061ea14f25
Author: yiguolei <[email protected]>
AuthorDate: Fri Aug 1 09:07:17 2025 +0800

    [bugfix](k8s) using stdout to output  (#54129)
    
    ### What problem does this PR solve?
    
    K8S using stdout to capture BE INFO logs. But when BE crash be will try
    to output crash stack to be.out file. In the past, it could not output
    to be.out file. In this feature, I format the behaviors of be log:
    1. -- daemon, output log to be.info file and output crash stack to
    be.out file.
    2. --console,
    2.1 enable_file_logger = true, output all logs to console (stdout) and
    output all logs to be.info and crash stack to be.out
    2.2 enable_file_logger = false, output all logs to console(stdout) and
    crash stack to be.out
    
    we will always output crash stack to logs/be.out file.
---
 be/src/common/logconfig.cpp | 66 ++++++++++++++++++++++++++++++++++++++++++---
 bin/start_be.sh             |  8 +++---
 2 files changed, 68 insertions(+), 6 deletions(-)

diff --git a/be/src/common/logconfig.cpp b/be/src/common/logconfig.cpp
index 88c7d4bc755..05ccc5477d3 100644
--- a/be/src/common/logconfig.cpp
+++ b/be/src/common/logconfig.cpp
@@ -36,6 +36,62 @@ static bool logging_initialized = false;
 
 static std::mutex logging_mutex;
 
+// Implement the custom log format: I20250118 10:53:06.239614 1318521 
timezone_utils.cpp:115] Preloaded653 timezones.
+struct StdoutLogSink : google::LogSink {
+    void send(google::LogSeverity severity, const char* /*full_filename*/,
+              const char* base_filename, int line, const 
google::LogMessageTime& time,
+              const char* message, std::size_t message_len) override {
+        // 1.  Convert log severity to corresponding character (I/W/E/F)
+        char severity_char;
+        switch (severity) {
+        case google::GLOG_INFO:
+            severity_char = 'I';
+            break;
+        case google::GLOG_WARNING:
+            severity_char = 'W';
+            break;
+        case google::GLOG_ERROR:
+            severity_char = 'E';
+            break;
+        case google::GLOG_FATAL:
+            severity_char = 'F';
+            break;
+        default:
+            severity_char = '?';
+            break;
+        }
+        // Set output formatting flags
+        std::cout << std::setfill('0');
+
+        // 1. Log severity (I/W/E/F)
+        std::cout << severity_char;
+
+        // 2. Date (YYYYMMDD)
+        // Note: tm_year is years since 1900, tm_mon is 0-based (0-11)
+        std::cout << std::setw(4) << (time.year() + 1900) << std::setw(2) << 
std::setfill('0')
+                  << (time.month() + 1) << std::setw(2) << std::setfill('0') 
<< time.day();
+
+        // 3. Time (HH:MM:SS.ffffff)
+        std::cout << " " << std::setw(2) << std::setfill('0') << time.hour() 
<< ":" << std::setw(2)
+                  << std::setfill('0') << time.min() << ":" << std::setw(2) << 
std::setfill('0')
+                  << time.sec() << "." << std::setw(6) << std::setfill('0') << 
time.usec();
+
+        // 4. Process ID
+        std::cout << " " << getpid();
+
+        // 5. Filename and line number
+        std::cout << " " << base_filename << ":" << line << "] ";
+
+        // 6. Log message
+        std::cout.write(message, message_len);
+
+        // Add newline and flush
+        std::cout << std::endl;
+    }
+};
+
+static StdoutLogSink stdout_log_sink;
+
 static bool iequals(const std::string& a, const std::string& b) {
     unsigned int sz = a.size();
     if (b.size() != sz) {
@@ -99,10 +155,13 @@ bool init_glog(const char* basename) {
 
     bool log_to_console = (getenv("DORIS_LOG_TO_STDERR") != nullptr);
     if (log_to_console) {
-        if (config::enable_file_logger) {
-            FLAGS_alsologtostderr = true;
+        if (doris::config::enable_file_logger) {
+            // will output log to be.info and output log to stdout
+            google::AddLogSink(&stdout_log_sink);
         } else {
-            FLAGS_logtostderr = true;
+            // enable_file_logger is false, will only output log to stdout
+            // Not output to stderr because be.out will output log to stderr
+            FLAGS_logtostdout = true;
         }
     }
 
@@ -213,6 +272,7 @@ bool init_glog(const char* basename) {
 
 void shutdown_logging() {
     std::lock_guard<std::mutex> logging_lock(logging_mutex);
+    google::RemoveLogSink(&stdout_log_sink);
     google::ShutdownGoogleLogging();
 }
 
diff --git a/bin/start_be.sh b/bin/start_be.sh
index 04cac90818b..f2709cb5a25 100755
--- a/bin/start_be.sh
+++ b/bin/start_be.sh
@@ -107,9 +107,9 @@ log() {
     cur_date=$(date +"%Y-%m-%d %H:%M:%S,$(date +%3N)")
     if [[ "${RUN_CONSOLE}" -eq 1 ]]; then
         echo "StdoutLogger ${cur_date} $1"
-    else
-        echo "StdoutLogger ${cur_date} $1" >>"${STDOUT_LOGGER}"
     fi
+    # always output start time info into be.out file
+    echo "StdoutLogger ${cur_date} $1" >>"${STDOUT_LOGGER}"
 }
 
 jdk_version() {
@@ -459,8 +459,10 @@ elif [[ "${RUN_DAEMON}" -eq 1 ]]; then
         nohup ${LIMIT:+${LIMIT}} "${DORIS_HOME}/lib/doris_be" "$@" 
>>"${LOG_DIR}/be.out" 2>&1 </dev/null &
     fi
 elif [[ "${RUN_CONSOLE}" -eq 1 ]]; then
+    # stdout outputs console
+    # stderr outputs be.out
     export DORIS_LOG_TO_STDERR=1
-    ${LIMIT:+${LIMIT}} "${DORIS_HOME}/lib/doris_be" "$@" 2>&1 </dev/null
+    ${LIMIT:+${LIMIT}} "${DORIS_HOME}/lib/doris_be" "$@" 
2>>"${LOG_DIR}/be.out" </dev/null
 else
     ${LIMIT:+${LIMIT}} "${DORIS_HOME}/lib/doris_be" "$@" >>"${LOG_DIR}/be.out" 
2>&1 </dev/null
 fi


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to