ipn/local: log OS-specific diagnostic information as JSON (#11700)

There is an undocumented 16KiB limit for text log messages.
However, the limit for JSON messages is 256KiB.
Even worse, logging JSON as text results in significant overhead
since each double quote needs to be escaped.

Instead, use logger.Logf.JSON to explicitly log the info as JSON.

We also modify osdiag to return the information as structured data
rather than implicitly have the package log on our behalf.
This gives more control to the caller on how to log.

Updates #7802

Signed-off-by: Joe Tsai <joetsai@digital-static.net>
This commit is contained in:
Joe Tsai 2024-04-22 16:45:01 -07:00 committed by GitHub
parent 06502b9048
commit 63b3c82587
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 10 additions and 27 deletions

View File

@ -131,7 +131,7 @@ func isWindowsService() bool {
// Windows started.
func runWindowsService(pol *logpolicy.Policy) error {
go func() {
osdiag.LogSupportInfo(logger.WithPrefix(log.Printf, "Support Info: "), osdiag.LogSupportInfoReasonStartup)
logger.Logf(log.Printf).JSON(1, "SupportInfo", osdiag.SupportInfo(osdiag.LogSupportInfoReasonStartup))
}()
if logSCMInteractions, _ := syspolicy.GetBoolean(syspolicy.LogSCMInteractions, false); logSCMInteractions {

View File

@ -380,7 +380,7 @@ func (h *Handler) serveBugReport(w http.ResponseWriter, r *http.Request) {
envknob.LogCurrent(logger.WithPrefix(h.logf, "user bugreport: "))
// OS-specific details
osdiag.LogSupportInfo(logger.WithPrefix(h.logf, "user bugreport OS: "), osdiag.LogSupportInfoReasonBugReport)
h.logf.JSON(1, "UserBugReportOS", osdiag.SupportInfo(osdiag.LogSupportInfoReasonBugReport))
if defBool(r.URL.Query().Get("diagnose"), false) {
h.b.Doctor(r.Context(), logger.WithPrefix(h.logf, "diag: "))

View File

@ -4,8 +4,6 @@
// Package osdiag provides loggers for OS-specific diagnostic information.
package osdiag
import "tailscale.com/types/logger"
// LogSupportInfoReason is an enumeration indicating the reason for logging
// support info.
type LogSupportInfoReason int
@ -15,9 +13,8 @@
LogSupportInfoReasonBugReport // a bugreport is in the process of being gathered.
)
// LogSupportInfo obtains OS-specific diagnostic information useful for
// troubleshooting and support, and writes it to logf. The reason argument is
// useful for governing the verbosity of this function's output.
func LogSupportInfo(logf logger.Logf, reason LogSupportInfoReason) {
logSupportInfo(logf, reason)
// SupportInfo obtains OS-specific diagnostic information for troubleshooting
// and support. The reason governs the verbosity of the output.
func SupportInfo(reason LogSupportInfoReason) map[string]any {
return supportInfo(reason)
}

View File

@ -5,7 +5,6 @@
package osdiag
import "tailscale.com/types/logger"
func logSupportInfo(logger.Logf, LogSupportInfoReason) {
func supportInfo(LogSupportInfoReason) map[string]any {
return nil
}

View File

@ -5,10 +5,8 @@
import (
"encoding/binary"
"encoding/json"
"errors"
"fmt"
"io"
"path/filepath"
"strings"
"unicode/utf16"
@ -18,7 +16,6 @@
"github.com/dblohm7/wingoes/pe"
"golang.org/x/sys/windows"
"golang.org/x/sys/windows/registry"
"tailscale.com/types/logger"
"tailscale.com/util/osdiag/internal/wsc"
"tailscale.com/util/winutil"
"tailscale.com/util/winutil/authenticode"
@ -34,15 +31,6 @@
initialValueBufLen = 80 // large enough to contain a stringified GUID encoded as UTF-16
)
func logSupportInfo(logf logger.Logf, reason LogSupportInfoReason) {
var b strings.Builder
if err := getSupportInfo(&b, reason); err != nil {
logf("error encoding support info: %v", err)
return
}
logf("%s", b.String())
}
const (
supportInfoKeyModules = "modules"
supportInfoKeyPageFile = "pageFile"
@ -51,7 +39,7 @@ func logSupportInfo(logf logger.Logf, reason LogSupportInfoReason) {
supportInfoKeyWinsockLSP = "winsockLSP"
)
func getSupportInfo(w io.Writer, reason LogSupportInfoReason) error {
func supportInfo(reason LogSupportInfoReason) map[string]any {
output := make(map[string]any)
regInfo, err := getRegistrySupportInfo(registry.LOCAL_MACHINE, []string{winutil.RegPolicyBase, winutil.RegBase})
@ -86,8 +74,7 @@ func getSupportInfo(w io.Writer, reason LogSupportInfoReason) error {
}
}
enc := json.NewEncoder(w)
return enc.Encode(output)
return output
}
type getRegistrySupportInfoBufs struct {