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

O Operator
Diff

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

added on local at 2026-07-11 18:55:00

Added
+85
lines
Removed
-0
lines
Context
0
unchanged
Blobs
from
to 0c1ec2c322e7
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 if (defined $ENV{CONTENT_LENGTH} && $ENV{CONTENT_LENGTH} > 0) {
27 read(STDIN, $body, $ENV{CONTENT_LENGTH});
28 }
29 my $stamp = POSIX::strftime('%Y-%m-%d %H:%M:%S', localtime);
30 my @hdrs;
31 foreach my $k (sort keys %ENV) {
32 next unless $k =~ /^(HTTP_|CONTENT_|REQUEST_|REMOTE_)/;
33 push @hdrs, " $k = $ENV{$k}";
34 }
35 if (open(my $fh, '>>', $LOG)) {
36 print $fh "==================================================\n";
37 print $fh "[$stamp] delivery received\n";
38 print $fh join("\n", @hdrs), "\n";
39 print $fh "-- body ($ENV{CONTENT_LENGTH} bytes) --\n";
40 print $fh $body, "\n";
41 close($fh);
42 }
43 print "Content-Type: application/json\n\n";
44 print '{"ok":true,"received_bytes":' . length($body) . '}';
45 exit 0;
46}
47
48# GET modes
49if ($cgi->param('raw')) {
50 print "Content-Type: text/plain; charset=utf-8\nCache-Control: no-cache\n\n";
51 if (open(my $fh, '<', $LOG)) {
52 my @lines = <$fh>; close($fh);
53 # tail last 500 lines
54 my $start = @lines > 500 ? scalar(@lines) - 500 : 0;
55 print join('', @lines[$start .. $#lines]);
56 } else {
57 print "(no deliveries yet)\n";
58 }
59 exit 0;
60}
61
62# HTML view
63print "Content-Type: text/html; charset=utf-8\nCache-Control: no-cache\n\n";
64my $body = '';
65if (open(my $fh, '<', $LOG)) {
66 local $/; $body = <$fh>; close($fh);
67}
68my $entries = 0;
69$entries++ while $body =~ /===+/g;
70
71my $esc = $body // '';
72$esc =~ s/&/&amp;/g; $esc =~ s/</&lt;/g; $esc =~ s/>/&gt;/g;
73
74print <<"HTML";
75<!doctype html><html><head><meta charset="utf-8"><title>Alert catcher -- DriftSense</title>
76<link rel="stylesheet" href="/assets/styles/drift_sense.css">
77<meta http-equiv="refresh" content="10">
78</head><body>
79<div style="padding:24px;max-width:1200px;margin:0 auto">
80 <h1 style="color:var(--accent);font-family:var(--sans)">Alert test catcher</h1>
81 <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>
82 <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>
83</div>
84</body></html>
85HTML