Add website analytics
Release / release (push) Successful in 3m49s
CI / test (push) Successful in 4m45s

A Tianji-style Websites section: a small tracking script, a public collection endpoint, and a
page per website with visitors, page views, visits, bounce rate, a chart and top lists for pages,
referrers, browsers, systems, devices, countries, languages and events. No cookies and no stored
IP address or user agent. SANDBAR_TRUST_PROXY makes the client address come from the proxy.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
VeillaxandClaude Sonnet 5.5 committed 2026-10-27 04:22:55 -06:00
1 parent 4ea4fe5289
commit b4fd31a182
13 files changed
+843 -22

No files matched your search

+9
View File
@@ -25,6 +25,9 @@ func (s *Server) Handler() http.Handler {
mux.HandleFunc("GET /status.json", s.statusJSON)
mux.HandleFunc("GET /healthz", func(w http.ResponseWriter, r *http.Request) { io.WriteString(w, "ok") })
mux.HandleFunc("GET /metrics", s.metrics)
mux.HandleFunc("GET /script.js", s.serveTracker)
mux.HandleFunc("POST /api/send", s.collect)
mux.HandleFunc("OPTIONS /api/send", s.collect)
mux.HandleFunc("GET /api/v1/hb/{token}", s.heartbeat)
mux.HandleFunc("POST /api/v1/hb/{token}", s.heartbeat)
@@ -105,6 +108,9 @@ func (s *Server) Handler() http.Handler {
}
return nil
}, nil)
s.crud(mux, "websites", "website", true, func() any { return &Website{} }, prepareWebsite, nil)
mux.HandleFunc("GET /api/v1/websites/{id}/stats", s.auth(false, s.websiteStatsHandler))
mux.HandleFunc("GET /api/v1/website-summary", s.auth(false, s.websiteSummary))
mux.HandleFunc("GET /api/v1/system/update", s.auth(true, s.updateStatus))
mux.HandleFunc("POST /api/v1/system/update", s.auth(true, s.updateApply))
mux.HandleFunc("POST /api/v1/channels/{id}/test", s.auth(true, s.testChannel))
@@ -349,6 +355,9 @@ func (s *Server) crud(mux *http.ServeMux, path, kind string, adminWrite bool, ne
if kind == "monitor" {
s.deleteMonitorData(id)
}
if kind == "website" {
s.deleteWebsiteData(id)
}
fail2(w, s.st.del(kind, id))
}))
}