1# Log capturing for the Kokoro runtime environment. 2# 3# This script should be `source`d from Kokoro build scripts to configure log 4# capturing when running under Kokoro. 5# 6# When not running under Kokoro, no logs will be collected. If you want to run 7# locally and collect logs anyway, set the KOKORO_ARTIFACTS_DIR environment 8# variable to a directory where the logs should go. 9# 10# The job `.cfg` file needs the following stanzas to declare the captured logs 11# as outputs (yes, these are globs, not regexes): 12# 13# action: { 14# define_artifacts: { 15# regex: "**/*sponge_log.log" 16# regex: "**/*sponge_log.xml" 17# } 18# } 19# 20# Use the provided functions below as build/test fixtures, e.g.: 21# 22# source kokoro/capture_logs.sh 23# caplog build/step1 <build command> 24# caplog tests/step2 <test command> 25# 26# If log capturing is enabled, this script will set some variables that can be 27# used if necessary: 28# 29# CAPLOG_DIR is used for logs 30# CAPLOG_CMAKE_ARGS contains extra cmake args to enable test XML output 31# CAPLOG_CTEST_ARGS contains extra ctest args to capture combined test logs 32# 33# For example: 34# 35# if [[ -v CAPLOG_DIR_BUILD ]]; then 36# cp extra_diagnostics.log "${CAPLOG_DIR_BUILD}/diagnostics.log" 37# fi 38# 39# # Use ${...:-} form under `set -u`: 40# caplog build/01_configure cmake -G Ninja ${CAPLOG_CMAKE_ARGS:-} 41# caplog build/02_build cmake --build 42# caplog test/03_test ctest ${CAPLOG_CTEST_ARGS:-} 43 44if [[ -z ${KOKORO_ARTIFACTS_DIR:-} ]]; then 45 function caplog() { shift; "$@"; } 46else 47 48 CAPLOG_DIR="$(mktemp -d)" 49 CAPLOG_CMAKE_ARGS="-Dprotobuf_TEST_XML_OUTDIR=${CAPLOG_DIR}/tests/" 50 CAPLOG_CTEST_ARGS="--verbose" 51 52 # Captures the stdout/stderr of a command to a named log file. 53 # Usage: caplog NAME COMMAND [ARGS...] 54 function caplog() { 55 _name="${CAPLOG_DIR}/${1%.log}.log"; shift 56 mkdir -p "${_name%/*}" 57 date 58 time ( "$@" 2>&1 | tee "${_name}" ) 59 if [[ $? != 0 ]] ; then 60 cat "${_name}" 61 return 1 62 fi 63 } 64 65 # Trap handler: renames logs on script exit so they will be found by Kokoro. 66 function _caplog_onexit() { 67 _rc=$? 68 set +x 69 echo "Collecting logs [${BASH_SOURCE}]" 70 71 find "${CAPLOG_DIR}" -type f -name '*.log' \ 72 | while read _textlog; do 73 # Ensure an XML file exists for each .log file. 74 touch ${_textlog%.log}.xml 75 done 76 77 find "${CAPLOG_DIR}" -type f \( -name '*.xml' -or -name '*.log' \) \ 78 | while read _src; do 79 # Move to artifacts dir, preserving the path relative to CAPLOG_DIR. 80 # The filename changes from foo/bar.log to foo/bar/sponge_log.log. 81 _logfile=${_src/${CAPLOG_DIR}\//} 82 _stem=${KOKORO_ARTIFACTS_DIR}/${_logfile%.*} 83 _ext=${_logfile##*.} 84 mkdir -p ${_stem} 85 mv -v "${_src}" "${_stem}/sponge_log.${_ext}" 86 done 87 rm -rv "${CAPLOG_DIR}" 88 exit ${_rc} 89 } 90 trap _caplog_onexit EXIT 91 92fi 93