mirror of
https://github.com/tailscale/tailscale.git
synced 2024-11-29 04:55:31 +00:00
ipn: add c2n endpoint for sockstats logs
Signed-off-by: Will Norris <will@tailscale.com>
This commit is contained in:
parent
a1d9f65354
commit
09e0ccf4c2
@ -83,6 +83,9 @@ func (b *LocalBackend) handleC2N(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
writeJSON(res)
|
writeJSON(res)
|
||||||
|
case "/sockstats":
|
||||||
|
w.Header().Set("Content-Type", "text/plain")
|
||||||
|
b.sockstatLogger.WriteLogs(w)
|
||||||
default:
|
default:
|
||||||
http.Error(w, "unknown c2n path", http.StatusBadRequest)
|
http.Error(w, "unknown c2n path", http.StatusBadRequest)
|
||||||
}
|
}
|
||||||
|
@ -310,7 +310,7 @@ func NewLocalBackend(logf logger.Logf, logid string, store ipn.StateStore, diale
|
|||||||
|
|
||||||
// for now, only log sockstats on unstable builds
|
// for now, only log sockstats on unstable builds
|
||||||
if version.IsUnstableBuild() {
|
if version.IsUnstableBuild() {
|
||||||
b.sockstatLogger, err = sockstatlog.NewLogger(logpolicy.LogsDir(logf))
|
b.sockstatLogger, err = sockstatlog.NewLogger(logpolicy.LogsDir(logf), logf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("error setting up sockstat logger: %v", err)
|
log.Printf("error setting up sockstat logger: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -6,12 +6,14 @@
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"tailscale.com/logtail/filch"
|
"tailscale.com/logtail/filch"
|
||||||
"tailscale.com/net/sockstats"
|
"tailscale.com/net/sockstats"
|
||||||
|
"tailscale.com/types/logger"
|
||||||
"tailscale.com/util/mak"
|
"tailscale.com/util/mak"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -21,6 +23,7 @@
|
|||||||
// Logger logs statistics about network sockets.
|
// Logger logs statistics about network sockets.
|
||||||
type Logger struct {
|
type Logger struct {
|
||||||
ticker time.Ticker
|
ticker time.Ticker
|
||||||
|
logf logger.Logf
|
||||||
logbuffer *filch.Filch
|
logbuffer *filch.Filch
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,7 +49,7 @@ type event struct {
|
|||||||
// NewLogger returns a new Logger that will store stats in logdir.
|
// NewLogger returns a new Logger that will store stats in logdir.
|
||||||
// On platforms that do not support sockstat logging, a nil Logger will be returned.
|
// On platforms that do not support sockstat logging, a nil Logger will be returned.
|
||||||
// The returned Logger is not yet running.
|
// The returned Logger is not yet running.
|
||||||
func NewLogger(logdir string) (*Logger, error) {
|
func NewLogger(logdir string, logf logger.Logf) (*Logger, error) {
|
||||||
if !sockstats.IsAvailable {
|
if !sockstats.IsAvailable {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
@ -62,6 +65,7 @@ func NewLogger(logdir string) (*Logger, error) {
|
|||||||
|
|
||||||
return &Logger{
|
return &Logger{
|
||||||
ticker: *time.NewTicker(pollPeriod),
|
ticker: *time.NewTicker(pollPeriod),
|
||||||
|
logf: logf,
|
||||||
logbuffer: filch,
|
logbuffer: filch,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
@ -92,7 +96,9 @@ func (l *Logger) poll() {
|
|||||||
if stats.CurrentInterfaceCellular {
|
if stats.CurrentInterfaceCellular {
|
||||||
e.IsCellularInterface = 1
|
e.IsCellularInterface = 1
|
||||||
}
|
}
|
||||||
enc.Encode(e)
|
if err := enc.Encode(e); err != nil {
|
||||||
|
l.logf("sockstatlog: error encoding log: %v", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lastTime = t
|
lastTime = t
|
||||||
@ -105,6 +111,27 @@ func (l *Logger) Shutdown() {
|
|||||||
l.logbuffer.Close()
|
l.logbuffer.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WriteLogs reads local logs, combining logs into events, and writes them to w.
|
||||||
|
// Logs within eventWindow are combined into the same event.
|
||||||
|
func (l *Logger) WriteLogs(w io.Writer) {
|
||||||
|
if l == nil || l.logbuffer == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for {
|
||||||
|
b, err := l.logbuffer.TryReadLine()
|
||||||
|
if err != nil {
|
||||||
|
l.logf("sockstatlog: error reading log: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if b == nil {
|
||||||
|
// no more log messages
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Write(b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// delta calculates the delta stats between two SockStats snapshots.
|
// delta calculates the delta stats between two SockStats snapshots.
|
||||||
// b is assumed to have occurred after a.
|
// b is assumed to have occurred after a.
|
||||||
// Zero values are omitted from the returned map, and an empty map is returned if no bytes were transferred.
|
// Zero values are omitted from the returned map, and an empty map is returned if no bytes were transferred.
|
||||||
|
Loading…
Reference in New Issue
Block a user