Skip to content

Commit

Permalink
A bit more cat-log refactoring.
Browse files Browse the repository at this point in the history
  • Loading branch information
hjoliver committed Apr 15, 2018
1 parent c19eab8 commit 7c721c2
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 97 deletions.
146 changes: 62 additions & 84 deletions bin/cylc-cat-log
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ from cylc.cfgspec.glbl_cfg import glbl_cfg
from cylc.task_id import TaskID
from cylc.suite_logging import SUITE_LOG_OPTS
from cylc.task_job_logs import (
JOB_LOG_OPTS, OPT_JOB_OUT, OPT_JOB_ERR, NN, JOB_LOGS_LOCAL)
JOB_LOG_OUT, JOB_LOG_ERR, JOB_LOG_OPTS, NN, JOB_LOGS_LOCAL)
from parsec.fileparse import read_and_proc


Expand Down Expand Up @@ -94,22 +94,6 @@ def split_user_at_host(user_at_host):
return (user, host)


def join_user_at_host(user, host):
"""join user, host into user@host, with explicit localhost."""
user_at_host = None
if is_remote(host, user):
if host and user:
# other user on other host
user_at_host = user + "@" + host
elif host:
# local user on other host
user_at_host = host
elif user:
# other user on other localhost
user_at_host = user + "@localhost"
return user_at_host


def view_log(logpath, mode, tailer_tmpl, batchview_cmd=None, remote=False):
"""View (by mode) local log file. This is only called on the file host.
Expand Down Expand Up @@ -229,76 +213,31 @@ def get_option_parser():
return parser


def get_task_job_log_path(
options, suite_name, point, task, submit_num, user_at_host):
"""Return file path of a task job log, given the options."""
user, host = split_user_at_host(user_at_host)
try:
basename = JOB_LOG_OPTS[options.filename or 'o']
except KeyError:
basename = options.filename
if submit_num != NN:
submit_num = "%02d" % int(submit_num)
if os.path.isabs(basename):
return basename
else:
return os.path.normpath(os.path.join(
glbl_cfg().get_derived_host_item(
suite_name, "suite job log directory", host, user),
point, task, submit_num, basename))


def get_task_job_attrs(options, suite_name, point, task, submit_num):
"""Return (user@host, batchview_cmd) of a task job log.
def get_task_job_attrs(suite_name, point, task, submit_num):
"""Return job (user_at_host, batch_sys_name, live_job_id).
user@host is set if task job is run remotely and for relevant log files.
batchview_cmd is a special command to view stdout/stderr files (from global
config, if such a command is needed and exists on the system).
live_job_id is batch system job ID if job is running, else None.
"""
if options.filename in ['d', 'a'] or options.filename in JOB_LOGS_LOCAL:
return (None, None)
suite_dao = CylcSuiteDAO(
os.path.join(
glbl_cfg().get_derived_host_item(
suite_name,
"suite run directory"),
suite_name, "suite run directory"),
"log", CylcSuiteDAO.DB_FILE_BASE_NAME),
is_public=True)
task_job_data = suite_dao.select_task_job(None, point, task, submit_num)
suite_dao.close()
if task_job_data is None:
return (None, None)
user, host = split_user_at_host(str(task_job_data["user_at_host"]))
user_at_host = join_user_at_host(user, host)
if (options.mode in ['l', 'p'] or options.filename not in ['e', 'o'] or
not task_job_data["batch_sys_name"] or
not task_job_data["batch_sys_job_id"] or
not task_job_data["time_run"] or task_job_data["time_run_exit"]):
return (user_at_host, None)
key = None
if options.filename == OPT_JOB_OUT:
if options.mode == 'c':
key = "out viewer"
elif options.mode == 't':
key = "out tailer"
elif options.filename == OPT_JOB_ERR:
if options.mode == 'c':
key = "err viewer"
elif options.mode == 't':
key = "err tailer"
if key is None:
return (user_at_host, None)

