mirror of https://github.com/mongodb/mongo
SERVER-113309 direct bazel wrapper output to a logfile (#43855)
GitOrigin-RevId: 403948b8ec293e41032aef2b5b5685fac00db6db
This commit is contained in:
parent
d508bd671b
commit
cde3170368
|
|
@ -10,11 +10,62 @@ sys.path.append(REPO_ROOT)
|
|||
from bazel.wrapper_hook.wrapper_debug import wrapper_debug
|
||||
|
||||
|
||||
def get_terminal_stream(fd_env_var: str):
|
||||
"""Return a Python file object for the original terminal FD."""
|
||||
fd_str = os.environ.get(fd_env_var)
|
||||
if not fd_str:
|
||||
return None
|
||||
|
||||
# Handle Windows CON device
|
||||
if fd_str == "CON":
|
||||
# On Windows, open CON device for console output
|
||||
# Use the appropriate stream based on the variable name
|
||||
if "STDOUT" in fd_env_var:
|
||||
try:
|
||||
return open("CON", "w", buffering=1)
|
||||
except (OSError, IOError):
|
||||
return None
|
||||
elif "STDERR" in fd_env_var:
|
||||
try:
|
||||
return open("CON", "w", buffering=1)
|
||||
except (OSError, IOError):
|
||||
return None
|
||||
return None
|
||||
|
||||
# Handle Unix file descriptors
|
||||
if fd_str.isdigit():
|
||||
fd = int(fd_str)
|
||||
try:
|
||||
return os.fdopen(fd, "w", buffering=1)
|
||||
except (OSError, ValueError):
|
||||
return None
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def setup_auth_wrapper():
|
||||
from buildscripts.bazel_rules_mongo.engflow_auth.engflow_auth import setup_auth
|
||||
|
||||
term_out = get_terminal_stream("MONGO_WRAPPER_STDOUT_FD")
|
||||
term_err = get_terminal_stream("MONGO_WRAPPER_STDERR_FD")
|
||||
|
||||
# Save current stdout/stderr
|
||||
old_stdout = sys.stdout
|
||||
old_stderr = sys.stderr
|
||||
|
||||
try:
|
||||
if term_out:
|
||||
sys.stdout = term_out
|
||||
if term_err:
|
||||
sys.stderr = term_err
|
||||
|
||||
setup_auth(verbose=False)
|
||||
|
||||
finally:
|
||||
# Restore original stdout/stderr to whatever wrapper has
|
||||
sys.stdout = old_stdout
|
||||
sys.stderr = old_stderr
|
||||
|
||||
|
||||
def engflow_auth(args):
|
||||
start = time.time()
|
||||
|
|
|
|||
64
tools/bazel
64
tools/bazel
|
|
@ -119,6 +119,12 @@ done
|
|||
if [ -z $current_bazel_command ]; then
|
||||
skip_python=1
|
||||
fi
|
||||
SLOW_PATH=0
|
||||
if [[ "$skip_python" == "0" ]]; then
|
||||
# We'll do wrapper hook / python installation
|
||||
SLOW_PATH=1
|
||||
fi
|
||||
|
||||
|
||||
if [ "$skip_python" == "0" ]; then
|
||||
# known list of commands to skip
|
||||
|
|
@ -134,7 +140,47 @@ if [ "$skip_python" == "0" ]; then
|
|||
fi
|
||||
|
||||
if [ "$skip_python" == "1" ]; then
|
||||
exec "$bazel_real" $@
|
||||
# Fast path: no wrapper output, run Bazel directly to terminal
|
||||
exec "$bazel_real" "$@"
|
||||
fi
|
||||
|
||||
|
||||
if [[ "$SLOW_PATH" == "1" ]]; then
|
||||
ORIGINAL_ARGS=("$@")
|
||||
|
||||
# Save original terminal output FDs
|
||||
exec 3>&1 4>&2
|
||||
export MONGO_WRAPPER_STDOUT_FD=3
|
||||
export MONGO_WRAPPER_STDERR_FD=4
|
||||
|
||||
LOG_DIR=${MONGO_BAZEL_LOG_DIR:-"$REPO_ROOT/.bazel_logs"}
|
||||
mkdir -p "$LOG_DIR"
|
||||
LOGFILE="${LOG_DIR}/bazel_wrapper_$(date +%Y%m%d_%H%M%S)_$$.log"
|
||||
|
||||
# Redirect stdout/stderr to logfile
|
||||
exec >"$LOGFILE" 2>&1
|
||||
|
||||
WRAPPER_START_EPOCH=$(date +%s)
|
||||
|
||||
GREEN='\033[0;32m'
|
||||
RED='\033[1;31m'
|
||||
NO_COLOR='\033[0m'
|
||||
|
||||
echo -e "${GREEN}INFO:${NO_COLOR} running wrapper hook..." >&4
|
||||
|
||||
print_summary() {
|
||||
local exit_code=$?
|
||||
local end_epoch=$(date +%s)
|
||||
local duration=$(( end_epoch - WRAPPER_START_EPOCH ))
|
||||
if [[ $exit_code -ne 0 ]]; then
|
||||
echo -e "${RED}ERROR:${NO_COLOR} wrapper hook failed: " >&4
|
||||
cat "$LOGFILE" >&4
|
||||
else
|
||||
echo "Bazel wrapper finished. Exit code: ${exit_code}. Duration: ${duration}s" >&4
|
||||
fi
|
||||
}
|
||||
|
||||
trap 'print_summary' EXIT
|
||||
fi
|
||||
|
||||
# find existing python installs
|
||||
|
|
@ -153,15 +199,19 @@ fi
|
|||
if [[ "$python" = "" ]] || [ ! -f $python ]; then
|
||||
>&2 echo "python prereq missing, using bazel to install python..."
|
||||
>&2 $bazel_real build --bes_backend= --bes_results_url= @py_${os}_${ARCH}//:all
|
||||
if [[ $? != 0 ]]; then
|
||||
>&2 $bazel_real build --config=local @py_${os}_${ARCH}//:all
|
||||
if [[ $? != 0 ]]; then
|
||||
if [[ ! -z "$CI" ]] || [[ $MONGO_BAZEL_WRAPPER_FALLBACK == 1 ]]; then
|
||||
>&2 echo "wrapper script failed to install python! falling back to normal bazel call..."
|
||||
exec "$bazel_real" $@
|
||||
"$bazel_real" "$@"
|
||||
exit $?
|
||||
else
|
||||
exit $?
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# update python location if it was missing and we had to install it
|
||||
if [[ "$python" = "" ]] || [ ! -f $python ]; then
|
||||
|
|
@ -201,7 +251,8 @@ fi
|
|||
if [[ $exit_code != 0 ]]; then
|
||||
if [[ ! -z "$CI" ]] || [[ $MONGO_BAZEL_WRAPPER_FALLBACK == 1 ]]; then
|
||||
>&2 echo "wrapper script failed! falling back to normal bazel call..."
|
||||
exec "$bazel_real" $@
|
||||
"$bazel_real" "$@"
|
||||
exit $?
|
||||
else
|
||||
exit $?
|
||||
fi
|
||||
|
|
@ -224,11 +275,14 @@ fi
|
|||
if [[ $autocomplete_query == 1 ]]; then
|
||||
plus_targets=$(</tmp/mongo_autocomplete_plus_targets)
|
||||
query_output=$("${new_args[@]@Q}")
|
||||
echo $query_output $plus_targets | tr " " "\n"
|
||||
echo $query_output $plus_targets | tr " " "\n" >&3
|
||||
else
|
||||
trap - EXIT
|
||||
# Slow path: restore stdout/stderr so Bazel prints normally
|
||||
exec 1>&3 2>&4
|
||||
|
||||
$bazel_real "${new_args[@]}"
|
||||
bazel_exit_code=$?
|
||||
# Run post-bazel hook in subshell
|
||||
( >&2 $python $REPO_ROOT/bazel/wrapper_hook/post_bazel_hook.py $bazel_real )
|
||||
exit $bazel_exit_code
|
||||
fi
|
||||
|
|
|
|||
160
tools/bazel.bat
160
tools/bazel.bat
|
|
@ -1,6 +1,36 @@
|
|||
@echo off
|
||||
setlocal EnableDelayedExpansion
|
||||
|
||||
rem Enable ANSI escape codes for colors (Windows 10+)
|
||||
rem Get ESC character for ANSI colors (set once at the start)
|
||||
for /f %%A in ('echo prompt $E ^| cmd') do set "ESC=%%A"
|
||||
|
||||
rem Enable virtual terminal processing for ANSI escape codes (Windows 10+)
|
||||
rem Create a temporary PowerShell script to enable VT processing
|
||||
set "VT_SCRIPT=%TEMP%\bazel_vt_%RANDOM%.ps1"
|
||||
(
|
||||
echo [Console]::OutputEncoding = [System.Text.Encoding]::UTF8
|
||||
echo $signature = @'
|
||||
echo [DllImport("kernel32.dll", SetLastError=true^)]
|
||||
echo public static extern IntPtr GetStdHandle(int nStdHandle^);
|
||||
echo [DllImport("kernel32.dll", SetLastError=true^)]
|
||||
echo public static extern bool GetConsoleMode(IntPtr hConsoleHandle, out uint lpMode^);
|
||||
echo [DllImport("kernel32.dll", SetLastError=true^)]
|
||||
echo public static extern bool SetConsoleMode(IntPtr hConsoleHandle, uint dwMode^);
|
||||
echo '@
|
||||
echo $type = Add-Type -MemberDefinition $signature -Name Win32Utils -Namespace Console -PassThru
|
||||
echo $STD_OUTPUT_HANDLE = -11
|
||||
echo $STD_ERROR_HANDLE = -12
|
||||
echo $ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004
|
||||
echo $hOut = $type::GetStdHandle($STD_OUTPUT_HANDLE^)
|
||||
echo $hErr = $type::GetStdHandle($STD_ERROR_HANDLE^)
|
||||
echo $mode = 0
|
||||
echo if ($type::GetConsoleMode($hOut, [ref]$mode^)^) { $null = $type::SetConsoleMode($hOut, $mode -bor $ENABLE_VIRTUAL_TERMINAL_PROCESSING^) }
|
||||
echo if ($type::GetConsoleMode($hErr, [ref]$mode^)^) { $null = $type::SetConsoleMode($hErr, $mode -bor $ENABLE_VIRTUAL_TERMINAL_PROCESSING^) }
|
||||
) > "%VT_SCRIPT%"
|
||||
>nul 2>&1 powershell -NoProfile -ExecutionPolicy Bypass -File "%VT_SCRIPT%"
|
||||
del "%VT_SCRIPT%" >nul 2>&1
|
||||
|
||||
echo common --//bazel/config:running_through_bazelisk > .bazelrc.bazelisk
|
||||
|
||||
set REPO_ROOT=%~dp0..
|
||||
|
|
@ -40,22 +70,51 @@ if !skip_python!=="0" if !current_bazel_command!=="info" set skip_python="1"
|
|||
|
||||
if !skip_python!=="1" (
|
||||
"%BAZEL_REAL%" %*
|
||||
exit %ERRORLEVEL%
|
||||
exit /b %ERRORLEVEL%
|
||||
)
|
||||
|
||||
rem === Set up logging for SLOW_PATH (equivalent to bash SLOW_PATH=1) ===
|
||||
rem Where the log will be stored
|
||||
set "LOG_DIR=%REPO_ROOT%\.bazel_logs"
|
||||
if not exist "%LOG_DIR%" mkdir "%LOG_DIR%"
|
||||
set "LOGFILE=%LOG_DIR%\bazel_wrapper_%DATE:/=_%_%TIME::=_%_%RANDOM%.log"
|
||||
|
||||
rem Set up environment variables for terminal output (for engflow_check.py)
|
||||
rem On Windows, we use CON device for console output
|
||||
rem Note: Windows doesn't support file descriptor duplication like Unix,
|
||||
rem so we'll set these to indicate console output should go to CON
|
||||
set "MONGO_WRAPPER_STDOUT_FD=CON"
|
||||
set "MONGO_WRAPPER_STDERR_FD=CON"
|
||||
|
||||
rem === Start timing ===
|
||||
set STARTTIME=%TIME%
|
||||
|
||||
rem === Capture output to logfile starting now ===
|
||||
rem Note: We redirect Python installation and wrapper_hook.py output to logfile
|
||||
|
||||
REM find existing python installs
|
||||
set python=""
|
||||
if exist %REPO_ROOT%\bazel-%cur_dir% (
|
||||
call :find_pyhon
|
||||
)
|
||||
if not exist "!python!" (
|
||||
echo python prereq missing, using bazel to install python... 1>&2
|
||||
"%BAZEL_REAL%" build --bes_backend= --bes_results_url= @py_windows_x86_64//:all 1>&2
|
||||
|
||||
if %ERRORLEVEL% NEQ 0 (
|
||||
if "%CI%"=="" if "%MONGO_BAZEL_WRAPPER_FALLBACK%"=="" exit %ERRORLEVEL%
|
||||
echo wrapper script failed to install python! falling back to normal bazel call... 1>&2
|
||||
(
|
||||
echo python prereq missing, using bazel to install python...
|
||||
"%BAZEL_REAL%" build --bes_backend= --bes_results_url= @py_windows_x86_64//:all
|
||||
if !ERRORLEVEL! NEQ 0 (
|
||||
"%BAZEL_REAL%" build --config=local @py_windows_x86_64//:all
|
||||
if !ERRORLEVEL! NEQ 0 (
|
||||
if "%CI%"=="" if "%MONGO_BAZEL_WRAPPER_FALLBACK%"=="" exit /b !ERRORLEVEL!
|
||||
echo wrapper script failed to install python! falling back to normal bazel call...
|
||||
"%BAZEL_REAL%" %*
|
||||
exit %ERRORLEVEL%
|
||||
exit /b !ERRORLEVEL!
|
||||
)
|
||||
)
|
||||
) > "%LOGFILE%" 2>&1
|
||||
if !ERRORLEVEL! NEQ 0 (
|
||||
echo %ESC%[1;31mERROR:%ESC%[0m Python installation failed:
|
||||
type "%LOGFILE%"
|
||||
exit /b !ERRORLEVEL!
|
||||
)
|
||||
)
|
||||
|
||||
|
|
@ -63,18 +122,55 @@ if not exist "!python!" (
|
|||
call :find_pyhon
|
||||
)
|
||||
|
||||
SET STARTTIME=%TIME%
|
||||
|
||||
rem === Call Python wrapper, log to file ===
|
||||
set "MONGO_BAZEL_WRAPPER_ARGS=%tmp%\bat~%RANDOM%.tmp"
|
||||
echo "" > %MONGO_BAZEL_WRAPPER_ARGS%
|
||||
%python% %REPO_ROOT%/bazel/wrapper_hook/wrapper_hook.py "%BAZEL_REAL%" %* 1>&2
|
||||
if %ERRORLEVEL% NEQ 0 (
|
||||
if "%CI%"=="" if "%MONGO_BAZEL_WRAPPER_FALLBACK%"=="" exit %ERRORLEVEL%
|
||||
echo wrapper script failed! falling back to normal bazel call... 1>&2
|
||||
"%BAZEL_REAL%" %*
|
||||
exit %ERRORLEVEL%
|
||||
|
||||
rem Print info message to terminal (equivalent to bash echo to FD 4)
|
||||
echo %ESC%[0;32mINFO:%ESC%[0m running wrapper hook... 1>&2
|
||||
|
||||
(
|
||||
%python% %REPO_ROOT%/bazel/wrapper_hook/wrapper_hook.py "%BAZEL_REAL%" %*
|
||||
) >> "%LOGFILE%" 2>&1
|
||||
|
||||
set "exit_code=%ERRORLEVEL%"
|
||||
|
||||
rem Linter fails preempt bazel run (exit code 3)
|
||||
if %exit_code% EQU 3 (
|
||||
echo %ESC%[0;31mERROR:%ESC%[0m Linter run failed, see details above 1>&2
|
||||
echo %ESC%[0;32mINFO:%ESC%[0m Run the following to try to auto-fix the errors: 1>&2
|
||||
echo. 1>&2
|
||||
echo bazel run lint --fix 1>&2
|
||||
exit /b %exit_code%
|
||||
)
|
||||
|
||||
rem Calculate duration for summary (equivalent to bash print_summary)
|
||||
set ENDTIME=%TIME%
|
||||
FOR /F "tokens=1-4 delims=:.," %%a IN ("%STARTTIME%") DO (
|
||||
SET /A "start=(((%%a*60)+1%%b %% 100)*60+1%%c %% 100)*100+1%%d %% 100"
|
||||
)
|
||||
FOR /F "tokens=1-4 delims=:.," %%a IN ("%ENDTIME%") DO (
|
||||
SET /A "end=(((%%a*60)+1%%b %% 100)*60+1%%c %% 100)*100+1%%d %% 100"
|
||||
)
|
||||
SET /A elapsed=end-start
|
||||
SET /A hh=elapsed/(60*60*100), rest=elapsed%%(60*60*100), mm=rest/(60*100), rest%%=60*100, ss=rest/100, cc=rest%%100
|
||||
IF %hh% lss 10 SET hh=0%hh%
|
||||
IF %mm% lss 10 SET mm=0%mm%
|
||||
IF %ss% lss 10 SET ss=0%ss%
|
||||
IF %cc% lss 10 SET cc=0%cc%
|
||||
|
||||
if %exit_code% NEQ 0 (
|
||||
echo %ESC%[1;31mERROR:%ESC%[0m wrapper hook failed: 1>&2
|
||||
type "%LOGFILE%" 1>&2
|
||||
|
||||
if "%CI%"=="" if "%MONGO_BAZEL_WRAPPER_FALLBACK%"=="" exit /b %exit_code%
|
||||
echo wrapper script failed! falling back to normal bazel call... 1>&2
|
||||
"%BAZEL_REAL%" %*
|
||||
exit /b %ERRORLEVEL%
|
||||
)
|
||||
|
||||
rem === Read new args back in ===
|
||||
set "new_args="
|
||||
for /F "delims=" %%a in (%MONGO_BAZEL_WRAPPER_ARGS%) do (
|
||||
set str="%%a"
|
||||
call set str=!str: =^ !
|
||||
|
|
@ -82,43 +178,21 @@ for /F "delims=" %%a in (%MONGO_BAZEL_WRAPPER_ARGS%) do (
|
|||
)
|
||||
del %MONGO_BAZEL_WRAPPER_ARGS%
|
||||
|
||||
REM Final Calculations
|
||||
SET ENDTIME=%TIME%
|
||||
FOR /F "tokens=1-4 delims=:.," %%a IN ("%STARTTIME%") DO (
|
||||
SET /A "start=(((%%a*60)+1%%b %% 100)*60+1%%c %% 100)*100+1%%d %% 100"
|
||||
)
|
||||
|
||||
FOR /F "tokens=1-4 delims=:.," %%a IN ("%ENDTIME%") DO (
|
||||
SET /A "end=(((%%a*60)+1%%b %% 100)*60+1%%c %% 100)*100+1%%d %% 100"
|
||||
)
|
||||
|
||||
REM Calculate the elapsed time by subtracting values
|
||||
SET /A elapsed=end-start
|
||||
|
||||
REM Format the results for output
|
||||
SET /A hh=elapsed/(60*60*100), rest=elapsed%%(60*60*100), mm=rest/(60*100), rest%%=60*100, ss=rest/100, cc=rest%%100
|
||||
IF %hh% lss 10 SET hh=0%hh%
|
||||
IF %mm% lss 10 SET mm=0%mm%
|
||||
IF %ss% lss 10 SET ss=0%ss%
|
||||
IF %cc% lss 10 SET cc=0%cc%
|
||||
SET DURATION=%mm%m and %ss%.%cc%s
|
||||
|
||||
if "%MONGO_BAZEL_WRAPPER_DEBUG%"=="1" (
|
||||
ECHO [WRAPPER_HOOK_DEBUG]: wrapper hook script input args: %* 1>&2
|
||||
ECHO [WRAPPER_HOOK_DEBUG]: wrapper hook script new args: !new_args! 1>&2
|
||||
ECHO [WRAPPER_HOOK_DEBUG]: wrapper hook script took %DURATION% 1>&2
|
||||
echo [WRAPPER_HOOK_DEBUG]: wrapper hook script input args: %* 1>&2
|
||||
echo [WRAPPER_HOOK_DEBUG]: wrapper hook script new args: !new_args! 1>&2
|
||||
echo [WRAPPER_HOOK_DEBUG]: wrapper hook script took %mm%m and %ss%.%cc%s 1>&2
|
||||
)
|
||||
|
||||
"%BAZEL_REAL%" !new_args!
|
||||
exit /b %ERRORLEVEL%
|
||||
|
||||
EXIT /B %ERRORLEVEL%
|
||||
|
||||
:: Functions
|
||||
|
||||
:find_pyhon
|
||||
dir %REPO_ROOT% | C:\Windows\System32\find.exe "bazel-%cur_dir%" > %REPO_ROOT%\tmp_bazel_symlink_dir.txt
|
||||
for /f "tokens=2 delims=[" %%i in (%REPO_ROOT%\tmp_bazel_symlink_dir.txt) do set bazel_real_dir=%%i
|
||||
del %REPO_ROOT%\tmp_bazel_symlink_dir.txt
|
||||
set bazel_real_dir=!bazel_real_dir:~0,-1!
|
||||
set python="!bazel_real_dir!\..\..\external\_main~setup_mongo_python_toolchains~py_windows_x86_64\dist\python.exe"
|
||||
EXIT /B 0
|
||||
exit /b 0
|
||||
Loading…
Reference in New Issue