ipn/ipnlocal: add c2n handler to flush logtail for support debugging
Updates tailscale/corp#8564 Change-Id: I0c619d4007069f90cffd319fba66bd034d63e84d Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
parent
673b3d8dbd
commit
69c0b7e712
|
@ -526,6 +526,9 @@ func getLocalBackend(ctx context.Context, logf logger.Logf, logid string) (_ *ip
|
|||
return nil, fmt.Errorf("ipnlocal.NewLocalBackend: %w", err)
|
||||
}
|
||||
lb.SetVarRoot(opts.VarRoot)
|
||||
if logPol != nil {
|
||||
lb.SetLogFlusher(logPol.Logtail.StartFlush)
|
||||
}
|
||||
if root := lb.TailscaleVarRoot(); root != "" {
|
||||
dnsfallback.SetCachePath(filepath.Join(root, "derpmap.cached.json"))
|
||||
}
|
||||
|
|
|
@ -26,6 +26,16 @@ func (b *LocalBackend) handleC2N(w http.ResponseWriter, r *http.Request) {
|
|||
// Test handler.
|
||||
body, _ := io.ReadAll(r.Body)
|
||||
w.Write(body)
|
||||
case "/logtail/flush":
|
||||
if r.Method != "POST" {
|
||||
http.Error(w, "bad method", http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
if b.TryFlushLogs() {
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
} else {
|
||||
http.Error(w, "no log flusher wired up", http.StatusInternalServerError)
|
||||
}
|
||||
case "/debug/goroutines":
|
||||
w.Header().Set("Content-Type", "text/plain")
|
||||
w.Write(goroutines.ScrubbedGoroutineDump())
|
||||
|
|
|
@ -140,6 +140,7 @@ type LocalBackend struct {
|
|||
gotPortPollRes chan struct{} // closed upon first readPoller result
|
||||
newDecompressor func() (controlclient.Decompressor, error)
|
||||
varRoot string // or empty if SetVarRoot never called
|
||||
logFlushFunc func() // or nil if SetLogFlusher wasn't called
|
||||
sshAtomicBool atomic.Bool
|
||||
shutdownCalled bool // if Shutdown has been called
|
||||
|
||||
|
@ -3015,6 +3016,25 @@ func (b *LocalBackend) SetVarRoot(dir string) {
|
|||
b.varRoot = dir
|
||||
}
|
||||
|
||||
// SetLogFlusher sets a func to be called to flush log uploads.
|
||||
//
|
||||
// It should only be called before the LocalBackend is used.
|
||||
func (b *LocalBackend) SetLogFlusher(flushFunc func()) {
|
||||
b.logFlushFunc = flushFunc
|
||||
}
|
||||
|
||||
// TryFlushLogs calls the log flush function. It returns false if a log flush
|
||||
// function was never initialized with SetLogFlusher.
|
||||
//
|
||||
// TryFlushLogs should not block.
|
||||
func (b *LocalBackend) TryFlushLogs() bool {
|
||||
if b.logFlushFunc == nil {
|
||||
return false
|
||||
}
|
||||
b.logFlushFunc()
|
||||
return true
|
||||
}
|
||||
|
||||
// TailscaleVarRoot returns the root directory of Tailscale's writable
|
||||
// storage area. (e.g. "/var/lib/tailscale")
|
||||
//
|
||||
|
|
|
@ -292,6 +292,7 @@ func (h *Handler) serveBugReport(w http.ResponseWriter, r *http.Request) {
|
|||
http.Error(w, "only POST allowed", http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
defer h.b.TryFlushLogs() // kick off upload after bugreport's done logging
|
||||
|
||||
logMarker := func() string {
|
||||
return fmt.Sprintf("BUG-%v-%v-%v", h.backendLogID, time.Now().UTC().Format("20060102150405Z"), randHex(8))
|
||||
|
|
|
@ -461,12 +461,24 @@ func (l *Logger) upload(ctx context.Context, body []byte, origlen int) (uploaded
|
|||
return true, nil
|
||||
}
|
||||
|
||||
// Flush uploads all logs to the server.
|
||||
// It blocks until complete or there is an unrecoverable error.
|
||||
// Flush uploads all logs to the server. It blocks until complete or there is an
|
||||
// unrecoverable error.
|
||||
//
|
||||
// TODO(bradfitz): this apparently just returns nil, as of tailscale/corp@9c2ec35.
|
||||
// Finish cleaning this up.
|
||||
func (l *Logger) Flush() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// StartFlush starts a log upload, if anything is pending.
|
||||
//
|
||||
// If l is nil, StartFlush is a no-op.
|
||||
func (l *Logger) StartFlush() {
|
||||
if l != nil {
|
||||
l.tryDrainWake()
|
||||
}
|
||||
}
|
||||
|
||||
// logtailDisabled is whether logtail uploads to logcatcher are disabled.
|
||||
var logtailDisabled atomic.Bool
|
||||
|
||||
|
|
|
@ -88,7 +88,8 @@ type CapabilityVersion int
|
|||
// - 49: 2022-11-03: Client understands EarlyNoise
|
||||
// - 50: 2022-11-14: Client understands CapabilityIngress
|
||||
// - 51: 2022-11-30: Client understands CapabilityTailnetLockAlpha
|
||||
const CurrentCapabilityVersion CapabilityVersion = 51
|
||||
// - 52: 2023-01-05: client can handle c2n POST /logtail/flush
|
||||
const CurrentCapabilityVersion CapabilityVersion = 52
|
||||
|
||||
type StableID string
|
||||
|
||||
|
|
Loading…
Reference in New Issue