Diff -- /var/www/vhosts/3dshawn.com/site1/purge_log.cgi
Diff
/var/www/vhosts/3dshawn.com/site1/purge_log.cgi
added on local at 2026-07-12 00:19:31
Added
+89
lines
Removed
-0
lines
Context
0
unchanged
Blobs
from
to 2bea94a2b744
to 2bea94a2b744
Unified diff
Naive LCS-based line diff. Additions in emerald, deletions in rose. Both sides decompressed live from BLOB_STORE.| 1 | #!/usr/bin/perl | |
| 2 | #====================================================================== | |
| 3 | # DriftSense -- /purge_log.cgi | |
| 4 | # | |
| 5 | # Audit-trail view of the auto-purge daemon. Shows dry-run plans and | |
| 6 | # live purges side-by-side so operators can preview what live mode | |
| 7 | # would reclaim before flipping the switch in /etc/cron.d/drift_sense. | |
| 8 | #====================================================================== | |
| 9 | use strict; | |
| 10 | use warnings; | |
| 11 | use CGI (); | |
| 12 | use MODS::Config; | |
| 13 | use MODS::DBConnect; | |
| 14 | use MODS::Template; | |
| 15 | use MODS::PageWrapper; | |
| 16 | ||
| 17 | my $cgi = CGI->new; | |
| 18 | my $db = MODS::DBConnect->new; | |
| 19 | my $tpl = MODS::Template->new; | |
| 20 | $|=1; | |
| 21 | ||
| 22 | my $dbh = $db->db_connect or die "DB connect failed\n"; | |
| 23 | ||
| 24 | my $mode = $cgi->param('mode') || 'all'; # all | dry_run | live | |
| 25 | my $days = int($cgi->param('days') || 30); | |
| 26 | $days = 1 if $days < 1; $days = 365 if $days > 365; | |
| 27 | ||
| 28 | my $where = "purged_at >= DATE_SUB(NOW(), INTERVAL $days DAY)"; | |
| 29 | $where .= " AND dry_run = 1" if $mode eq 'dry_run'; | |
| 30 | $where .= " AND dry_run = 0" if $mode eq 'live'; | |
| 31 | ||
| 32 | # ---- KPIs ----------------------------------------------------------- | |
| 33 | my $dry_kpi = $db->db_readwrite($dbh, qq~ | |
| 34 | SELECT COUNT(*) AS n, COALESCE(SUM(freed_bytes),0) AS bytes | |
| 35 | FROM PURGE_LOG WHERE dry_run = 1 AND purged_at >= DATE_SUB(NOW(), INTERVAL $days DAY) | |
| 36 | ~, __FILE__, __LINE__); | |
| 37 | my $live_kpi = $db->db_readwrite($dbh, qq~ | |
| 38 | SELECT COUNT(*) AS n, COALESCE(SUM(freed_bytes),0) AS bytes | |
| 39 | FROM PURGE_LOG WHERE dry_run = 0 AND purged_at >= DATE_SUB(NOW(), INTERVAL $days DAY) | |
| 40 | ~, __FILE__, __LINE__); | |
| 41 | ||
| 42 | # ---- Rows ----------------------------------------------------------- | |
| 43 | my @rows = $db->db_readwrite_multiple($dbh, qq~ | |
| 44 | SELECT purge_id, blob_sha, freed_bytes, reason, dry_run, | |
| 45 | DATE_FORMAT(purged_at, '%b %d %H:%i') AS purged_h, | |
| 46 | UNIX_TIMESTAMP(purged_at) AS purged_epoch | |
| 47 | FROM PURGE_LOG | |
| 48 | WHERE $where | |
| 49 | ORDER BY purge_id DESC | |
| 50 | LIMIT 300 | |
| 51 | ~, __FILE__, __LINE__); | |
| 52 | foreach my $r (@rows) { | |
| 53 | $r->{sha_short} = substr($r->{blob_sha} // '', 0, 12); | |
| 54 | $r->{size_h} = _fmt_bytes($r->{freed_bytes} || 0); | |
| 55 | $r->{mode_pill} = $r->{dry_run} ? 'pill-mute' : 'pill-warn'; | |
| 56 | $r->{mode_label} = $r->{dry_run} ? 'dry-run' : 'live'; | |
| 57 | $r->{purged_epoch} //= 0; | |
| 58 | } | |
| 59 | ||
| 60 | $db->db_disconnect($dbh); | |
| 61 | ||
| 62 | my $tvars = { | |
| 63 | rows => \@rows, | |
| 64 | has_rows => scalar(@rows) ? 1 : 0, | |
| 65 | total => scalar @rows, | |
| 66 | days => $days, | |
| 67 | mode => $mode, | |
| 68 | dry_ct => ($dry_kpi && $dry_kpi->{n}) || 0, | |
| 69 | dry_bytes_h => _fmt_bytes(($dry_kpi && $dry_kpi->{bytes}) || 0), | |
| 70 | live_ct => ($live_kpi && $live_kpi->{n}) || 0, | |
| 71 | live_bytes_h => _fmt_bytes(($live_kpi && $live_kpi->{bytes}) || 0), | |
| 72 | all_sel => ($mode eq 'all') ? 'is-active' : '', | |
| 73 | dry_sel => ($mode eq 'dry_run') ? 'is-active' : '', | |
| 74 | live_sel => ($mode eq 'live') ? 'is-active' : '', | |
| 75 | }; | |
| 76 | print "Content-Type: text/html; charset=utf-8\nCache-Control: no-cache\n\n"; | |
| 77 | my @body = $tpl->template('purge_log.html', $tvars); | |
| 78 | MODS::PageWrapper->new->wrapper( | |
| 79 | page_title => 'Purge log', page_key => 'purge_log', | |
| 80 | body_html => join('', @body), userinfo => { display_name => 'Operator' }, | |
| 81 | ); | |
| 82 | ||
| 83 | sub _fmt_bytes { | |
| 84 | my $n = shift; $n //= 0; | |
| 85 | return "$n B" if $n < 1024; | |
| 86 | return sprintf('%.1f KB', $n/1024) if $n < 1024*1024; | |
| 87 | return sprintf('%.1f MB', $n/1024/1024) if $n < 1024*1024*1024; | |
| 88 | return sprintf('%.1f GB', $n/1024/1024/1024); | |
| 89 | } |