at main 2.8 kB view raw
1#!/usr/bin/env -S uv run --script 2# /// script 3# requires-python = ">=3.11" 4# dependencies = ["redis"] 5# /// 6"""check recent docket task runs. 7 8usage: 9 ./scripts/docket_runs.py # uses DOCKET_URL from env 10 ./scripts/docket_runs.py --env staging # uses staging redis 11 ./scripts/docket_runs.py --env production # uses production redis 12 ./scripts/docket_runs.py --limit 20 # show more runs 13""" 14 15import argparse 16import os 17 18import redis 19 20 21def main(): 22 parser = argparse.ArgumentParser(description="check docket task runs") 23 parser.add_argument( 24 "--env", 25 choices=["local", "staging", "production"], 26 default="local", 27 help="environment to check (default: local, uses DOCKET_URL)", 28 ) 29 parser.add_argument( 30 "--limit", type=int, default=10, help="number of runs to show (default: 10)" 31 ) 32 args = parser.parse_args() 33 34 # get redis url 35 if args.env == "local": 36 url = os.environ.get("DOCKET_URL", "redis://localhost:6379") 37 elif args.env == "staging": 38 url = os.environ.get("DOCKET_URL_STAGING") 39 if not url: 40 print("error: DOCKET_URL_STAGING not set") 41 print("hint: flyctl proxy 6380:6379 -a plyr-redis-stg") 42 print(" export DOCKET_URL_STAGING=redis://localhost:6380") 43 return 1 44 elif args.env == "production": 45 url = os.environ.get("DOCKET_URL_PRODUCTION") 46 if not url: 47 print("error: DOCKET_URL_PRODUCTION not set") 48 print("hint: flyctl proxy 6381:6379 -a plyr-redis") 49 print(" export DOCKET_URL_PRODUCTION=redis://localhost:6381") 50 return 1 51 52 print(f"connecting to {args.env}...") 53 r = redis.from_url(url) 54 55 # get all run keys 56 keys = r.keys("plyr:runs:*") 57 if not keys: 58 print("no runs found") 59 return 0 60 61 print(f"found {len(keys)} total runs, showing last {args.limit}:\n") 62 63 for key in sorted(keys, reverse=True)[: args.limit]: 64 data = r.hgetall(key) 65 run_id = key.decode().split(":")[-1] 66 67 # extract fields safely 68 function = data.get(b"function", b"?").decode() 69 state = data.get(b"state", b"?").decode() 70 started = ( 71 data.get(b"started_at", b"").decode()[:19] 72 if data.get(b"started_at") 73 else "?" 74 ) 75 completed = ( 76 data.get(b"completed_at", b"").decode()[:19] 77 if data.get(b"completed_at") 78 else "-" 79 ) 80 # state emoji 81 emoji = {"completed": "", "failed": "", "running": ""}.get(state, "?") 82 83 print( 84 f"{emoji} {run_id[:8]} {function:<20} {state:<10} {started}{completed}" 85 ) 86 87 return 0 88 89 90if __name__ == "__main__": 91 raise SystemExit(main())