diff --git a/cylc/flow/scripts/cat_log.py b/cylc/flow/scripts/cat_log.py index a98f2de520d..f0dea477a14 100755 --- a/cylc/flow/scripts/cat_log.py +++ b/cylc/flow/scripts/cat_log.py @@ -261,11 +261,6 @@ def view_log( # Print location even if the workflow does not exist yet. print(logpath) return 0 - if not os.path.exists(logpath) and batchview_cmd is None: - # Note: batchview_cmd may not need to have access to logpath, so don't - # test for existence of path if it is set. - sys.stderr.write('file not found: %s\n' % logpath) - return 1 if mode == 'print-dir': print(os.path.dirname(logpath)) return 0 @@ -273,6 +268,11 @@ def view_log( for entry in sorted(os.listdir(os.path.dirname(logpath))): print(entry) return 0 + if not os.path.exists(logpath) and batchview_cmd is None: + # Note: batchview_cmd may not need to have access to logpath, so don't + # test for existence of path if it is set. + sys.stderr.write('file not found: %s\n' % logpath) + return 1 if prepend_path: from cylc.flow.hostuserutil import get_host print(f'# {get_host()}:{logpath}') @@ -374,7 +374,7 @@ def get_task_job_attrs(workflow_id, point, task, submit_num): ) as dao: task_job_data = dao.select_task_job(point, task, submit_num) if task_job_data is None: - return (None, None, None) + return (None, None, None, None) job_runner_name = task_job_data["job_runner_name"] job_id = task_job_data["job_id"] if (not job_runner_name or not job_id @@ -383,7 +383,12 @@ def get_task_job_attrs(workflow_id, point, task, submit_num): live_job_id = None else: live_job_id = job_id - return (task_job_data["platform_name"], job_runner_name, live_job_id) + return ( + task_job_data["platform_name"], + job_runner_name, + live_job_id, + bool(task_job_data['submit_status']), + ) @cli_function(get_option_parser) @@ -512,7 +517,7 @@ def main( with suppress(KeyError): options.filename = JOB_LOG_OPTS[options.filename] # KeyError: Is already long form (standard log, or custom). - platform_name, job_runner_name, live_job_id = get_task_job_attrs( + platform_name, _, live_job_id, submit_failed = get_task_job_attrs( workflow_id, point, task, submit_num) platform = get_platform(platform_name) batchview_cmd = None @@ -538,11 +543,26 @@ def main( batchview_cmd = batchview_cmd_tmpl % { "job_id": str(live_job_id)} + local_log_dir = os.path.normpath( + get_workflow_run_job_dir( + workflow_id, point, task, submit_num + ) + ) + log_is_remote = (is_remote_platform(platform) and (options.filename != JOB_LOG_ACTIVITY)) log_is_retrieved = (platform['retrieve job logs'] and live_job_id is None) - if log_is_remote and (not log_is_retrieved or options.force_remote): + if ( + # only go remote for log files we can't get locally + log_is_remote + # don't look for remote log files for submit-failed tasks + # (there might not be any at all) + and not submit_failed + # don't go remote if the log should be retrieved (unless + # --force-remote is specified) + and (not log_is_retrieved or options.force_remote) + ): logpath = os.path.normpath(get_remote_workflow_run_job_dir( workflow_id, point, task, submit_num, options.filename)) @@ -568,11 +588,22 @@ def main( manage=(mode == 'tail'), text=False ) + if ( + mode == 'list-dir' + and os.path.exists( + os.path.expandvars( + os.path.join( + os.path.dirname(logpath), + 'job-activity.log' + ) + ) + ) + ): + # add the local-only job-activity.log file to the remote-list + print('job-activity.log') else: # Local task job or local job log. - logpath = os.path.normpath(get_workflow_run_job_dir( - workflow_id, point, task, submit_num, - options.filename)) + logpath = os.path.join(local_log_dir, options.filename) tail_tmpl = os.path.expandvars(platform["tail command template"]) out = view_log( logpath, diff --git a/tests/functional/cylc-cat-log/00-local.t b/tests/functional/cylc-cat-log/00-local.t index cf5c6d067e3..96709c536e1 100755 --- a/tests/functional/cylc-cat-log/00-local.t +++ b/tests/functional/cylc-cat-log/00-local.t @@ -18,7 +18,7 @@ # Test "cylc cat-log" on the workflow host. . "$(dirname "$0")/test_header" #------------------------------------------------------------------------------- -set_test_number 41 +set_test_number 43 install_workflow "${TEST_NAME_BASE}" "${TEST_NAME_BASE}" #------------------------------------------------------------------------------- TEST_NAME="${TEST_NAME_BASE}-validate" @@ -142,6 +142,13 @@ run_ok "${TEST_NAME}-get-path" cylc cat-log -m p "${WORKFLOW_NAME}//1/a-task" run_ok "${TEST_NAME}" cylc cat-log --prepend-path "${WORKFLOW_NAME}//1/a-task" grep_ok "$(cat "#.*${TEST_NAME}-get-path.stdout")" "${TEST_NAME}.stdout" #------------------------------------------------------------------------------- +TEST_NAME=${TEST_NAME_BASE}-submit-failed +run_ok "${TEST_NAME}" cylc cat-log -m l "${WORKFLOW_NAME}//1/submit-failed" +contains_ok "${TEST_NAME}.stdout" <<__END__ +job.tmp +job-activity.log +__END__ +#------------------------------------------------------------------------------- TEST_NAME=${TEST_NAME_BASE}-list-no-install-dir rm -r "${WORKFLOW_RUN_DIR}/log/install" run_ok "${TEST_NAME}-get-path" cylc cat-log -m l "${WORKFLOW_NAME}" diff --git a/tests/functional/cylc-cat-log/00-local/flow.cylc b/tests/functional/cylc-cat-log/00-local/flow.cylc index 383443109a0..43daf69c6bb 100644 --- a/tests/functional/cylc-cat-log/00-local/flow.cylc +++ b/tests/functional/cylc-cat-log/00-local/flow.cylc @@ -6,7 +6,7 @@ inactivity timeout = PT3M [scheduling] [[graph]] - R1 = a-task + R1 = submit-failed:submit-failed => a-task [runtime] [[a-task]] script = """ @@ -18,4 +18,10 @@ echo "drugs and money" > ${CYLC_TASK_LOG_ROOT}.custom-log # Generate a warning message in the workflow log. cylc message -p WARNING 'marmite and squashed bananas' + # Remove the submit-failed task. + cylc remove "${CYLC_WORKFLOW_NAME}//1/submit-failed" """ + [[submit-failed]] + # This causes a submission failure due to Bash syntax check. + # In this case the job file isn't even written remotely. + script = if diff --git a/tests/functional/cylc-cat-log/01-remote.t b/tests/functional/cylc-cat-log/01-remote.t index 4d1d4a0a3ac..cec9de4d8ab 100755 --- a/tests/functional/cylc-cat-log/01-remote.t +++ b/tests/functional/cylc-cat-log/01-remote.t @@ -89,6 +89,7 @@ TEST_NAME=${TEST_NAME_BASE}-task-list-remote-NN cylc cat-log -f j -m l "${WORKFLOW_NAME}//1/a-task" >"${TEST_NAME}.out" contains_ok "${TEST_NAME}.out" <<__END__ job +job-activity.log job.custom-log job.err job.out