log/filelogger, logpolicy: put Windows disk logs next to the log config

filelogger always wrote under %ProgramData%\Tailscale\Logs, even though
logpolicy already picks %LocalAppData%\Tailscale for its config when
tailscaled isn't privileged enough for %ProgramData%. A tailscaled run by
a regular user therefore logged "failed to create local log directory" and
kept no disk logs. Take the directory from the caller instead: logpolicy
passes the Logs subdirectory of whichever directory it chose, which is the
same %ProgramData% path as before for the service.

Updates #2791

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Change-Id: I3b5d7f9a1c3e5b7d9f1a3c5e7b9d1f3a5c7e9b1d
This commit is contained in:
Brad Fitzpatrick authored and Brad Fitzpatrick committed 2026-09-24 11:52:30 -07:00
1 parent e87076a378
commit 506f261427
2 files changed
+9 -6

No files matched your search

+5 -5
View File
@@ -25,17 +25,17 @@ const (
maxFiles = 50
)
// New returns a logf wrapper that appends to local disk log
// files on Windows, rotating old log files as needed to stay under
// file count & byte limits.
func New(fileBasePrefix, logID string, logf logger.Logf) logger.Logf {
// New returns a logf wrapper that appends to local disk log files in dir on
// Windows, creating dir if needed and rotating old log files as needed to
// stay under file count & byte limits. If dir can't be created, it logs
// that and returns logf unchanged.
func New(dir, fileBasePrefix, logID string, logf logger.Logf) logger.Logf {
if runtime.GOOS != "windows" {
panic("not yet supported on any platform except Windows")
}
if logf == nil {
panic("nil logf")
}
dir := filepath.Join(os.Getenv("ProgramData"), "Tailscale", "Logs")
if err := os.MkdirAll(dir, 0700); err != nil {
log.Printf("failed to create local log directory; not writing logs to disk: %v", err)
+4 -1
View File
@@ -687,7 +687,10 @@ func (opts Options) init(disableLogging bool) (*logtail.Config, *Policy) {
logID := newc.PublicID.String()
exe, _ := os.Executable()
if strings.EqualFold(filepath.Base(exe), "tailscaled.exe") {
diskLogf := filelogger.New("tailscale-service", logID, lw.Logf)
// Alongside the log config: %ProgramData%\Tailscale\Logs for
// the service, or %LocalAppData%\Tailscale\Logs for a tailscaled
// run by a regular user. See LogsDir.
diskLogf := filelogger.New(filepath.Join(opts.Dir, "Logs"), "tailscale-service", logID, lw.Logf)
logOutput = logger.FuncWriter(diskLogf)
}
}