From 416f742cdbfb9c16404c223f2524bade32f100fb Mon Sep 17 00:00:00 2001 From: Mike McLean Date: Apr 05 2025 01:00:54 +0000 Subject: [PATCH 1/4] scheduler-logs --watch option --- diff --git a/cli/koji_cli/commands.py b/cli/koji_cli/commands.py index 114d530..4cb34f4 100644 --- a/cli/koji_cli/commands.py +++ b/cli/koji_cli/commands.py @@ -8417,6 +8417,8 @@ def handle_scheduler_logs(goptions, session, args): help="Logs until given timestamp (included)") parser.add_option("--limit", action="store", type=int, default=None, help="Limit data to last N items. [default: %default]") + parser.add_option("--watch", action="store_true", + help="Monitor scheduler logs") (options, args) = parser.parse_args(args) if len(args) != 0: parser.error("There are no arguments for this command") @@ -8436,31 +8438,21 @@ def handle_scheduler_logs(goptions, session, args): clauses.append(['msg_ts', '>=', options.from_ts]) if options.to_ts: clauses.append(['msg_ts', '<', options.to_ts]) + if options.watch: + if session.hub_version < (1, 35, 0): + parser.error('This option is not supported with hub version %s' % session.hub_version_str) + if options.to_ts: + parser.error('The --watch option cannot be used with --to') fields = ('id', 'task_id', 'host_id', 'host_name', 'msg_ts', 'msg') kwargs = {'clauses': clauses, 'fields': fields} if session.hub_version < (1, 34, 0): error("Hub version is %s and doesn't support scheduler methods " "introduced in 1.34." % session.hub_version_str) - if options.limit is not None: - if session.hub_version >= (1, 34, 1): - kwargs['opts'] = {'order': '-id', 'limit': options.limit} - logs = session.scheduler.getLogMessages(**kwargs) if options.limit is not None: if session.hub_version >= (1, 34, 1): - # server did it for us, but we need to reverse - # don't use reversed() as it will be exhausted after modification loop later - logs.reverse() - else: - # emulate limit - logs = logs[-options.limit:] - if session.hub_version < (1, 34, 1): - # emulate order - logs.sort(key=lambda r: r['id']) - - for log in logs: - log['time'] = time.asctime(time.localtime(log['msg_ts'])) + kwargs['opts'] = {'order': '-id', 'limit': options.limit} mask = ("%(task_id)-10s %(host_name)-20s %(time)-25s %(msg)-30s") if not goptions.quiet: @@ -8473,8 +8465,38 @@ def handle_scheduler_logs(goptions, session, args): print(h) print('-' * len(h)) - for log in logs: - print(mask % log) + while True: + logs = session.scheduler.getLogMessages(**kwargs) + + if options.limit is not None: + if session.hub_version >= (1, 34, 1): + # server did it for us, but we need to reverse + # don't use reversed() as it will be exhausted after modification loop later + logs.reverse() + else: + # emulate limit + logs = logs[-options.limit:] + if session.hub_version < (1, 34, 1): + # emulate order + logs.sort(key=lambda r: r['id']) + + for log in logs: + log['time'] = time.asctime(time.localtime(log['msg_ts'])) + + for log in logs: + print(mask % log) + + if not options.watch: + break + else: + if logs: + # update query for next pass + last_id = logs[-1]['id'] + options.limit = None + kwargs['opts'] = {'order': 'id'} + kwargs['clauses'] = clauses + [['id', '>', last_id]] + time.sleep(goptions.poll_interval) + continue def handle_promote_build(goptions, session, args): From 1d97c429eb133d2dd997e4ebe03caf9b9da4437e Mon Sep 17 00:00:00 2001 From: Mike McLean Date: Apr 05 2025 01:00:54 +0000 Subject: [PATCH 2/4] add more options, adjust time display --- diff --git a/cli/koji_cli/commands.py b/cli/koji_cli/commands.py index 4cb34f4..f5ca09e 100644 --- a/cli/koji_cli/commands.py +++ b/cli/koji_cli/commands.py @@ -8411,6 +8411,14 @@ def handle_scheduler_logs(goptions, session, args): help="Filter by task ID") parser.add_option("--host", type="str", action="store", help="Filter by host (name/ID)") + parser.add_option("--channel", type="str", action="store", + help="Filter by task channel (name/ID)") + parser.add_option("--arch", type="str", action="store", + help="Filter by task arch") + parser.add_option("--method", type="str", action="store", + help="Filter by task method") + parser.add_option("--owner", type="str", action="store", + help="Filter by task owner (name/ID)") parser.add_option("--from", type="float", action="store", dest="from_ts", help="Logs from given timestamp") parser.add_option("--to", type="float", action="store", dest="to_ts", @@ -8432,8 +8440,24 @@ def handle_scheduler_logs(goptions, session, args): try: host_id = int(options.host) except ValueError: - host_id = session.getHost(options.host)['id'] + host_id = session.getHost(options.host, strict=True)['id'] clauses.append(['host_id', host_id]) + if options.channel: + try: + channel_id = int(options.channel) + except ValueError: + channel_id = session.getChannel(options.channel, strict=True)['id'] + clauses.append(['channel_id', channel_id]) + if options.arch: + clauses.append(['arch', options.arch]) + if options.method: + clauses.append(['method', options.method]) + if options.owner: + try: + owner_id = int(options.owner) + except ValueError: + owner_id = session.getUser(options.owner, strict=True)['id'] + clauses.append(['owner', owner_id]) if options.from_ts: clauses.append(['msg_ts', '>=', options.from_ts]) if options.to_ts: @@ -8454,7 +8478,7 @@ def handle_scheduler_logs(goptions, session, args): if session.hub_version >= (1, 34, 1): kwargs['opts'] = {'order': '-id', 'limit': options.limit} - mask = ("%(task_id)-10s %(host_name)-20s %(time)-25s %(msg)-30s") + mask = ("%(time)-20s %(task_id)-10s %(host_name)-30s %(msg)-30s") if not goptions.quiet: h = mask % { 'task_id': 'Task', @@ -8481,7 +8505,7 @@ def handle_scheduler_logs(goptions, session, args): logs.sort(key=lambda r: r['id']) for log in logs: - log['time'] = time.asctime(time.localtime(log['msg_ts'])) + log['time'] = koji.formatTime(log['msg_ts']) for log in logs: print(mask % log) @@ -8496,7 +8520,6 @@ def handle_scheduler_logs(goptions, session, args): kwargs['opts'] = {'order': 'id'} kwargs['clauses'] = clauses + [['id', '>', last_id]] time.sleep(goptions.poll_interval) - continue def handle_promote_build(goptions, session, args): From 832101e32fc9a92a77ad9b0faa85ccf8509fa4d3 Mon Sep 17 00:00:00 2001 From: Mike McLean Date: Apr 07 2025 21:31:28 +0000 Subject: [PATCH 3/4] trying a different output format --- diff --git a/cli/koji_cli/commands.py b/cli/koji_cli/commands.py index f5ca09e..cedebb3 100644 --- a/cli/koji_cli/commands.py +++ b/cli/koji_cli/commands.py @@ -8478,16 +8478,7 @@ def handle_scheduler_logs(goptions, session, args): if session.hub_version >= (1, 34, 1): kwargs['opts'] = {'order': '-id', 'limit': options.limit} - mask = ("%(time)-20s %(task_id)-10s %(host_name)-30s %(msg)-30s") - if not goptions.quiet: - h = mask % { - 'task_id': 'Task', - 'host_name': 'Host', - 'time': 'Time', - 'msg': 'Message', - } - print(h) - print('-' * len(h)) + mask = ("%(time)s %(task_id)s %(host_name)s - %(msg)s") while True: logs = session.scheduler.getLogMessages(**kwargs) From a3b02d6898293317b9bf8dee452d71bdbcfbe328 Mon Sep 17 00:00:00 2001 From: Mike McLean Date: Apr 07 2025 21:37:09 +0000 Subject: [PATCH 4/4] friendlier time options --- diff --git a/cli/koji_cli/commands.py b/cli/koji_cli/commands.py index cedebb3..7da3b62 100644 --- a/cli/koji_cli/commands.py +++ b/cli/koji_cli/commands.py @@ -8406,7 +8406,7 @@ def anon_handle_scheduler_info(goptions, session, args): def handle_scheduler_logs(goptions, session, args): "[monitor] Query scheduler logs" usage = "usage: %prog scheduler-logs " - parser = OptionParser(usage=get_usage_str(usage)) + parser = OptionParser(usage=get_usage_str(usage), option_class=TimeOption) parser.add_option("--task", type="int", action="store", help="Filter by task ID") parser.add_option("--host", type="str", action="store", @@ -8419,9 +8419,9 @@ def handle_scheduler_logs(goptions, session, args): help="Filter by task method") parser.add_option("--owner", type="str", action="store", help="Filter by task owner (name/ID)") - parser.add_option("--from", type="float", action="store", dest="from_ts", + parser.add_option("--from", "--after", type="time", action="store", dest="from_ts", help="Logs from given timestamp") - parser.add_option("--to", type="float", action="store", dest="to_ts", + parser.add_option("--to", "--before", type="time", action="store", dest="to_ts", help="Logs until given timestamp (included)") parser.add_option("--limit", action="store", type=int, default=None, help="Limit data to last N items. [default: %default]")