feat: add file logging to %APPDATA%\Wraith\wraith.log for headless debugging
All checks were successful
Build & Sign Wraith / Build Windows + Sign (push) Successful in 1m5s
All checks were successful
Build & Sign Wraith / Build Windows + Sign (push) Successful in 1m5s
slog now writes to wraith.log instead of stdout. Debug-level logging enabled. ConnectSSH and UpdateConnection log credential resolution details. This lets us diagnose the pubkey auth issue without needing a console window. Check: %APPDATA%\Wraith\wraith.log after attempting a connection. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
9338fef0c2
commit
ddd214d6d8
@ -4,6 +4,7 @@ import (
|
|||||||
"database/sql"
|
"database/sql"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log/slog"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@ -311,6 +312,12 @@ func scanConnections(rows *sql.Rows) ([]Connection, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *ConnectionService) UpdateConnection(id int64, input UpdateConnectionInput) (*Connection, error) {
|
func (s *ConnectionService) UpdateConnection(id int64, input UpdateConnectionInput) (*Connection, error) {
|
||||||
|
slog.Info("UpdateConnection called",
|
||||||
|
"id", id,
|
||||||
|
"name", input.Name,
|
||||||
|
"credentialID", input.CredentialID,
|
||||||
|
"groupID", input.GroupID,
|
||||||
|
)
|
||||||
setClauses := []string{"updated_at = CURRENT_TIMESTAMP"}
|
setClauses := []string{"updated_at = CURRENT_TIMESTAMP"}
|
||||||
args := []interface{}{}
|
args := []interface{}{}
|
||||||
|
|
||||||
@ -330,9 +337,13 @@ func (s *ConnectionService) UpdateConnection(id int64, input UpdateConnectionInp
|
|||||||
setClauses = append(setClauses, "group_id = ?")
|
setClauses = append(setClauses, "group_id = ?")
|
||||||
args = append(args, *input.GroupID)
|
args = append(args, *input.GroupID)
|
||||||
}
|
}
|
||||||
if input.CredentialID != nil {
|
// Always update credential_id — nil clears it, non-nil sets it.
|
||||||
|
// Unlike other fields, credential assignment is explicit on every save.
|
||||||
setClauses = append(setClauses, "credential_id = ?")
|
setClauses = append(setClauses, "credential_id = ?")
|
||||||
|
if input.CredentialID != nil {
|
||||||
args = append(args, *input.CredentialID)
|
args = append(args, *input.CredentialID)
|
||||||
|
} else {
|
||||||
|
args = append(args, nil)
|
||||||
}
|
}
|
||||||
if input.Tags != nil {
|
if input.Tags != nil {
|
||||||
tags, _ := json.Marshal(input.Tags)
|
tags, _ := json.Marshal(input.Tags)
|
||||||
|
|||||||
34
main.go
34
main.go
@ -4,6 +4,8 @@ import (
|
|||||||
"embed"
|
"embed"
|
||||||
"log"
|
"log"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
wraithapp "github.com/vstockwell/wraith/internal/app"
|
wraithapp "github.com/vstockwell/wraith/internal/app"
|
||||||
"github.com/wailsapp/wails/v3/pkg/application"
|
"github.com/wailsapp/wails/v3/pkg/application"
|
||||||
@ -16,7 +18,11 @@ var version = "dev"
|
|||||||
var assets embed.FS
|
var assets embed.FS
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
slog.Info("starting Wraith")
|
// Set up file logging so we can debug without a console window
|
||||||
|
if logFile := setupFileLogging(); logFile != nil {
|
||||||
|
defer logFile.Close()
|
||||||
|
}
|
||||||
|
slog.Info("starting Wraith", "version", version)
|
||||||
|
|
||||||
wraith, err := wraithapp.New(version)
|
wraith, err := wraithapp.New(version)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -57,3 +63,29 @@ func main() {
|
|||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// setupFileLogging configures slog to write to %APPDATA%\Wraith\wraith.log (Windows)
|
||||||
|
// or ~/.local/share/wraith/wraith.log (macOS/Linux). Returns the file handle for deferred close.
|
||||||
|
func setupFileLogging() *os.File {
|
||||||
|
var logDir string
|
||||||
|
if appData := os.Getenv("APPDATA"); appData != "" {
|
||||||
|
logDir = filepath.Join(appData, "Wraith")
|
||||||
|
} else if home, err := os.UserHomeDir(); err == nil {
|
||||||
|
logDir = filepath.Join(home, ".local", "share", "wraith")
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
os.MkdirAll(logDir, 0755)
|
||||||
|
logPath := filepath.Join(logDir, "wraith.log")
|
||||||
|
|
||||||
|
f, err := os.OpenFile(logPath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
handler := slog.NewTextHandler(f, &slog.HandlerOptions{Level: slog.LevelDebug})
|
||||||
|
slog.SetDefault(slog.New(handler))
|
||||||
|
log.SetOutput(f)
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user