Skip to content

Commit af812e7

Browse files
Merge pull request #607 from MetRonnie/cat-log
Log any cat-log failure when listing log files
2 parents d8756e6 + dfb1ab4 commit af812e7

File tree

1 file changed

+27
-25
lines changed

1 file changed

+27
-25
lines changed

cylc/uiserver/resolvers.py

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -16,46 +16,47 @@
1616
"""GraphQL resolvers for use in data accessing and mutation of workflows."""
1717

1818
import asyncio
19-
from contextlib import suppress
2019
import errno
21-
from getpass import getuser
2220
import os
23-
from copy import deepcopy
2421
import signal
25-
from subprocess import Popen, PIPE, DEVNULL
22+
from contextlib import suppress
23+
from copy import deepcopy
24+
from getpass import getuser
25+
from subprocess import (
26+
DEVNULL,
27+
PIPE,
28+
Popen,
29+
)
2630
from typing import (
31+
TYPE_CHECKING,
2732
Any,
2833
AsyncGenerator,
2934
Callable,
3035
Dict,
3136
Iterable,
3237
List,
3338
Optional,
34-
TYPE_CHECKING,
3539
Tuple,
3640
Union,
3741
)
3842

39-
from graphql.language.base import print_ast
4043
import psutil
41-
4244
from cylc.flow.data_store_mgr import WORKFLOW
43-
from cylc.flow.exceptions import (
44-
ServiceFileError,
45-
WorkflowFilesError,
46-
)
45+
from cylc.flow.exceptions import ServiceFileError, WorkflowFilesError
4746
from cylc.flow.id import Tokens
4847
from cylc.flow.network.resolvers import BaseResolvers
49-
from cylc.flow.scripts.clean import CleanOptions
50-
from cylc.flow.scripts.clean import run
48+
from cylc.flow.scripts.clean import CleanOptions, run
49+
from graphql.language.base import print_ast
5150

5251
if TYPE_CHECKING:
5352
from concurrent.futures import Executor
5453
from logging import Logger
5554
from optparse import Values
56-
from graphql import ResolveInfo
55+
5756
from cylc.flow.data_store_mgr import DataStoreMgr
5857
from cylc.flow.option_parsers import Options
58+
from graphql import ResolveInfo
59+
5960
from cylc.uiserver.workflows_mgr import WorkflowsManager
6061

6162

@@ -429,7 +430,7 @@ async def cat_log(cls, id_: Tokens, log, info, file=None):
429430
yield {'connected': False}
430431

431432
@classmethod
432-
async def cat_log_files(cls, id_: Tokens):
433+
async def cat_log_files(cls, id_: Tokens, log: 'Logger') -> List[str]:
433434
"""Calls cat log to get list of available log files.
434435
435436
Note kept separate from the cat_log method above as this is a one off
@@ -438,26 +439,27 @@ async def cat_log_files(cls, id_: Tokens):
438439
file checking.
439440
"""
440441
cmd: List[str] = ['cylc', 'cat-log', '-m', 'l', '-o', id_.id]
442+
log.debug(f"$ {' '.join(cmd)}")
441443
proc_job = await asyncio.subprocess.create_subprocess_exec(
442444
*cmd,
443445
stdout=asyncio.subprocess.PIPE,
444446
stderr=asyncio.subprocess.PIPE,
445447
)
446-
# wait for proc to finish
447-
await proc_job.wait()
448-
449-
# MOTD returned in stderr, no use in returning
450-
out_job, _ = await proc_job.communicate()
451-
if out_job:
448+
ret_code = await proc_job.wait()
449+
out, err = await proc_job.communicate()
450+
if ret_code:
451+
log.error(
452+
f"Command failed ({ret_code}): {' '.join(cmd)}\n{err.decode()}"
453+
)
454+
if out:
452455
return sorted(
453456
# return the log files in reverse sort order
454457
# this means that the most recent log file rotations
455458
# will be at the top of the list
456-
out_job.decode().splitlines(),
459+
out.decode().splitlines(),
457460
reverse=True,
458461
)
459-
else:
460-
return []
462+
return []
461463

462464

463465
class Resolvers(BaseResolvers):
@@ -569,7 +571,7 @@ async def query_service(
569571
self,
570572
id_: Tokens,
571573
):
572-
return await Services.cat_log_files(id_)
574+
return await Services.cat_log_files(id_, self.log)
573575

574576

575577
def kill_process_tree(

0 commit comments

Comments
 (0)