diff --git a/cmd/guilds_tree.go b/cmd/guilds_tree.go index 2e0af9ca..bc7a37ac 100644 --- a/cmd/guilds_tree.go +++ b/cmd/guilds_tree.go @@ -2,7 +2,7 @@ package cmd import ( "fmt" - "log" + "log/slog" "slices" "sort" "strings" @@ -62,7 +62,7 @@ func (gt *GuildsTree) createFolderNode(folder gateway.GuildFolder) { for _, gID := range folder.GuildIDs { g, err := discordState.Cabinet.Guild(gID) if err != nil { - log.Printf("guild %v not found in state: %v\n", gID, err) + slog.Info("guild not found in state", "err", err, "guild", g) continue } @@ -113,7 +113,7 @@ func (gt *GuildsTree) createChannelNode(n *tview.TreeNode, c discord.Channel) *t if c.Type != discord.DirectMessage && c.Type != discord.GroupDM { ps, err := discordState.Permissions(c.ID, discordState.Ready().User.ID) if err != nil { - log.Println(err) + slog.Error("failed to get permissions", "err", err, "channel_id", c.ID) return nil } @@ -183,7 +183,7 @@ func (gt *GuildsTree) onSelected(n *tview.TreeNode) { case discord.GuildID: cs, err := discordState.Cabinet.Channels(ref) if err != nil { - log.Println(err) + slog.Error("failed to get channels", "err", err, "guild_id", ref) return } @@ -198,7 +198,7 @@ func (gt *GuildsTree) onSelected(n *tview.TreeNode) { c, err := discordState.Cabinet.Channel(ref) if err != nil { - log.Println(err) + slog.Error("failed to get channel", "channel_id", ref) return } @@ -209,7 +209,7 @@ func (gt *GuildsTree) onSelected(n *tview.TreeNode) { case nil: // Direct messages cs, err := discordState.PrivateChannels() if err != nil { - log.Println(err) + slog.Error("failed to get private channels", "err", err) return } diff --git a/cmd/main_flex.go b/cmd/main_flex.go index 3d4cec24..e46161bd 100644 --- a/cmd/main_flex.go +++ b/cmd/main_flex.go @@ -1,7 +1,7 @@ package cmd import ( - "log" + "log/slog" "github.com/ayn2op/discordo/internal/constants" "github.com/gdamore/tcell/v2" @@ -56,9 +56,12 @@ func (mf *MainFlex) onInputCapture(event *tcell.EventKey) *tcell.EventKey { return nil case cfg.Keys.Logout: app.Stop() + if err := keyring.Delete(constants.Name, "token"); err != nil { - log.Fatal(err) + slog.Error("failed to delete token from keyring", "err", err) + return nil } + return nil case cfg.Keys.ToggleGuildsTree: // The guilds tree is visible if the numbers of items is two. diff --git a/cmd/message_input.go b/cmd/message_input.go index ba2ddf5d..0298dc1e 100644 --- a/cmd/message_input.go +++ b/cmd/message_input.go @@ -1,7 +1,7 @@ package cmd import ( - "log" + "log/slog" "os" "os/exec" "strings" @@ -80,10 +80,11 @@ func (mi *MessageInput) send() { return } + logger := slog.With("channel_id", mainFlex.guildsTree.selectedChannelID) if mi.replyMessageIdx != -1 { ms, err := discordState.Cabinet.Messages(mainFlex.guildsTree.selectedChannelID) if err != nil { - log.Println(err) + logger.Error("failed to get messages", "err", err) return } @@ -99,13 +100,13 @@ func (mi *MessageInput) send() { go func() { if _, err := discordState.SendMessageComplex(mainFlex.guildsTree.selectedChannelID, data); err != nil { - log.Println("failed to send message:", err) + slog.Error("failed to send message", "err", err) } }() } else { go func() { if _, err := discordState.SendMessage(mainFlex.guildsTree.selectedChannelID, text); err != nil { - log.Println("failed to send message:", err) + slog.Error("failed to send message", "err", err) } }() } @@ -125,7 +126,7 @@ func (mi *MessageInput) editor() { f, err := os.CreateTemp("", constants.TmpFilePattern) if err != nil { - log.Println(err) + slog.Error("failed to create temporary file", "err", err) return } _, _ = f.WriteString(mi.GetText()) @@ -141,14 +142,14 @@ func (mi *MessageInput) editor() { app.Suspend(func() { err := cmd.Run() if err != nil { - log.Println(err) + slog.Error("failed to run command", "err", err, "command", cmd) return } }) msg, err := os.ReadFile(f.Name()) if err != nil { - log.Println(err) + slog.Error("failed to read temporary file", "err", err, "name", f.Name()) return } diff --git a/cmd/messages_text.go b/cmd/messages_text.go index a0a02049..e0abaf1f 100644 --- a/cmd/messages_text.go +++ b/cmd/messages_text.go @@ -4,7 +4,7 @@ import ( "errors" "fmt" "io" - "log" + "log/slog" "slices" "strings" "time" @@ -56,7 +56,7 @@ func newMessagesText() *MessagesText { func (mt *MessagesText) drawMsgs(cID discord.ChannelID) { ms, err := discordState.Messages(cID, uint(cfg.MessagesLimit)) if err != nil { - log.Println(err) + slog.Error("failed to get messages", "err", err, "channel_id", cID) return } @@ -200,7 +200,7 @@ func (mt *MessagesText) onInputCapture(event *tcell.EventKey) *tcell.EventKey { func (mt *MessagesText) _select(name string) { ms, err := discordState.Cabinet.Messages(mainFlex.guildsTree.selectedChannelID) if err != nil { - log.Println(err) + slog.Error("failed to get messages", "err", err, "channel_id", mainFlex.guildsTree.selectedChannelID) return } @@ -252,13 +252,13 @@ func (mt *MessagesText) _select(name string) { func (mt *MessagesText) yank() { msg, err := mt.getSelectedMessage() if err != nil { - log.Println(err) + slog.Error("failed to get selected message", "err", err) return } err = clipboard.WriteAll(msg.Content) if err != nil { - log.Println("failed to write to clipboard:", err) + slog.Error("failed to write to clipboard", "err", err) return } } @@ -266,7 +266,7 @@ func (mt *MessagesText) yank() { func (mt *MessagesText) open() { msg, err := mt.getSelectedMessage() if err != nil { - log.Println(err) + slog.Error("failed to get selected message", "err", err) return } @@ -278,7 +278,7 @@ func (mt *MessagesText) open() { for _, a := range attachments { go func() { if err := open.Start(a.URL); err != nil { - log.Println(err) + slog.Error("failed to open URL", "err", err, "url", a.URL) } }() } @@ -295,7 +295,7 @@ func (mt *MessagesText) reply(mention bool) { msg, err := mt.getSelectedMessage() if err != nil { - log.Println(err) + slog.Error("failed to get selected message", "err", err) return } @@ -309,7 +309,7 @@ func (mt *MessagesText) delete() { msg, err := mt.getSelectedMessage() if err != nil { - log.Println(err) + slog.Error("failed to get selected message", "err", err) return } @@ -330,17 +330,18 @@ func (mt *MessagesText) delete() { } if err := discordState.DeleteMessage(mainFlex.guildsTree.selectedChannelID, msg.ID, ""); err != nil { - log.Println(err) + slog.Error("failed to delete message", "err", err, "channel_id", mainFlex.guildsTree.selectedChannelID, "message_id", msg.ID) return } if err := discordState.MessageRemove(mainFlex.guildsTree.selectedChannelID, msg.ID); err != nil { - log.Println(err) + slog.Error("failed to delete message", "err", err, "channel_id", mainFlex.guildsTree.selectedChannelID, "message_id", msg.ID) + return } ms, err := discordState.Cabinet.Messages(mainFlex.guildsTree.selectedChannelID) if err != nil { - log.Println(err) + slog.Error("failed to delete message", "err", err, "channel_id", mainFlex.guildsTree.selectedChannelID) return } diff --git a/cmd/run.go b/cmd/run.go index 91dca64e..450837a9 100644 --- a/cmd/run.go +++ b/cmd/run.go @@ -1,7 +1,7 @@ package cmd import ( - "log" + "log/slog" "github.com/ayn2op/discordo/internal/config" "github.com/ayn2op/discordo/internal/logger" @@ -33,12 +33,14 @@ func Run(token string) error { lf := NewLoginForm(func(token string, err error) { if err != nil { app.Stop() - log.Fatal(err) + slog.Error("failed to login", "err", err) + return } if err := openState(token); err != nil { app.Stop() - log.Fatal(err) + slog.Error("failed to open state", "err", err) + return } app.SetRoot(mainFlex, true) diff --git a/cmd/state.go b/cmd/state.go index 711935d9..c2791e0d 100644 --- a/cmd/state.go +++ b/cmd/state.go @@ -2,7 +2,7 @@ package cmd import ( "context" - "log" + "log/slog" "runtime" "slices" @@ -45,7 +45,7 @@ func openState(token string) error { func (s *State) onRequest(r httpdriver.Request) error { req, ok := r.(*httpdriver.DefaultRequest) if ok { - log.Printf("method = %s; url = %s\n", req.Method, req.URL) + slog.Info("new HTTP request", "method", req.Method, "path", req.URL.Path) } return nil diff --git a/internal/logger/logger.go b/internal/logger/logger.go index 2874af34..be845613 100644 --- a/internal/logger/logger.go +++ b/internal/logger/logger.go @@ -1,7 +1,7 @@ package logger import ( - "log" + "log/slog" "os" "path/filepath" @@ -30,12 +30,14 @@ func Load() error { return err } - f, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY, os.ModePerm) + file, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY, os.ModePerm) if err != nil { return err } - log.SetOutput(f) - log.SetFlags(log.LstdFlags | log.Lshortfile) + l := slog.New(slog.NewTextHandler(file, &slog.HandlerOptions{ + AddSource: true, + })) + slog.SetDefault(l) return nil } diff --git a/main.go b/main.go index 71096132..54bb9960 100644 --- a/main.go +++ b/main.go @@ -2,7 +2,7 @@ package main import ( "flag" - "log" + "log/slog" "github.com/ayn2op/discordo/cmd" "github.com/ayn2op/discordo/internal/constants" @@ -10,7 +10,6 @@ import ( ) func main() { - // Declare and parse all flags first token := flag.String("token", "", "authentication token") flag.Parse() @@ -18,13 +17,13 @@ func main() { if *token == "" { t, err := keyring.Get(constants.Name, "token") if err != nil { - log.Println("failed to get token from keyring:", err) + slog.Info("failed to get token from keyring", "err", err) } else { *token = t } } if err := cmd.Run(*token); err != nil { - log.Fatal(err) + slog.Error("failed to run", "err", err) } }