SIMON Master Console Rebuild
True command center for SIMON + WEB360
This rebuild gives you a cleaner production spine: interactive tree, live viewer, guarded editor, dynamic graphics, architecture map, and note storage. It is designed to sit beside your existing
console.php
and become the stronger replacement path.
Dashboard
Tree
Viewer
System Map
File Registry
Notes
Files
15,312
Folders
410
Scanned Size
3.85 GB
PHP Files
891
Editable Text Files
12,573
File viewer
guarded to /htdocs
/sitelogs/help.php
<?php declare(strict_types=1); require_once __DIR__ . '/_bootstrap.php'; <meta charset="utf-8" /> <meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover" /> <title>GAYLORD SINCLAIR β SIMON Traffic Intelligence β’ Help & Error Codes</title> <meta name="theme-color" content="#070b16" /> <style> :root { --bg:#070b16; --edge:#25345e; --text:#eaf2ff; --muted:#9db3e6; --c-cyan:#6ae0ff; --c-indigo:#8aa8ff; --c-violet:#7c4dff; --card:rgba(255,255,255,.06); } *{box-sizing:border-box} html,body{height:100%} body{ margin:0; color:var(--text); font-family:ui-sans-serif,system-ui,Inter,Segoe UI,Roboto,Arial; background: radial-gradient(140% 110% at 50% -10%, #0b1432 0%, var(--bg) 55%, #050814 100%); } /* subtle starfield */ .bg{position:fixed;inset:-10%;pointer-events:none;z-index:-1;mix-blend-mode:screen} .bg.s1{background-image: radial-gradient(1px 1px at 12% 20%, rgba(255,255,255,.45) 50%, transparent 51%), radial-gradient(1px 1px at 70% 60%, rgba(255,255,255,.35) 50%, transparent 51%); background-size:900px 900px;opacity:.35;filter:blur(.3px)} .bg.s2{background-image: radial-gradient(1px 1px at 40% 80%, rgba(255,255,255,.28) 50%, transparent 51%), radial-gradient(1px 1px at 20% 50%, rgba(255,255,255,.22) 50%, transparent 51%); background-size:1100px 1100px;opacity:.28;filter:blur(.6px)} header{position:sticky;top:0;z-index:40; background:linear-gradient(180deg, rgba(7,11,22,.96), rgba(7,11,22,.66)); border-bottom:1px solid var(--edge); backdrop-filter:blur(10px)} .inner{max-width:1200px;margin:0 auto;padding:14px 16px} h1.title3d{ margin:0;font-weight:900;letter-spacing:.6px;line-height:1; font-size:clamp(1.2rem,3.2vw,1.8rem);color:transparent; background:conic-gradient(from 90deg,var(--c-cyan),var(--c-indigo),var(--c-violet),var(--c-cyan)); -webkit-background-clip:text;background-clip:text;text-shadow:0 0 18px rgba(124,77,255,.45) } .tm{font-size:.65em;font-weight:800;color:#bcd3ff;margin-left:.25rem} .wrap{max-width:1200px;margin:0 auto;padding:16px;display:grid;grid-template-columns:280px 1fr;gap:16px} @media (max-width:900px){.wrap{grid-template-columns:1fr}} .toc{position:sticky;top:76px;align-self:start;border:1px solid var(--edge);border-radius:16px; background:linear-gradient(180deg, rgba(255,255,255,.10), rgba(255,255,255,.03)); box-shadow:0 14px 40px rgba(0,0,0,.35), inset 0 1px 0 rgba(255,255,255,.10);padding:12px} .toc h3{margin:6px 0 10px} .toc a{display:block;color:var(--text);text-decoration:none;padding:6px 8px;border-radius:10px} .toc a:hover{background:rgba(255,255,255,.06)} .mut{color:var(--muted)} .small{font-size:.92rem} .card{ background:linear-gradient(180deg, rgba(255,255,255,.10), rgba(255,255,255,.03)); border:1px solid var(--edge);border-radius:16px;padding:14px; box-shadow:0 14px 40px rgba(0,0,0,.35), inset 0 1px 0 rgba(255,255,255,.10); margin-bottom:16px } .grid{display:grid;grid-template-columns:1fr 1fr;gap:16px} @media (max-width:900px){.grid{grid-template-columns:1fr}} .search{display:flex;gap:10px;align-items:center;margin:0 0 12px 0} input[type="search"]{ width:100%;background:#141c31;color:var(--text); border:1px solid #2a3245;border-radius:10px;padding:10px 12px } .btn{ padding:8px 12px;border:1px solid #2a3245;border-radius:10px; background:linear-gradient(180deg, rgba(255,255,255,.12), rgba(255,255,255,.04)); color:var(--text);text-decoration:none;cursor:pointer } table{width:100%;border-collapse:collapse;margin:8px 0} th,td{border:1px solid #2a3245;padding:8px 10px;vertical-align:top} th{background:#18213a;text-align:left;position:sticky;top:0;z-index:1} mark{background:#fff176;color:#121212;padding:0 2px;border-radius:3px} footer.foot{border-top:1px solid var(--edge);margin-top:28px; background:linear-gradient(180deg, rgba(7,11,22,.66), rgba(7,11,22,.92))} </style> </head> <body> <div class="bg s1"></div><div class="bg s2"></div> <header> <div class="inner"> <h1 class="title3d">GAYLORD SINCLAIR <sup class="tm">β’</sup> <span class="mut">SIMON Traffic Intelligence β Help & Manual</span></h1> </div> </header> <div class="wrap"> <!-- TOC --> <nav class="toc"> <h3>Contents</h3> <a href="#overview">Overview</a> <a href="#start">Getting Started</a> <a href="#controls">Controls & Parameters</a> <a href="#tabs">Tabs Explained</a> <a href="#tips">Best Practices</a> <a href="#events">Console Events</a> <a href="#http">HTTP Code Reference</a> <a href="#troubleshoot">Troubleshooting</a> <a href="#credits">Credits</a> </nav> <!-- MAIN --> <main> <!-- Search --> <div class="card"> <div class="search"> <input id="q" type="search" placeholder="Search the manual, event names, or HTTP codes (e.g., 404, upload, ipinfo, history.json)..." autocomplete="off" /> <button class="btn" id="clearBtn" title="Clear search">Clear</button> </div> <p class="mut small">Live search filters all sections & tables and <em>highlights</em> matches. Press <b>Esc</b> to clear.</p> </div> <!-- Overview --> <section class="card" id="overview" data-index> <h2>π Overview</h2> <p>SIMON Traffic Intelligence turns raw web server access logs into clear dashboards: top paths, IPs, referrers, bots vs humans, daily trends, anomalies, CSV export, email reports, and a history engine for monthly/yearly charts.</p> <ul> <li><b>Summary</b> β Insights & charts with filters.</li> <li><b>Files</b> β Upload/manage <code>.log</code>, <code>.gz</code>, <code>.txt</code>.</li> <li><b>IP Intel</b> β Profile a single IP (RDNS, optional geo via ipinfo.io, activity).</li> <li><b>Help</b> β This manual and quick references.</li> </ul> </section> <!-- Getting Started --> <section class="card" id="start" data-index> <h2>π§ Getting Started</h2> <ol> <li>Open <b>Files</b> and upload one or more access logs (supports <code>.gz</code> rotations).</li> <li>Open <b>Summary</b> β it auto-picks the newest log (or choose <code>file=all</code>).</li> <li>Adjust filters: <code>status</code> (404/4xx/5xx), <code>ip</code>, <code>path_regex</code>, <code>ua_regex</code>.</li> <li>Click <b>Rollup now</b> once to build <code>history.json</code> for monthly/yearly charts.</li> <li>Optionally send a styled report via <b>Email</b> to your admin address.</li> </ol> </section> <!-- Controls --> <section class="card" id="controls" data-index> <h2>βοΈ Controls & Parameters</h2> <table> <tr><th>Parameter</th><th>Meaning</th></tr> <tr><td><code>file</code></td><td><b>auto</b> (newest), <b>all</b>, or a specific filename; comma-list allowed.</td></tr> <tr><td><code>top</code></td><td>How many rows to show in βTop Nβ tables (default 15).</td></tr> <tr><td><code>tail_mb</code></td><td>How many MB of each file to parse (default 8; max 128).</td></tr> <tr><td><code>status</code></td><td>Filter by code (e.g., <code>404</code>, <code>4xx</code>, <code>5xx</code>).</td></tr> <tr><td><code>ip</code></td><td>Exact IP filter.</td></tr> <tr><td><code>path_regex</code></td><td>Regex include filter for path (e.g., <code>#^/arcade/#</code>).</td></tr> <tr><td><code>ua_regex</code></td><td>Regex include filter for User-Agent (e.g., <code>/bot|crawler/i</code>).</td></tr> </table> </section> <!-- Tabs Explained --> <section class="card" id="tabs" data-index> <h2>π Tabs Explained</h2> <div class="grid"> <div> <h3>Summary</h3> <ul> <li><b>At a Glance</b> β file stats, parsed lines, hits.</li> <li><b>Status Breakdown</b> β shows <em>code + meaning</em> (e.g., <code>404 β Not Found</code>).</li> <li><b>Top Paths / IPs / Referrers / Agents</b> β CSV export + drill.</li> <li><b>Daily & Forecast</b> β 7-day MA + lightweight regression forecast.</li> <li><b>Humans vs Bots</b> β UA heuristic separation.</li> <li><b>Suspicious Paths</b> β flags scans (<code>/wp-admin</code>, <code>.env</code>, <code>phpmyadmin</code>β¦)</li> <li><b>High Error IPs</b> β quick .htaccess blocklist snippet generator.</li> </ul> </div> <div> <h3>Files</h3> <ul> <li>Upload raw access logs (up to ~25 MB each, adjustable).</li> <li>Supports <code>.log</code>, <code>.txt</code>, <code>.gz</code> (rotated logs OK).</li> <li>Download any log from the table.</li> </ul> <h3>IP Intel</h3> <ul> <li>Enter an IP to analyze timeline, hour-of-day activity, error rate, and methods.</li> <li>Shows RDNS and, if configured, ipinfo.io geo/org metadata.</li> <li>Export drill rows for that IP to CSV.</li> </ul> </div> </div> </section> <!-- Best Practices --> <section class="card" id="tips" data-index> <h2>π‘ Best Practices</h2> <ul> <li>Keep uploads modest; rotate/gzip logs regularly.</li> <li>Gate the console with a token or IP restriction if public.</li> <li>Use <code>?format=json</code> for automation/external dashboards.</li> <li>Schedule periodic rollups so <code>history.json</code> stays fresh.</li> <li>When slow, limit to one file and reduce <code>tail_mb</code>.</li> </ul> </section> <!-- Console Events --> <section class="card" id="events" data-index> <h2>π§Ύ Console Events & App-Level Errors</h2> <p class="mut small">Events are typically recorded as JSON Lines: <code>{t, type, msg, meta}</code>.</p> <table id="evtTable"> <tr><th>Event / Error</th><th>Description</th></tr> <tr><td>upload_ok</td><td>Upload succeeded (name/size recorded).</td></tr> <tr><td>upload_err</td><td>Upload failed (invalid file, too large, or save error).</td></tr> <tr><td>parse_stats</td><td>Summary parsed (files, lines, unparsed samples).</td></tr> <tr><td>rollup_run</td><td>History rollup saved to <code>history.json</code> (manual or auto).</td></tr> <tr><td>email_ok</td><td>Email summary successfully sent.</td></tr> <tr><td>email_err</td><td>Email sending failed (<code>mail()</code> returned false).</td></tr> <tr><td>Unauthorized token</td><td>Token required or incorrect (<code>?token=β¦</code>).</td></tr> <tr><td>Bad filename</td><td>Unsafe or disallowed filename during upload.</td></tr> <tr><td>No logs to roll up</td><td>Rollup attempted with no parsed logs.</td></tr> <tr><td>no history yetβrun action=rollup</td><td>History charts need an initial rollup.</td></tr> </table> </section> <!-- HTTP Codes --> <section class="card" id="http" data-index> <h2>π HTTP Status Code Reference</h2> <p class="mut small">Common codes youβll see in the Status Breakdown.</p> <div style="max-height:420px;overflow:auto"> <table id="httpTable"> <tr><th>Code</th><th>Meaning</th></tr> <!-- Informational --> <tr><td>100</td><td>Continue</td></tr> <tr><td>101</td><td>Switching Protocols</td></tr> <tr><td>102</td><td>Processing</td></tr> <tr><td>103</td><td>Early Hints</td></tr> <!-- Success --> <tr><td>200</td><td>OK</td></tr> <tr><td>201</td><td>Created</td></tr> <tr><td>202</td><td>Accepted</td></tr> <tr><td>203</td><td>Non-Authoritative Information</td></tr> <tr><td>204</td><td>No Content</td></tr> <tr><td>205</td><td>Reset Content</td></tr> <tr><td>206</td><td>Partial Content</td></tr> <tr><td>207</td><td>Multi-Status</td></tr> <tr><td>208</td><td>Already Reported</td></tr> <tr><td>226</td><td>IM Used</td></tr> <!-- Redirects --> <tr><td>300</td><td>Multiple Choices</td></tr> <tr><td>301</td><td>Moved Permanently</td></tr> <tr><td>302</td><td>Found</td></tr> <tr><td>303</td><td>See Other</td></tr> <tr><td>304</td><td>Not Modified</td></tr> <tr><td>307</td><td>Temporary Redirect</td></tr> <tr><td>308</td><td>Permanent Redirect</td></tr> <!-- Client errors --> <tr><td>400</td><td>Bad Request</td></tr> <tr><td>401</td><td>Unauthorized</td></tr> <tr><td>402</td><td>Payment Required</td></tr> <tr><td>403</td><td>Forbidden</td></tr> <tr><td>404</td><td>Not Found</td></tr> <tr><td>405</td><td>Method Not Allowed</td></tr> <tr><td>406</td><td>Not Acceptable</td></tr> <tr><td>407</td><td>Proxy Authentication Required</td></tr> <tr><td>408</td><td>Request Timeout</td></tr> <tr><td>409</td><td>Conflict</td></tr> <tr><td>410</td><td>Gone</td></tr> <tr><td>411</td><td>Length Required</td></tr> <tr><td>412</td><td>Precondition Failed</td></tr> <tr><td>413</td><td>Payload Too Large</td></tr> <tr><td>414</td><td>URI Too Long</td></tr> <tr><td>415</td><td>Unsupported Media Type</td></tr> <tr><td>416</td><td>Range Not Satisfiable</td></tr> <tr><td>417</td><td>Expectation Failed</td></tr> <tr><td>418</td><td>I'm a teapot</td></tr> <tr><td>421</td><td>Misdirected Request</td></tr> <tr><td>422</td><td>Unprocessable Content</td></tr> <tr><td>423</td><td>Locked</td></tr> <tr><td>424</td><td>Failed Dependency</td></tr> <tr><td>425</td><td>Too Early</td></tr> <tr><td>426</td><td>Upgrade Required</td></tr> <tr><td>428</td><td>Precondition Required</td></tr> <tr><td>429</td><td>Too Many Requests</td></tr> <tr><td>431</td><td>Request Header Fields Too Large</td></tr> <tr><td>451</td><td>Unavailable For Legal Reasons</td></tr> <!-- Server errors --> <tr><td>500</td><td>Internal Server Error</td></tr> <tr><td>501</td><td>Not Implemented</td></tr> <tr><td>502</td><td>Bad Gateway</td></tr> <tr><td>503</td><td>Service Unavailable</td></tr> <tr><td>504</td><td>Gateway Timeout</td></tr> <tr><td>505</td><td>HTTP Version Not Supported</td></tr> <tr><td>506</td><td>Variant Also Negotiates</td></tr> <tr><td>507</td><td>Insufficient Storage</td></tr> <tr><td>508</td><td>Loop Detected</td></tr> <tr><td>510</td><td>Not Extended</td></tr> <tr><td>511</td><td>Network Authentication Required</td></tr> </table> </div> </section> <!-- Troubleshooting --> <section class="card" id="troubleshoot" data-index> <h2>π οΈ Troubleshooting</h2> <ul> <li><b>Blank screen</b> β Check <code>.htaccess</code> rewrite loops and PHP handler; verify no fatal syntax errors.</li> <li><b>Unauthorized token</b> β Disable token gate or append <code>?token=...</code>.</li> <li><b>mail() returned false</b> β Verify sender domain, SPF/DMARC, and hosting mail config.</li> <li><b>No history yet</b> β Run a rollup to seed <code>history.json</code>.</li> <li><b>Slow parse</b> β Lower <code>tail_mb</code> and/or choose a single file.</li> <li><b>Upload blocked</b> β Keep filenames simple; raise upload limits if necessary.</li> </ul> </section> <!-- Credits --> <section class="card" id="credits" data-index> <h2>π Credits</h2> <p>Designed & produced by <b>GAYLORD SINCLAIRβ’</b> β Gaylord Sinclair Publishing LLC.</p> </section> <footer class="foot"> <div class="inner small">β’ Gaylord Sinclair Publishing LLC β All Rights Reserved</div> </footer> </main> </div> <script> /* Live search across sections and tables with highlighting */ (function(){ const q = document.getElementById('q'); const clearBtn = document.getElementById('clearBtn'); const sections = Array.from(document.querySelectorAll('[data-index]')); const tables = [document.getElementById('evtTable'), document.getElementById('httpTable')].filter(Boolean); function stripMarks(el){ el.querySelectorAll('mark').forEach(m => { const t = document.createTextNode(m.textContent); m.parentNode.replaceChild(t, m); m.parentNode.normalize && m.parentNode.normalize(); }); } function escReg(s){ return s.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&'); } function highlight(el, term){ if (!term) return; const rx = new RegExp('(' + escReg(term) + ')', 'ig'); const walker = document.createTreeWalker(el, NodeFilter.SHOW_TEXT, { acceptNode: n => n.nodeValue.trim().length ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT }); const nodes = []; while (walker.nextNode()) nodes.push(walker.currentNode); nodes.forEach(node => { const parent = node.parentNode; if (!parent) return; const frag = document.createDocumentFragment(); const parts = node.nodeValue.split(rx); parts.forEach((part, i) => { if (i % 2 === 1) { const mark = document.createElement('mark'); mark.textContent = part; frag.appendChild(mark); } else { frag.appendChild(document.createTextNode(part)); } }); parent.replaceChild(frag, node); }); } function filter(){ const term = q.value.trim(); // reset view sections.forEach(s => { s.style.display = ''; stripMarks(s); }); tables.forEach(t => { Array.from(t.querySelectorAll('tr')).forEach(tr => { tr.style.display=''; stripMarks(tr); }); }); if (!term) return; // filter sections sections.forEach(s => { const txt = s.textContent.toLowerCase(); if (!txt.includes(term.toLowerCase())) s.style.display = 'none'; else highlight(s, term); }); // filter tables (keep headers) tables.forEach(t => { const rows = Array.from(t.querySelectorAll('tr')); rows.forEach((tr, idx) => { if (idx === 0) return; // header row const txt = tr.textContent.toLowerCase(); if (!txt.includes(term.toLowerCase())) tr.style.display = 'none'; else highlight(tr, term); }); }); } function clearSearch(){ q.value = ''; sections.forEach(s => { s.style.display = ''; stripMarks(s); }); tables.forEach(t => { Array.from(t.querySelectorAll('tr')).forEach(tr => { tr.style.display=''; stripMarks(tr); }); }); q.focus(); } let timer = null; q.addEventListener('input', () => { clearTimeout(timer); timer = setTimeout(filter, 120); }); q.addEventListener('keydown', e => { if (e.key === 'Escape') clearSearch(); }); clearBtn.addEventListener('click', clearSearch); })(); </script> </body> </html>
Save file
Quick jump
open a path
Open