Skip to content

Commit

Permalink
Merge pull request #6480 from oliver-sanders/cat-log-list-tailable-files
Browse files Browse the repository at this point in the history
cat-log: list out/err files when available via tailer
  • Loading branch information
oliver-sanders authored Feb 14, 2025
2 parents 9fe7f51 + 4714a46 commit ba6043d
Show file tree
Hide file tree
Showing 4 changed files with 150 additions and 14 deletions.
1 change: 1 addition & 0 deletions changes.d/6480.fix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
`cat-log`: List log files which are available via a configured tailer/viewer command.
51 changes: 37 additions & 14 deletions cylc/flow/scripts/cat_log.py
Original file line number Diff line number Diff line change
Expand Up @@ -596,28 +596,51 @@ def _main(
cmd.append('--prepend-path')
cmd.append(workflow_id)
# TODO: Add Intelligent Host selection to this
proc = None
with suppress(KeyboardInterrupt):
# (Ctrl-C while tailing)
# NOTE: This will raise NoHostsError if the platform is not
# contactable
remote_cylc_cmd(
proc = remote_cylc_cmd(
cmd,
platform,
capture_process=False,
capture_process=(mode == 'list-dir'),
manage=(mode == 'tail'),
text=False
text=(mode == 'list-dir'),
)
if (
mode == 'list-dir'
and os.path.exists(
os.path.join(
local_log_dir,
'job-activity.log'
)
)
):
# add the local-only job-activity.log file to the remote-list
print('job-activity.log')

# add and missing items to file listing results
if isinstance(proc, Popen):
# i.e: if mode=='list-dir' and ctrl+c not pressed
out, err = proc.communicate()
files = out.splitlines()

# add files which can be accessed via a tailer
if live_job_id is not None:
if (
# NOTE: only list the file if it can be viewed in
# both modes
(platform['out tailer'] and platform['out viewer'])
and 'job.out' not in files
):
files.append('job.out')
if (
(platform['err tailer'] and platform['err viewer'])
and 'job.err' not in files
):
files.append('job.err')

# add the job-activity.log file which is always local
if os.path.exists(
os.path.join(local_log_dir, 'job-activity.log')
):
files.append('job-activity.log')

files.sort()
print('\n'.join(files))
print(err, file=sys.stderr)
sys.exit(proc.returncode)

else:
# Local task job or local job log.
logpath = os.path.join(local_log_dir, options.filename)
Expand Down
87 changes: 87 additions & 0 deletions tests/functional/cylc-cat-log/13-remote-out-err-tailer.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
#!/usr/bin/env bash
# THIS FILE IS PART OF THE CYLC WORKFLOW ENGINE.
# Copyright (C) NIWA & British Crown (Met Office) & Contributors.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#-------------------------------------------------------------------------------
# Test "cylc cat-log" with custom out/err tailers
export REQUIRE_PLATFORM='loc:remote runner:background fs:indep comms:tcp'
. "$(dirname "$0")/test_header"
#-------------------------------------------------------------------------------
set_test_number 12
#-------------------------------------------------------------------------------
# run the workflow
TEST_NAME="${TEST_NAME_BASE}-validate"
install_workflow "${TEST_NAME_BASE}" "${TEST_NAME_BASE}"
run_ok "${TEST_NAME}" cylc validate "${WORKFLOW_NAME}"
workflow_run_ok "${TEST_NAME_BASE}-run" cylc play -N "${WORKFLOW_NAME}"
#-------------------------------------------------------------------------------
# change the platform the task ran on to the remote platform
sqlite3 "${HOME}/cylc-run/${WORKFLOW_NAME}/log/db" "
UPDATE
task_jobs
SET
platform_name = '${CYLC_TEST_PLATFORM}',
run_status = null
WHERE
name = 'foo'
AND cycle = '1'
;"
#-------------------------------------------------------------------------------
# test cylc cat-log --mode=list-dir will not list job.out / err
# (no tailer / viewer configured)
create_test_global_config "" "
[platforms]
[[$CYLC_TEST_PLATFORM]]
out tailer =
err tailer =
out viewer =
err viewer =
"
TEST_NAME="${TEST_NAME_BASE}-list-dir-no-tailers"
# NOTE: command will fail due to missing remote directory (this tests remote
# error code is preserved)
run_fail "${TEST_NAME}" cylc cat-log "${WORKFLOW_NAME}//1/foo" -m 'list-dir'
# the job.out and job.err filees
grep_fail "job.out" "${TEST_NAME}.stdout"
grep_fail "job.err" "${TEST_NAME}.stdout"
#-------------------------------------------------------------------------------
# test cylc cat-log --mode=list-dir lists the tailed files
# (both tailer and viewer configured)
create_test_global_config "" "
[platforms]
[[$CYLC_TEST_PLATFORM]]
out tailer = echo OUT
err tailer = echo ERR
out viewer = echo OUT
err viewer = echo ERR
"
# test cylc cat-log --mode=list-dir lists the tailed files
TEST_NAME="${TEST_NAME_BASE}-list-dir-with-tailers"
# NOTE: command will fail due to missing remote directory (this tests remote
# error code is preserved)
run_fail "${TEST_NAME}" cylc cat-log "${WORKFLOW_NAME}//1/foo" -m 'list-dir'
# the job.out and job.err filees
grep_ok "job.out" "${TEST_NAME}.stdout"
grep_ok "job.err" "${TEST_NAME}.stdout"
#-------------------------------------------------------------------------------
# test cylc cat-log runs the custom tailers
TEST_NAME="${TEST_NAME_BASE}-cat-out"
run_ok "${TEST_NAME}" cylc cat-log "${WORKFLOW_NAME}//1/foo" -f o -m t
grep_ok "OUT" "${TEST_NAME}.stdout"
run_ok "${TEST_NAME}" cylc cat-log "${WORKFLOW_NAME}//1/foo" -f e -m t
grep_ok "ERR" "${TEST_NAME}.stdout"
#-------------------------------------------------------------------------------
purge
exit
25 changes: 25 additions & 0 deletions tests/functional/cylc-cat-log/13-remote-out-err-tailer/flow.cylc
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
[scheduler]
[[events]]
abort on stall timeout = True
stall timeout = PT2M

[scheduling]
[[graph]]
R1 = foo

[runtime]
[[foo]]
script = """
# wait for the started message to be received
cylc__job__poll_grep_workflow_log -E 'foo.*running'
# remove the out/err files
rm "${CYLC_TASK_LOG_DIR}/job.out"
rm "${CYLC_TASK_LOG_DIR}/job.err"
# stop the workflow, orphaning this job
cylc stop --now --now "${CYLC_WORKFLOW_ID}" 2>/dev/null >/dev/null
# suppress any subsequent messages
rm "${CYLC_WORKFLOW_RUN_DIR}/.service/contact"
"""

0 comments on commit ba6043d

Please sign in to comment.