ipn/localapi: add endpoint for adding debug log entries
Allows the iOS and macOS apps to include their frontend logs when generating bug reports (tailscale/corp#9982). Signed-off-by: Mihai Parparita <mihai@tailscale.com>
This commit is contained in:
parent
7083246409
commit
731688e5cc
|
@ -73,6 +73,7 @@ var handler = map[string]localAPIHandler{
|
||||||
"debug-portmap": (*Handler).serveDebugPortmap,
|
"debug-portmap": (*Handler).serveDebugPortmap,
|
||||||
"debug-peer-endpoint-changes": (*Handler).serveDebugPeerEndpointChanges,
|
"debug-peer-endpoint-changes": (*Handler).serveDebugPeerEndpointChanges,
|
||||||
"debug-capture": (*Handler).serveDebugCapture,
|
"debug-capture": (*Handler).serveDebugCapture,
|
||||||
|
"debug-log": (*Handler).serveDebugLog,
|
||||||
"derpmap": (*Handler).serveDERPMap,
|
"derpmap": (*Handler).serveDERPMap,
|
||||||
"dev-set-state-store": (*Handler).serveDevSetStateStore,
|
"dev-set-state-store": (*Handler).serveDevSetStateStore,
|
||||||
"set-push-device-token": (*Handler).serveSetPushDeviceToken,
|
"set-push-device-token": (*Handler).serveSetPushDeviceToken,
|
||||||
|
@ -1820,6 +1821,47 @@ func (h *Handler) serveDebugCapture(w http.ResponseWriter, r *http.Request) {
|
||||||
h.b.StreamDebugCapture(r.Context(), w)
|
h.b.StreamDebugCapture(r.Context(), w)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *Handler) serveDebugLog(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if !h.PermitRead {
|
||||||
|
http.Error(w, "debug-log access denied", http.StatusForbidden)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if r.Method != httpm.POST {
|
||||||
|
http.Error(w, "only POST allowed", http.StatusMethodNotAllowed)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer h.b.TryFlushLogs() // kick off upload after we're done logging
|
||||||
|
|
||||||
|
type logRequestJSON struct {
|
||||||
|
Lines []string
|
||||||
|
Prefix string
|
||||||
|
}
|
||||||
|
|
||||||
|
var logRequest logRequestJSON
|
||||||
|
if err := json.NewDecoder(r.Body).Decode(&logRequest); err != nil {
|
||||||
|
http.Error(w, "invalid JSON body", 400)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
prefix := logRequest.Prefix
|
||||||
|
if prefix == "" {
|
||||||
|
prefix = "debug-log"
|
||||||
|
}
|
||||||
|
logf := logger.WithPrefix(h.logf, prefix+": ")
|
||||||
|
|
||||||
|
// We can write logs too fast for logtail to handle, even when
|
||||||
|
// opting-out of rate limits. Limit ourselves to at most one message
|
||||||
|
// per 20ms and a burst of 60 log lines, which should be fast enough to
|
||||||
|
// not block for too long but slow enough that we can upload all lines.
|
||||||
|
logf = logger.SlowLoggerWithClock(r.Context(), logf, 20*time.Millisecond, 60, time.Now)
|
||||||
|
|
||||||
|
for _, line := range logRequest.Lines {
|
||||||
|
logf("%s", line)
|
||||||
|
}
|
||||||
|
|
||||||
|
w.WriteHeader(http.StatusNoContent)
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
metricInvalidRequests = clientmetric.NewCounter("localapi_invalid_requests")
|
metricInvalidRequests = clientmetric.NewCounter("localapi_invalid_requests")
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue