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

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


The following commit(s) were added to refs/heads/branch-4.1 by this push:
     new ce89c2b1ef0 branch-4.1: [feature](build) Add build profiling support 
via DORIS_BUILD_PROFILE #61410 (#61424)
ce89c2b1ef0 is described below

commit ce89c2b1ef05f75ec098dddb23508087a3752209
Author: github-actions[bot] 
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Wed Mar 18 14:36:38 2026 +0800

    branch-4.1: [feature](build) Add build profiling support via 
DORIS_BUILD_PROFILE #61410 (#61424)
    
    Cherry-picked from #61410
    
    Co-authored-by: shuke <[email protected]>
---
 .gitignore       |   2 +
 build.sh         |  13 ++++
 build_profile.sh | 186 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 201 insertions(+)

diff --git a/.gitignore b/.gitignore
index b515321338c..91c21130cd8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -16,6 +16,8 @@ core.*
 nohup.out
 /custom_env.sh
 /custom_env_mac.sh
+/.build_profile.jsonl
+/.build_profile_state.*
 derby.log
 dependency-reduced-pom.xml
 yarn.lock
diff --git a/build.sh b/build.sh
index 6eb0d6bb1fd..a5e4a7e637e 100755
--- a/build.sh
+++ b/build.sh
@@ -38,6 +38,15 @@ export TP_LIB_DIR="${DORIS_THIRDPARTY}/installed/lib"
 HADOOP_DEPS_NAME="hadoop-deps"
 . "${DORIS_HOME}/env.sh"
 
