<!-- CANARY: REQ=REQ-SERVER-STARTUP-INTEGRATION-001; FEATURE="Server Startup Integration Tests"; ASPECT=EndToEndServerTesting; STATUS=TESTED; OWNER=server; UPDATED=2025-10-05 --> <h2 id="monitoring-and-telemetry" class="position-relative d-flex align-items-center group"> <span>Monitoring and Telemetry</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="monitoring-and-telemetry" aria-haspopup="dialog" aria-label="Share link: Monitoring and Telemetry"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h2><div id="headingShareModal" class="heading-share-modal" role="dialog" aria-modal="true" aria-labelledby="headingShareTitle" hidden> <div class="hsm-dialog" role="document"> <div class="hsm-header"> <h2 id="headingShareTitle" class="h6 mb-0 fw-bold">Share this section</h2> <button type="button" class="hsm-close" aria-label="Close"> <i class="fa-solid fa-xmark"></i> </button> </div> <div class="hsm-body"> <label for="headingShareInput" class="form-label small text-muted mb-1 text-uppercase fw-bold" style="font-size: 0.7rem; letter-spacing: 0.5px;">Permalink</label> <div class="input-group mb-4 hsm-url-group"> <input id="headingShareInput" type="text" class="form-control font-monospace" readonly aria-readonly="true" style="font-size: 0.85rem;" /> <button class="btn btn-primary hsm-copy" type="button" aria-label="Copy" title="Copy"> <i class="fa-duotone fa-clipboard" aria-hidden="true"></i> </button> </div> <div class="small fw-bold mb-2 text-muted text-uppercase" style="font-size: 0.7rem; letter-spacing: 0.5px;">Share via</div> <div class="hsm-share-grid"> <a id="share-twitter" class="btn btn-outline-secondary w-100" target="_blank" rel="noopener noreferrer"> <i class="fa-brands fa-twitter me-2"></i>Twitter </a> <a id="share-linkedin" class="btn btn-outline-secondary w-100" target="_blank" rel="noopener noreferrer"> <i class="fa-brands fa-linkedin me-2"></i>LinkedIn </a> <a id="share-facebook" class="btn btn-outline-secondary w-100" target="_blank" rel="noopener noreferrer"> <i class="fa-brands fa-facebook me-2"></i>Facebook </a> </div> </div> </div> </div> <style> .heading-share-modal { position: fixed; inset: 0; display: flex; justify-content: center; align-items: center; background: rgba(0, 0, 0, 0.6); z-index: 1050; padding: 1rem; backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px); } .heading-share-modal[hidden] { display: none !important; } .hsm-dialog { max-width: 420px; width: 100%; background: var(--bs-body-bg, #fff); color: var(--bs-body-color, #212529); border: 1px solid var(--bs-border-color, rgba(0,0,0,0.1)); border-radius: 1rem; box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25); overflow: hidden; animation: hsm-fade-in 0.2s ease-out; } @keyframes hsm-fade-in { from { opacity: 0; transform: scale(0.95); } to { opacity: 1; transform: scale(1); } } [data-bs-theme="dark"] .hsm-dialog { background: #1e293b; border-color: rgba(255,255,255,0.1); color: #f8f9fa; } .hsm-header { display: flex; justify-content: space-between; align-items: center; padding: 1rem 1.5rem; border-bottom: 1px solid var(--bs-border-color, rgba(0,0,0,0.1)); background: rgba(0,0,0,0.02); } [data-bs-theme="dark"] .hsm-header { background: rgba(255,255,255,0.02); border-color: rgba(255,255,255,0.1); } .hsm-close { background: transparent; border: none; color: inherit; opacity: 0.5; padding: 0.25rem 0.5rem; border-radius: 0.25rem; font-size: 1.2rem; line-height: 1; transition: opacity 0.2s; } .hsm-close:hover { opacity: 1; } .hsm-body { padding: 1.5rem; } .hsm-url-group { display: flex !important; align-items: stretch; } .hsm-url-group .form-control { flex: 1; min-width: 0; margin: 0; background: var(--bs-secondary-bg, #f8f9fa); border-color: var(--bs-border-color, #dee2e6); border-top-right-radius: 0; border-bottom-right-radius: 0; height: 42px; } .hsm-url-group .btn { flex: 0 0 auto; margin: 0; margin-left: -1px; border-top-left-radius: 0; border-bottom-left-radius: 0; height: 42px; display: flex; align-items: center; justify-content: center; padding: 0 1.25rem; z-index: 2; } [data-bs-theme="dark"] .hsm-url-group .form-control { background: #0f172a; border-color: #334155; color: #e2e8f0; } .hsm-share-grid { display: flex; flex-direction: column; gap: 0.5rem; } .hsm-share-grid .btn { display: flex; align-items: center; justify-content: center; font-size: 0.9rem; padding: 0.6rem; border-color: var(--bs-border-color); width: 100%; } [data-bs-theme="dark"] .hsm-share-grid .btn { color: #e2e8f0; border-color: #475569; } [data-bs-theme="dark"] .hsm-share-grid .btn:hover { background: #334155; border-color: #cbd5e1; } </style> <script> (function(){ const modal = document.getElementById('headingShareModal'); if(!modal) return; const input = modal.querySelector('#headingShareInput'); const copyBtn = modal.querySelector('.hsm-copy'); const twitter = modal.querySelector('#share-twitter'); const linkedin = modal.querySelector('#share-linkedin'); const facebook = modal.querySelector('#share-facebook'); const closeBtn = modal.querySelector('.hsm-close'); let lastFocus=null; let trapBound=false; function buildUrl(id){ return window.location.origin + window.location.pathname + '#' + id; } function isOpen(){ return !modal.hasAttribute('hidden'); } function hydrate(id){ const url=buildUrl(id); input.value=url; const enc=encodeURIComponent(url); const text=encodeURIComponent(document.title); if(twitter) twitter.href=`https://twitter.com/intent/tweet?url=${enc}&text=${text}`; if(linkedin) linkedin.href=`https://www.linkedin.com/sharing/share-offsite/?url=${enc}`; if(facebook) facebook.href=`https://www.facebook.com/sharer/sharer.php?u=${enc}`; } function openModal(id){ lastFocus=document.activeElement; hydrate(id); if(!isOpen()){ modal.removeAttribute('hidden'); } requestAnimationFrame(()=>{ input.focus(); }); trapFocus(); } function closeModal(){ if(!isOpen()) return; modal.setAttribute('hidden',''); if(lastFocus && typeof lastFocus.focus==='function') lastFocus.focus(); } function copyCurrent(){ try{ navigator.clipboard.writeText(input.value).then(()=>feedback(true),()=>fallback()); } catch(e){ fallback(); } } function fallback(){ input.select(); try{ document.execCommand('copy'); feedback(true);}catch(e){ feedback(false);} } function feedback(ok){ if(!copyBtn) return; const icon=copyBtn.querySelector('i'); if(!icon) return; const prev=copyBtn.getAttribute('data-prev')||icon.className; if(!copyBtn.getAttribute('data-prev')) copyBtn.setAttribute('data-prev',prev); icon.className= ok ? 'fa-duotone fa-clipboard-check':'fa-duotone fa-circle-exclamation'; setTimeout(()=>{ icon.className=prev; },1800); } function handleShareClick(e){ e.preventDefault(); const btn=e.currentTarget; const id=btn.getAttribute('data-share-target'); if(id) openModal(id); } function bindShareButtons(){ document.querySelectorAll('.h-share').forEach(btn=>{ if(!btn.dataset.hShareBound){ btn.addEventListener('click', handleShareClick); btn.dataset.hShareBound='1'; } }); } bindShareButtons(); if(document.readyState==='loading'){ document.addEventListener('DOMContentLoaded', bindShareButtons); } else { requestAnimationFrame(bindShareButtons); } document.addEventListener('click', function(e){ const shareBtn=e.target.closest && e.target.closest('.h-share'); if(shareBtn && !shareBtn.dataset.hShareBound){ handleShareClick.call(shareBtn, e); } }, true); document.addEventListener('click', e=>{ if(e.target===modal) closeModal(); if(e.target.closest && e.target.closest('.hsm-close')){ e.preventDefault(); closeModal(); } if(copyBtn && (e.target===copyBtn || (e.target.closest && e.target.closest('.hsm-copy')))) { e.preventDefault(); copyCurrent(); } }); document.addEventListener('keydown', e=>{ if(e.key==='Escape' && isOpen()) closeModal(); }); function trapFocus(){ if(trapBound) return; trapBound=true; modal.addEventListener('keydown', f=>{ if(f.key==='Tab' && isOpen()){ const focusable=[...modal.querySelectorAll('a[href],button,input,textarea,select,[tabindex]:not([tabindex="-1"])')].filter(el=>!el.hasAttribute('disabled')); if(!focusable.length) return; const first=focusable[0]; const last=focusable[focusable.length-1]; if(f.shiftKey && document.activeElement===first){ f.preventDefault(); last.focus(); } else if(!f.shiftKey && document.activeElement===last){ f.preventDefault(); first.focus(); } } }); } if(closeBtn) closeBtn.addEventListener('click', e=>{ e.preventDefault(); closeModal(); }); })(); </script><p>Comprehensive observability for Geode: health checks, Prometheus metrics, optional telemetry, and audit logging.</p> <h3 id="health-and-readiness-endpoints" class="position-relative d-flex align-items-center group"> <span>Health and Readiness Endpoints</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="health-and-readiness-endpoints" aria-haspopup="dialog" aria-label="Share link: Health and Readiness Endpoints"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3><p>From <code>USAGE.md</code>:</p> <h4 id="health-check" class="position-relative d-flex align-items-center group"> <span>Health Check</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="health-check" aria-haspopup="dialog" aria-label="Share link: Health Check"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p><strong>Endpoint</strong>: <code>GET /health</code></p> <p><strong>Purpose</strong>: Verify server is running and responsive</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">curl -f http://localhost:8080/health <span class="o">||</span> <span class="nb">echo</span> <span class="s2">&#34;Health check failed&#34;</span> </span></span></code></pre></div><p><strong>Response</strong> (healthy):</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;status&#34;</span><span class="p">:</span> <span class="s2">&#34;healthy&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;timestamp&#34;</span><span class="p">:</span> <span class="s2">&#34;2024-01-15T14:30:00Z&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;version&#34;</span><span class="p">:</span> <span class="s2">&#34;0.2.18&#34;</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span></code></pre></div><p><strong>Response</strong> (unhealthy):</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;status&#34;</span><span class="p">:</span> <span class="s2">&#34;unhealthy&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;error&#34;</span><span class="p">:</span> <span class="s2">&#34;database connection failed&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;timestamp&#34;</span><span class="p">:</span> <span class="s2">&#34;2024-01-15T14:30:00Z&#34;</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span></code></pre></div><p><strong>HTTP status codes</strong>:</p> <ul> <li><code>200 OK</code> - Healthy</li> <li><code>503 Service Unavailable</code> - Unhealthy</li> </ul> <h4 id="readiness-check" class="position-relative d-flex align-items-center group"> <span>Readiness Check</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="readiness-check" aria-haspopup="dialog" aria-label="Share link: Readiness Check"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p><strong>Endpoint</strong>: <code>GET /ready</code></p> <p><strong>Purpose</strong>: Verify server is ready to accept traffic (useful for Kubernetes liveness probes)</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">curl -f http://localhost:8080/ready </span></span></code></pre></div><p><strong>Response</strong> (ready):</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;status&#34;</span><span class="p">:</span> <span class="s2">&#34;ready&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;timestamp&#34;</span><span class="p">:</span> <span class="s2">&#34;2024-01-15T14:30:00Z&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;connections&#34;</span><span class="p">:</span> <span class="mi">42</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;active_transactions&#34;</span><span class="p">:</span> <span class="mi">3</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span></code></pre></div><p><strong>Response</strong> (not ready):</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;status&#34;</span><span class="p">:</span> <span class="s2">&#34;not_ready&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;reason&#34;</span><span class="p">:</span> <span class="s2">&#34;initialization in progress&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;timestamp&#34;</span><span class="p">:</span> <span class="s2">&#34;2024-01-15T14:30:00Z&#34;</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span></code></pre></div><p><strong>Kubernetes liveness probe</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">livenessProbe</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">httpGet</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">path</span><span class="p">:</span><span class="w"> </span><span class="l">/health</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">port</span><span class="p">:</span><span class="w"> </span><span class="m">8080</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">initialDelaySeconds</span><span class="p">:</span><span class="w"> </span><span class="m">30</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">periodSeconds</span><span class="p">:</span><span class="w"> </span><span class="m">10</span><span class="w"> </span></span></span></code></pre></div><p><strong>Kubernetes readiness probe</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">readinessProbe</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">httpGet</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">path</span><span class="p">:</span><span class="w"> </span><span class="l">/ready</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">port</span><span class="p">:</span><span class="w"> </span><span class="m">8080</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">initialDelaySeconds</span><span class="p">:</span><span class="w"> </span><span class="m">5</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">periodSeconds</span><span class="p">:</span><span class="w"> </span><span class="m">5</span><span class="w"> </span></span></span></code></pre></div> <h3 id="prometheus-metrics" class="position-relative d-flex align-items-center group"> <span>Prometheus Metrics</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="prometheus-metrics" aria-haspopup="dialog" aria-label="Share link: Prometheus Metrics"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3><p>From <code>USAGE.md</code>:</p> <h4 id="metrics-endpoint" class="position-relative d-flex align-items-center group"> <span>Metrics Endpoint</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="metrics-endpoint" aria-haspopup="dialog" aria-label="Share link: Metrics Endpoint"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p><strong>Endpoint</strong>: <code>GET /metrics</code></p> <p><strong>Format</strong>: Prometheus text exposition format</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">curl http://localhost:8080/metrics </span></span></code></pre></div> <h4 id="key-metrics" class="position-relative d-flex align-items-center group"> <span>Key Metrics</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="key-metrics" aria-haspopup="dialog" aria-label="Share link: Key Metrics"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>From <code>USAGE.md</code>, key metrics list:</p> <h5 id="query-metrics" class="position-relative d-flex align-items-center group"> <span>Query Metrics</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="query-metrics" aria-haspopup="dialog" aria-label="Share link: Query Metrics"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h5><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gdscript3" data-lang="gdscript3"><span class="line"><span class="cl"><span class="c1"># HELP geode_queries_total Total number of queries executed</span> </span></span><span class="line"><span class="cl"><span class="c1"># TYPE geode_queries_total counter</span> </span></span><span class="line"><span class="cl"><span class="n">geode_queries_total</span><span class="p">{</span><span class="n">graph</span><span class="o">=</span><span class="s2">&#34;SocialNetwork&#34;</span><span class="p">,</span><span class="n">status</span><span class="o">=</span><span class="s2">&#34;success&#34;</span><span class="p">}</span> <span class="mi">12345</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># HELP geode_query_duration_seconds Query execution time</span> </span></span><span class="line"><span class="cl"><span class="c1"># TYPE geode_query_duration_seconds histogram</span> </span></span><span class="line"><span class="cl"><span class="n">geode_query_duration_seconds_bucket</span><span class="p">{</span><span class="n">graph</span><span class="o">=</span><span class="s2">&#34;SocialNetwork&#34;</span><span class="p">,</span><span class="n">le</span><span class="o">=</span><span class="s2">&#34;0.001&#34;</span><span class="p">}</span> <span class="mi">100</span> </span></span><span class="line"><span class="cl"><span class="n">geode_query_duration_seconds_bucket</span><span class="p">{</span><span class="n">graph</span><span class="o">=</span><span class="s2">&#34;SocialNetwork&#34;</span><span class="p">,</span><span class="n">le</span><span class="o">=</span><span class="s2">&#34;0.01&#34;</span><span class="p">}</span> <span class="mi">500</span> </span></span><span class="line"><span class="cl"><span class="n">geode_query_duration_seconds_bucket</span><span class="p">{</span><span class="n">graph</span><span class="o">=</span><span class="s2">&#34;SocialNetwork&#34;</span><span class="p">,</span><span class="n">le</span><span class="o">=</span><span class="s2">&#34;0.1&#34;</span><span class="p">}</span> <span class="mi">1200</span> </span></span><span class="line"><span class="cl"><span class="n">geode_query_duration_seconds_bucket</span><span class="p">{</span><span class="n">graph</span><span class="o">=</span><span class="s2">&#34;SocialNetwork&#34;</span><span class="p">,</span><span class="n">le</span><span class="o">=</span><span class="s2">&#34;1.0&#34;</span><span class="p">}</span> <span class="mi">1250</span> </span></span><span class="line"><span class="cl"><span class="n">geode_query_duration_seconds_sum</span><span class="p">{</span><span class="n">graph</span><span class="o">=</span><span class="s2">&#34;SocialNetwork&#34;</span><span class="p">}</span> <span class="mf">45.67</span> </span></span><span class="line"><span class="cl"><span class="n">geode_query_duration_seconds_count</span><span class="p">{</span><span class="n">graph</span><span class="o">=</span><span class="s2">&#34;SocialNetwork&#34;</span><span class="p">}</span> <span class="mi">1250</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># HELP geode_query_errors_total Total number of query errors</span> </span></span><span class="line"><span class="cl"><span class="c1"># TYPE geode_query_errors_total counter</span> </span></span><span class="line"><span class="cl"><span class="n">geode_query_errors_total</span><span class="p">{</span><span class="n">graph</span><span class="o">=</span><span class="s2">&#34;SocialNetwork&#34;</span><span class="p">,</span><span class="n">error_type</span><span class="o">=</span><span class="s2">&#34;syntax&#34;</span><span class="p">}</span> <span class="mi">12</span> </span></span><span class="line"><span class="cl"><span class="n">geode_query_errors_total</span><span class="p">{</span><span class="n">graph</span><span class="o">=</span><span class="s2">&#34;SocialNetwork&#34;</span><span class="p">,</span><span class="n">error_type</span><span class="o">=</span><span class="s2">&#34;constraint_violation&#34;</span><span class="p">}</span> <span class="mi">5</span> </span></span></code></pre></div> <h5 id="transaction-metrics" class="position-relative d-flex align-items-center group"> <span>Transaction Metrics</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="transaction-metrics" aria-haspopup="dialog" aria-label="Share link: Transaction Metrics"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h5><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gdscript3" data-lang="gdscript3"><span class="line"><span class="cl"><span class="c1"># HELP geode_transactions_active Currently active transactions</span> </span></span><span class="line"><span class="cl"><span class="c1"># TYPE geode_transactions_active gauge</span> </span></span><span class="line"><span class="cl"><span class="n">geode_transactions_active</span> <span class="mi">3</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># HELP geode_transactions_committed Total committed transactions</span> </span></span><span class="line"><span class="cl"><span class="c1"># TYPE geode_transactions_committed counter</span> </span></span><span class="line"><span class="cl"><span class="n">geode_transactions_committed</span> <span class="mi">5678</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># HELP geode_transactions_aborted Total aborted transactions</span> </span></span><span class="line"><span class="cl"><span class="c1"># TYPE geode_transactions_aborted counter</span> </span></span><span class="line"><span class="cl"><span class="n">geode_transactions_aborted</span><span class="p">{</span><span class="n">reason</span><span class="o">=</span><span class="s2">&#34;serialization_error&#34;</span><span class="p">}</span> <span class="mi">23</span> </span></span><span class="line"><span class="cl"><span class="n">geode_transactions_aborted</span><span class="p">{</span><span class="n">reason</span><span class="o">=</span><span class="s2">&#34;constraint_violation&#34;</span><span class="p">}</span> <span class="mi">15</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># HELP geode_transaction_duration_seconds Transaction execution time</span> </span></span><span class="line"><span class="cl"><span class="c1"># TYPE geode_transaction_duration_seconds histogram</span> </span></span><span class="line"><span class="cl"><span class="n">geode_transaction_duration_seconds_bucket</span><span class="p">{</span><span class="n">le</span><span class="o">=</span><span class="s2">&#34;0.1&#34;</span><span class="p">}</span> <span class="mi">4500</span> </span></span><span class="line"><span class="cl"><span class="n">geode_transaction_duration_seconds_bucket</span><span class="p">{</span><span class="n">le</span><span class="o">=</span><span class="s2">&#34;1.0&#34;</span><span class="p">}</span> <span class="mi">5600</span> </span></span><span class="line"><span class="cl"><span class="n">geode_transaction_duration_seconds_bucket</span><span class="p">{</span><span class="n">le</span><span class="o">=</span><span class="s2">&#34;10.0&#34;</span><span class="p">}</span> <span class="mi">5670</span> </span></span></code></pre></div> <h5 id="storage-metrics" class="position-relative d-flex align-items-center group"> <span>Storage Metrics</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="storage-metrics" aria-haspopup="dialog" aria-label="Share link: Storage Metrics"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h5><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl"># HELP geode_storage_pages_total Total number of data pages </span></span><span class="line"><span class="cl"># TYPE geode_storage_pages_total gauge </span></span><span class="line"><span class="cl">geode_storage_pages_total 1234567 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"># HELP geode_storage_cache_hits Cache hit count </span></span><span class="line"><span class="cl"># TYPE geode_storage_cache_hits counter </span></span><span class="line"><span class="cl">geode_storage_cache_hits 98765432 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"># HELP geode_storage_cache_misses Cache miss count </span></span><span class="line"><span class="cl"># TYPE geode_storage_cache_misses counter </span></span><span class="line"><span class="cl">geode_storage_cache_misses 1234567 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"># HELP geode_storage_cache_hit_ratio Cache hit ratio </span></span><span class="line"><span class="cl"># TYPE geode_storage_cache_hit_ratio gauge </span></span><span class="line"><span class="cl">geode_storage_cache_hit_ratio 0.987 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"># HELP geode_wal_writes_bytes Write-Ahead Log bytes written </span></span><span class="line"><span class="cl"># TYPE geode_wal_writes_bytes counter </span></span><span class="line"><span class="cl">geode_wal_writes_bytes 123456789012 </span></span></code></pre></div> <h5 id="connection-metrics" class="position-relative d-flex align-items-center group"> <span>Connection Metrics</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="connection-metrics" aria-haspopup="dialog" aria-label="Share link: Connection Metrics"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h5><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl"># HELP geode_connections_active Currently active client connections </span></span><span class="line"><span class="cl"># TYPE geode_connections_active gauge </span></span><span class="line"><span class="cl">geode_connections_active 42 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"># HELP geode_connections_total Total connections since start </span></span><span class="line"><span class="cl"># TYPE geode_connections_total counter </span></span><span class="line"><span class="cl">geode_connections_total 12345 </span></span></code></pre></div> <h5 id="index-metrics" class="position-relative d-flex align-items-center group"> <span>Index Metrics</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="index-metrics" aria-haspopup="dialog" aria-label="Share link: Index Metrics"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h5><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl"># HELP geode_index_lookups_total Index lookup count </span></span><span class="line"><span class="cl"># TYPE geode_index_lookups_total counter </span></span><span class="line"><span class="cl">geode_index_lookups_total{index=&#34;person_age_idx&#34;,type=&#34;btree&#34;} 45678 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"># HELP geode_index_size_bytes Index size in bytes </span></span><span class="line"><span class="cl"># TYPE geode_index_size_bytes gauge </span></span><span class="line"><span class="cl">geode_index_size_bytes{index=&#34;person_age_idx&#34;,type=&#34;btree&#34;} 12345678 </span></span></code></pre></div> <h4 id="prometheus-configuration" class="position-relative d-flex align-items-center group"> <span>Prometheus Configuration</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="prometheus-configuration" aria-haspopup="dialog" aria-label="Share link: Prometheus Configuration"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p><strong>prometheus.yml</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">global</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">scrape_interval</span><span class="p">:</span><span class="w"> </span><span class="l">15s</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">evaluation_interval</span><span class="p">:</span><span class="w"> </span><span class="l">15s</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">scrape_configs</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">job_name</span><span class="p">:</span><span class="w"> </span><span class="s1">&#39;geode&#39;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">static_configs</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">targets</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s1">&#39;localhost:8080&#39;</span><span class="p">]</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">metrics_path</span><span class="p">:</span><span class="w"> </span><span class="s1">&#39;/metrics&#39;</span><span class="w"> </span></span></span></code></pre></div><p><strong>Start Prometheus</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">prometheus --config.file<span class="o">=</span>prometheus.yml </span></span></code></pre></div><p><strong>Query examples</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-promql" data-lang="promql"><span class="line"><span class="cl"><span class="c1"># Query rate (QPS)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kr">rate</span><span class="o">(</span><span class="nv">geode_queries_total</span><span class="p">[</span><span class="s">5m</span><span class="p">]</span><span class="o">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1"># 95th percentile query latency</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kr">histogram_quantile</span><span class="o">(</span><span class="mf">0.95</span><span class="p">,</span><span class="w"> </span><span class="kr">rate</span><span class="o">(</span><span class="nv">geode_query_duration_seconds_bucket</span><span class="p">[</span><span class="s">5m</span><span class="p">]</span><span class="o">))</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1"># Cache hit ratio</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nv">geode_storage_cache_hit_ratio</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1"># Transaction abort rate</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kr">rate</span><span class="o">(</span><span class="nv">geode_transactions_aborted</span><span class="p">[</span><span class="s">5m</span><span class="p">]</span><span class="o">)</span><span class="w"> </span></span></span></code></pre></div> <h3 id="optional-telemetry" class="position-relative d-flex align-items-center group"> <span>Optional Telemetry</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="optional-telemetry" aria-haspopup="dialog" aria-label="Share link: Optional Telemetry"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3><p>From <code>TELEMETRY.md</code>:</p> <p><strong>Paging telemetry</strong> outputs detailed system events to stderr (JSONL format).</p> <p><strong>Purpose</strong>: Debugging, CI/testing, performance analysis</p> <p><strong>Enable</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Enable paging telemetry</span> </span></span><span class="line"><span class="cl"><span class="nb">export</span> <span class="nv">GEODE_TELEMETRY_PAGING</span><span class="o">=</span><span class="m">1</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">./geode serve </span></span></code></pre></div><p><strong>Output</strong> (stderr, JSONL):</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span><span class="nt">&#34;event&#34;</span><span class="p">:</span><span class="s2">&#34;page_read&#34;</span><span class="p">,</span><span class="nt">&#34;page_id&#34;</span><span class="p">:</span><span class="mi">12345</span><span class="p">,</span><span class="nt">&#34;timestamp&#34;</span><span class="p">:</span><span class="s2">&#34;2024-01-15T14:30:00.123Z&#34;</span><span class="p">,</span><span class="nt">&#34;duration_us&#34;</span><span class="p">:</span><span class="mi">42</span><span class="p">}</span> </span></span><span class="line"><span class="cl"><span class="p">{</span><span class="nt">&#34;event&#34;</span><span class="p">:</span><span class="s2">&#34;page_write&#34;</span><span class="p">,</span><span class="nt">&#34;page_id&#34;</span><span class="p">:</span><span class="mi">12346</span><span class="p">,</span><span class="nt">&#34;timestamp&#34;</span><span class="p">:</span><span class="s2">&#34;2024-01-15T14:30:00.456Z&#34;</span><span class="p">,</span><span class="nt">&#34;duration_us&#34;</span><span class="p">:</span><span class="mi">156</span><span class="p">}</span> </span></span><span class="line"><span class="cl"><span class="p">{</span><span class="nt">&#34;event&#34;</span><span class="p">:</span><span class="s2">&#34;index_lookup&#34;</span><span class="p">,</span><span class="nt">&#34;index&#34;</span><span class="p">:</span><span class="s2">&#34;person_age_idx&#34;</span><span class="p">,</span><span class="nt">&#34;key&#34;</span><span class="p">:</span><span class="mi">30</span><span class="p">,</span><span class="nt">&#34;timestamp&#34;</span><span class="p">:</span><span class="s2">&#34;2024-01-15T14:30:00.789Z&#34;</span><span class="p">,</span><span class="nt">&#34;duration_us&#34;</span><span class="p">:</span><span class="mi">23</span><span class="p">}</span> </span></span></code></pre></div><p><strong>CI/Testing toggles</strong> (from <code>TELEMETRY.md</code>):</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Disable telemetry in tests (reduce noise)</span> </span></span><span class="line"><span class="cl"><span class="nb">export</span> <span class="nv">GEODE_TELEMETRY_PAGING</span><span class="o">=</span><span class="m">0</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Enable verbose telemetry for debugging</span> </span></span><span class="line"><span class="cl"><span class="nb">export</span> <span class="nv">GEODE_TELEMETRY_VERBOSE</span><span class="o">=</span><span class="m">1</span> </span></span></code></pre></div><p><strong>Note</strong>: Paging telemetry has performance overhead (~5-10%). Use only for debugging/testing.</p> <h3 id="audit-logs-and-tracing" class="position-relative d-flex align-items-center group"> <span>Audit Logs and Tracing</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="audit-logs-and-tracing" aria-haspopup="dialog" aria-label="Share link: Audit Logs and Tracing"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3><p>From <code>AUDIT_LOGGING.md</code>:</p> <h4 id="audit-log-configuration" class="position-relative d-flex align-items-center group"> <span>Audit Log Configuration</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="audit-log-configuration" aria-haspopup="dialog" aria-label="Share link: Audit Log Configuration"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p><strong>Enable audit logging</strong> (<code>geode.yaml</code>):</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">security</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">audit</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">enabled</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">log_path</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;/var/log/geode/audit.jsonl&#34;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c"># Syslog/CEF forwarding</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">syslog</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">enabled</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">address</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;syslog.example.com:514&#34;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">format</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;CEF&#34;</span><span class="w"> </span><span class="c"># Common Event Format</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c"># Retention</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">retention_days</span><span class="p">:</span><span class="w"> </span><span class="m">365</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">max_size</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;10GB&#34;</span><span class="w"> </span></span></span></code></pre></div> <h4 id="whats-logged" class="position-relative d-flex align-items-center group"> <span>What&amp;rsquo;s Logged</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="whats-logged" aria-haspopup="dialog" aria-label="Share link: Whats Logged"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p><strong>Events logged</strong>:</p> <ul> <li>✅ Authentication (login, logout, failed attempts)</li> <li>✅ Authorization decisions (policy evaluations)</li> <li>✅ Schema changes (CREATE/ALTER/DROP)</li> <li>✅ Administrative actions (user/role management)</li> <li>✅ Query metadata (timestamp, user, graph, execution time)</li> </ul> <p><strong>Events NOT logged</strong> (privacy/security):</p> <ul> <li>❌ Query text (avoid logging sensitive data)</li> <li>❌ Query parameters</li> <li>❌ Result sets</li> </ul> <h4 id="audit-log-entry-format" class="position-relative d-flex align-items-center group"> <span>Audit Log Entry Format</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="audit-log-entry-format" aria-haspopup="dialog" aria-label="Share link: Audit Log Entry Format"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p><strong>Example</strong> (JSONL):</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;timestamp&#34;</span><span class="p">:</span> <span class="s2">&#34;2024-01-15T14:30:00.123Z&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;event_type&#34;</span><span class="p">:</span> <span class="s2">&#34;query_executed&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;user&#34;</span><span class="p">:</span> <span class="s2">&#34;alice&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;graph&#34;</span><span class="p">:</span> <span class="s2">&#34;SocialNetwork&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;session_id&#34;</span><span class="p">:</span> <span class="s2">&#34;550e8400-e29b-41d4-a716-446655440000&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;trace_id&#34;</span><span class="p">:</span> <span class="s2">&#34;7c9e8d6f-5b4a-3c2d-1e0f-9a8b7c6d5e4f&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;execution_time_ms&#34;</span><span class="p">:</span> <span class="mf">23.5</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;rows_returned&#34;</span><span class="p">:</span> <span class="mi">150</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;prev_log_hash&#34;</span><span class="p">:</span> <span class="s2">&#34;e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nt">&#34;signature&#34;</span><span class="p">:</span> <span class="s2">&#34;3045022100...&#34;</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span></code></pre></div><p><strong>Tamper-evident properties</strong>:</p> <ul> <li><strong>Hash chain</strong>: Each entry includes <code>prev_log_hash</code> (SHA-256 of previous entry)</li> <li><strong>Signatures</strong>: Entries signed with server private key for non-repudiation</li> <li><strong>Tracing IDs</strong>: <code>trace_id</code> correlates events across distributed systems</li> </ul> <h4 id="tracing-ids" class="position-relative d-flex align-items-center group"> <span>Tracing IDs</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="tracing-ids" aria-haspopup="dialog" aria-label="Share link: Tracing IDs"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p><strong>Purpose</strong>: Correlate events across:</p> <ul> <li>Multiple queries in a transaction</li> <li>Distributed query execution (federated queries)</li> <li>CDC webhooks and downstream processing</li> </ul> <p><strong>Example: Distributed trace</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="c1">// Client query </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="p">{</span><span class="nt">&#34;trace_id&#34;</span><span class="p">:</span> <span class="s2">&#34;7c9e8d6f-5b4a-3c2d-1e0f-9a8b7c6d5e4f&#34;</span><span class="p">,</span> <span class="nt">&#34;event&#34;</span><span class="p">:</span> <span class="s2">&#34;query_started&#34;</span><span class="p">,</span> <span class="err">...</span><span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1">// Federated execution on shard 1 </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="p">{</span><span class="nt">&#34;trace_id&#34;</span><span class="p">:</span> <span class="s2">&#34;7c9e8d6f-5b4a-3c2d-1e0f-9a8b7c6d5e4f&#34;</span><span class="p">,</span> <span class="nt">&#34;event&#34;</span><span class="p">:</span> <span class="s2">&#34;shard_query&#34;</span><span class="p">,</span> <span class="nt">&#34;shard&#34;</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span> <span class="err">...</span><span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1">// Federated execution on shard 2 </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="p">{</span><span class="nt">&#34;trace_id&#34;</span><span class="p">:</span> <span class="s2">&#34;7c9e8d6f-5b4a-3c2d-1e0f-9a8b7c6d5e4f&#34;</span><span class="p">,</span> <span class="nt">&#34;event&#34;</span><span class="p">:</span> <span class="s2">&#34;shard_query&#34;</span><span class="p">,</span> <span class="nt">&#34;shard&#34;</span><span class="p">:</span> <span class="mi">2</span><span class="p">,</span> <span class="err">...</span><span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1">// Result merge </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="p">{</span><span class="nt">&#34;trace_id&#34;</span><span class="p">:</span> <span class="s2">&#34;7c9e8d6f-5b4a-3c2d-1e0f-9a8b7c6d5e4f&#34;</span><span class="p">,</span> <span class="nt">&#34;event&#34;</span><span class="p">:</span> <span class="s2">&#34;result_merged&#34;</span><span class="p">,</span> <span class="err">...</span><span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1">// Query completed </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="p">{</span><span class="nt">&#34;trace_id&#34;</span><span class="p">:</span> <span class="s2">&#34;7c9e8d6f-5b4a-3c2d-1e0f-9a8b7c6d5e4f&#34;</span><span class="p">,</span> <span class="nt">&#34;event&#34;</span><span class="p">:</span> <span class="s2">&#34;query_completed&#34;</span><span class="p">,</span> <span class="err">...</span><span class="p">}</span> </span></span></code></pre></div> <h4 id="audit-log-analysis" class="position-relative d-flex align-items-center group"> <span>Audit Log Analysis</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="audit-log-analysis" aria-haspopup="dialog" aria-label="Share link: Audit Log Analysis"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p><strong>Verify hash chain integrity</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Python script to verify audit log integrity</span> </span></span><span class="line"><span class="cl">import json </span></span><span class="line"><span class="cl">import hashlib </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="nv">prev_hash</span> <span class="o">=</span> None </span></span><span class="line"><span class="cl">with open<span class="o">(</span><span class="s1">&#39;/var/log/geode/audit.jsonl&#39;</span><span class="o">)</span> as f: </span></span><span class="line"><span class="cl"> <span class="k">for</span> line_num, line in enumerate<span class="o">(</span>f, 1<span class="o">)</span>: </span></span><span class="line"><span class="cl"> <span class="nv">entry</span> <span class="o">=</span> json.loads<span class="o">(</span>line<span class="o">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># Compute expected hash</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> prev_hash is not None: </span></span><span class="line"><span class="cl"> <span class="k">if</span> entry<span class="o">[</span><span class="s1">&#39;prev_log_hash&#39;</span><span class="o">]</span> !<span class="o">=</span> prev_hash: </span></span><span class="line"><span class="cl"> print<span class="o">(</span>f<span class="s2">&#34;Hash chain broken at line {line_num}!&#34;</span><span class="o">)</span> </span></span><span class="line"><span class="cl"> exit<span class="o">(</span>1<span class="o">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># Update for next iteration</span> </span></span><span class="line"><span class="cl"> <span class="nv">prev_hash</span> <span class="o">=</span> hashlib.sha256<span class="o">(</span>line.encode<span class="o">())</span>.hexdigest<span class="o">()</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">print<span class="o">(</span><span class="s2">&#34;Audit log integrity verified&#34;</span><span class="o">)</span> </span></span></code></pre></div><p><strong>Query audit logs</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Find all queries by user &#39;alice&#39;</span> </span></span><span class="line"><span class="cl">cat /var/log/geode/audit.jsonl <span class="p">|</span> jq <span class="s1">&#39;select(.user == &#34;alice&#34;)&#39;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Find failed authentication attempts</span> </span></span><span class="line"><span class="cl">cat /var/log/geode/audit.jsonl <span class="p">|</span> jq <span class="s1">&#39;select(.event_type == &#34;auth_failed&#34;)&#39;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Find slow queries (&gt;1 second)</span> </span></span><span class="line"><span class="cl">cat /var/log/geode/audit.jsonl <span class="p">|</span> jq <span class="s1">&#39;select(.execution_time_ms &gt; 1000)&#39;</span> </span></span></code></pre></div> <h3 id="logging-configuration" class="position-relative d-flex align-items-center group"> <span>Logging Configuration</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="logging-configuration" aria-haspopup="dialog" aria-label="Share link: Logging Configuration"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3><p>From <code>DOCKER_LOG_LEVEL_CONFIG.md</code>:</p> <h4 id="log-levels" class="position-relative d-flex align-items-center group"> <span>Log Levels</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="log-levels" aria-haspopup="dialog" aria-label="Share link: Log Levels"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Set log level (debug/info/warn/error)</span> </span></span><span class="line"><span class="cl"><span class="nb">export</span> <span class="nv">LOG_LEVEL</span><span class="o">=</span>info </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">./geode serve </span></span></code></pre></div><p><strong>Docker</strong> (<code>docker-compose.yml</code>):</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">services</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">geode</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">image</span><span class="p">:</span><span class="w"> </span><span class="l">geodedb/geode:latest</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">environment</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">LOG_LEVEL</span><span class="p">:</span><span class="w"> </span><span class="l">info </span><span class="w"> </span><span class="c"># or debug, warn, error</span><span class="w"> </span></span></span></code></pre></div><p><strong>Defaults</strong>:</p> <ul> <li><strong>Development</strong>: <code>debug</code></li> <li><strong>Production</strong>: <code>info</code></li> </ul> <h4 id="log-formats" class="position-relative d-flex align-items-center group"> <span>Log Formats</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="log-formats" aria-haspopup="dialog" aria-label="Share link: Log Formats"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p><strong>Text format</strong> (human-readable):</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">2024-01-15T14:30:00.123Z INFO [geode::server] Server started on 0.0.0.0:3141 </span></span><span class="line"><span class="cl">2024-01-15T14:30:01.456Z DEBUG [geode::query] Executing query for user &#39;alice&#39; </span></span><span class="line"><span class="cl">2024-01-15T14:30:01.789Z WARN [geode::storage] Cache miss for page 12345 </span></span></code></pre></div><p><strong>JSON format</strong> (machine-readable):</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span><span class="nt">&#34;timestamp&#34;</span><span class="p">:</span><span class="s2">&#34;2024-01-15T14:30:00.123Z&#34;</span><span class="p">,</span><span class="nt">&#34;level&#34;</span><span class="p">:</span><span class="s2">&#34;INFO&#34;</span><span class="p">,</span><span class="nt">&#34;module&#34;</span><span class="p">:</span><span class="s2">&#34;geode::server&#34;</span><span class="p">,</span><span class="nt">&#34;message&#34;</span><span class="p">:</span><span class="s2">&#34;Server started on 0.0.0.0:3141&#34;</span><span class="p">}</span> </span></span><span class="line"><span class="cl"><span class="p">{</span><span class="nt">&#34;timestamp&#34;</span><span class="p">:</span><span class="s2">&#34;2024-01-15T14:30:01.456Z&#34;</span><span class="p">,</span><span class="nt">&#34;level&#34;</span><span class="p">:</span><span class="s2">&#34;DEBUG&#34;</span><span class="p">,</span><span class="nt">&#34;module&#34;</span><span class="p">:</span><span class="s2">&#34;geode::query&#34;</span><span class="p">,</span><span class="nt">&#34;message&#34;</span><span class="p">:</span><span class="s2">&#34;Executing query for user &#39;alice&#39;&#34;</span><span class="p">}</span> </span></span></code></pre></div><p><strong>Configure</strong> (<code>geode.yaml</code>):</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">logging</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">level</span><span class="p">:</span><span class="w"> </span><span class="s1">&#39;info&#39;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">format</span><span class="p">:</span><span class="w"> </span><span class="s1">&#39;json&#39;</span><span class="w"> </span><span class="c"># or &#39;text&#39;</span><span class="w"> </span></span></span></code></pre></div> <h3 id="grafana-dashboards" class="position-relative d-flex align-items-center group"> <span>Grafana Dashboards</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="grafana-dashboards" aria-haspopup="dialog" aria-label="Share link: Grafana Dashboards"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3><p>From <code>deployment/DEPLOYMENT.md</code>:</p> <p><strong>Access Grafana</strong>: <code>http://localhost:3000</code> (admin/admin)</p> <h4 id="import-geode-dashboard" class="position-relative d-flex align-items-center group"> <span>Import Geode Dashboard</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="import-geode-dashboard" aria-haspopup="dialog" aria-label="Share link: Import Geode Dashboard"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><ol> <li><strong>Download</strong> dashboard JSON from <code>docs/deployment/grafana-dashboard.json</code></li> <li><strong>Import</strong> in Grafana: Home → Dashboards → Import</li> <li><strong>Configure</strong> data source: Select Prometheus</li> </ol> <h4 id="dashboard-panels" class="position-relative d-flex align-items-center group"> <span>Dashboard Panels</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="dashboard-panels" aria-haspopup="dialog" aria-label="Share link: Dashboard Panels"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p><strong>Query Performance</strong>:</p> <ul> <li>Query rate (QPS)</li> <li>50th/95th/99th percentile latency</li> <li>Error rate</li> </ul> <p><strong>Transaction Metrics</strong>:</p> <ul> <li>Active transactions</li> <li>Commit/abort rate</li> <li>Serialization error rate</li> </ul> <p><strong>Storage</strong>:</p> <ul> <li>Cache hit ratio</li> <li>Page read/write rate</li> <li>WAL write throughput</li> </ul> <p><strong>Connections</strong>:</p> <ul> <li>Active connections</li> <li>Connection rate</li> </ul> <p><strong>Alerts</strong>:</p> <ul> <li>High error rate (&gt;1%)</li> <li>High latency (p95 &gt;1s)</li> <li>Cache hit ratio low (&lt;80%)</li> <li>Transaction abort rate high (&gt;10%)</li> </ul> <h3 id="loki-log-aggregation" class="position-relative d-flex align-items-center group"> <span>Loki Log Aggregation</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="loki-log-aggregation" aria-haspopup="dialog" aria-label="Share link: Loki Log Aggregation"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3><p>From <code>deployment/DEPLOYMENT.md</code>:</p> <p><strong>Loki + Promtail</strong> aggregate logs from all Geode instances.</p> <p><strong>Promtail configuration</strong> (<code>promtail-config.yaml</code>):</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">server</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">http_listen_port</span><span class="p">:</span><span class="w"> </span><span class="m">9080</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">grpc_listen_port</span><span class="p">:</span><span class="w"> </span><span class="m">0</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">clients</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">url</span><span class="p">:</span><span class="w"> </span><span class="l">http://loki:3100/loki/api/v1/push</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">scrape_configs</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">job_name</span><span class="p">:</span><span class="w"> </span><span class="l">geode</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">static_configs</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">targets</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="l">localhost</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">labels</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">job</span><span class="p">:</span><span class="w"> </span><span class="l">geode</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">__path__</span><span class="p">:</span><span class="w"> </span><span class="l">/var/log/geode/*.log</span><span class="w"> </span></span></span></code></pre></div><p><strong>Query logs in Grafana</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl"># All logs from geode </span></span><span class="line"><span class="cl">{job=&#34;geode&#34;} </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"># Error logs only </span></span><span class="line"><span class="cl">{job=&#34;geode&#34;} |= &#34;ERROR&#34; </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"># Query execution logs </span></span><span class="line"><span class="cl">{job=&#34;geode&#34;} |= &#34;query_executed&#34; </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"># Slow queries </span></span><span class="line"><span class="cl">{job=&#34;geode&#34;} | json | execution_time_ms &gt; 1000 </span></span></code></pre></div> <h3 id="next-steps" class="position-relative d-flex align-items-center group"> <span>Next Steps</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="next-steps" aria-haspopup="dialog" aria-label="Share link: Next Steps"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3><ul> <li><strong><a href="/docs/ops/deployment" >Deployment Guide</a> </strong> - Production stack setup</li> <li><strong><a href="/docs/security/overview" >Security Guide</a> </strong> - Audit logging and integrity</li> <li><strong><a href="/docs/architecture/performance-and-scaling" >Performance and Scaling</a> </strong> - Performance metrics interpretation</li> <li><strong><a href="/docs/ops/telemetry-advanced/" >Telemetry Reference</a> </strong> - Complete telemetry documentation</li> </ul>