Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions harnesses/aggregator-head-lag/cmd/script/loghub.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ import (
"bufio"
"fmt"
"io"
"log"
"net/http"
"os"
"strconv"
"strings"
"sync"
"time"
)
Expand All @@ -29,6 +31,12 @@ type logRing struct {

var globalLogRing = &logRing{max: logRingMax}

// serializedLogRing keeps the Serialized monitor's lines apart, so they
// survive the GeckoTerminal tape that turns the shared ring over in under
// an hour, and so Serialized can read its own lines without seeing the
// other providers'. Served at /logs/serialized.
var serializedLogRing = &logRing{max: 20000}

func (b *logRing) push(line string) {
entry := time.Now().UTC().Format("2006-01-02T15:04:05.000Z") + " " + line
b.mu.Lock()
Expand Down Expand Up @@ -72,6 +80,10 @@ func doInstallLogCapture() {
}
os.Stdout = w
os.Stderr = w
// The log package captured the original stderr at init; without this
// every log.Printf line (drops, slow trades, duplicates) bypassed the
// rings and only reached the platform log.
log.SetOutput(w)

go func() {
scanner := bufio.NewScanner(r)
Expand All @@ -81,6 +93,9 @@ func doInstallLogCapture() {
line := scanner.Text()
fmt.Fprintln(originalStdout, line)
globalLogRing.push(line)
if strings.Contains(line, "[SERIALIZED]") {
serializedLogRing.push(line)
}
}
_, _ = io.Copy(originalStdout, r)
_ = originalStderr
Expand Down Expand Up @@ -112,3 +127,32 @@ func logsHandler() http.Handler {
}
})
}

// serializedLogsHandler serves GET /logs/serialized?tail=N, the Serialized
// monitor's lines only (connects, drops, slow trades with hash and both
// clocks, duplicate deliveries). It takes its own token,
// SERIALIZED_LOGS_TOKEN, in X-Logs-Token, so it can be handed to
// Serialized without opening the full log. Disabled when the env is unset.
func serializedLogsHandler() http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
expected := os.Getenv("SERIALIZED_LOGS_TOKEN")
if expected == "" {
http.Error(w, "logs disabled: SERIALIZED_LOGS_TOKEN unset", http.StatusForbidden)
return
}
if r.Header.Get("X-Logs-Token") != expected {
http.Error(w, "forbidden", http.StatusForbidden)
return
}
tail := 2000
if t := r.URL.Query().Get("tail"); t != "" {
if n, err := strconv.Atoi(t); err == nil && n > 0 {
tail = n
}
}
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
for _, l := range serializedLogRing.snapshot(tail) {
fmt.Fprintln(w, l)
}
})
}
1 change: 1 addition & 0 deletions harnesses/aggregator-head-lag/cmd/script/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -633,6 +633,7 @@ func StartMetricsServer(addr string) error {

// Debug: tail of in-memory log ring (shared loghub package)
mux.Handle("/logs", logsHandler())
mux.Handle("/logs/serialized", serializedLogsHandler())

return http.ListenAndServe(addr, mux)
}
Expand Down
Loading