[client] Add debug for duration option to netbird ui (#3772)

This commit is contained in:
Viktor Liu
2025-05-01 23:25:27 +02:00
committed by GitHub
parent 7b64953eed
commit 01c3719c5d
5 changed files with 586 additions and 102 deletions

View File

@@ -54,11 +54,14 @@ func main() {
daemonAddr, showSettings, showNetworks, showDebug, errorMsg, saveLogsInFile := parseFlags()
// Initialize file logging if needed.
var logFile string
if saveLogsInFile {
if err := initLogFile(); err != nil {
file, err := initLogFile()
if err != nil {
log.Errorf("error while initializing log: %v", err)
return
}
logFile = file
}
// Create the Fyne application.
@@ -72,7 +75,7 @@ func main() {
}
// Create the service client (this also builds the settings or networks UI if requested).
client := newServiceClient(daemonAddr, a, showSettings, showNetworks, showDebug)
client := newServiceClient(daemonAddr, logFile, a, showSettings, showNetworks, showDebug)
// Watch for theme/settings changes to update the icon.
go watchSettingsChanges(a, client)
@@ -115,9 +118,9 @@ func parseFlags() (daemonAddr string, showSettings, showNetworks, showDebug bool
}
// initLogFile initializes logging into a file.
func initLogFile() error {
func initLogFile() (string, error) {
logFile := path.Join(os.TempDir(), fmt.Sprintf("netbird-ui-%d.log", os.Getpid()))
return util.InitLog("trace", logFile)
return logFile, util.InitLog("trace", logFile)
}
// watchSettingsChanges listens for Fyne theme/settings changes and updates the client icon.
@@ -160,9 +163,10 @@ var iconConnectingMacOS []byte
var iconErrorMacOS []byte
type serviceClient struct {
ctx context.Context
addr string
conn proto.DaemonServiceClient
ctx context.Context
cancel context.CancelFunc
addr string
conn proto.DaemonServiceClient
icAbout []byte
icConnected []byte
@@ -224,12 +228,13 @@ type serviceClient struct {
updateIndicationLock sync.Mutex
isUpdateIconActive bool
showNetworks bool
wRoutes fyne.Window
wNetworks fyne.Window
eventManager *event.Manager
exitNodeMu sync.Mutex
mExitNodeItems []menuHandler
logFile string
}
type menuHandler struct {
@@ -240,11 +245,14 @@ type menuHandler struct {
// newServiceClient instance constructor
//
// This constructor also builds the UI elements for the settings window.
func newServiceClient(addr string, a fyne.App, showSettings bool, showNetworks bool, showDebug bool) *serviceClient {
func newServiceClient(addr string, logFile string, a fyne.App, showSettings bool, showNetworks bool, showDebug bool) *serviceClient {
ctx, cancel := context.WithCancel(context.Background())
s := &serviceClient{
ctx: context.Background(),
ctx: ctx,
cancel: cancel,
addr: addr,
app: a,
logFile: logFile,
sendNotification: false,
showAdvancedSettings: showSettings,
@@ -256,9 +264,7 @@ func newServiceClient(addr string, a fyne.App, showSettings bool, showNetworks b
switch {
case showSettings:
s.showSettingsUI()
return s
case showNetworks:
s.showNetworksUI()
case showDebug:
@@ -309,6 +315,8 @@ func (s *serviceClient) updateIcon() {
func (s *serviceClient) showSettingsUI() {
// add settings window UI elements.
s.wSettings = s.app.NewWindow("NetBird Settings")
s.wSettings.SetOnClosed(s.cancel)
s.iMngURL = widget.NewEntry()
s.iAdminURL = widget.NewEntry()
s.iConfigFile = widget.NewEntry()
@@ -784,7 +792,7 @@ func (s *serviceClient) onTrayReady() {
func (s *serviceClient) runSelfCommand(command, arg string) {
proc, err := os.Executable()
if err != nil {
log.Errorf("show %s failed with error: %v", command, err)
log.Errorf("Error getting executable path: %v", err)
return
}
@@ -793,14 +801,48 @@ func (s *serviceClient) runSelfCommand(command, arg string) {
fmt.Sprintf("--daemon-addr=%s", s.addr),
)
out, err := cmd.CombinedOutput()
if exitErr, ok := err.(*exec.ExitError); ok && exitErr.ExitCode() == 1 {
log.Errorf("start %s UI: %v, %s", command, err, string(out))
if out := s.attachOutput(cmd); out != nil {
defer func() {
if err := out.Close(); err != nil {
log.Errorf("Error closing log file %s: %v", s.logFile, err)
}
}()
}
log.Printf("Running command: %s --%s=%s --daemon-addr=%s", proc, command, arg, s.addr)
err = cmd.Run()
if err != nil {
var exitErr *exec.ExitError
if errors.As(err, &exitErr) {
log.Printf("Command '%s %s' failed with exit code %d", command, arg, exitErr.ExitCode())
} else {
log.Printf("Failed to start/run command '%s %s': %v", command, arg, err)
}
return
}
if len(out) != 0 {
log.Infof("command %s executed: %s", command, string(out))
log.Printf("Command '%s %s' completed successfully.", command, arg)
}
func (s *serviceClient) attachOutput(cmd *exec.Cmd) *os.File {
if s.logFile == "" {
// attach child's streams to parent's streams
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
return nil
}
out, err := os.OpenFile(s.logFile, os.O_WRONLY|os.O_APPEND, 0)
if err != nil {
log.Errorf("Failed to open log file %s: %v", s.logFile, err)
return nil
}
cmd.Stdout = out
cmd.Stderr = out
return out
}
func normalizedVersion(version string) string {
@@ -813,9 +855,7 @@ func normalizedVersion(version string) string {
// onTrayExit is called when the tray icon is closed.
func (s *serviceClient) onTrayExit() {
for _, item := range s.mExitNodeItems {
item.cancel()
}
s.cancel()
}
// getSrvClient connection to the service.
@@ -824,7 +864,7 @@ func (s *serviceClient) getSrvClient(timeout time.Duration) (proto.DaemonService
return s.conn, nil
}
ctx, cancel := context.WithTimeout(context.Background(), timeout)
ctx, cancel := context.WithTimeout(s.ctx, timeout)
defer cancel()
conn, err := grpc.DialContext(