conf = glbl_cfg().get_host_item("batch systems", host, user)
try:
batchview_cmd_tmpl = conf[str(task_job_data["batch_sys_name"])][key]
except KeyError:
return (user_at_host, None)
return (None, None, None)
batch_sys_name = task_job_data["batch_sys_name"]
batch_sys_job_id = task_job_data["batch_sys_job_id"]
if (not batch_sys_name or not batch_sys_job_id
or not task_job_data["time_run"]
or task_job_data["time_run_exit"]):
live_job_id = None
else:
return (user_at_host, batchview_cmd_tmpl % {
"job_id": str(task_job_data["batch_sys_job_id"])})

live_job_id = batch_sys_job_id
return (task_job_data["user_at_host"], batch_sys_name, live_job_id)

def tmpfile_edit(tmpfile, geditor=False):
"""Edit a temporary read-only file containing the string filestr.
Expand Down Expand Up @@ -394,21 +333,55 @@ def main():
parser.error("Illegal task ID: %s" % task_id)
if options.submit_num != NN:
try:
submit_num = int(options.submit_num)
options.submit_num = "%02d" % int(options.submit_num)
except ValueError:
parser.error("Illegal submit number: %s" % options.submit_num)
if options.filename is None:
options.filename = OPT_JOB_OUT
user_at_host, batchview_cmd = get_task_job_attrs(
options, suite_name, point, task, options.submit_num)
logpath = get_task_job_log_path(
options, suite_name, point, task, options.submit_num, user_at_host)
options.filename = JOB_LOG_OUT
else:
# Convert short filename args to long (e.g. 'o' to 'job.out').
try:
options.filename = JOB_LOG_OPTS[options.filename]
except KeyError:
# Is already long form (standard log, or custom).
pass
user_at_host, batch_sys_name, live_job_id = get_task_job_attrs(
suite_name, point, task, options.submit_num)
user, host = split_user_at_host(user_at_host)
batchview_cmd = None
if live_job_id is not None:
# Get special batch system log viewer command (e.g. qcat) if one
# exists, the log is out or err, and the job is live.
conf_key = None
if options.filename == JOB_LOG_OUT:
if options.mode == 'c':
conf_key = "out viewer"
elif options.mode == 't':
conf_key = "out tailer"
elif options.filename == JOB_LOG_ERR:
if options.mode == 'c':
conf_key = "err viewer"
elif options.mode == 't':
conf_key = "err tailer"
if conf_key is not None:
conf = glbl_cfg().get_host_item("batch systems", host, user)
batchview_cmd_tmpl = None
try:
batchview_cmd_tmpl = conf[batch_sys_name][key]
except KeyError:
pass
if batchview_cmd_tmpl is not None:
batchview_cmd = batchview_cmd_tmpl % {
"job_id": str(live_job_id)}
pout = None
if user_at_host:
# Reinvoke the cat-log command on the remote account.
user, host = split_user_at_host(user_at_host)
if is_remote(user, host) and (options.filename not in JOB_LOGS_LOCAL):
logpath = os.path.normpath(os.path.join(
glbl_cfg().get_derived_host_item(
suite_name, "suite job log directory", host, user),
point, task, options.submit_num, options.filename))
tail_tmpl = str(glbl_cfg().get_host_item(
"tail command template", host, user))
# Reinvoke the cat-log command on the remote account.
cmd = ['cat-log']
if cylc.flags.debug:
cmd.append('--debug')
Expand All @@ -435,6 +408,11 @@ def main():
data = proc.stdout.read(BUFSIZE)
os.chmod(out, S_IRUSR)
else:
# Local task job or local job log.
logpath = os.path.normpath(os.path.join(
glbl_cfg().get_derived_host_item(
suite_name, "suite job log directory"),
point, task, options.submit_num, options.filename))
tail_tmpl = str(glbl_cfg().get_host_item("tail command template"))
out = view_log(logpath, mode, tail_tmpl, batchview_cmd)
if out == 1:
Expand Down
2 changes: 1 addition & 1 deletion doc/src/cylc-user-guide/siterc.tex
Original file line number Diff line number Diff line change
Expand Up @@ -607,7 +607,7 @@ \subsection{[hosts]}
Host specific default for the~\ref{runtime-events-handler-retry-delays}
setting.

\paragraph[tail command template]{[hosts] \textrightarrow [[HOST]] \textrightarrow local tail command template}
\paragraph[tail command template]{[hosts] \textrightarrow [[HOST]] \textrightarrow tail command template}
\label{local-tail-template}

A command template (with \lstinline=%(filename)s= substitution) to tail-follow
Expand Down
17 changes: 7 additions & 10 deletions lib/cylc/task_job_logs.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,10 @@
JOB_LOG_XTRACE = "job.xtrace" # Note this is also defined in job.sh.
JOB_LOG_DIFF = "job-edit.diff"

OPT_JOB_OUT = 'o'
OPT_JOB_ERR = 'e'

JOB_LOG_OPTS = {
'j': JOB_LOG_JOB,
OPT_JOB_OUT: JOB_LOG_OUT,
OPT_JOB_ERR: JOB_LOG_ERR,
'o': JOB_LOG_OUT,
'e': JOB_LOG_ERR,
'a': JOB_LOG_ACTIVITY,
's': JOB_LOG_STATUS,
'x': JOB_LOG_XTRACE,
Expand All @@ -56,21 +53,21 @@ def get_task_job_id(point, name, submit_num=None):
return os.path.join(str(point), name, submit_num)


def get_task_job_log(suite, point, name, submit_num=None, tail=None):
def get_task_job_log(suite, point, name, submit_num=None, suffix=None):
"""Return the full job log path."""
args = [
glbl_cfg().get_derived_host_item(suite, "suite job log directory"),
get_task_job_id(point, name, submit_num)]
if tail is not None:
args.append(tail)
if suffix is not None:
args.append(suffix)
return os.path.join(*args)


def get_task_job_activity_log(suite, point, name, submit_num=None):
"""Shorthand for get_task_job_log(..., tail="job-activity.log")."""
"""Shorthand for get_task_job_log(..., suffix="job-activity.log")."""
return get_task_job_log(suite, point, name, submit_num, JOB_LOG_ACTIVITY)


def get_task_job_job_log(suite, point, name, submit_num=None):
"""Shorthand for get_task_job_log(..., tail="job")."""
"""Shorthand for get_task_job_log(..., suffix="job")."""
return get_task_job_log(suite, point, name, submit_num, JOB_LOG_JOB)
4 changes: 2 additions & 2 deletions tests/cylc-cat-log/04-local-tail.t
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
# 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 a custom local tail command.
# Test "cylc cat-log" with a custom tail command.
. $(dirname $0)/test_header
#-------------------------------------------------------------------------------
set_test_number 4
Expand All @@ -30,7 +30,7 @@ suite_run_ok "${TEST_NAME_BASE}-run" cylc run "${SUITE_NAME}"
create_test_globalrc "" "
[hosts]
[[localhost]]
local tail command template = $PWD/bin/my-tailer.sh %(filename)s"
tail command template = $PWD/bin/my-tailer.sh %(filename)s"
#-------------------------------------------------------------------------------
sleep 10
TEST_NAME=$TEST_NAME_BASE-cat-log
Expand Down
1 change: 1 addition & 0 deletions tests/cylc-cat-log/05-remote-tail.t
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
CYLC_TEST_IS_GENERIC=false
. $(dirname $0)/test_header
#-------------------------------------------------------------------------------
create_test_globalrc
CYLC_TEST_HOST="$( \
cylc get-global-config -i '[test battery]remote host' 2>'/dev/null')"
CYLC_TEST_OWNER="$( \
Expand Down
2 changes: 2 additions & 0 deletions tests/cylc-cat-log/08-editor-remote.t
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

. "$(dirname $0)"/test_header

create_test_globalrc

HOST="$( cylc get-global-config -i '[test battery]remote host' 2>'/dev/null')"
OWNER="$( cylc get-global-config -i '[test battery]remote owner' 2>'/dev/null')"
if [[ -z "${OWNER}${HOST}" ]]; then
Expand Down

0 comments on commit 7c721c2

Please sign in to comment.