+# ===== Build Profile =====
+if [[ "${DORIS_BUILD_PROFILE}" == "1" ]]; then
+    _BP_STATE="${DORIS_HOME}/.build_profile_state.$$"
+    "${DORIS_HOME}/build_profile.sh" collect "${_BP_STATE}" "$*"
+    trap '"${DORIS_HOME}/build_profile.sh" record "${_BP_STATE}" 130; exit 
130' INT TERM
+    trap '"${DORIS_HOME}/build_profile.sh" record "${_BP_STATE}" $?; exit $?' 
ERR
+fi
+# ===== End Build Profile =====
+
 # Check args
 usage() {
     echo "
@@ -1060,4 +1069,8 @@ if [[ -n "${DORIS_POST_BUILD_HOOK}" ]]; then
     eval "${DORIS_POST_BUILD_HOOK}"
 fi
 
+if [[ "${DORIS_BUILD_PROFILE}" == "1" ]]; then
+    "${DORIS_HOME}/build_profile.sh" record "${_BP_STATE}" 0
+fi
+
 exit 0
diff --git a/build_profile.sh b/build_profile.sh
new file mode 100755
index 00000000000..b3df313dca2
--- /dev/null
+++ b/build_profile.sh
@@ -0,0 +1,186 @@
+#!/usr/bin/env bash
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+##############################################################
+# Build profiling helper for build.sh
+# Usage:
+#   build_profile.sh collect <state_file> <build_args>
+#   build_profile.sh record  <state_file> <exit_code>
+#
+# Controlled by DORIS_BUILD_PROFILE=1 in custom_env.sh.
+# All errors are non-fatal — profiling failures never affect
+# the build itself.
+##############################################################
+
+set +e
+
+DORIS_HOME="${DORIS_HOME:-$(cd "$(dirname "${BASH_SOURCE[0]}")" &>/dev/null && 
pwd)}"
+LOG_FILE="${DORIS_HOME}/.build_profile.jsonl"
+
+# Auto-detect base branch: find the closest remote main branch to HEAD
+detect_base_branch() {
+    local min_count=999999 best="unknown"
+    while read -r ref; do
+        local count
+        count=$(git rev-list --count HEAD ^"${ref}" 2>/dev/null) || continue
+        if [[ "${count}" -lt "${min_count}" ]]; then
+            min_count="${count}"
+            best="${ref#origin/}"
+        fi
+    done < <(git branch -r | grep -oE 
'origin/(master|branch-[0-9.]+|branch-selectdb-doris-[0-9.]+)$')
+    echo "${best}"
+}
+
+# Collect modified files: git diff + untracked, filtered by mtime > 
last_build_time
+collect_files() {
+    local last_time="$1"
+    while IFS= read -r f; do
+        [[ -z "$f" || ! -f "$f" ]] && continue
+        local mtime
+        if [[ "$(uname -s)" == "Darwin" ]]; then
+            mtime=$(stat -f %m "$f")
+        else
+            mtime=$(stat -c %Y "$f")
+        fi
+        [[ "$mtime" -gt "$last_time" ]] && echo "$f"
+    done < <(git diff --name-only 2>/dev/null; git ls-files --others 
--exclude-standard 2>/dev/null)
+}
+
+# Read last_build_time from log (0 for first build)
+get_last_build_time() {
+    local last_time=0
+    if [[ -f "${LOG_FILE}" ]]; then
+        last_time=$(tail -1 "${LOG_FILE}" | python3 -c \
+            "import sys,json; print(json.load(sys.stdin).get('start_time',0))" 
2>/dev/null || echo 0)
+    fi
+    echo "${last_time}"
+}
+
+cmd_collect() {
+    local state_file="$1"
+    local build_args="$2"
+
+    if ! command -v python3 &>/dev/null; then
+        echo "WARNING: python3 not found, build profiling disabled"
+        return 1
+    fi
+
+    local start_time
+    start_time=$(date +%s)
+    local user
+    user=$(whoami)
+    local build_dir
+    build_dir=$(pwd)
+    local commit
+    commit=$(git rev-parse --short HEAD 2>/dev/null || echo "unknown")
+    local base_branch
+    base_branch=$(detect_base_branch)
+    local last_time
+    last_time=$(get_last_build_time)
+    local files
+    files=$(collect_files "${last_time}")
+
+    # Write state to temp file
+    cat > "${state_file}" <<EOF
+_BP_START=${start_time}
+_BP_USER=${user}
+_BP_DIR=${build_dir}
+_BP_COMMIT=${commit}
+_BP_BASE_BRANCH=${base_branch}
+_BP_ARGS=${build_args}
+EOF
+    # Write files as separate lines after a marker
+    echo "===FILES==="  >> "${state_file}"
+    echo "${files}"     >> "${state_file}"
+}
+
+cmd_record() {
+    local state_file="$1"
+    local exit_code="$2"
+
+    if [[ ! -f "${state_file}" ]]; then
+        echo "WARNING: build profile state file not found, skipping"
+        return 1
+    fi
+
+    # Read state (only lines matching _BP_* pattern)
+    local _BP_START _BP_USER _BP_DIR _BP_COMMIT _BP_BASE_BRANCH _BP_ARGS
+    while IFS='=' read -r key value; do
+        [[ "$key" == "===FILES===" ]] && break
+        [[ "$key" == _BP_* ]] || continue
+        eval "${key}='${value}'"
+    done < "${state_file}"
+
+    # Read files (everything after ===FILES=== marker)
+    local files
+    files=$(sed -n '/^===FILES===$/,$ p' "${state_file}" | tail -n +2)
+
+    local end_time
+    end_time=$(date +%s)
+    local load_avg
+    load_avg=$(uptime | grep -oE 'load average[s]?: .*' | sed 's/load 
average[s]\{0,1\}: //')
+
+    # Write record via python3 (env vars + stdin for safety)
+    echo "${files}" | \
+    _BP_USER="${_BP_USER}" \
+    _BP_DIR="${_BP_DIR}" \
+    _BP_BASE_BRANCH="${_BP_BASE_BRANCH}" \
+    _BP_COMMIT="${_BP_COMMIT}" \
+    _BP_ARGS="${_BP_ARGS}" \
+    _BP_START="${_BP_START}" \
+    _BP_EXIT_CODE="${exit_code}" \
+    _BP_END_TIME="${end_time}" \
+    _BP_LOAD_AVG="${load_avg}" \
+    python3 -c "
+import json, os, sys
+
+files = [line.strip() for line in sys.stdin if line.strip()]
+start = int(os.environ['_BP_START'])
+end = int(os.environ['_BP_END_TIME'])
+record = {
+    'user': os.environ['_BP_USER'],
+    'build_dir': os.environ['_BP_DIR'],
+    'base_branch': os.environ['_BP_BASE_BRANCH'],
+    'commit': os.environ['_BP_COMMIT'],
+    'args': os.environ.get('_BP_ARGS', ''),
+    'files': files,
+    'start_time': start,
+    'end_time': end,
+    'duration_sec': end - start,
+    'exit_code': int(os.environ['_BP_EXIT_CODE']),
+    'load_avg': os.environ['_BP_LOAD_AVG'],
+}
+print(json.dumps(record))
+" >> "${LOG_FILE}"
+
+    # Clean up state file
+    rm -f "${state_file}"
+}
+
+case "$1" in
+    collect)
+        cmd_collect "$2" "$3"
+        ;;
+    record)
+        cmd_record "$2" "$3"
+        ;;
+    *)
+        echo "Usage: $0 {collect|record} <state_file> <args|exit_code>"
+        exit 1
+        ;;
+esac


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

Reply via email to