Documentation
¶
Index ¶
- func GzipMiddleware(next http.Handler) http.Handler
- type Broker
- func (b *Broker) ClientCount() int
- func (b *Broker) LastNotifyUnix() int64
- func (b *Broker) LastSource() string
- func (b *Broker) Notify()
- func (b *Broker) NotifyCount() int64
- func (b *Broker) NotifySource(source string)
- func (b *Broker) Subscribe() chan string
- func (b *Broker) Unsubscribe(ch chan string)
- type CalendarResponse
- type Handler
- func (h *Handler) Calendar(w http.ResponseWriter, r *http.Request)
- func (h *Handler) CodexCalendar(w http.ResponseWriter, r *http.Request)
- func (h *Handler) CodexDaily(w http.ResponseWriter, r *http.Request)
- func (h *Handler) CodexDashboard(w http.ResponseWriter, r *http.Request)
- func (h *Handler) CodexDurations(w http.ResponseWriter, r *http.Request)
- func (h *Handler) CodexIntraday(w http.ResponseWriter, r *http.Request)
- func (h *Handler) CodexModels(w http.ResponseWriter, r *http.Request)
- func (h *Handler) CodexRequests(w http.ResponseWriter, r *http.Request)
- func (h *Handler) CodexSessions(w http.ResponseWriter, r *http.Request)
- func (h *Handler) DailyModel(w http.ResponseWriter, r *http.Request)
- func (h *Handler) Dashboard(w http.ResponseWriter, r *http.Request)
- func (h *Handler) Durations(w http.ResponseWriter, r *http.Request)
- func (h *Handler) Events(w http.ResponseWriter, r *http.Request)
- func (h *Handler) GeminiCalendar(w http.ResponseWriter, r *http.Request)
- func (h *Handler) GeminiDaily(w http.ResponseWriter, r *http.Request)
- func (h *Handler) GeminiDashboard(w http.ResponseWriter, r *http.Request)
- func (h *Handler) GeminiDurations(w http.ResponseWriter, r *http.Request)
- func (h *Handler) GeminiIntraday(w http.ResponseWriter, r *http.Request)
- func (h *Handler) GeminiModels(w http.ResponseWriter, r *http.Request)
- func (h *Handler) GeminiRequests(w http.ResponseWriter, r *http.Request)
- func (h *Handler) GeminiSessions(w http.ResponseWriter, r *http.Request)
- func (h *Handler) Health(w http.ResponseWriter, r *http.Request)
- func (h *Handler) HourlyModel(w http.ResponseWriter, r *http.Request)
- func (h *Handler) Intraday(w http.ResponseWriter, r *http.Request)
- func (h *Handler) Models(w http.ResponseWriter, r *http.Request)
- func (h *Handler) PricingLookup(w http.ResponseWriter, r *http.Request)
- func (h *Handler) Register(mux *http.ServeMux)
- func (h *Handler) Requests(w http.ResponseWriter, r *http.Request)
- func (h *Handler) Sessions(w http.ResponseWriter, r *http.Request)
- func (h *Handler) SetPricer(p pricing.Registry)
- func (h *Handler) Status(w http.ResponseWriter, r *http.Request)
- type HourlyResponse
- type IntradayResponse
- type PagedResponse
- type PricingLookupResponse
- type PricingStatus
- type StatusResponse
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Broker ¶
type Broker struct {
// contains filtered or unexported fields
}
Broker manages SSE client channels.
Each Notify call broadcasts a "source" tag (`claude` or `codex`) so the web UI can selectively refresh only the active tab. Notify() (no args) is kept for backward compatibility and tags the event as "claude".
func (*Broker) ClientCount ¶
func (*Broker) LastNotifyUnix ¶
func (*Broker) LastSource ¶
LastSource returns the source tag of the most recent broadcast, or "" if no broadcast has happened yet.
func (*Broker) Notify ¶
func (b *Broker) Notify()
Notify broadcasts a Claude-tagged update. Equivalent to NotifySource("claude").
func (*Broker) NotifyCount ¶
func (*Broker) NotifySource ¶
NotifySource broadcasts an update tagged with the given source.
func (*Broker) Unsubscribe ¶
type CalendarResponse ¶
type CalendarResponse struct {
Data []db.CalendarDay `json:"data"`
}
type Handler ¶
type Handler struct {
// contains filtered or unexported fields
}
Handler serves the REST API and SSE endpoints for the cc-otel web dashboard.
func NewHandler ¶
func NewHandler(repo *db.Repository, broker *Broker, cfg *config.Config, configPath string) *Handler
NewHandler creates a Handler with the given database repository, SSE broker, config, and the absolute path of the config file the daemon actually loaded.
func (*Handler) Calendar ¶
func (h *Handler) Calendar(w http.ResponseWriter, r *http.Request)
Calendar returns compact per-day aggregates for the dashboard usage calendar.
func (*Handler) CodexCalendar ¶
func (h *Handler) CodexCalendar(w http.ResponseWriter, r *http.Request)
CodexCalendar returns compact per-day aggregates for the Codex usage calendar.
func (*Handler) CodexDaily ¶
func (h *Handler) CodexDaily(w http.ResponseWriter, r *http.Request)
CodexDaily returns paged per-(date, model) rollup rows for the Codex tab.
func (*Handler) CodexDashboard ¶
func (h *Handler) CodexDashboard(w http.ResponseWriter, r *http.Request)
CodexDashboard returns aggregated KPI cards for the Codex tab.
func (*Handler) CodexDurations ¶
func (h *Handler) CodexDurations(w http.ResponseWriter, r *http.Request)
CodexDurations returns per-model latency stats. Token-throughput columns are always zero since Codex does not emit per-request token rates.
func (*Handler) CodexIntraday ¶
func (h *Handler) CodexIntraday(w http.ResponseWriter, r *http.Request)
CodexIntraday returns per-(time-bucket, model) Codex stats.
func (*Handler) CodexModels ¶
func (h *Handler) CodexModels(w http.ResponseWriter, r *http.Request)
CodexModels returns the distinct list of Codex models seen so far.
func (*Handler) CodexRequests ¶
func (h *Handler) CodexRequests(w http.ResponseWriter, r *http.Request)
CodexRequests returns paged Codex API request rows.
func (*Handler) CodexSessions ¶
func (h *Handler) CodexSessions(w http.ResponseWriter, r *http.Request)
CodexSessions returns paged session aggregates.
func (*Handler) DailyModel ¶
func (h *Handler) DailyModel(w http.ResponseWriter, r *http.Request)
DailyModel returns per-day, per-model token usage and cost with pagination.
func (*Handler) Dashboard ¶
func (h *Handler) Dashboard(w http.ResponseWriter, r *http.Request)
Dashboard returns aggregated token usage and cost KPIs for a date range.
func (*Handler) Durations ¶
func (h *Handler) Durations(w http.ResponseWriter, r *http.Request)
Durations returns per-model average duration stats for the selected date range. Query:
- from=YYYY-MM-DD&to=YYYY-MM-DD (preferred)
- or range=today|week|month|all
- optional: model=<name> to filter down to a single model
- optional: limit=<n> (default 2000, max 2000)
func (*Handler) Events ¶
func (h *Handler) Events(w http.ResponseWriter, r *http.Request)
Events streams Server-Sent Events to the client, pushing "update" on each new OTEL record.
func (*Handler) GeminiCalendar ¶
func (h *Handler) GeminiCalendar(w http.ResponseWriter, r *http.Request)
GeminiCalendar returns compact per-day aggregates for the Gemini usage calendar.
func (*Handler) GeminiDaily ¶
func (h *Handler) GeminiDaily(w http.ResponseWriter, r *http.Request)
GeminiDaily returns paged per-(date, model) rollup rows for the Gemini tab.
func (*Handler) GeminiDashboard ¶
func (h *Handler) GeminiDashboard(w http.ResponseWriter, r *http.Request)
GeminiDashboard returns aggregated KPI cards for the Gemini tab.
func (*Handler) GeminiDurations ¶
func (h *Handler) GeminiDurations(w http.ResponseWriter, r *http.Request)
GeminiDurations returns per-model latency stats for Gemini CLI telemetry.
func (*Handler) GeminiIntraday ¶
func (h *Handler) GeminiIntraday(w http.ResponseWriter, r *http.Request)
GeminiIntraday returns per-(time-bucket, model) Gemini stats.
func (*Handler) GeminiModels ¶
func (h *Handler) GeminiModels(w http.ResponseWriter, r *http.Request)
GeminiModels returns the distinct list of Gemini models seen so far.
func (*Handler) GeminiRequests ¶
func (h *Handler) GeminiRequests(w http.ResponseWriter, r *http.Request)
GeminiRequests returns paged Gemini API request rows.
func (*Handler) GeminiSessions ¶
func (h *Handler) GeminiSessions(w http.ResponseWriter, r *http.Request)
GeminiSessions returns paged session aggregates.
func (*Handler) Health ¶
func (h *Handler) Health(w http.ResponseWriter, r *http.Request)
Health reports database connectivity (200 ok, 503 error).
func (*Handler) HourlyModel ¶
func (h *Handler) HourlyModel(w http.ResponseWriter, r *http.Request)
HourlyModel returns per-hour, per-model token usage and cost for a single local day. Query params: - date=YYYY-MM-DD (optional; defaults to today) - model=<name> (optional filter)
func (*Handler) Intraday ¶
func (h *Handler) Intraday(w http.ResponseWriter, r *http.Request)
Intraday returns per-(time-bucket, model) stats across a [from, to] window of at most 7 local days, bucketed at 15/30/60 minutes. Designed for the new line-chart "Intraday by Model" view; defaults to today + 30-min buckets.
Query params:
- from=YYYY-MM-DD, to=YYYY-MM-DD (optional; default = today)
- range=<today|week|month|all> (used only if from/to omitted)
- bucket=15|30|60 (default 30)
- model=<name> (optional filter)
func (*Handler) Models ¶
func (h *Handler) Models(w http.ResponseWriter, r *http.Request)
Models returns the distinct model names seen in the database.
func (*Handler) PricingLookup ¶
func (h *Handler) PricingLookup(w http.ResponseWriter, r *http.Request)
PricingLookup answers "why does cc-otel think model X costs Y?". Useful when a row's cost_usd looks wrong: hit /api/pricing/lookup?model=glm-4.6 to confirm whether the registry resolved at all and which entry won.
func (*Handler) Requests ¶
func (h *Handler) Requests(w http.ResponseWriter, r *http.Request)
Requests returns individual API request records with optional model and date filters.
func (*Handler) Sessions ¶
func (h *Handler) Sessions(w http.ResponseWriter, r *http.Request)
Sessions returns per-session aggregated stats with pagination.
type HourlyResponse ¶
type HourlyResponse struct {
Date string `json:"date"`
Data []db.HourlyModelSummary `json:"data"`
}
type IntradayResponse ¶
type IntradayResponse struct {
From string `json:"from"`
To string `json:"to"`
BucketMinutes int `json:"bucket_minutes"`
Data []db.IntradayModelSummary `json:"data"`
}
IntradayResponse wraps Intraday for the JSON envelope; From/To are inclusive local YYYY-MM-DD; BucketMinutes echoes back the granularity actually used so the client can label its axis without re-deriving it.
type PagedResponse ¶
type PricingLookupResponse ¶
type PricingLookupResponse struct {
Query string `json:"query"`
Found bool `json:"found"`
Kind string `json:"kind"` // "exact" | "alias" | "prefix" | "miss"
MatchedKey string `json:"matched_key,omitempty"`
Source string `json:"source,omitempty"`
Input float64 `json:"input,omitempty"`
Output float64 `json:"output,omitempty"`
CacheRead float64 `json:"cache_read,omitempty"`
CacheWrite float64 `json:"cache_creation,omitempty"`
IsClaude bool `json:"is_claude"` // Claude is intentionally absent — surfaced so callers know why
}
PricingLookupResponse describes one model lookup against the registry. Returned by /api/pricing/lookup.
type PricingStatus ¶
type PricingStatus struct {
TableSize int `json:"table_size"`
UserOverrides int `json:"user_overrides"`
LastRefreshAt int64 `json:"last_refresh_at"`
LastRefreshMsg string `json:"last_refresh_status"`
LastRefreshErr string `json:"last_refresh_error,omitempty"`
LastChangedRows int `json:"last_refresh_changed"`
MissCount24h int `json:"miss_count_24h"`
MissModelsTop []string `json:"miss_models_top"`
}
PricingStatus mirrors pricing.Snapshot with JSON-friendly names. Kept separate so the api package doesn't expose the internal struct directly.
type StatusResponse ¶
type StatusResponse struct {
ServerTimeUnix int64 `json:"server_time_unix"`
DBOK bool `json:"db_ok"`
SSEClients int `json:"sse_clients"`
LastUpdate int64 `json:"last_update_unix"`
NotifyCount int64 `json:"notify_count"`
WebPort int `json:"web_port"`
OTELPort int `json:"otel_port"`
OTELReceiverListening bool `json:"otel_receiver_listening"`
// ConfigPath is the absolute path of the config file this daemon loaded at startup.
// DBPath is the resolved SQLite path after yaml + CC_OTEL_DB_PATH env override.
ConfigPath string `json:"config_path"`
DBPath string `json:"db_path"`
// Pricing is omitted when no pricing registry is wired (legacy callers /
// tests). The frontend Server Status popup keys off the presence of this
// block to decide whether to render the Pricing row.
Pricing *PricingStatus `json:"pricing,omitempty"`
}