Skip to content

Commit 279f1ab

Browse files
authored
extended stats command (#275)
1 parent fdd3128 commit 279f1ab

3 files changed

Lines changed: 74 additions & 73 deletions

File tree

src/discord-cluster-manager/cogs/admin_cog.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -762,7 +762,8 @@ async def update_competition(
762762
logger.exception("Error updating problem set", exc_info=e)
763763

764764
@with_error_handling
765-
async def show_bot_stats(self, interaction: discord.Interaction):
765+
@discord.app_commands.describe(last_day_only="Only show stats for the last day")
766+
async def show_bot_stats(self, interaction: discord.Interaction, last_day_only: bool):
766767
is_admin = await self.admin_check(interaction)
767768
if not is_admin:
768769
await send_discord_message(
@@ -773,7 +774,7 @@ async def show_bot_stats(self, interaction: discord.Interaction):
773774
return
774775

775776
with self.bot.leaderboard_db as db:
776-
stats = db.generate_stats()
777+
stats = db.generate_stats(last_day_only)
777778
msg = """```"""
778779
for k, v in stats.items():
779780
msg += f"\n{k} = {v}"

src/discord-cluster-manager/leaderboard_db.py

Lines changed: 69 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -530,104 +530,102 @@ def get_leaderboard_submissions(
530530
for submission in self.cursor.fetchall()
531531
]
532532

533-
def generate_stats(self):
533+
def generate_stats(self, last_day: bool):
534534
try:
535-
return self._generate_stats()
535+
return self._generate_stats(last_day)
536536
except Exception as e:
537537
logging.exception("error generating stats", exc_info=e)
538538
raise
539539

540-
def _generate_stats(self):
541-
# code-level stats
542-
self.cursor.execute(
543-
"""
544-
SELECT COUNT(*) FROM leaderboard.code_files;
545-
"""
546-
)
547-
num_unique_codes = self.cursor.fetchone()[0]
548-
549-
# submission-level stats
550-
self.cursor.execute(
551-
"""
552-
SELECT
553-
COUNT(*),
554-
COUNT(*) FILTER (WHERE NOT done),
555-
COUNT(DISTINCT user_id),
556-
COUNT(*) FILTER (WHERE submission_time > %s)
557-
FROM leaderboard.submission;
558-
""",
559-
(datetime.datetime.now() - datetime.timedelta(days=1),),
560-
)
561-
num_sub, num_sub_wait, num_users, num_last_day = self.cursor.fetchone()
562-
563-
# run-level stats
564-
self.cursor.execute(
565-
"""
566-
SELECT
567-
COUNT(*),
568-
COUNT(*) FILTER (WHERE passed),
569-
COUNT(score),
570-
COUNT(*) FILTER (WHERE secret)
571-
FROM leaderboard.runs;
572-
"""
573-
)
574-
num_run, num_run_pass, num_scored, num_secret = self.cursor.fetchone()
575-
540+
def _generate_runner_stats(self, last_day: bool = False):
541+
select_expr = "WHERE NOW() - s.submission_time <= interval '24 hours'" if last_day else ""
576542
# per-runner stats
577543
self.cursor.execute(
578-
"""
544+
f"""
579545
SELECT
580546
runner,
581547
COUNT(*),
582548
COUNT(*) FILTER (WHERE passed),
583549
COUNT(score),
584-
COUNT(*) FILTER (WHERE secret)
585-
FROM leaderboard.runs
550+
COUNT(*) FILTER (WHERE secret),
551+
MAX(runs.start_time - s.submission_time),
552+
AVG(runs.start_time - s.submission_time),
553+
SUM(runs.end_time - runs.start_time)
554+
FROM leaderboard.runs JOIN leaderboard.submission s ON submission_id = s.id
555+
{select_expr}
586556
GROUP BY runner;
587557
"""
588558
)
589559

590-
result = {
591-
"num_unique_codes": num_unique_codes,
592-
"num_submissions": num_sub,
593-
"sub_waiting": num_sub_wait,
594-
"num_users": num_users,
595-
"sub_last_day": num_last_day,
596-
"num_runs": num_run,
597-
"runs_passed": num_run_pass,
598-
"runs_scored": num_scored,
599-
"runs_secret": num_secret,
600-
}
601-
560+
result = {}
602561
for row in self.cursor.fetchall():
603562
result[f"num_run.{row[0]}"] = row[1]
604563
result[f"runs_passed.{row[0]}"] = row[2]
605564
result[f"runs_scored.{row[0]}"] = row[3]
606565
result[f"runs_secret.{row[0]}"] = row[4]
566+
result[f"max_delay.{row[0]}"] = row[5]
567+
result[f"avg_delay.{row[0]}"] = row[6]
568+
result[f"total_runtime.{row[0]}"] = row[7]
569+
570+
return result
607571

608-
# calculate heavy hitters
572+
def _generate_submission_stats(self, last_day: bool = False):
573+
select_expr = "WHERE NOW() - submission_time <= interval '24 hours'" if last_day else ""
609574
self.cursor.execute(
610-
"""
611-
WITH run_durations AS (
612-
SELECT
613-
s.user_id AS user_id,
614-
r.end_time - r.start_time AS duration
615-
FROM leaderboard.runs r
616-
JOIN leaderboard.submission s ON r.submission_id = s.id
617-
WHERE NOW() - s.submission_time <= interval '24 hours'
618-
)
575+
f"""
619576
SELECT
620-
user_id,
621-
SUM(duration) AS total
622-
FROM run_durations
623-
GROUP BY user_id
624-
ORDER BY total DESC
625-
LIMIT 10;
577+
COUNT(*),
578+
COUNT(*) FILTER (WHERE NOT done),
579+
COUNT(DISTINCT user_id)
580+
FROM leaderboard.submission
581+
{select_expr}
582+
;
626583
"""
627584
)
585+
num_sub, num_sub_wait, num_users = self.cursor.fetchone()
586+
return {
587+
"num_submissions": num_sub,
588+
"sub_waiting": num_sub_wait,
589+
"num_users": num_users,
590+
}
628591

629-
for row in self.cursor.fetchall():
630-
result[f"total.{row[0]}"] = row[1]
592+
def _generate_stats(self, last_day: bool = False):
593+
result = self._generate_submission_stats(last_day)
594+
result.update(self._generate_runner_stats(last_day))
595+
596+
# code-level stats
597+
if not last_day:
598+
self.cursor.execute(
599+
"""
600+
SELECT COUNT(*) FROM leaderboard.code_files;
601+
"""
602+
)
603+
result["num_unique_codes"] = self.cursor.fetchone()[0]
604+
605+
else:
606+
# calculate heavy hitters
607+
self.cursor.execute(
608+
"""
609+
WITH run_durations AS (
610+
SELECT
611+
s.user_id AS user_id,
612+
r.end_time - r.start_time AS duration
613+
FROM leaderboard.runs r
614+
JOIN leaderboard.submission s ON r.submission_id = s.id
615+
WHERE NOW() - s.submission_time <= interval '24 hours'
616+
)
617+
SELECT
618+
user_id,
619+
SUM(duration) AS total
620+
FROM run_durations
621+
GROUP BY user_id
622+
ORDER BY total DESC
623+
LIMIT 10;
624+
"""
625+
)
626+
627+
for row in self.cursor.fetchall():
628+
result[f"total.{row[0]}"] = row[1]
631629

632630
return result
633631

src/discord-cluster-manager/report.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ class Text:
5151
"""
5252
Text represents markdown-formatted text to be added to the report.
5353
"""
54+
5455
text: str
5556

5657

@@ -64,6 +65,7 @@ class Log:
6465
message, it can be broken up automatically (and reasonably) into multiple
6566
smaller messages.
6667
"""
68+
6769
header: str
6870
content: str
6971

0 commit comments

Comments
 (0)