<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Otelite Dashboard</title>
<link rel="stylesheet" href="/css/styles.css">
</head>
<body>
<div id="app">
<header class="header">
<div class="header-content">
<h1 class="logo">Otelite Dashboard</h1>
<nav class="nav">
<button class="nav-btn active" data-view="logs">Logs</button>
<button class="nav-btn" data-view="traces">Traces</button>
<button class="nav-btn" data-view="metrics">Metrics</button>
<button class="nav-btn" data-view="usage">Usage</button>
<button class="nav-btn" data-view="setup">Setup</button>
</nav>
<div class="connection-status">
<div class="status-wrapper" id="status-wrapper" role="button" tabindex="0" aria-label="Server status">
<span class="status-indicator" id="status-indicator"></span>
<span class="status-text" id="status-text">Connected</span>
</div>
<div class="status-popover" id="status-popover"></div>
</div>
</div>
</header>
<main class="main-content">
<div id="logs-view" class="view active">
<div class="view-header">
<h2>Logs</h2>
<div class="controls">
<input type="text" id="log-search" class="search-input" placeholder="Search logs...">
<select id="severity-filter" class="filter-select">
<option value="">All Severities</option>
<option value="ERROR">Error</option>
<option value="WARN">Warning</option>
<option value="INFO">Info</option>
<option value="DEBUG">Debug</option>
<option value="TRACE">Trace</option>
</select>
<button id="export-logs" class="btn-secondary">Export</button>
</div>
</div>
<div id="logs-container" class="logs-container">
<div class="empty-state">
<p>No logs yet</p>
<p class="empty-state-hint">Logs will appear here as they are received. See the <strong>Setup</strong> tab for configuration instructions.</p>
</div>
</div>
</div>
<div id="traces-view" class="view">
<div class="view-header">
<h2>Traces</h2>
<div class="controls">
<select id="trace-status-filter" class="filter-select">
<option value="">All Statuses</option>
<option value="ok">OK</option>
<option value="error">Error</option>
</select>
</div>
</div>
<div id="traces-container" class="traces-container">
<div class="empty-state">
<p>No traces available</p>
<p class="empty-state-hint">Traces will appear here as they are received</p>
</div>
</div>
</div>
<div id="metrics-view" class="view">
<div class="view-header">
<h2>Metrics</h2>
<div class="controls">
<select id="time-range" class="filter-select">
<option value="300">Last 5 minutes</option>
<option value="3600">Last 1 hour</option>
<option value="21600">Last 6 hours</option>
<option value="86400">Last 24 hours</option>
</select>
</div>
</div>
<div class="metrics-layout">
<div id="metrics-list" class="metrics-list">
<div class="empty-state">
<p>No metrics available</p>
<p class="empty-state-hint">Metrics will appear here as they are received</p>
</div>
</div>
<div id="metrics-graph" class="metrics-graph">
<div class="empty-state">
<p>Select a metric to view</p>
</div>
</div>
</div>
</div>
<div id="usage-view" class="view">
<div class="view-header">
<h2>GenAI Usage</h2>
</div>
<div id="usage-container"></div>
</div>
<div id="setup-view" class="view">
<div class="view-header">
<h2>Setup</h2>
</div>
<div class="setup-container">
<div class="onboarding-section">
<h3>Otelite is listening on</h3>
<ul class="endpoint-list">
<li><strong>OTLP gRPC:</strong> <code>localhost:4317</code></li>
<li><strong>OTLP HTTP:</strong> <code>http://localhost:4318</code></li>
</ul>
</div>
<div class="onboarding-section">
<h3>Configuration examples</h3>
<details class="config-example">
<summary><strong>Claude Code (Environment Variables)</strong></summary>
<pre><code># Set these environment variables before running Claude Code:
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318
export OTEL_SERVICE_NAME=claude-code
export OTEL_LOGS_EXPORTER=otlp
export OTEL_METRICS_EXPORTER=otlp
# Claude Code will automatically send telemetry to Otelite</code></pre>
</details>
<details class="config-example">
<summary><strong>Python (OpenTelemetry SDK)</strong></summary>
<pre><code>from opentelemetry import trace
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
exporter = OTLPSpanExporter(endpoint="http://localhost:4318/v1/traces")
provider = TracerProvider()
provider.add_span_processor(BatchSpanProcessor(exporter))
trace.set_tracer_provider(provider)
tracer = trace.get_tracer(__name__)
with tracer.start_as_current_span("my-operation"):
print("Hello from Python!")</code></pre>
</details>
<details class="config-example">
<summary><strong>Python (OpenAI SDK with instrumentation)</strong></summary>
<pre><code>from opentelemetry.instrumentation.openai import OpenAIInstrumentor
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
import openai
exporter = OTLPSpanExporter(endpoint="http://localhost:4318/v1/traces")
provider = TracerProvider()
provider.add_span_processor(BatchSpanProcessor(exporter))
OpenAIInstrumentor().instrument()
client = openai.OpenAI()
response = client.chat.completions.create(
model="gpt-4",
messages=[{"role": "user", "content": "Hello!"}]
)</code></pre>
</details>
<details class="config-example">
<summary><strong>Node.js (OpenTelemetry SDK)</strong></summary>
<pre><code>const { NodeTracerProvider } = require('@opentelemetry/sdk-trace-node');
const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-http');
const { BatchSpanProcessor } = require('@opentelemetry/sdk-trace-base');
const provider = new NodeTracerProvider();
provider.addSpanProcessor(new BatchSpanProcessor(new OTLPTraceExporter({
url: 'http://localhost:4318/v1/traces'
})));
provider.register();</code></pre>
</details>
<details class="config-example">
<summary><strong>Go (OpenTelemetry SDK)</strong></summary>
<pre><code>exporter, _ := otlptracehttp.New(context.Background(),
otlptracehttp.WithEndpoint("localhost:4318"),
otlptracehttp.WithInsecure(),
)
provider := trace.NewTracerProvider(trace.WithBatcher(exporter))
otel.SetTracerProvider(provider)</code></pre>
</details>
<details class="config-example">
<summary><strong>Test with otel-cli</strong></summary>
<pre><code># Install: https://github.com/equinix-labs/otel-cli
otel-cli exec --endpoint http://localhost:4318 --service my-test -- echo "Hello Otelite!"</code></pre>
</details>
</div>
<div class="onboarding-section">
<h3>CLI commands</h3>
<ul>
<li><code>otelite logs list</code> — view recent logs</li>
<li><code>otelite traces list</code> — view recent traces</li>
<li><code>otelite metrics list</code> — view recent metrics</li>
<li><code>otelite tui</code> — launch terminal UI</li>
</ul>
</div>
</div>
</div>
</main>
</div>
<div id="loading-overlay" class="loading-overlay hidden">
<div class="spinner"></div>
</div>
<script type="module" src="/js/api.js"></script>
<script type="module" src="/js/logs.js"></script>
<script type="module" src="/js/traces.js"></script>
<script type="module" src="/js/metrics.js"></script>
<script type="module" src="/js/usage.js"></script>
<script type="module" src="/js/app.js"></script>
</body>
</html>