Diff -- /var/www/vhosts/3dshawn.com/site1/alert_test_catcher.cgi
Diff

/var/www/vhosts/3dshawn.com/site1/alert_test_catcher.cgi

added on local at 2026-07-11 18:57:53

Added
+95
lines
Removed
-0
lines
Context
0
unchanged
Blobs
from
to 215f8f105f61
Restore this content →
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 -- /alert_test_catcher.cgi
4#
5# Tiny endpoint that accepts POSTs from the alert dispatcher and appends
6# the raw body + headers to /var/log/drift_sense/test_catcher.log. Used
7# for end-to-end alert testing without needing an external webhook.
8#
9# GET /alert_test_catcher.cgi -> HTML view of the last N events
10# POST anything -> log it, return 200 JSON
11# GET /alert_test_catcher.cgi?raw=1 -> tail the log as text/plain
12#======================================================================
13use strict;
14use warnings;
15use CGI ();
16use POSIX ();
17
18my $LOG = '/var/log/drift_sense/test_catcher.log';
19
20$|=1;
21my $cgi = CGI->new;
22my $method = $ENV{REQUEST_METHOD} || 'GET';
23
24if ($method eq 'POST') {
25 my $body = '';
26 # Prefer CGI.pm's POSTDATA -- handles Plesk/nginx buffering + suEXEC
27 # STDIN quirks reliably; fall back to sysread if that returns empty.
28 $body = $cgi->param('POSTDATA') // '';
29 if ($body eq '' && defined $ENV{CONTENT_LENGTH} && $ENV{CONTENT_LENGTH} > 0) {
30 binmode STDIN;
31 my $want = int($ENV{CONTENT_LENGTH});
32 while (length($body) < $want) {
33 my $chunk = '';
34 my $n = sysread(STDIN, $chunk, $want - length($body));
35 last unless $n;
36 $body .= $chunk;
37 }
38 }
39 my $stamp = POSIX::strftime('%Y-%m-%d %H:%M:%S', localtime);
40 my @hdrs;
41 foreach my $k (sort keys %ENV) {
42 next unless $k =~ /^(HTTP_|CONTENT_|REQUEST_|REMOTE_)/;
43 push @hdrs, " $k = $ENV{$k}";
44 }
45 if (open(my $fh, '>>', $LOG)) {
46 print $fh "==================================================\n";
47 print $fh "[$stamp] delivery received\n";
48 print $fh join("\n", @hdrs), "\n";
49 print $fh "-- body ($ENV{CONTENT_LENGTH} bytes) --\n";
50 print $fh $body, "\n";
51 close($fh);
52 }
53 print "Content-Type: application/json\n\n";
54 print '{"ok":true,"received_bytes":' . length($body) . '}';
55 exit 0;
56}
57
58# GET modes
59if ($cgi->param('raw')) {
60 print "Content-Type: text/plain; charset=utf-8\nCache-Control: no-cache\n\n";
61 if (open(my $fh, '<', $LOG)) {
62 my @lines = <$fh>; close($fh);
63 # tail last 500 lines
64 my $start = @lines > 500 ? scalar(@lines) - 500 : 0;
65 print join('', @lines[$start .. $#lines]);
66 } else {
67 print "(no deliveries yet)\n";
68 }
69 exit 0;
70}
71
72# HTML view
73print "Content-Type: text/html; charset=utf-8\nCache-Control: no-cache\n\n";
74my $body = '';
75if (open(my $fh, '<', $LOG)) {
76 local $/; $body = <$fh>; close($fh);
77}
78my $entries = 0;
79$entries++ while $body =~ /===+/g;
80
81my $esc = $body // '';
82$esc =~ s/&/&amp;/g; $esc =~ s/</&lt;/g; $esc =~ s/>/&gt;/g;
83
84print <<"HTML";
85<!doctype html><html><head><meta charset="utf-8"><title>Alert catcher -- DriftSense</title>
86<link rel="stylesheet" href="/assets/styles/drift_sense.css">
87<meta http-equiv="refresh" content="10">
88</head><body>
89<div style="padding:24px;max-width:1200px;margin:0 auto">
90 <h1 style="color:var(--accent);font-family:var(--sans)">Alert test catcher</h1>
91 <p style="color:var(--text-dim)">POST anything here and it gets appended to <code>$LOG</code>. Auto-refreshes every 10s. <a href="?raw=1" style="color:var(--accent-hi)">raw view</a></p>
92 <div style="color:var(--text);font-size:12.5px;font-family:var(--mono);background:var(--bg-2);border:1px solid var(--border);border-radius:12px;padding:14px 16px;white-space:pre-wrap;max-height:75vh;overflow:auto">$esc</div>
93</div>
94</body></html>
95HTML
Keyboard: j next diff k previous diff g top G bottom r restore c compile-check ? help