xref: /aosp_15_r20/external/protobuf/kokoro/caplog.sh (revision 1b3f573f81763fcece89efc2b6a5209149e44ab8)
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