mirror of
https://github.com/tailscale/tailscale.git
synced 2025-10-03 19:41:34 +02:00
feature/logtail: pull logtail + netlog out to modular features
Removes 434 KB from the minimal Linux binary, or ~3%. Primarily this comes from not linking in the zstd encoding code. Fixes #17323 Change-Id: I0a90de307dfa1ad7422db7aa8b1b46c782bfaaf7 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
parent
e466488a2a
commit
11b770fbc9
@ -158,7 +158,7 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de
|
|||||||
tailscale.com/types/logger from tailscale.com/appc+
|
tailscale.com/types/logger from tailscale.com/appc+
|
||||||
tailscale.com/types/logid from tailscale.com/cmd/tailscaled+
|
tailscale.com/types/logid from tailscale.com/cmd/tailscaled+
|
||||||
tailscale.com/types/mapx from tailscale.com/ipn/ipnext
|
tailscale.com/types/mapx from tailscale.com/ipn/ipnext
|
||||||
tailscale.com/types/netlogtype from tailscale.com/net/connstats+
|
tailscale.com/types/netlogtype from tailscale.com/net/connstats
|
||||||
tailscale.com/types/netmap from tailscale.com/control/controlclient+
|
tailscale.com/types/netmap from tailscale.com/control/controlclient+
|
||||||
tailscale.com/types/nettype from tailscale.com/ipn/localapi+
|
tailscale.com/types/nettype from tailscale.com/ipn/localapi+
|
||||||
tailscale.com/types/opt from tailscale.com/control/controlknobs+
|
tailscale.com/types/opt from tailscale.com/control/controlknobs+
|
||||||
@ -205,11 +205,10 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de
|
|||||||
tailscale.com/util/syspolicy/ptype from tailscale.com/ipn/ipnlocal+
|
tailscale.com/util/syspolicy/ptype from tailscale.com/ipn/ipnlocal+
|
||||||
tailscale.com/util/systemd from tailscale.com/control/controlclient+
|
tailscale.com/util/systemd from tailscale.com/control/controlclient+
|
||||||
tailscale.com/util/testenv from tailscale.com/control/controlclient+
|
tailscale.com/util/testenv from tailscale.com/control/controlclient+
|
||||||
tailscale.com/util/truncate from tailscale.com/logtail
|
|
||||||
tailscale.com/util/usermetric from tailscale.com/health+
|
tailscale.com/util/usermetric from tailscale.com/health+
|
||||||
tailscale.com/util/vizerror from tailscale.com/tailcfg+
|
tailscale.com/util/vizerror from tailscale.com/tailcfg+
|
||||||
tailscale.com/util/winutil from tailscale.com/ipn/ipnauth
|
tailscale.com/util/winutil from tailscale.com/ipn/ipnauth
|
||||||
tailscale.com/util/zstdframe from tailscale.com/control/controlclient+
|
tailscale.com/util/zstdframe from tailscale.com/control/controlclient
|
||||||
tailscale.com/version from tailscale.com/clientupdate+
|
tailscale.com/version from tailscale.com/clientupdate+
|
||||||
tailscale.com/version/distro from tailscale.com/clientupdate+
|
tailscale.com/version/distro from tailscale.com/clientupdate+
|
||||||
tailscale.com/wgengine from tailscale.com/cmd/tailscaled+
|
tailscale.com/wgengine from tailscale.com/cmd/tailscaled+
|
||||||
|
@ -402,7 +402,7 @@ func ipnServerOpts() (o serverOptions) {
|
|||||||
return o
|
return o
|
||||||
}
|
}
|
||||||
|
|
||||||
var logPol *logpolicy.Policy
|
var logPol *logpolicy.Policy // or nil if not used
|
||||||
var debugMux *http.ServeMux
|
var debugMux *http.ServeMux
|
||||||
|
|
||||||
func run() (err error) {
|
func run() (err error) {
|
||||||
@ -432,15 +432,19 @@ func run() (err error) {
|
|||||||
sys.Set(netMon)
|
sys.Set(netMon)
|
||||||
}
|
}
|
||||||
|
|
||||||
pol := logpolicy.New(logtail.CollectionNode, netMon, sys.HealthTracker.Get(), nil /* use log.Printf */)
|
var publicLogID logid.PublicID
|
||||||
pol.SetVerbosityLevel(args.verbose)
|
if buildfeatures.HasLogTail {
|
||||||
logPol = pol
|
pol := logpolicy.New(logtail.CollectionNode, netMon, sys.HealthTracker.Get(), nil /* use log.Printf */)
|
||||||
defer func() {
|
pol.SetVerbosityLevel(args.verbose)
|
||||||
// Finish uploading logs after closing everything else.
|
publicLogID = pol.PublicID
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
logPol = pol
|
||||||
defer cancel()
|
defer func() {
|
||||||
pol.Shutdown(ctx)
|
// Finish uploading logs after closing everything else.
|
||||||
}()
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
||||||
|
defer cancel()
|
||||||
|
pol.Shutdown(ctx)
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
if err := envknob.ApplyDiskConfigError(); err != nil {
|
if err := envknob.ApplyDiskConfigError(); err != nil {
|
||||||
log.Printf("Error reading environment config: %v", err)
|
log.Printf("Error reading environment config: %v", err)
|
||||||
@ -449,7 +453,7 @@ func run() (err error) {
|
|||||||
if isWinSvc {
|
if isWinSvc {
|
||||||
// Run the IPN server from the Windows service manager.
|
// Run the IPN server from the Windows service manager.
|
||||||
log.Printf("Running service...")
|
log.Printf("Running service...")
|
||||||
if err := runWindowsService(pol); err != nil {
|
if err := runWindowsService(logPol); err != nil {
|
||||||
log.Printf("runservice: %v", err)
|
log.Printf("runservice: %v", err)
|
||||||
}
|
}
|
||||||
log.Printf("Service ended.")
|
log.Printf("Service ended.")
|
||||||
@ -493,7 +497,7 @@ func run() (err error) {
|
|||||||
hostinfo.SetApp(app)
|
hostinfo.SetApp(app)
|
||||||
}
|
}
|
||||||
|
|
||||||
return startIPNServer(context.Background(), logf, pol.PublicID, sys)
|
return startIPNServer(context.Background(), logf, publicLogID, sys)
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -503,6 +507,7 @@ var (
|
|||||||
|
|
||||||
var sigPipe os.Signal // set by sigpipe.go
|
var sigPipe os.Signal // set by sigpipe.go
|
||||||
|
|
||||||
|
// logID may be the zero value if logging is not in use.
|
||||||
func startIPNServer(ctx context.Context, logf logger.Logf, logID logid.PublicID, sys *tsd.System) error {
|
func startIPNServer(ctx context.Context, logf logger.Logf, logID logid.PublicID, sys *tsd.System) error {
|
||||||
ln, err := safesocket.Listen(args.socketpath)
|
ln, err := safesocket.Listen(args.socketpath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -600,6 +605,7 @@ var (
|
|||||||
hookNewNetstack feature.Hook[func(_ logger.Logf, _ *tsd.System, onlyNetstack bool) (tsd.NetstackImpl, error)]
|
hookNewNetstack feature.Hook[func(_ logger.Logf, _ *tsd.System, onlyNetstack bool) (tsd.NetstackImpl, error)]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// logID may be the zero value if logging is not in use.
|
||||||
func getLocalBackend(ctx context.Context, logf logger.Logf, logID logid.PublicID, sys *tsd.System) (_ *ipnlocal.LocalBackend, retErr error) {
|
func getLocalBackend(ctx context.Context, logf logger.Logf, logID logid.PublicID, sys *tsd.System) (_ *ipnlocal.LocalBackend, retErr error) {
|
||||||
if logPol != nil {
|
if logPol != nil {
|
||||||
logPol.Logtail.SetNetMon(sys.NetMon.Get())
|
logPol.Logtail.SetNetMon(sys.NetMon.Get())
|
||||||
|
@ -149,6 +149,8 @@ var syslogf logger.Logf = logger.Discard
|
|||||||
//
|
//
|
||||||
// At this point we're still the parent process that
|
// At this point we're still the parent process that
|
||||||
// Windows started.
|
// Windows started.
|
||||||
|
//
|
||||||
|
// pol may be nil.
|
||||||
func runWindowsService(pol *logpolicy.Policy) error {
|
func runWindowsService(pol *logpolicy.Policy) error {
|
||||||
go func() {
|
go func() {
|
||||||
logger.Logf(log.Printf).JSON(1, "SupportInfo", osdiag.SupportInfo(osdiag.LogSupportInfoReasonStartup))
|
logger.Logf(log.Printf).JSON(1, "SupportInfo", osdiag.SupportInfo(osdiag.LogSupportInfoReasonStartup))
|
||||||
@ -169,7 +171,7 @@ func runWindowsService(pol *logpolicy.Policy) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ipnService struct {
|
type ipnService struct {
|
||||||
Policy *logpolicy.Policy
|
Policy *logpolicy.Policy // or nil if logging not in use
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called by Windows to execute the windows service.
|
// Called by Windows to execute the windows service.
|
||||||
@ -186,7 +188,11 @@ func (service *ipnService) Execute(args []string, r <-chan svc.ChangeRequest, ch
|
|||||||
doneCh := make(chan struct{})
|
doneCh := make(chan struct{})
|
||||||
go func() {
|
go func() {
|
||||||
defer close(doneCh)
|
defer close(doneCh)
|
||||||
args := []string{"/subproc", service.Policy.PublicID.String()}
|
publicID := "none"
|
||||||
|
if service.Policy != nil {
|
||||||
|
publicID = service.Policy.PublicID.String()
|
||||||
|
}
|
||||||
|
args := []string{"/subproc", publicID}
|
||||||
// Make a logger without a date prefix, as filelogger
|
// Make a logger without a date prefix, as filelogger
|
||||||
// and logtail both already add their own. All we really want
|
// and logtail both already add their own. All we really want
|
||||||
// from the log package is the automatic newline.
|
// from the log package is the automatic newline.
|
||||||
|
13
feature/buildfeatures/feature_logtail_disabled.go
Normal file
13
feature/buildfeatures/feature_logtail_disabled.go
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
// Copyright (c) Tailscale Inc & AUTHORS
|
||||||
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
|
// Code generated by gen.go; DO NOT EDIT.
|
||||||
|
|
||||||
|
//go:build ts_omit_logtail
|
||||||
|
|
||||||
|
package buildfeatures
|
||||||
|
|
||||||
|
// HasLogTail is whether the binary was built with support for modular feature "upload logs to log.tailscale.com (debug logs for bug reports and also by network flow logs if enabled)".
|
||||||
|
// Specifically, it's whether the binary was NOT built with the "ts_omit_logtail" build tag.
|
||||||
|
// It's a const so it can be used for dead code elimination.
|
||||||
|
const HasLogTail = false
|
13
feature/buildfeatures/feature_logtail_enabled.go
Normal file
13
feature/buildfeatures/feature_logtail_enabled.go
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
// Copyright (c) Tailscale Inc & AUTHORS
|
||||||
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
|
// Code generated by gen.go; DO NOT EDIT.
|
||||||
|
|
||||||
|
//go:build !ts_omit_logtail
|
||||||
|
|
||||||
|
package buildfeatures
|
||||||
|
|
||||||
|
// HasLogTail is whether the binary was built with support for modular feature "upload logs to log.tailscale.com (debug logs for bug reports and also by network flow logs if enabled)".
|
||||||
|
// Specifically, it's whether the binary was NOT built with the "ts_omit_logtail" build tag.
|
||||||
|
// It's a const so it can be used for dead code elimination.
|
||||||
|
const HasLogTail = true
|
13
feature/buildfeatures/feature_netlog_disabled.go
Normal file
13
feature/buildfeatures/feature_netlog_disabled.go
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
// Copyright (c) Tailscale Inc & AUTHORS
|
||||||
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
|
// Code generated by gen.go; DO NOT EDIT.
|
||||||
|
|
||||||
|
//go:build ts_omit_netlog
|
||||||
|
|
||||||
|
package buildfeatures
|
||||||
|
|
||||||
|
// HasNetLog is whether the binary was built with support for modular feature "Network flow logging support".
|
||||||
|
// Specifically, it's whether the binary was NOT built with the "ts_omit_netlog" build tag.
|
||||||
|
// It's a const so it can be used for dead code elimination.
|
||||||
|
const HasNetLog = false
|
13
feature/buildfeatures/feature_netlog_enabled.go
Normal file
13
feature/buildfeatures/feature_netlog_enabled.go
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
// Copyright (c) Tailscale Inc & AUTHORS
|
||||||
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
|
// Code generated by gen.go; DO NOT EDIT.
|
||||||
|
|
||||||
|
//go:build !ts_omit_netlog
|
||||||
|
|
||||||
|
package buildfeatures
|
||||||
|
|
||||||
|
// HasNetLog is whether the binary was built with support for modular feature "Network flow logging support".
|
||||||
|
// Specifically, it's whether the binary was NOT built with the "ts_omit_netlog" build tag.
|
||||||
|
// It's a const so it can be used for dead code elimination.
|
||||||
|
const HasNetLog = true
|
@ -115,7 +115,11 @@ var Features = map[FeatureTag]FeatureMeta{
|
|||||||
"iptables": {"IPTables", "Linux iptables support", nil},
|
"iptables": {"IPTables", "Linux iptables support", nil},
|
||||||
"kube": {"Kube", "Kubernetes integration", nil},
|
"kube": {"Kube", "Kubernetes integration", nil},
|
||||||
"linuxdnsfight": {"LinuxDNSFight", "Linux support for detecting DNS fights (inotify watching of /etc/resolv.conf)", nil},
|
"linuxdnsfight": {"LinuxDNSFight", "Linux support for detecting DNS fights (inotify watching of /etc/resolv.conf)", nil},
|
||||||
"oauthkey": {"OAuthKey", "OAuth secret-to-authkey resolution support", nil},
|
"logtail": {
|
||||||
|
Sym: "LogTail",
|
||||||
|
Desc: "upload logs to log.tailscale.com (debug logs for bug reports and also by network flow logs if enabled)",
|
||||||
|
},
|
||||||
|
"oauthkey": {"OAuthKey", "OAuth secret-to-authkey resolution support", nil},
|
||||||
"outboundproxy": {
|
"outboundproxy": {
|
||||||
Sym: "OutboundProxy",
|
Sym: "OutboundProxy",
|
||||||
Desc: "Outbound localhost HTTP/SOCK5 proxy support",
|
Desc: "Outbound localhost HTTP/SOCK5 proxy support",
|
||||||
@ -123,7 +127,12 @@ var Features = map[FeatureTag]FeatureMeta{
|
|||||||
},
|
},
|
||||||
"portlist": {"PortList", "Optionally advertise listening service ports", nil},
|
"portlist": {"PortList", "Optionally advertise listening service ports", nil},
|
||||||
"portmapper": {"PortMapper", "NAT-PMP/PCP/UPnP port mapping support", nil},
|
"portmapper": {"PortMapper", "NAT-PMP/PCP/UPnP port mapping support", nil},
|
||||||
"netstack": {"Netstack", "gVisor netstack (userspace networking) support", nil},
|
"netlog": {
|
||||||
|
Sym: "NetLog",
|
||||||
|
Desc: "Network flow logging support",
|
||||||
|
Deps: []FeatureTag{"logtail"},
|
||||||
|
},
|
||||||
|
"netstack": {"Netstack", "gVisor netstack (userspace networking) support", nil},
|
||||||
"networkmanager": {
|
"networkmanager": {
|
||||||
Sym: "NetworkManager",
|
Sym: "NetworkManager",
|
||||||
Desc: "Linux NetworkManager integration",
|
Desc: "Linux NetworkManager integration",
|
||||||
|
@ -202,7 +202,7 @@ type LocalBackend struct {
|
|||||||
store ipn.StateStore // non-nil; TODO(bradfitz): remove; use sys
|
store ipn.StateStore // non-nil; TODO(bradfitz): remove; use sys
|
||||||
dialer *tsdial.Dialer // non-nil; TODO(bradfitz): remove; use sys
|
dialer *tsdial.Dialer // non-nil; TODO(bradfitz): remove; use sys
|
||||||
pushDeviceToken syncs.AtomicValue[string]
|
pushDeviceToken syncs.AtomicValue[string]
|
||||||
backendLogID logid.PublicID
|
backendLogID logid.PublicID // or zero value if logging not in use
|
||||||
unregisterSysPolicyWatch func()
|
unregisterSysPolicyWatch func()
|
||||||
varRoot string // or empty if SetVarRoot never called
|
varRoot string // or empty if SetVarRoot never called
|
||||||
logFlushFunc func() // or nil if SetLogFlusher wasn't called
|
logFlushFunc func() // or nil if SetLogFlusher wasn't called
|
||||||
@ -456,6 +456,8 @@ type clientGen func(controlclient.Options) (controlclient.Client, error)
|
|||||||
// but is not actually running.
|
// but is not actually running.
|
||||||
//
|
//
|
||||||
// If dialer is nil, a new one is made.
|
// If dialer is nil, a new one is made.
|
||||||
|
//
|
||||||
|
// The logID may be the zero value if logging is not in use.
|
||||||
func NewLocalBackend(logf logger.Logf, logID logid.PublicID, sys *tsd.System, loginFlags controlclient.LoginFlags) (_ *LocalBackend, err error) {
|
func NewLocalBackend(logf logger.Logf, logID logid.PublicID, sys *tsd.System, loginFlags controlclient.LoginFlags) (_ *LocalBackend, err error) {
|
||||||
e := sys.Engine.Get()
|
e := sys.Engine.Get()
|
||||||
store := sys.StateStore.Get()
|
store := sys.StateStore.Get()
|
||||||
|
@ -28,6 +28,7 @@ import (
|
|||||||
"tailscale.com/client/tailscale/apitype"
|
"tailscale.com/client/tailscale/apitype"
|
||||||
"tailscale.com/clientupdate"
|
"tailscale.com/clientupdate"
|
||||||
"tailscale.com/envknob"
|
"tailscale.com/envknob"
|
||||||
|
"tailscale.com/feature/buildfeatures"
|
||||||
"tailscale.com/health/healthmsg"
|
"tailscale.com/health/healthmsg"
|
||||||
"tailscale.com/hostinfo"
|
"tailscale.com/hostinfo"
|
||||||
"tailscale.com/ipn"
|
"tailscale.com/ipn"
|
||||||
@ -575,6 +576,15 @@ func (h *Handler) serveGoroutines(w http.ResponseWriter, r *http.Request) {
|
|||||||
func (h *Handler) serveLogTap(w http.ResponseWriter, r *http.Request) {
|
func (h *Handler) serveLogTap(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
|
|
||||||
|
if !buildfeatures.HasLogTail {
|
||||||
|
// TODO(bradfitz): separate out logtail tap functionality from upload
|
||||||
|
// functionality to make this possible? But seems unlikely people would
|
||||||
|
// want just this. They could "tail -f" or "journalctl -f" their logs
|
||||||
|
// themselves.
|
||||||
|
http.Error(w, "logtap not supported in this build", http.StatusNotImplemented)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Require write access (~root) as the logs could contain something
|
// Require write access (~root) as the logs could contain something
|
||||||
// sensitive.
|
// sensitive.
|
||||||
if !h.PermitWrite {
|
if !h.PermitWrite {
|
||||||
|
@ -17,6 +17,7 @@ import (
|
|||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"tailscale.com/feature/buildfeatures"
|
||||||
"tailscale.com/health"
|
"tailscale.com/health"
|
||||||
"tailscale.com/logpolicy"
|
"tailscale.com/logpolicy"
|
||||||
"tailscale.com/logtail"
|
"tailscale.com/logtail"
|
||||||
@ -97,7 +98,7 @@ func SockstatLogID(logID logid.PublicID) logid.PrivateID {
|
|||||||
// The netMon parameter is optional. It should be specified in environments where
|
// The netMon parameter is optional. It should be specified in environments where
|
||||||
// Tailscaled is manipulating the routing table.
|
// Tailscaled is manipulating the routing table.
|
||||||
func NewLogger(logdir string, logf logger.Logf, logID logid.PublicID, netMon *netmon.Monitor, health *health.Tracker) (*Logger, error) {
|
func NewLogger(logdir string, logf logger.Logf, logID logid.PublicID, netMon *netmon.Monitor, health *health.Tracker) (*Logger, error) {
|
||||||
if !sockstats.IsAvailable {
|
if !sockstats.IsAvailable || !buildfeatures.HasLogTail {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
if netMon == nil {
|
if netMon == nil {
|
||||||
|
@ -31,6 +31,7 @@ import (
|
|||||||
"golang.org/x/term"
|
"golang.org/x/term"
|
||||||
"tailscale.com/atomicfile"
|
"tailscale.com/atomicfile"
|
||||||
"tailscale.com/envknob"
|
"tailscale.com/envknob"
|
||||||
|
"tailscale.com/feature/buildfeatures"
|
||||||
"tailscale.com/health"
|
"tailscale.com/health"
|
||||||
"tailscale.com/hostinfo"
|
"tailscale.com/hostinfo"
|
||||||
"tailscale.com/log/filelogger"
|
"tailscale.com/log/filelogger"
|
||||||
@ -106,6 +107,7 @@ type Policy struct {
|
|||||||
// Logtail is the logger.
|
// Logtail is the logger.
|
||||||
Logtail *logtail.Logger
|
Logtail *logtail.Logger
|
||||||
// PublicID is the logger's instance identifier.
|
// PublicID is the logger's instance identifier.
|
||||||
|
// It may be the zero value if logging is not in use.
|
||||||
PublicID logid.PublicID
|
PublicID logid.PublicID
|
||||||
// Logf is where to write informational messages about this Logger.
|
// Logf is where to write informational messages about this Logger.
|
||||||
Logf logger.Logf
|
Logf logger.Logf
|
||||||
@ -682,7 +684,7 @@ func (opts Options) init(disableLogging bool) (*logtail.Config, *Policy) {
|
|||||||
|
|
||||||
// New returns a new log policy (a logger and its instance ID).
|
// New returns a new log policy (a logger and its instance ID).
|
||||||
func (opts Options) New() *Policy {
|
func (opts Options) New() *Policy {
|
||||||
disableLogging := envknob.NoLogsNoSupport() || testenv.InTest() || runtime.GOOS == "plan9"
|
disableLogging := envknob.NoLogsNoSupport() || testenv.InTest() || runtime.GOOS == "plan9" || !buildfeatures.HasLogTail
|
||||||
_, policy := opts.init(disableLogging)
|
_, policy := opts.init(disableLogging)
|
||||||
return policy
|
return policy
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
// Copyright (c) Tailscale Inc & AUTHORS
|
// Copyright (c) Tailscale Inc & AUTHORS
|
||||||
// SPDX-License-Identifier: BSD-3-Clause
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
|
//go:build !ts_omit_logtail
|
||||||
|
|
||||||
package logtail
|
package logtail
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
65
logtail/config.go
Normal file
65
logtail/config.go
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
// Copyright (c) Tailscale Inc & AUTHORS
|
||||||
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
|
package logtail
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"tailscale.com/tstime"
|
||||||
|
"tailscale.com/types/logid"
|
||||||
|
)
|
||||||
|
|
||||||
|
// DefaultHost is the default host name to upload logs to when
|
||||||
|
// Config.BaseURL isn't provided.
|
||||||
|
const DefaultHost = "log.tailscale.com"
|
||||||
|
|
||||||
|
const defaultFlushDelay = 2 * time.Second
|
||||||
|
|
||||||
|
const (
|
||||||
|
// CollectionNode is the name of a logtail Config.Collection
|
||||||
|
// for tailscaled (or equivalent: IPNExtension, Android app).
|
||||||
|
CollectionNode = "tailnode.log.tailscale.io"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
Collection string // collection name, a domain name
|
||||||
|
PrivateID logid.PrivateID // private ID for the primary log stream
|
||||||
|
CopyPrivateID logid.PrivateID // private ID for a log stream that is a superset of this log stream
|
||||||
|
BaseURL string // if empty defaults to "https://log.tailscale.com"
|
||||||
|
HTTPC *http.Client // if empty defaults to http.DefaultClient
|
||||||
|
SkipClientTime bool // if true, client_time is not written to logs
|
||||||
|
LowMemory bool // if true, logtail minimizes memory use
|
||||||
|
Clock tstime.Clock // if set, Clock.Now substitutes uses of time.Now
|
||||||
|
Stderr io.Writer // if set, logs are sent here instead of os.Stderr
|
||||||
|
StderrLevel int // max verbosity level to write to stderr; 0 means the non-verbose messages only
|
||||||
|
Buffer Buffer // temp storage, if nil a MemoryBuffer
|
||||||
|
CompressLogs bool // whether to compress the log uploads
|
||||||
|
MaxUploadSize int // maximum upload size; 0 means using the default
|
||||||
|
|
||||||
|
// MetricsDelta, if non-nil, is a func that returns an encoding
|
||||||
|
// delta in clientmetrics to upload alongside existing logs.
|
||||||
|
// It can return either an empty string (for nothing) or a string
|
||||||
|
// that's safe to embed in a JSON string literal without further escaping.
|
||||||
|
MetricsDelta func() string
|
||||||
|
|
||||||
|
// FlushDelayFn, if non-nil is a func that returns how long to wait to
|
||||||
|
// accumulate logs before uploading them. 0 or negative means to upload
|
||||||
|
// immediately.
|
||||||
|
//
|
||||||
|
// If nil, a default value is used. (currently 2 seconds)
|
||||||
|
FlushDelayFn func() time.Duration
|
||||||
|
|
||||||
|
// IncludeProcID, if true, results in an ephemeral process identifier being
|
||||||
|
// included in logs. The ID is random and not guaranteed to be globally
|
||||||
|
// unique, but it can be used to distinguish between different instances
|
||||||
|
// running with same PrivateID.
|
||||||
|
IncludeProcID bool
|
||||||
|
|
||||||
|
// IncludeProcSequence, if true, results in an ephemeral sequence number
|
||||||
|
// being included in the logs. The sequence number is incremented for each
|
||||||
|
// log message sent, but is not persisted across process restarts.
|
||||||
|
IncludeProcSequence bool
|
||||||
|
}
|
@ -1,6 +1,8 @@
|
|||||||
// Copyright (c) Tailscale Inc & AUTHORS
|
// Copyright (c) Tailscale Inc & AUTHORS
|
||||||
// SPDX-License-Identifier: BSD-3-Clause
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
|
//go:build !ts_omit_logtail
|
||||||
|
|
||||||
// Package logtail sends logs to log.tailscale.com.
|
// Package logtail sends logs to log.tailscale.com.
|
||||||
package logtail
|
package logtail
|
||||||
|
|
||||||
@ -51,58 +53,6 @@ const lowMemRatio = 4
|
|||||||
// but not too large to be a notable waste of memory if retained forever.
|
// but not too large to be a notable waste of memory if retained forever.
|
||||||
const bufferSize = 4 << 10
|
const bufferSize = 4 << 10
|
||||||
|
|
||||||
// DefaultHost is the default host name to upload logs to when
|
|
||||||
// Config.BaseURL isn't provided.
|
|
||||||
const DefaultHost = "log.tailscale.com"
|
|
||||||
|
|
||||||
const defaultFlushDelay = 2 * time.Second
|
|
||||||
|
|
||||||
const (
|
|
||||||
// CollectionNode is the name of a logtail Config.Collection
|
|
||||||
// for tailscaled (or equivalent: IPNExtension, Android app).
|
|
||||||
CollectionNode = "tailnode.log.tailscale.io"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Config struct {
|
|
||||||
Collection string // collection name, a domain name
|
|
||||||
PrivateID logid.PrivateID // private ID for the primary log stream
|
|
||||||
CopyPrivateID logid.PrivateID // private ID for a log stream that is a superset of this log stream
|
|
||||||
BaseURL string // if empty defaults to "https://log.tailscale.com"
|
|
||||||
HTTPC *http.Client // if empty defaults to http.DefaultClient
|
|
||||||
SkipClientTime bool // if true, client_time is not written to logs
|
|
||||||
LowMemory bool // if true, logtail minimizes memory use
|
|
||||||
Clock tstime.Clock // if set, Clock.Now substitutes uses of time.Now
|
|
||||||
Stderr io.Writer // if set, logs are sent here instead of os.Stderr
|
|
||||||
StderrLevel int // max verbosity level to write to stderr; 0 means the non-verbose messages only
|
|
||||||
Buffer Buffer // temp storage, if nil a MemoryBuffer
|
|
||||||
CompressLogs bool // whether to compress the log uploads
|
|
||||||
MaxUploadSize int // maximum upload size; 0 means using the default
|
|
||||||
|
|
||||||
// MetricsDelta, if non-nil, is a func that returns an encoding
|
|
||||||
// delta in clientmetrics to upload alongside existing logs.
|
|
||||||
// It can return either an empty string (for nothing) or a string
|
|
||||||
// that's safe to embed in a JSON string literal without further escaping.
|
|
||||||
MetricsDelta func() string
|
|
||||||
|
|
||||||
// FlushDelayFn, if non-nil is a func that returns how long to wait to
|
|
||||||
// accumulate logs before uploading them. 0 or negative means to upload
|
|
||||||
// immediately.
|
|
||||||
//
|
|
||||||
// If nil, a default value is used. (currently 2 seconds)
|
|
||||||
FlushDelayFn func() time.Duration
|
|
||||||
|
|
||||||
// IncludeProcID, if true, results in an ephemeral process identifier being
|
|
||||||
// included in logs. The ID is random and not guaranteed to be globally
|
|
||||||
// unique, but it can be used to distinguish between different instances
|
|
||||||
// running with same PrivateID.
|
|
||||||
IncludeProcID bool
|
|
||||||
|
|
||||||
// IncludeProcSequence, if true, results in an ephemeral sequence number
|
|
||||||
// being included in the logs. The sequence number is incremented for each
|
|
||||||
// log message sent, but is not persisted across process restarts.
|
|
||||||
IncludeProcSequence bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewLogger(cfg Config, logf tslogger.Logf) *Logger {
|
func NewLogger(cfg Config, logf tslogger.Logf) *Logger {
|
||||||
if cfg.BaseURL == "" {
|
if cfg.BaseURL == "" {
|
||||||
cfg.BaseURL = "https://" + DefaultHost
|
cfg.BaseURL = "https://" + DefaultHost
|
||||||
|
44
logtail/logtail_omit.go
Normal file
44
logtail/logtail_omit.go
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
// Copyright (c) Tailscale Inc & AUTHORS
|
||||||
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
|
//go:build ts_omit_logtail
|
||||||
|
|
||||||
|
package logtail
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
tslogger "tailscale.com/types/logger"
|
||||||
|
"tailscale.com/types/logid"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Noop implementations of everything when ts_omit_logtail is set.
|
||||||
|
|
||||||
|
type Logger struct{}
|
||||||
|
|
||||||
|
type Buffer any
|
||||||
|
|
||||||
|
func Disable() {}
|
||||||
|
|
||||||
|
func NewLogger(cfg Config, logf tslogger.Logf) *Logger {
|
||||||
|
return &Logger{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*Logger) Write(p []byte) (n int, err error) {
|
||||||
|
return len(p), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*Logger) Logf(format string, args ...any) {}
|
||||||
|
func (*Logger) Shutdown(ctx context.Context) error { return nil }
|
||||||
|
func (*Logger) SetVerbosityLevel(level int) {}
|
||||||
|
|
||||||
|
func (l *Logger) SetSockstatsLabel(label any) {}
|
||||||
|
|
||||||
|
func (l *Logger) PrivateID() logid.PrivateID { return logid.PrivateID{} }
|
||||||
|
func (l *Logger) StartFlush() {}
|
||||||
|
|
||||||
|
func RegisterLogTap(dst chan<- string) (unregister func()) {
|
||||||
|
return func() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*Logger) SetNetMon(any) {}
|
@ -1,6 +1,8 @@
|
|||||||
// Copyright (c) Tailscale Inc & AUTHORS
|
// Copyright (c) Tailscale Inc & AUTHORS
|
||||||
// SPDX-License-Identifier: BSD-3-Clause
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
|
//go:build !ts_omit_netlog && !ts_omit_logtail
|
||||||
|
|
||||||
// Package netlog provides a logger that monitors a TUN device and
|
// Package netlog provides a logger that monitors a TUN device and
|
||||||
// periodically records any traffic into a log stream.
|
// periodically records any traffic into a log stream.
|
||||||
package netlog
|
package netlog
|
13
wgengine/netlog/netlog_omit.go
Normal file
13
wgengine/netlog/netlog_omit.go
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
// Copyright (c) Tailscale Inc & AUTHORS
|
||||||
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
|
//go:build ts_omit_netlog || ts_omit_logtail
|
||||||
|
|
||||||
|
package netlog
|
||||||
|
|
||||||
|
type Logger struct{}
|
||||||
|
|
||||||
|
func (*Logger) Startup(...any) error { return nil }
|
||||||
|
func (*Logger) Running() bool { return false }
|
||||||
|
func (*Logger) Shutdown(any) error { return nil }
|
||||||
|
func (*Logger) ReconfigRoutes(any) {}
|
@ -962,7 +962,7 @@ func (e *userspaceEngine) Reconfig(cfg *wgcfg.Config, routerCfg *router.Config,
|
|||||||
netLogIDsWasValid := !oldLogIDs.NodeID.IsZero() && !oldLogIDs.DomainID.IsZero()
|
netLogIDsWasValid := !oldLogIDs.NodeID.IsZero() && !oldLogIDs.DomainID.IsZero()
|
||||||
netLogIDsChanged := netLogIDsNowValid && netLogIDsWasValid && newLogIDs != oldLogIDs
|
netLogIDsChanged := netLogIDsNowValid && netLogIDsWasValid && newLogIDs != oldLogIDs
|
||||||
netLogRunning := netLogIDsNowValid && !routerCfg.Equal(&router.Config{})
|
netLogRunning := netLogIDsNowValid && !routerCfg.Equal(&router.Config{})
|
||||||
if envknob.NoLogsNoSupport() {
|
if !buildfeatures.HasNetLog || envknob.NoLogsNoSupport() {
|
||||||
netLogRunning = false
|
netLogRunning = false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1017,7 +1017,7 @@ func (e *userspaceEngine) Reconfig(cfg *wgcfg.Config, routerCfg *router.Config,
|
|||||||
|
|
||||||
// Shutdown the network logger because the IDs changed.
|
// Shutdown the network logger because the IDs changed.
|
||||||
// Let it be started back up by subsequent logic.
|
// Let it be started back up by subsequent logic.
|
||||||
if netLogIDsChanged && e.networkLogger.Running() {
|
if buildfeatures.HasNetLog && netLogIDsChanged && e.networkLogger.Running() {
|
||||||
e.logf("wgengine: Reconfig: shutting down network logger")
|
e.logf("wgengine: Reconfig: shutting down network logger")
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), networkLoggerUploadTimeout)
|
ctx, cancel := context.WithTimeout(context.Background(), networkLoggerUploadTimeout)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
@ -1028,7 +1028,7 @@ func (e *userspaceEngine) Reconfig(cfg *wgcfg.Config, routerCfg *router.Config,
|
|||||||
|
|
||||||
// Startup the network logger.
|
// Startup the network logger.
|
||||||
// Do this before configuring the router so that we capture initial packets.
|
// Do this before configuring the router so that we capture initial packets.
|
||||||
if netLogRunning && !e.networkLogger.Running() {
|
if buildfeatures.HasNetLog && netLogRunning && !e.networkLogger.Running() {
|
||||||
nid := cfg.NetworkLogging.NodeID
|
nid := cfg.NetworkLogging.NodeID
|
||||||
tid := cfg.NetworkLogging.DomainID
|
tid := cfg.NetworkLogging.DomainID
|
||||||
logExitFlowEnabled := cfg.NetworkLogging.LogExitFlowEnabled
|
logExitFlowEnabled := cfg.NetworkLogging.LogExitFlowEnabled
|
||||||
|
Loading…
x
Reference in New Issue
Block a user