From cd1999555714fb886493d2d04b6c472be55cebef Mon Sep 17 00:00:00 2001 From: Robin Jarry Date: Tue, 19 Jul 2022 22:31:51 +0200 Subject: [PATCH] logging: use level-based logger functions Do not pass logger objects around anymore. Shuffle some messages to make them consistent with the new logging API. Avoid using %v when a more specific verb exists for the argument types. The loggers are completely disabled (i.e. Sprintf is not even called) by default. They are only enabled when redirecting stdout to a file. Signed-off-by: Robin Jarry Acked-by: Moritz Poldrack --- aerc.go | 37 ++++++--------- commands/account/export-mbox.go | 21 +++++---- commands/account/import-mbox.go | 16 ++++--- commands/account/search.go | 5 ++- commands/compose/postpone.go | 4 +- commands/msg/forward.go | 5 ++- commands/msg/recall.go | 5 ++- commands/msg/unsubscribe.go | 5 ++- config/config.go | 9 ++-- config/triggers.go | 3 +- lib/crypto/crypto.go | 3 +- lib/crypto/gpg/gpg.go | 8 +--- lib/crypto/gpg/gpgbin/gpgbin.go | 33 +------------- lib/crypto/pgp/pgp.go | 11 ++--- lib/msgstore.go | 2 +- lib/socket.go | 18 +++----- lib/threadbuilder.go | 10 ++--- widgets/account-wizard.go | 3 +- widgets/account.go | 31 +++++-------- widgets/aerc.go | 23 ++++------ widgets/compose.go | 3 +- widgets/dirlist.go | 9 ++-- widgets/msglist.go | 5 +-- widgets/msgviewer.go | 5 +-- worker/imap/cache.go | 29 ++++++------ worker/imap/checkmail.go | 3 +- worker/imap/connect.go | 9 ++-- worker/imap/fetch.go | 10 ++--- worker/imap/flags.go | 10 ++--- worker/imap/idler.go | 13 +++--- worker/imap/list.go | 4 +- worker/imap/observer.go | 7 +-- worker/imap/open.go | 13 +++--- worker/imap/worker.go | 11 ++--- worker/maildir/container.go | 6 +-- worker/maildir/search.go | 5 ++- worker/maildir/worker.go | 79 ++++++++++++++++----------------- worker/mbox/worker.go | 29 ++++++------ worker/notmuch/eventhandlers.go | 4 +- worker/notmuch/lib/database.go | 15 +++---- worker/notmuch/worker.go | 54 +++++++++++----------- worker/types/worker.go | 28 +++++------- worker/worker.go | 7 +-- 43 files changed, 268 insertions(+), 342 deletions(-) diff --git a/aerc.go b/aerc.go index d43ed93..909d8e9 100644 --- a/aerc.go +++ b/aerc.go @@ -3,9 +3,6 @@ package main import ( "bytes" "fmt" - "io" - "io/ioutil" - "log" "os" "sort" "time" @@ -91,8 +88,10 @@ func getCompletions(aerc *widgets.Aerc, cmd string) []string { // set at build time var Version string -func usage() { - log.Fatal("Usage: aerc [-v] [mailto:...]") +func usage(msg string) { + fmt.Fprintln(os.Stderr, msg) + fmt.Fprintln(os.Stderr, "usage: aerc [-v] [mailto:...]") + os.Exit(1) } func setWindowTitle() { @@ -116,8 +115,7 @@ func main() { defer logging.PanicHandler() opts, optind, err := getopt.Getopts(os.Args, "v") if err != nil { - log.Print(err) - usage() + usage("error: " + err.Error()) return } for _, opt := range opts { @@ -130,7 +128,7 @@ func main() { retryExec := false args := os.Args[optind:] if len(args) > 1 { - usage() + usage("error: invalid arguments") return } else if len(args) == 1 { arg := args[0] @@ -143,20 +141,12 @@ func main() { retryExec = true } - var ( - logOut io.Writer - logger *log.Logger - ) if !isatty.IsTerminal(os.Stdout.Fd()) { - logOut = os.Stdout - } else { - logOut = ioutil.Discard - os.Stdout, _ = os.Open(os.DevNull) + logging.Init() } - logger = log.New(logOut, "", log.LstdFlags) - logger.Println("Starting up aerc") + logging.Infof("Starting up") - conf, err := config.LoadConfigFromFile(nil, logger) + conf, err := config.LoadConfigFromFile(nil) if err != nil { fmt.Fprintf(os.Stderr, "Failed to load config: %v\n", err) os.Exit(1) @@ -170,10 +160,10 @@ func main() { deferLoop := make(chan struct{}) c := crypto.New(conf.General.PgpProvider) - c.Init(logger) + c.Init() defer c.Close() - aerc = widgets.NewAerc(conf, logger, c, func(cmd []string) error { + aerc = widgets.NewAerc(conf, c, func(cmd []string) error { return execCommand(aerc, ui, cmd) }, func(cmd string) []string { return getCompletions(aerc, cmd) @@ -193,10 +183,9 @@ func main() { ui.EnableMouse() } - logger.Println("Starting Unix server") - as, err := lib.StartServer(logger) + as, err := lib.StartServer() if err != nil { - logger.Printf("Failed to start Unix server: %v (non-fatal)", err) + logging.Warnf("Failed to start Unix server: %v", err) } else { defer as.Close() as.OnMailto = aerc.Mailto diff --git a/commands/account/export-mbox.go b/commands/account/export-mbox.go index 528934e..3e86fc1 100644 --- a/commands/account/export-mbox.go +++ b/commands/account/export-mbox.go @@ -8,6 +8,7 @@ import ( "sync" "time" + "git.sr.ht/~rjarry/aerc/logging" "git.sr.ht/~rjarry/aerc/widgets" mboxer "git.sr.ht/~rjarry/aerc/worker/mbox" "git.sr.ht/~rjarry/aerc/worker/types" @@ -54,7 +55,7 @@ func (ExportMbox) Execute(aerc *widgets.Aerc, args []string) error { go func() { file, err := os.Create(filename) if err != nil { - acct.Logger().Println(args[0], err.Error()) + logging.Errorf("failed to create file: %v", err) aerc.PushError(err.Error()) return } @@ -72,28 +73,26 @@ func (ExportMbox) Execute(aerc *widgets.Aerc, args []string) error { for len(uids) > 0 { if retries > 0 { if retries > 10 { - errorMsg := fmt.Sprintln(args[0], "too many retries:", retries, "; stopping export") - acct.Logger().Println(errorMsg) - aerc.PushError(errorMsg) + errorMsg := fmt.Sprintf("too many retries: %d; stopping export", retries) + logging.Errorf(errorMsg) + aerc.PushError(args[0] + " " + errorMsg) break } sleeping := time.Duration(retries * 1e9 * 2) - acct.Logger().Println(args[0], "sleeping for", sleeping, "before retrying; retries:", retries) + logging.Debugf("sleeping for %s before retrying; retries: %d", sleeping, retries) time.Sleep(sleeping) } - acct.Logger().Println(args[0], "fetching", len(uids), "for export") + logging.Debugf("fetching %d for export", len(uids)) acct.Worker().PostAction(&types.FetchFullMessages{ Uids: uids, }, func(msg types.WorkerMessage) { switch msg := msg.(type) { case *types.Done: - acct.Logger().Println(args[0], "done") done <- true case *types.Error: - errMsg := fmt.Sprintln(args[0], "error encountered:", msg.Error.Error()) - acct.Logger().Println(errMsg) - aerc.PushError(errMsg) + logging.Errorf("failed to fetch message: %v", msg.Error) + aerc.PushError(args[0] + " error encountered: " + msg.Error.Error()) done <- false case *types.FullMessage: mu.Lock() @@ -115,7 +114,7 @@ func (ExportMbox) Execute(aerc *widgets.Aerc, args []string) error { } statusInfo := fmt.Sprintf("Exported %d of %d messages to %s.", ctr, len(store.Uids()), filename) aerc.PushStatus(statusInfo, 10*time.Second) - acct.Logger().Println(args[0], statusInfo) + logging.Infof(statusInfo) }() return nil diff --git a/commands/account/import-mbox.go b/commands/account/import-mbox.go index 1430deb..b497787 100644 --- a/commands/account/import-mbox.go +++ b/commands/account/import-mbox.go @@ -11,6 +11,7 @@ import ( "time" "git.sr.ht/~rjarry/aerc/commands" + "git.sr.ht/~rjarry/aerc/logging" "git.sr.ht/~rjarry/aerc/models" "git.sr.ht/~rjarry/aerc/widgets" mboxer "git.sr.ht/~rjarry/aerc/worker/mbox" @@ -54,7 +55,7 @@ func (ImportMbox) Execute(aerc *widgets.Aerc, args []string) error { importFolder := func() { statusInfo := fmt.Sprintln("Importing", filename, "to folder", folder) aerc.PushStatus(statusInfo, 10*time.Second) - acct.Logger().Println(args[0], statusInfo) + logging.Infof(statusInfo) f, err := os.Open(filename) if err != nil { aerc.PushError(err.Error()) @@ -77,7 +78,7 @@ func (ImportMbox) Execute(aerc *widgets.Aerc, args []string) error { var buf bytes.Buffer r, err := m.NewReader() if err != nil { - acct.Logger().Println(fmt.Sprintf("%s: could not get reader for uid %d", args[0], m.UID())) + logging.Errorf("could not get reader for uid %d", m.UID()) break } nbytes, _ := io.Copy(&buf, r) @@ -91,11 +92,11 @@ func (ImportMbox) Execute(aerc *widgets.Aerc, args []string) error { switch msg := msg.(type) { case *types.Unsupported: errMsg := fmt.Sprintf("%s: AppendMessage is unsupported", args[0]) - acct.Logger().Println(errMsg) + logging.Errorf(errMsg) aerc.PushError(errMsg) return case *types.Error: - acct.Logger().Println(args[0], msg.Error.Error()) + logging.Errorf("AppendMessage failed: %v", msg.Error) done <- false case *types.Done: atomic.AddUint32(&appended, 1) @@ -111,17 +112,18 @@ func (ImportMbox) Execute(aerc *widgets.Aerc, args []string) error { // error encountered; try to append again after a quick nap retries -= 1 sleeping := time.Duration((5 - retries) * 1e9) - acct.Logger().Println(args[0], "sleeping for", sleeping, "before append message", i, "again") + + logging.Debugf("sleeping for %s before append message %d again", sleeping, i) time.Sleep(sleeping) } case <-time.After(30 * time.Second): - acct.Logger().Println(args[0], "timed-out; appended", appended, "of", len(messages)) + logging.Warnf("timed-out; appended %d of %d", appended, len(messages)) return } } } infoStr := fmt.Sprintf("%s: imported %d of %d sucessfully.", args[0], appended, len(messages)) - acct.Logger().Println(infoStr) + logging.Infof(infoStr) aerc.SetStatus(infoStr) } diff --git a/commands/account/search.go b/commands/account/search.go index 7cae227..290aafc 100644 --- a/commands/account/search.go +++ b/commands/account/search.go @@ -5,6 +5,7 @@ import ( "strings" "git.sr.ht/~rjarry/aerc/lib/statusline" + "git.sr.ht/~rjarry/aerc/logging" "git.sr.ht/~rjarry/aerc/widgets" "git.sr.ht/~rjarry/aerc/worker/types" ) @@ -42,7 +43,7 @@ func (SearchFilter) Execute(aerc *widgets.Aerc, args []string) error { cb := func(msg types.WorkerMessage) { if _, ok := msg.(*types.Done); ok { acct.SetStatus(statusline.FilterResult(strings.Join(args, " "))) - acct.Logger().Printf("Filter results: %v", store.Uids()) + logging.Infof("Filter results: %v", store.Uids()) } } store.Sort(nil, cb) @@ -50,7 +51,7 @@ func (SearchFilter) Execute(aerc *widgets.Aerc, args []string) error { acct.SetStatus(statusline.Search("Searching...")) cb := func(uids []uint32) { acct.SetStatus(statusline.Search(strings.Join(args, " "))) - acct.Logger().Printf("Search results: %v", uids) + logging.Infof("Search results: %v", uids) store.ApplySearch(uids) // TODO: Remove when stores have multiple OnUpdate handlers acct.Messages().Invalidate() diff --git a/commands/compose/postpone.go b/commands/compose/postpone.go index 4b1e441..7469b23 100644 --- a/commands/compose/postpone.go +++ b/commands/compose/postpone.go @@ -47,7 +47,7 @@ func (Postpone) Execute(aerc *widgets.Aerc, args []string) error { return errors.New("No Postpone location configured") } - aerc.Logger().Println("Postponing mail") + logging.Infof("Postponing mail") header, err := composer.PrepareHeader() if err != nil { @@ -80,7 +80,7 @@ func (Postpone) Execute(aerc *widgets.Aerc, args []string) error { handleErr := func(err error) { aerc.PushError(err.Error()) - aerc.Logger().Println("Postponing failed:", err) + logging.Errorf("Postponing failed: %v", err) aerc.NewTab(composer, tabName) } diff --git a/commands/msg/forward.go b/commands/msg/forward.go index ad80fea..cd62417 100644 --- a/commands/msg/forward.go +++ b/commands/msg/forward.go @@ -15,6 +15,7 @@ import ( "git.sr.ht/~rjarry/aerc/lib" "git.sr.ht/~rjarry/aerc/lib/format" + "git.sr.ht/~rjarry/aerc/logging" "git.sr.ht/~rjarry/aerc/models" "git.sr.ht/~rjarry/aerc/widgets" "git.sr.ht/~rjarry/aerc/worker/types" @@ -73,7 +74,7 @@ func (forward) Execute(aerc *widgets.Aerc, args []string) error { if err != nil { return err } - acct.Logger().Println("Forwarding email " + msg.Envelope.MessageId) + logging.Infof("Forwarding email %s", msg.Envelope.MessageId) h := &mail.Header{} subject := "Fwd: " + msg.Envelope.Subject @@ -187,7 +188,7 @@ func (forward) Execute(aerc *widgets.Aerc, args []string) error { } bs, err := msg.BodyStructure.PartAtIndex(p) if err != nil { - acct.Logger().Println("forward: PartAtIndex:", err) + logging.Errorf("cannot get PartAtIndex %v: %v", p, err) continue } store.FetchBodyPart(msg.Uid, p, func(reader io.Reader) { diff --git a/commands/msg/recall.go b/commands/msg/recall.go index 3c9f0f2..477a363 100644 --- a/commands/msg/recall.go +++ b/commands/msg/recall.go @@ -13,6 +13,7 @@ import ( "github.com/pkg/errors" "git.sr.ht/~rjarry/aerc/lib" + "git.sr.ht/~rjarry/aerc/logging" "git.sr.ht/~rjarry/aerc/models" "git.sr.ht/~rjarry/aerc/widgets" "git.sr.ht/~rjarry/aerc/worker/types" @@ -69,7 +70,7 @@ func (Recall) Execute(aerc *widgets.Aerc, args []string) error { if err != nil { return errors.Wrap(err, "Recall failed") } - acct.Logger().Println("Recalling message " + msgInfo.Envelope.MessageId) + logging.Infof("Recalling message %s", msgInfo.Envelope.MessageId) composer, err := widgets.NewComposer(aerc, acct, aerc.Config(), acct.AccountConfig(), acct.Worker(), "", msgInfo.RFC822Headers, @@ -197,7 +198,7 @@ func (Recall) Execute(aerc *widgets.Aerc, args []string) error { } bs, err := msg.BodyStructure().PartAtIndex(p) if err != nil { - acct.Logger().Println("recall: PartAtIndex:", err) + logging.Infof("cannot get PartAtIndex %v: %v", p, err) continue } msg.FetchBodyPart(p, func(reader io.Reader) { diff --git a/commands/msg/unsubscribe.go b/commands/msg/unsubscribe.go index 126a23d..bec0f5c 100644 --- a/commands/msg/unsubscribe.go +++ b/commands/msg/unsubscribe.go @@ -9,6 +9,7 @@ import ( "time" "git.sr.ht/~rjarry/aerc/lib" + "git.sr.ht/~rjarry/aerc/logging" "git.sr.ht/~rjarry/aerc/models" "git.sr.ht/~rjarry/aerc/widgets" "github.com/emersion/go-message/mail" @@ -54,10 +55,10 @@ func (Unsubscribe) Execute(aerc *widgets.Aerc, args []string) error { if len(methods) == 0 { return fmt.Errorf("no methods found to unsubscribe") } - aerc.Logger().Printf("unsubscribe: found %d methods", len(methods)) + logging.Infof("unsubscribe: found %d methods", len(methods)) unsubscribe := func(method *url.URL) { - aerc.Logger().Printf("unsubscribe: trying to unsubscribe using %v", method.Scheme) + logging.Infof("unsubscribe: trying to unsubscribe using %s", method.Scheme) var err error switch strings.ToLower(method.Scheme) { case "mailto": diff --git a/config/config.go b/config/config.go index ebdee5e..22bbe2b 100644 --- a/config/config.go +++ b/config/config.go @@ -23,6 +23,7 @@ import ( "github.com/mitchellh/go-homedir" "git.sr.ht/~rjarry/aerc/lib/templates" + "git.sr.ht/~rjarry/aerc/logging" ) type GeneralConfig struct { @@ -649,7 +650,7 @@ func validatePgpProvider(section *ini.Section) error { return nil } -func LoadConfigFromFile(root *string, logger *log.Logger) (*AercConfig, error) { +func LoadConfigFromFile(root *string) (*AercConfig, error) { if root == nil { _root := path.Join(xdg.ConfigHome(), "aerc") root = &_root @@ -837,7 +838,7 @@ func LoadConfigFromFile(root *string, logger *log.Logger) (*AercConfig, error) { } if baseOnly { - err = config.LoadBinds(binds, baseSectionName, group, logger) + err = config.LoadBinds(binds, baseSectionName, group) if err != nil { return nil, err } @@ -887,7 +888,7 @@ func LoadBindingSection(sec *ini.Section) (*KeyBindings, error) { return bindings, nil } -func (config *AercConfig) LoadBinds(binds *ini.File, baseName string, baseGroup **KeyBindings, logger *log.Logger) error { +func (config *AercConfig) LoadBinds(binds *ini.File, baseName string, baseGroup **KeyBindings) error { if sec, err := binds.GetSection(baseName); err == nil { binds, err := LoadBindingSection(sec) @@ -942,7 +943,7 @@ func (config *AercConfig) LoadBinds(binds *ini.File, baseName string, baseGroup } } if !valid { - logger.Printf("Tried to define binds for unexistent account: %v\n", acctName) + logging.Warnf("binds.conf: unexistent account: %s", acctName) continue } contextualBind.ContextType = BIND_CONTEXT_ACCOUNT diff --git a/config/triggers.go b/config/triggers.go index 3005d59..daf4373 100644 --- a/config/triggers.go +++ b/config/triggers.go @@ -7,6 +7,7 @@ import ( "github.com/google/shlex" "git.sr.ht/~rjarry/aerc/lib/format" + "git.sr.ht/~rjarry/aerc/logging" "git.sr.ht/~rjarry/aerc/models" ) @@ -52,6 +53,6 @@ func (trig *TriggersConfig) ExecNewEmail(account *AccountConfig, return fmt.Sprintf(formatstr, args...), nil }) if err != nil { - fmt.Printf("Error from the new-email trigger: %s\n", err) + logging.Errorf("failed to run new-email trigger: %v", err) } } diff --git a/lib/crypto/crypto.go b/lib/crypto/crypto.go index 3c961ad..8f895b4 100644 --- a/lib/crypto/crypto.go +++ b/lib/crypto/crypto.go @@ -3,7 +3,6 @@ package crypto import ( "bytes" "io" - "log" "git.sr.ht/~rjarry/aerc/lib/crypto/gpg" "git.sr.ht/~rjarry/aerc/lib/crypto/pgp" @@ -17,7 +16,7 @@ type Provider interface { Encrypt(*bytes.Buffer, []string, string, openpgp.PromptFunction, *mail.Header) (io.WriteCloser, error) Sign(*bytes.Buffer, string, openpgp.PromptFunction, *mail.Header) (io.WriteCloser, error) ImportKeys(io.Reader) error - Init(*log.Logger) error + Init() error Close() GetSignerKeyId(string) (string, error) GetKeyId(string) (string, error) diff --git a/lib/crypto/gpg/gpg.go b/lib/crypto/gpg/gpg.go index 00125ba..e545e1c 100644 --- a/lib/crypto/gpg/gpg.go +++ b/lib/crypto/gpg/gpg.go @@ -3,7 +3,6 @@ package gpg import ( "bytes" "io" - "log" "os/exec" "git.sr.ht/~rjarry/aerc/lib/crypto/gpg/gpgbin" @@ -13,12 +12,9 @@ import ( ) // Mail satisfies the PGPProvider interface in aerc -type Mail struct { - logger *log.Logger -} +type Mail struct{} -func (m *Mail) Init(l *log.Logger) error { - m.logger = l +func (m *Mail) Init() error { _, err := exec.LookPath("gpg") return err } diff --git a/lib/crypto/gpg/gpgbin/gpgbin.go b/lib/crypto/gpg/gpgbin/gpgbin.go index 9f79e97..2eb83dc 100644 --- a/lib/crypto/gpg/gpgbin/gpgbin.go +++ b/lib/crypto/gpg/gpgbin/gpgbin.go @@ -6,15 +6,12 @@ import ( "errors" "fmt" "io" - "io/ioutil" - "log" - "os" "os/exec" "strconv" "strings" + "git.sr.ht/~rjarry/aerc/logging" "git.sr.ht/~rjarry/aerc/models" - "github.com/mattn/go-isatty" ) // gpg represents a gpg command with buffers attached to stdout and stderr @@ -112,17 +109,6 @@ func longKeyToUint64(key string) (uint64, error) { // parse parses the output of gpg --status-fd func parse(r io.Reader, md *models.MessageDetails) error { - var ( - logOut io.Writer - logger *log.Logger - ) - if !isatty.IsTerminal(os.Stdout.Fd()) { - logOut = os.Stdout - } else { - logOut = ioutil.Discard - os.Stdout, _ = os.Open(os.DevNull) - } - logger = log.New(logOut, "", log.LstdFlags) var err error var msgContent []byte var msgCollecting bool @@ -135,7 +121,7 @@ func parse(r io.Reader, md *models.MessageDetails) error { } if strings.HasPrefix(line, "[GNUPG:]") { msgCollecting = false - logger.Println(line) + logging.Debugf(line) } if msgCollecting { msgContent = append(msgContent, scanner.Bytes()...) @@ -270,18 +256,3 @@ var micalgs = map[int]string{ 10: "pgp-sha512", 11: "pgp-sha224", } - -func logger(s string) { - var ( - logOut io.Writer - logger *log.Logger - ) - if !isatty.IsTerminal(os.Stdout.Fd()) { - logOut = os.Stdout - } else { - logOut = ioutil.Discard - os.Stdout, _ = os.Open(os.DevNull) - } - logger = log.New(logOut, "", log.LstdFlags) - logger.Println(s) -} diff --git a/lib/crypto/pgp/pgp.go b/lib/crypto/pgp/pgp.go index 4dbe37c..647b091 100644 --- a/lib/crypto/pgp/pgp.go +++ b/lib/crypto/pgp/pgp.go @@ -5,12 +5,12 @@ import ( "fmt" "io" "io/ioutil" - "log" "os" "path" "strings" "time" + "git.sr.ht/~rjarry/aerc/logging" "git.sr.ht/~rjarry/aerc/models" "github.com/ProtonMail/go-crypto/openpgp" "github.com/ProtonMail/go-crypto/openpgp/armor" @@ -21,9 +21,7 @@ import ( "github.com/pkg/errors" ) -type Mail struct { - logger *log.Logger -} +type Mail struct{} var ( Keyring openpgp.EntityList @@ -31,9 +29,8 @@ var ( locked bool ) -func (m *Mail) Init(l *log.Logger) error { - m.logger = l - m.logger.Println("Initializing PGP keyring") +func (m *Mail) Init() error { + logging.Infof("Initializing PGP keyring") os.MkdirAll(path.Join(xdg.DataHome(), "aerc"), 0700) lockpath := path.Join(xdg.DataHome(), "aerc", "keyring.lock") diff --git a/lib/msgstore.go b/lib/msgstore.go index 240d4b7..52cd739 100644 --- a/lib/msgstore.go +++ b/lib/msgstore.go @@ -383,7 +383,7 @@ func (store *MessageStore) BuildThreads() bool { func (store *MessageStore) runThreadBuilder() { if store.builder == nil { - store.builder = NewThreadBuilder(store.worker.Logger) + store.builder = NewThreadBuilder() for _, msg := range store.Messages { store.builder.Update(msg) } diff --git a/lib/socket.go b/lib/socket.go index 902a7be..fa36172 100644 --- a/lib/socket.go +++ b/lib/socket.go @@ -4,7 +4,6 @@ import ( "bufio" "errors" "fmt" - "log" "net" "net/url" "os" @@ -18,24 +17,21 @@ import ( ) type AercServer struct { - logger *log.Logger listener net.Listener OnMailto func(addr *url.URL) error OnMbox func(source string) error } -func StartServer(logger *log.Logger) (*AercServer, error) { +func StartServer() (*AercServer, error) { sockpath := path.Join(xdg.RuntimeDir(), "aerc.sock") // remove the socket if it already exists os.Remove(sockpath) + logging.Infof("Starting Unix server: %s", sockpath) l, err := net.Listen("unix", sockpath) if err != nil { return nil, err } - as := &AercServer{ - logger: logger, - listener: l, - } + as := &AercServer{listener: l} // TODO: stash clients and close them on exit... bleh racey go func() { defer logging.PanicHandler() @@ -45,7 +41,7 @@ func StartServer(logger *log.Logger) (*AercServer, error) { if err != nil { // TODO: Something more useful, in some cases, on wednesdays, // after 2 PM, I guess? - as.logger.Printf("Closing Unix server: %v", err) + logging.Errorf("Closing Unix server: %v", err) return } go func() { @@ -66,13 +62,13 @@ var lastId int64 = 0 // access via atomic func (as *AercServer) handleClient(conn net.Conn) { clientId := atomic.AddInt64(&lastId, 1) - as.logger.Printf("Accepted Unix connection %d", clientId) + logging.Debugf("unix:%d accepted connection", clientId) scanner := bufio.NewScanner(conn) conn.SetDeadline(time.Now().Add(1 * time.Minute)) for scanner.Scan() { conn.SetDeadline(time.Now().Add(1 * time.Minute)) msg := scanner.Text() - as.logger.Printf("unix:%d: got message %s", clientId, msg) + logging.Debugf("unix:%d got message %s", clientId, msg) if !strings.ContainsRune(msg, ':') { conn.Write([]byte("error: invalid command\n")) continue @@ -105,7 +101,7 @@ func (as *AercServer) handleClient(conn net.Conn) { } } } - as.logger.Printf("Closed Unix connection %d", clientId) + logging.Debugf("unix:%d closed connection", clientId) } func ConnectAndExec(msg string) error { diff --git a/lib/threadbuilder.go b/lib/threadbuilder.go index 334a846..59abd2f 100644 --- a/lib/threadbuilder.go +++ b/lib/threadbuilder.go @@ -1,9 +1,9 @@ package lib import ( - "log" "time" + "git.sr.ht/~rjarry/aerc/logging" "git.sr.ht/~rjarry/aerc/models" "git.sr.ht/~rjarry/aerc/worker/types" "github.com/gatherstars-com/jwz" @@ -14,15 +14,13 @@ type ThreadBuilder struct { messageidToUid map[string]uint32 seen map[uint32]bool threadedUids []uint32 - logger *log.Logger } -func NewThreadBuilder(logger *log.Logger) *ThreadBuilder { +func NewThreadBuilder() *ThreadBuilder { tb := &ThreadBuilder{ threadBlocks: make(map[uint32]jwz.Threadable), messageidToUid: make(map[string]uint32), seen: make(map[uint32]bool), - logger: logger, } return tb } @@ -58,7 +56,7 @@ func (builder *ThreadBuilder) Threads(uids []uint32) []*types.Thread { builder.RebuildUids(threads) elapsed := time.Since(start) - builder.logger.Println("ThreadBuilder:", len(threads), "threads created in", elapsed) + logging.Infof("%d threads created in %s", len(threads), elapsed) return threads } @@ -74,7 +72,7 @@ func (builder *ThreadBuilder) generateStructure(uids []uint32) jwz.Threadable { threader := jwz.NewThreader() threadStructure, err := threader.ThreadSlice(jwzThreads) if err != nil { - builder.logger.Printf("ThreadBuilder: threading operation return error: %#v", err) + logging.Errorf("failed slicing threads: %v", err) } return threadStructure } diff --git a/widgets/account-wizard.go b/widgets/account-wizard.go index b352af6..ab69139 100644 --- a/widgets/account-wizard.go +++ b/widgets/account-wizard.go @@ -534,8 +534,7 @@ func (wizard *AccountWizard) finish(tutorial bool) { } wizard.conf.Accounts = append(wizard.conf.Accounts, account) - view, err := NewAccountView(wizard.aerc, wizard.conf, &account, - wizard.aerc.logger, wizard.aerc, nil) + view, err := NewAccountView(wizard.aerc, wizard.conf, &account, wizard.aerc, nil) if err != nil { wizard.aerc.NewTab(errorScreen(err.Error(), wizard.conf.Ui), account.Name) diff --git a/widgets/account.go b/widgets/account.go index c76b6fc..93a277d 100644 --- a/widgets/account.go +++ b/widgets/account.go @@ -3,7 +3,6 @@ package widgets import ( "errors" "fmt" - "log" "time" "github.com/gdamore/tcell/v2" @@ -29,7 +28,6 @@ type AccountView struct { labels []string grid *ui.Grid host TabHost - logger *log.Logger msglist *MessageList worker *types.Worker state *statusline.State @@ -45,7 +43,7 @@ func (acct *AccountView) UiConfig() *config.UIConfig { } func NewAccountView(aerc *Aerc, conf *config.AercConfig, acct *config.AccountConfig, - logger *log.Logger, host TabHost, deferLoop chan struct{}, + host TabHost, deferLoop chan struct{}, ) (*AccountView, error) { acctUiConf := conf.GetUiConfig(map[config.ContextType]string{ config.UI_CONTEXT_ACCOUNT: acct.Name, @@ -56,7 +54,6 @@ func NewAccountView(aerc *Aerc, conf *config.AercConfig, acct *config.AccountCon aerc: aerc, conf: conf, host: host, - logger: logger, state: statusline.NewState(acct.Name, len(conf.Accounts) > 1, conf.Statusline), uiConf: acctUiConf, } @@ -70,20 +67,20 @@ func NewAccountView(aerc *Aerc, conf *config.AercConfig, acct *config.AccountCon {Strategy: ui.SIZE_WEIGHT, Size: ui.Const(1)}, }) - worker, err := worker.NewWorker(acct.Source, logger) + worker, err := worker.NewWorker(acct.Source) if err != nil { host.SetError(fmt.Sprintf("%s: %s", acct.Name, err)) - logger.Printf("%s: %s\n", acct.Name, err) + logging.Errorf("%s: %v", acct.Name, err) return view, err } view.worker = worker - view.dirlist = NewDirectoryList(conf, acct, logger, worker) + view.dirlist = NewDirectoryList(conf, acct, worker) if acctUiConf.SidebarWidth > 0 { view.grid.AddChild(ui.NewBordered(view.dirlist, ui.BORDER_RIGHT, acctUiConf)) } - view.msglist = NewMessageList(conf, logger, aerc) + view.msglist = NewMessageList(conf, aerc) view.grid.AddChild(view.msglist).At(0, 1) go func() { @@ -134,7 +131,7 @@ func (acct *AccountView) UpdateStatus() { } func (acct *AccountView) PushStatus(status string, expiry time.Duration) { - acct.aerc.PushStatus(fmt.Sprintf("%s: %v", acct.acct.Name, status), expiry) + acct.aerc.PushStatus(fmt.Sprintf("%s: %s", acct.acct.Name, status), expiry) } func (acct *AccountView) PushError(err error) { @@ -149,10 +146,6 @@ func (acct *AccountView) Worker() *types.Worker { return acct.worker } -func (acct *AccountView) Logger() *log.Logger { - return acct.logger -} - func (acct *AccountView) Name() string { return acct.acct.Name } @@ -243,7 +236,7 @@ func (acct *AccountView) onMessage(msg types.WorkerMessage) { switch msg.InResponseTo().(type) { case *types.Connect, *types.Reconnect: acct.SetStatus(statusline.ConnectionActivity("Listing mailboxes...")) - acct.logger.Println("Listing mailboxes...") + logging.Debugf("Listing mailboxes...") acct.dirlist.UpdateList(func(dirs []string) { var dir string for _, _dir := range dirs { @@ -259,14 +252,14 @@ func (acct *AccountView) onMessage(msg types.WorkerMessage) { acct.dirlist.Select(dir) } acct.msglist.SetInitDone() - acct.logger.Println("Connected.") + logging.Infof("%s connected.", acct.acct.Name) acct.SetStatus(statusline.SetConnected(true)) acct.newConn = true }) case *types.Disconnect: acct.dirlist.ClearList() acct.msglist.SetStore(nil) - acct.logger.Println("Disconnected.") + logging.Infof("%s disconnected.", acct.acct.Name) acct.SetStatus(statusline.SetConnected(false)) case *types.OpenDirectory: if store, ok := acct.dirlist.SelectedMsgStore(); ok { @@ -371,13 +364,13 @@ func (acct *AccountView) onMessage(msg types.WorkerMessage) { case *types.LabelList: acct.labels = msg.Labels case *types.ConnError: - acct.logger.Printf("connection error: [%s] %v", acct.acct.Name, msg.Error) + logging.Errorf("%s connection error: %v", acct.acct.Name, msg.Error) acct.SetStatus(statusline.SetConnected(false)) acct.PushError(msg.Error) acct.msglist.SetStore(nil) acct.worker.PostAction(&types.Reconnect{}, nil) case *types.Error: - acct.logger.Printf("%v", msg.Error) + logging.Errorf("%s unexpected error: %v", acct.acct.Name, msg.Error) acct.PushError(msg.Error) } acct.UpdateStatus() @@ -401,7 +394,7 @@ func (acct *AccountView) CheckMail() { dirs := acct.dirlist.List() dirs = acct.dirlist.FilterDirs(dirs, acct.AccountConfig().CheckMailInclude, false) dirs = acct.dirlist.FilterDirs(dirs, exclude, true) - acct.logger.Printf("Checking for new mail on account %s", acct.Name()) + logging.Infof("Checking for new mail on account %s", acct.Name()) acct.SetStatus(statusline.ConnectionActivity("Checking for new mail...")) msg := &types.CheckMail{ Directories: dirs, diff --git a/widgets/aerc.go b/widgets/aerc.go index c56c4df..68144aa 100644 --- a/widgets/aerc.go +++ b/widgets/aerc.go @@ -4,7 +4,6 @@ import ( "errors" "fmt" "io" - "log" "net/url" "strings" "time" @@ -18,6 +17,7 @@ import ( "git.sr.ht/~rjarry/aerc/lib" "git.sr.ht/~rjarry/aerc/lib/crypto" "git.sr.ht/~rjarry/aerc/lib/ui" + "git.sr.ht/~rjarry/aerc/logging" "git.sr.ht/~rjarry/aerc/models" ) @@ -29,7 +29,6 @@ type Aerc struct { conf *config.AercConfig focused ui.Interactive grid *ui.Grid - logger *log.Logger simulating int statusbar *ui.Stack statusline *StatusLine @@ -49,7 +48,7 @@ type Choice struct { Command []string } -func NewAerc(conf *config.AercConfig, logger *log.Logger, +func NewAerc(conf *config.AercConfig, crypto crypto.Provider, cmd func(cmd []string) error, complete func(cmd string) []string, cmdHistory lib.History, deferLoop chan struct{}) *Aerc { @@ -77,7 +76,6 @@ func NewAerc(conf *config.AercConfig, logger *log.Logger, cmdHistory: cmdHistory, complete: complete, grid: grid, - logger: logger, statusbar: statusbar, statusline: statusline, prompts: ui.NewStack(conf.Ui), @@ -89,7 +87,7 @@ func NewAerc(conf *config.AercConfig, logger *log.Logger, conf.Triggers.ExecuteCommand = cmd for i, acct := range conf.Accounts { - view, err := NewAccountView(aerc, conf, &conf.Accounts[i], logger, aerc, deferLoop) + view, err := NewAccountView(aerc, conf, &conf.Accounts[i], aerc, deferLoop) if err != nil { tabs.Add(errorScreen(err.Error(), conf.Ui), acct.Name, nil) } else { @@ -136,11 +134,11 @@ func (aerc *Aerc) OnBeep(f func() error) { func (aerc *Aerc) Beep() { if aerc.beep == nil { - aerc.logger.Printf("should beep, but no beeper") + logging.Warnf("should beep, but no beeper") return } if err := aerc.beep(); err != nil { - aerc.logger.Printf("tried to beep, but could not: %v", err) + logging.Errorf("tried to beep, but could not: %v", err) } } @@ -311,10 +309,6 @@ func (aerc *Aerc) Config() *config.AercConfig { return aerc.conf } -func (aerc *Aerc) Logger() *log.Logger { - return aerc.logger -} - func (aerc *Aerc) SelectedAccount() *AccountView { return aerc.account(aerc.SelectedTabContent()) } @@ -616,7 +610,7 @@ func (aerc *Aerc) Mbox(source string) error { acctConf = *selectedAcct.acct info := fmt.Sprintf("Loading outgoing mbox mail settings from account [%s]", selectedAcct.Name()) aerc.PushStatus(info, 10*time.Second) - aerc.Logger().Println(info) + logging.Infof(info) } else { acctConf.From = "" } @@ -627,7 +621,7 @@ func (aerc *Aerc) Mbox(source string) error { acctConf.Postpone = "Drafts" acctConf.CopyTo = "Sent" - mboxView, err := NewAccountView(aerc, aerc.conf, &acctConf, aerc.logger, aerc, nil) + mboxView, err := NewAccountView(aerc, aerc.conf, &acctConf, aerc, nil) if err != nil { aerc.NewTab(errorScreen(err.Error(), aerc.conf.Ui), acctConf.Name) } else { @@ -648,8 +642,7 @@ func (aerc *Aerc) CloseBackends() error { err := c.Close() if err != nil { returnErr = err - aerc.logger.Printf("Closing backend failed for %v: %v\n", - acct.Name(), err) + logging.Errorf("Closing backend failed for %s: %v", acct.Name(), err) } } return returnErr diff --git a/widgets/compose.go b/widgets/compose.go index 87331bd..a4ed27c 100644 --- a/widgets/compose.go +++ b/widgets/compose.go @@ -23,6 +23,7 @@ import ( "git.sr.ht/~rjarry/aerc/lib/format" "git.sr.ht/~rjarry/aerc/lib/templates" "git.sr.ht/~rjarry/aerc/lib/ui" + "git.sr.ht/~rjarry/aerc/logging" "git.sr.ht/~rjarry/aerc/models" "git.sr.ht/~rjarry/aerc/worker/types" ) @@ -89,7 +90,7 @@ func NewComposer(aerc *Aerc, acct *AccountView, conf *config.AercConfig, cmpl := completer.New(cmd, func(err error) { aerc.PushError( fmt.Sprintf("could not complete header: %v", err)) - worker.Logger.Printf("could not complete header: %v", err) + logging.Errorf("could not complete header: %v", err) }) email, err := ioutil.TempFile("", "aerc-compose-*.eml") diff --git a/widgets/dirlist.go b/widgets/dirlist.go index 5c3416c..2047c30 100644 --- a/widgets/dirlist.go +++ b/widgets/dirlist.go @@ -3,7 +3,6 @@ package widgets import ( "context" "fmt" - "log" "math" "os" "regexp" @@ -55,7 +54,6 @@ type DirectoryList struct { acctConf *config.AccountConfig store *lib.DirStore dirs []string - logger *log.Logger selecting string selected string spinner *Spinner @@ -67,7 +65,7 @@ type DirectoryList struct { } func NewDirectoryList(conf *config.AercConfig, acctConf *config.AccountConfig, - logger *log.Logger, worker *types.Worker, + worker *types.Worker, ) DirectoryLister { ctx, cancel := context.WithCancel(context.Background()) @@ -76,7 +74,6 @@ func NewDirectoryList(conf *config.AercConfig, acctConf *config.AccountConfig, dirlist := &DirectoryList{ aercConf: conf, acctConf: acctConf, - logger: logger, store: lib.NewDirStore(), worker: worker, skipSelect: ctx, @@ -202,7 +199,7 @@ func (dirlist *DirectoryList) Select(name string) { }) dirlist.Invalidate() case <-ctx.Done(): - dirlist.logger.Println("dirlist: skip", name) + logging.Debugf("dirlist: skip %s", name) return } }(ctx) @@ -531,7 +528,7 @@ func (dirlist *DirectoryList) getSortCriteria() []*types.SortCriterion { } criteria, err := libsort.GetSortCriteria(dirlist.UiConfig().Sort) if err != nil { - dirlist.logger.Printf("getSortCriteria failed: %v", err) + logging.Errorf("getSortCriteria failed: %v", err) return nil } return criteria diff --git a/widgets/msglist.go b/widgets/msglist.go index e9603ca..a190c18 100644 --- a/widgets/msglist.go +++ b/widgets/msglist.go @@ -2,7 +2,6 @@ package widgets import ( "fmt" - "log" "math" "strings" @@ -22,7 +21,6 @@ type MessageList struct { ui.Invalidatable Scrollable conf *config.AercConfig - logger *log.Logger height int nmsgs int spinner *Spinner @@ -31,10 +29,9 @@ type MessageList struct { aerc *Aerc } -func NewMessageList(conf *config.AercConfig, logger *log.Logger, aerc *Aerc) *MessageList { +func NewMessageList(conf *config.AercConfig, aerc *Aerc) *MessageList { ml := &MessageList{ conf: conf, - logger: logger, spinner: NewSpinner(&conf.Ui), isInitalizing: true, aerc: aerc, diff --git a/widgets/msgviewer.go b/widgets/msgviewer.go index 59384d4..eec786c 100644 --- a/widgets/msgviewer.go +++ b/widgets/msgviewer.go @@ -229,7 +229,7 @@ func createSwitcher(acct *AccountView, switcher *PartSwitcher, return err } selectedPriority := -1 - fmt.Printf("Selecting best message from %v\n", conf.Viewer.Alternatives) + logging.Infof("Selecting best message from %v", conf.Viewer.Alternatives) for i, pv := range switcher.parts { pv.OnInvalidate(func(_ ui.Drawable) { switcher.Invalidate() @@ -312,8 +312,7 @@ func (mv *MessageViewer) ToggleHeaders() { mv.conf.Viewer.ShowHeaders = !mv.conf.Viewer.ShowHeaders err := createSwitcher(mv.acct, switcher, mv.conf, mv.msg) if err != nil { - mv.acct.Logger().Printf( - "warning: error during create switcher - %v", err) + logging.Errorf("cannot create switcher: %v", err) } switcher.Invalidate() } diff --git a/worker/imap/cache.go b/worker/imap/cache.go index ecbedd8..863b071 100644 --- a/worker/imap/cache.go +++ b/worker/imap/cache.go @@ -9,6 +9,7 @@ import ( "path" "time" + "git.sr.ht/~rjarry/aerc/logging" "git.sr.ht/~rjarry/aerc/models" "git.sr.ht/~rjarry/aerc/worker/types" "github.com/emersion/go-message" @@ -33,18 +34,18 @@ func (w *IMAPWorker) initCacheDb(acct string) { cd, err := cacheDir() if err != nil { w.cache = nil - w.worker.Logger.Panicf("cache: unable to find cache directory: %v", err) + logging.Errorf("unable to find cache directory: %v", err) return } p := path.Join(cd, acct) db, err := leveldb.OpenFile(p, nil) if err != nil { w.cache = nil - w.worker.Logger.Printf("cache: error opening cache db: %v", err) + logging.Errorf("failed opening cache db: %v", err) return } w.cache = db - w.worker.Logger.Printf("cache: cache db opened: %s", p) + logging.Infof("cache db opened: %s", p) if w.config.cacheMaxAge.Hours() > 0 { go w.cleanCache() } @@ -53,11 +54,11 @@ func (w *IMAPWorker) initCacheDb(acct string) { func (w *IMAPWorker) cacheHeader(mi *models.MessageInfo) { uv := fmt.Sprintf("%d", w.selected.UidValidity) uid := fmt.Sprintf("%d", mi.Uid) - w.worker.Logger.Printf("cache: caching header for message %s.%s", uv, uid) + logging.Debugf("caching header for message %s.%s", uv, uid) hdr := bytes.NewBuffer(nil) err := textproto.WriteHeader(hdr, mi.RFC822Headers.Header.Header) if err != nil { - w.worker.Logger.Printf("cache: error writing header %s.%s: %v", uv, uid, err) + logging.Errorf("cannot write header %s.%s: %v", uv, uid, err) return } h := &CachedHeader{ @@ -72,18 +73,18 @@ func (w *IMAPWorker) cacheHeader(mi *models.MessageInfo) { enc := gob.NewEncoder(data) err = enc.Encode(h) if err != nil { - w.worker.Logger.Printf("cache: error encoding message %s.%s: %v", uv, uid, err) + logging.Errorf("cannot encode message %s.%s: %v", uv, uid, err) return } err = w.cache.Put([]byte("header."+uv+"."+uid), data.Bytes(), nil) if err != nil { - w.worker.Logger.Printf("cache: error writing header to database for message %s.%s: %v", uv, uid, err) + logging.Errorf("cannot write header for message %s.%s: %v", uv, uid, err) return } } func (w *IMAPWorker) getCachedHeaders(msg *types.FetchMessageHeaders) []uint32 { - w.worker.Logger.Println("Retrieving headers from cache") + logging.Debugf("Retrieving headers from cache: %v", msg.Uids) var need, found []uint32 uv := fmt.Sprintf("%d", w.selected.UidValidity) for _, uid := range msg.Uids { @@ -97,14 +98,14 @@ func (w *IMAPWorker) getCachedHeaders(msg *types.FetchMessageHeaders) []uint32 { dec := gob.NewDecoder(bytes.NewReader(data)) err = dec.Decode(ch) if err != nil { - w.worker.Logger.Printf("cache: error decoding cached header %s.%s: %v", uv, u, err) + logging.Errorf("cannot decode cached header %s.%s: %v", uv, u, err) need = append(need, uid) continue } hr := bytes.NewReader(ch.Header) textprotoHeader, err := textproto.ReadHeader(bufio.NewReader(hr)) if err != nil { - w.worker.Logger.Printf("cache: error reading cached header %s.%s: %v", uv, u, err) + logging.Errorf("cannot read cached header %s.%s: %v", uv, u, err) need = append(need, uid) continue } @@ -118,7 +119,7 @@ func (w *IMAPWorker) getCachedHeaders(msg *types.FetchMessageHeaders) []uint32 { RFC822Headers: hdr, } found = append(found, uid) - w.worker.Logger.Printf("cache: located cached header %s.%s", uv, u) + logging.Debugf("located cached header %s.%s", uv, u) w.worker.PostMessage(&types.MessageInfo{ Message: types.RespondTo(msg), Info: mi, @@ -154,14 +155,14 @@ func (w *IMAPWorker) cleanCache() { dec := gob.NewDecoder(bytes.NewReader(data)) err := dec.Decode(ch) if err != nil { - w.worker.Logger.Printf("cache: error cleaning database %d: %v", w.selected.UidValidity, err) + logging.Errorf("cannot clean database %d: %v", w.selected.UidValidity, err) continue } exp := ch.Created.Add(w.config.cacheMaxAge) if exp.Before(time.Now()) { err = w.cache.Delete(iter.Key(), nil) if err != nil { - w.worker.Logger.Printf("cache: error cleaning database %d: %v", w.selected.UidValidity, err) + logging.Errorf("cannot clean database %d: %v", w.selected.UidValidity, err) continue } removed = removed + 1 @@ -170,5 +171,5 @@ func (w *IMAPWorker) cleanCache() { } iter.Release() elapsed := time.Since(start) - w.worker.Logger.Printf("cache: cleaned cache, removed %d of %d entries in %f seconds", removed, scanned, elapsed.Seconds()) + logging.Infof("cleaned cache, removed %d of %d entries in %s", removed, scanned, elapsed) } diff --git a/worker/imap/checkmail.go b/worker/imap/checkmail.go index 57af3af..21f2e4b 100644 --- a/worker/imap/checkmail.go +++ b/worker/imap/checkmail.go @@ -1,6 +1,7 @@ package imap import ( + "git.sr.ht/~rjarry/aerc/logging" "git.sr.ht/~rjarry/aerc/models" "git.sr.ht/~rjarry/aerc/worker/types" "github.com/emersion/go-imap" @@ -13,7 +14,7 @@ func (w *IMAPWorker) handleCheckMailMessage(msg *types.CheckMail) { imap.StatusUnseen, } for _, dir := range msg.Directories { - w.worker.Logger.Printf("Getting status of directory %s", dir) + logging.Debugf("Getting status of directory %s", dir) status, err := w.client.Status(dir, items) if err != nil { w.worker.PostMessage(&types.Error{ diff --git a/worker/imap/connect.go b/worker/imap/connect.go index 2581c6d..5f8cd1c 100644 --- a/worker/imap/connect.go +++ b/worker/imap/connect.go @@ -7,6 +7,7 @@ import ( "time" "git.sr.ht/~rjarry/aerc/lib" + "git.sr.ht/~rjarry/aerc/logging" "github.com/emersion/go-imap" "github.com/emersion/go-imap/client" ) @@ -66,7 +67,7 @@ func (w *IMAPWorker) connect() (*client.Client, error) { return nil, fmt.Errorf("Unknown IMAP scheme %s", w.config.scheme) } - c.ErrorLog = w.worker.Logger + c.ErrorLog = logging.ErrorLogger() if w.config.user != nil { username := w.config.user.Username() @@ -162,14 +163,12 @@ func (w *IMAPWorker) setKeepaliveParameters(conn *net.TCPConn) error { // Max number of probes before failure err := lib.SetTcpKeepaliveProbes(fd, w.config.keepalive_probes) if err != nil { - w.worker.Logger.Printf( - "cannot set tcp keepalive probes: %v\n", err) + logging.Errorf("cannot set tcp keepalive probes: %v", err) } // Wait time after an unsuccessful probe err = lib.SetTcpKeepaliveInterval(fd, w.config.keepalive_interval) if err != nil { - w.worker.Logger.Printf( - "cannot set tcp keepalive interval: %v\n", err) + logging.Errorf("cannot set tcp keepalive interval: %v", err) } }) return err diff --git a/worker/imap/fetch.go b/worker/imap/fetch.go index cf27e38..6ef0bac 100644 --- a/worker/imap/fetch.go +++ b/worker/imap/fetch.go @@ -26,7 +26,7 @@ func (imapw *IMAPWorker) handleFetchMessageHeaders( nil) return } - imapw.worker.Logger.Printf("Fetching message headers") + logging.Infof("Fetching message headers: %v", toFetch) section := &imap.BodySectionName{ BodyPartName: imap.BodyPartName{ Specifier: imap.HeaderSpecifier, @@ -47,8 +47,8 @@ func (imapw *IMAPWorker) handleFetchMessageHeaders( reader := _msg.GetBody(section) textprotoHeader, err := textproto.ReadHeader(bufio.NewReader(reader)) if err != nil { - imapw.worker.Logger.Printf( - "message %v: could not read header: %v", _msg.Uid, err) + logging.Errorf( + "message %d: could not read header: %v", _msg.Uid, err) imapw.worker.PostMessage(&types.Error{ Message: types.RespondTo(msg), Error: err, @@ -78,7 +78,7 @@ func (imapw *IMAPWorker) handleFetchMessageHeaders( func (imapw *IMAPWorker) handleFetchMessageBodyPart( msg *types.FetchMessageBodyPart) { - imapw.worker.Logger.Printf("Fetching message part") + logging.Infof("Fetching message %d part: %v", msg.Uid, msg.Part) var partHeaderSection imap.BodySectionName partHeaderSection.Peek = true @@ -148,7 +148,7 @@ func (imapw *IMAPWorker) handleFetchMessageBodyPart( func (imapw *IMAPWorker) handleFetchFullMessages( msg *types.FetchFullMessages) { - imapw.worker.Logger.Printf("Fetching full messages") + logging.Infof("Fetching full messages: %v", msg.Uids) section := &imap.BodySectionName{} items := []imap.FetchItem{ imap.FetchEnvelope, diff --git a/worker/imap/flags.go b/worker/imap/flags.go index 2bded2a..5b2ac41 100644 --- a/worker/imap/flags.go +++ b/worker/imap/flags.go @@ -28,7 +28,7 @@ func (imapw *IMAPWorker) handleDeleteMessages(msg *types.DeleteMessages) { for seqNum := range ch { if uid, found := imapw.seqMap.Pop(seqNum); !found { - imapw.worker.Logger.Printf("handleDeleteMessages unknown seqnum: %v", seqNum) + logging.Errorf("handleDeleteMessages unknown seqnum: %d", seqNum) } else { deleted = append(deleted, uid) } @@ -73,8 +73,8 @@ func (imapw *IMAPWorker) handleAnsweredMessages(msg *types.AnsweredMessages) { }, func(_msg types.WorkerMessage) { switch m := _msg.(type) { case *types.Error: - err := fmt.Errorf("handleAnsweredMessages: %v", m.Error) - imapw.worker.Logger.Printf("could not fetch headers: %s", err) + err := fmt.Errorf("handleAnsweredMessages: %w", m.Error) + logging.Errorf("could not fetch headers: %v", err) emitErr(err) case *types.Done: imapw.worker.PostMessage(&types.Done{Message: types.RespondTo(msg)}, nil) @@ -104,8 +104,8 @@ func (imapw *IMAPWorker) handleFlagMessages(msg *types.FlagMessages) { }, func(_msg types.WorkerMessage) { switch m := _msg.(type) { case *types.Error: - err := fmt.Errorf("handleFlagMessages: %v", m.Error) - imapw.worker.Logger.Printf("could not fetch headers: %s", err) + err := fmt.Errorf("handleFlagMessages: %w", m.Error) + logging.Errorf("could not fetch headers: %v", err) emitErr(err) case *types.Done: imapw.worker.PostMessage(&types.Done{Message: types.RespondTo(msg)}, nil) diff --git a/worker/imap/idler.go b/worker/imap/idler.go index bac690f..055bab8 100644 --- a/worker/imap/idler.go +++ b/worker/imap/idler.go @@ -84,8 +84,7 @@ func (i *idler) Start() { }) i.idleing = false i.done <- err - i.log("elapsed idle time:", - time.Since(now)) + i.log("elapsed idle time: %v", time.Since(now)) } }() @@ -105,7 +104,7 @@ func (i *idler) Stop() error { if err == nil { i.log("<=(idle)") } else { - i.log("<=(idle) with err:", err) + i.log("<=(idle) with err: %v", err) } reterr = nil case <-time.After(i.config.idle_timeout): @@ -144,7 +143,7 @@ func (i *idler) waitOnIdle() { Message: types.RespondTo(&types.Connect{}), }, nil) } else { - i.log("<=(idle) waited; with err:", err) + i.log("<=(idle) waited; with err: %v", err) } i.setWaiting(false) i.stop = make(chan struct{}) @@ -155,7 +154,7 @@ func (i *idler) waitOnIdle() { }() } -func (i *idler) log(args ...interface{}) { - header := fmt.Sprintf("idler (%p) [idle:%t,wait:%t]", i, i.idleing, i.waiting) - i.worker.Logger.Println(append([]interface{}{header}, args...)...) +func (i *idler) log(format string, v ...interface{}) { + msg := fmt.Sprintf(format, v...) + logging.Debugf("idler (%p) [idle:%t,wait:%t] %s", i, i.idleing, i.waiting, msg) } diff --git a/worker/imap/list.go b/worker/imap/list.go index 026aa9a..51f4d3e 100644 --- a/worker/imap/list.go +++ b/worker/imap/list.go @@ -10,7 +10,7 @@ import ( func (imapw *IMAPWorker) handleListDirectories(msg *types.ListDirectories) { mailboxes := make(chan *imap.MailboxInfo) - imapw.worker.Logger.Println("Listing mailboxes") + logging.Infof("Listing mailboxes") done := make(chan interface{}) go func() { @@ -62,7 +62,7 @@ func (imapw *IMAPWorker) handleSearchDirectory(msg *types.SearchDirectory) { }, nil) } - imapw.worker.Logger.Println("Executing search") + logging.Infof("Executing search") criteria, err := parseSearch(msg.Argv) if err != nil { emitError(err) diff --git a/worker/imap/observer.go b/worker/imap/observer.go index e49744c..448128c 100644 --- a/worker/imap/observer.go +++ b/worker/imap/observer.go @@ -6,6 +6,7 @@ import ( "sync" "time" + "git.sr.ht/~rjarry/aerc/logging" "git.sr.ht/~rjarry/aerc/worker/types" "github.com/emersion/go-imap" ) @@ -146,7 +147,7 @@ func (o *observer) emit(errMsg string) { }, nil) } -func (o *observer) log(args ...interface{}) { - header := fmt.Sprintf("observer (%p) [running:%t]", o, o.running) - o.worker.Logger.Println(append([]interface{}{header}, args...)...) +func (o *observer) log(format string, args ...interface{}) { + msg := fmt.Sprintf(format, args...) + logging.Debugf("observer (%p) [running:%t] %s", o, o.running, msg) } diff --git a/worker/imap/open.go b/worker/imap/open.go index b52a3c6..636b936 100644 --- a/worker/imap/open.go +++ b/worker/imap/open.go @@ -5,11 +5,12 @@ import ( sortthread "github.com/emersion/go-imap-sortthread" + "git.sr.ht/~rjarry/aerc/logging" "git.sr.ht/~rjarry/aerc/worker/types" ) func (imapw *IMAPWorker) handleOpenDirectory(msg *types.OpenDirectory) { - imapw.worker.Logger.Printf("Opening %s", msg.Directory) + logging.Infof("Opening %s", msg.Directory) sel, err := imapw.client.Select(msg.Directory, false) if err != nil { @@ -26,7 +27,7 @@ func (imapw *IMAPWorker) handleOpenDirectory(msg *types.OpenDirectory) { func (imapw *IMAPWorker) handleFetchDirectoryContents( msg *types.FetchDirectoryContents) { - imapw.worker.Logger.Printf("Fetching UID list") + logging.Infof("Fetching UID list") searchCriteria, err := parseSearch(msg.FilterCriteria) if err != nil { @@ -51,7 +52,7 @@ func (imapw *IMAPWorker) handleFetchDirectoryContents( } else { if err != nil { // Non fatal, but we do want to print to get some debug info - imapw.worker.Logger.Printf("can't check for SORT support: %v", err) + logging.Errorf("can't check for SORT support: %v", err) } uids, err = imapw.client.UidSearch(searchCriteria) } @@ -61,7 +62,7 @@ func (imapw *IMAPWorker) handleFetchDirectoryContents( Error: err, }, nil) } else { - imapw.worker.Logger.Printf("Found %d UIDs", len(uids)) + logging.Infof("Found %d UIDs", len(uids)) imapw.seqMap.Clear() imapw.worker.PostMessage(&types.DirectoryContents{ Message: types.RespondTo(msg), @@ -97,7 +98,7 @@ func translateSortCriterions( func (imapw *IMAPWorker) handleDirectoryThreaded( msg *types.FetchDirectoryThreaded) { - imapw.worker.Logger.Printf("Fetching threaded UID list") + logging.Infof("Fetching threaded UID list") searchCriteria, err := parseSearch(msg.FilterCriteria) if err != nil { @@ -117,7 +118,7 @@ func (imapw *IMAPWorker) handleDirectoryThreaded( } else { aercThreads, count := convertThreads(threads, nil) sort.Sort(types.ByUID(aercThreads)) - imapw.worker.Logger.Printf("Found %d threaded messages", count) + logging.Infof("Found %d threaded messages", count) imapw.seqMap.Clear() imapw.worker.PostMessage(&types.DirectoryThreaded{ Message: types.RespondTo(msg), diff --git a/worker/imap/worker.go b/worker/imap/worker.go index 3ed646d..dee089e 100644 --- a/worker/imap/worker.go +++ b/worker/imap/worker.go @@ -12,6 +12,7 @@ import ( "github.com/syndtr/goleveldb/leveldb" "git.sr.ht/~rjarry/aerc/lib" + "git.sr.ht/~rjarry/aerc/logging" "git.sr.ht/~rjarry/aerc/models" "git.sr.ht/~rjarry/aerc/worker/handlers" "git.sr.ht/~rjarry/aerc/worker/types" @@ -89,12 +90,12 @@ func (w *IMAPWorker) newClient(c *client.Client) { sort, err := w.client.sort.SupportSort() if err == nil && sort { w.caps.Sort = true - w.worker.Logger.Println("Server Capability found: Sort") + logging.Infof("Server Capability found: Sort") } thread, err := w.client.thread.SupportThread() if err == nil && thread { w.caps.Thread = true - w.worker.Logger.Println("Server Capability found: Thread") + logging.Infof("Server Capability found: Thread") } } @@ -223,7 +224,7 @@ func (w *IMAPWorker) handleMessage(msg types.WorkerMessage) error { } func (w *IMAPWorker) handleImapUpdate(update client.Update) { - w.worker.Logger.Printf("(= %T", update) + logging.Debugf("(= %T", update) switch update := update.(type) { case *client.MailboxUpdate: status := update.Mailbox @@ -246,7 +247,7 @@ func (w *IMAPWorker) handleImapUpdate(update client.Update) { msg := update.Message if msg.Uid == 0 { if uid, found := w.seqMap.Get(msg.SeqNum); !found { - w.worker.Logger.Printf("MessageUpdate unknown seqnum: %v", msg.SeqNum) + logging.Errorf("MessageUpdate unknown seqnum: %d", msg.SeqNum) return } else { msg.Uid = uid @@ -263,7 +264,7 @@ func (w *IMAPWorker) handleImapUpdate(update client.Update) { }, nil) case *client.ExpungeUpdate: if uid, found := w.seqMap.Pop(update.SeqNum); !found { - w.worker.Logger.Printf("ExpungeUpdate unknown seqnum: %v", update.SeqNum) + logging.Errorf("ExpungeUpdate unknown seqnum: %d", update.SeqNum) } else { w.worker.PostMessage(&types.MessagesDeleted{ Uids: []uint32{uid}, diff --git a/worker/maildir/container.go b/worker/maildir/container.go index fb0b190..83f850a 100644 --- a/worker/maildir/container.go +++ b/worker/maildir/container.go @@ -2,7 +2,6 @@ package maildir import ( "fmt" - "log" "os" "path/filepath" "sort" @@ -17,14 +16,13 @@ import ( // the Maildir spec type Container struct { dir string - log *log.Logger uids *uidstore.Store recentUIDS map[uint32]struct{} // used to set the recent flag maildirpp bool // whether to use Maildir++ directory layout } // NewContainer creates a new container at the specified directory -func NewContainer(dir string, l *log.Logger, maildirpp bool) (*Container, error) { +func NewContainer(dir string, maildirpp bool) (*Container, error) { f, err := os.Open(dir) if err != nil { return nil, err @@ -37,7 +35,7 @@ func NewContainer(dir string, l *log.Logger, maildirpp bool) (*Container, error) if !s.IsDir() { return nil, fmt.Errorf("Given maildir '%s' not a directory", dir) } - return &Container{dir: dir, uids: uidstore.NewStore(), log: l, + return &Container{dir: dir, uids: uidstore.NewStore(), recentUIDS: make(map[uint32]struct{}), maildirpp: maildirpp}, nil } diff --git a/worker/maildir/search.go b/worker/maildir/search.go index 7f97fb1..b8e91df 100644 --- a/worker/maildir/search.go +++ b/worker/maildir/search.go @@ -11,6 +11,7 @@ import ( "git.sr.ht/~sircmpwn/getopt" "git.sr.ht/~rjarry/aerc/lib" + "git.sr.ht/~rjarry/aerc/logging" "git.sr.ht/~rjarry/aerc/models" ) @@ -87,7 +88,7 @@ func getParsedFlag(name string) maildir.Flag { func (w *Worker) search(criteria *searchCriteria) ([]uint32, error) { requiredParts := getRequiredParts(criteria) - w.worker.Logger.Printf("Required parts bitmask for search: %b", requiredParts) + logging.Infof("Required parts bitmask for search: %b", requiredParts) keys, err := w.c.UIDs(*w.selected) if err != nil { @@ -99,7 +100,7 @@ func (w *Worker) search(criteria *searchCriteria) ([]uint32, error) { success, err := w.searchKey(key, criteria, requiredParts) if err != nil { // don't return early so that we can still get some results - w.worker.Logger.Printf("Failed to search key %v: %v", key, err) + logging.Errorf("Failed to search key %d: %v", key, err) } else if success { matchedUids = append(matchedUids, key) } diff --git a/worker/maildir/worker.go b/worker/maildir/worker.go index 222b672..ec34455 100644 --- a/worker/maildir/worker.go +++ b/worker/maildir/worker.go @@ -17,6 +17,7 @@ import ( "github.com/emersion/go-maildir" "github.com/fsnotify/fsnotify" + "git.sr.ht/~rjarry/aerc/logging" "git.sr.ht/~rjarry/aerc/models" "git.sr.ht/~rjarry/aerc/worker/handlers" "git.sr.ht/~rjarry/aerc/worker/lib" @@ -109,18 +110,18 @@ func (w *Worker) handleFSEvent(ev fsnotify.Event) { } err := w.c.SyncNewMail(*w.selected) if err != nil { - w.worker.Logger.Printf("could not move new to cur : %v", err) + logging.Errorf("could not move new to cur : %v", err) return } uids, err := w.c.UIDs(*w.selected) if err != nil { - w.worker.Logger.Printf("could not scan UIDs: %v", err) + logging.Errorf("could not scan UIDs: %v", err) return } sortedUids, err := w.sort(uids, w.currentSortCriteria) if err != nil { - w.worker.Logger.Printf("error sorting directory: %v", err) + logging.Errorf("error sorting directory: %v", err) return } w.worker.PostMessage(&types.DirectoryContents{ @@ -201,18 +202,18 @@ func (w *Worker) getDirectoryInfo(name string) *models.DirectoryInfo { for _, v := range files { key, flags, err := splitMaildirFile(v) if err != nil { - w.worker.Logger.Printf("%q: error parsing flags (%q): %v", v, key, err) + logging.Errorf("%q: error parsing flags (%q): %v", v, key, err) continue } keyFlags[key] = flags } } else { - w.worker.Logger.Printf("disabled flags cache: %q: %v", dir, err) + logging.Infof("disabled flags cache: %q: %v", dir, err) } uids, err := w.c.UIDs(dir) if err != nil { - w.worker.Logger.Printf("could not get uids: %v", err) + logging.Errorf("could not get uids: %v", err) return dirInfo } @@ -220,7 +221,7 @@ func (w *Worker) getDirectoryInfo(name string) *models.DirectoryInfo { for _, uid := range uids { message, err := w.c.Message(dir, uid) if err != nil { - w.worker.Logger.Printf("could not get message: %v", err) + logging.Errorf("could not get message: %v", err) continue } var flags []maildir.Flag @@ -228,17 +229,17 @@ func (w *Worker) getDirectoryInfo(name string) *models.DirectoryInfo { ok := false flags, ok = keyFlags[message.key] if !ok { - w.worker.Logger.Printf("message (key=%q uid=%d) not found in map cache", message.key, message.uid) + logging.Debugf("message (key=%q uid=%d) not found in map cache", message.key, message.uid) flags, err = message.Flags() if err != nil { - w.worker.Logger.Printf("could not get flags: %v", err) + logging.Errorf("could not get flags: %v", err) continue } } } else { flags, err = message.Flags() if err != nil { - w.worker.Logger.Printf("could not get flags: %v", err) + logging.Errorf("could not get flags: %v", err) continue } } @@ -303,7 +304,7 @@ func (w *Worker) handleMessage(msg types.WorkerMessage) error { func (w *Worker) handleConfigure(msg *types.Configure) error { u, err := url.Parse(msg.Config.Source) if err != nil { - w.worker.Logger.Printf("error configuring maildir worker: %v", err) + logging.Errorf("error configuring maildir worker: %v", err) return err } dir := u.Path @@ -317,13 +318,13 @@ func (w *Worker) handleConfigure(msg *types.Configure) error { if len(dir) == 0 { return fmt.Errorf("could not resolve maildir from URL '%s'", msg.Config.Source) } - c, err := NewContainer(dir, w.worker.Logger, w.maildirpp) + c, err := NewContainer(dir, w.maildirpp) if err != nil { - w.worker.Logger.Printf("could not configure maildir: %s", dir) + logging.Errorf("could not configure maildir: %s", dir) return err } w.c = c - w.worker.Logger.Printf("configured base maildir: %s", dir) + logging.Infof("configured base maildir: %s", dir) return nil } @@ -340,7 +341,7 @@ func (w *Worker) handleListDirectories(msg *types.ListDirectories) error { } dirs, err := w.c.ListFolders() if err != nil { - w.worker.Logger.Printf("error listing directories: %v", err) + logging.Errorf("failed listing directories: %v", err) return err } for _, name := range dirs { @@ -360,7 +361,7 @@ func (w *Worker) handleListDirectories(msg *types.ListDirectories) error { } func (w *Worker) handleOpenDirectory(msg *types.OpenDirectory) error { - w.worker.Logger.Printf("opening %s", msg.Directory) + logging.Infof("opening %s", msg.Directory) // open the directory dir, err := w.c.OpenDirectory(msg.Directory) @@ -422,13 +423,13 @@ func (w *Worker) handleFetchDirectoryContents( } else { uids, err = w.c.UIDs(*w.selected) if err != nil { - w.worker.Logger.Printf("error scanning uids: %v", err) + logging.Errorf("failed scanning uids: %v", err) return err } } sortedUids, err := w.sort(uids, msg.SortCriteria) if err != nil { - w.worker.Logger.Printf("error sorting directory: %v", err) + logging.Errorf("failed sorting directory: %v", err) return err } w.currentSortCriteria = msg.SortCriteria @@ -447,14 +448,14 @@ func (w *Worker) sort(uids []uint32, criteria []*types.SortCriterion) ([]uint32, for _, uid := range uids { info, err := w.msgInfoFromUid(uid) if err != nil { - w.worker.Logger.Printf("could not get message info: %v", err) + logging.Errorf("could not get message info: %v", err) continue } msgInfos = append(msgInfos, info) } sortedUids, err := lib.Sort(msgInfos, criteria) if err != nil { - w.worker.Logger.Printf("could not sort the messages: %v", err) + logging.Errorf("could not sort the messages: %v", err) return nil, err } return sortedUids, nil @@ -463,7 +464,7 @@ func (w *Worker) sort(uids []uint32, criteria []*types.SortCriterion) ([]uint32, func (w *Worker) handleCreateDirectory(msg *types.CreateDirectory) error { dir := w.c.Dir(msg.Directory) if err := dir.Init(); err != nil { - w.worker.Logger.Printf("could not create directory %s: %v", + logging.Errorf("could not create directory %s: %v", msg.Directory, err) return err } @@ -473,7 +474,7 @@ func (w *Worker) handleCreateDirectory(msg *types.CreateDirectory) error { func (w *Worker) handleRemoveDirectory(msg *types.RemoveDirectory) error { dir := w.c.Dir(msg.Directory) if err := os.RemoveAll(string(dir)); err != nil { - w.worker.Logger.Printf("could not remove directory %s: %v", + logging.Errorf("could not remove directory %s: %v", msg.Directory, err) return err } @@ -485,7 +486,7 @@ func (w *Worker) handleFetchMessageHeaders( for _, uid := range msg.Uids { info, err := w.msgInfoFromUid(uid) if err != nil { - w.worker.Logger.Printf("could not get message info: %v", err) + logging.Errorf("could not get message info: %v", err) w.err(msg, err) continue } @@ -504,12 +505,12 @@ func (w *Worker) handleFetchMessageBodyPart( // get reader m, err := w.c.Message(*w.selected, msg.Uid) if err != nil { - w.worker.Logger.Printf("could not get message %d: %v", msg.Uid, err) + logging.Errorf("could not get message %d: %v", msg.Uid, err) return err } r, err := m.NewBodyPartReader(msg.Part) if err != nil { - w.worker.Logger.Printf( + logging.Errorf( "could not get body part reader for message=%d, parts=%#v: %v", msg.Uid, msg.Part, err) return err @@ -529,12 +530,12 @@ func (w *Worker) handleFetchFullMessages(msg *types.FetchFullMessages) error { for _, uid := range msg.Uids { m, err := w.c.Message(*w.selected, uid) if err != nil { - w.worker.Logger.Printf("could not get message %d: %v", uid, err) + logging.Errorf("could not get message %d: %v", uid, err) return err } r, err := m.NewReader() if err != nil { - w.worker.Logger.Printf("could not get message reader: %v", err) + logging.Errorf("could not get message reader: %v", err) return err } defer r.Close() @@ -565,7 +566,7 @@ func (w *Worker) handleDeleteMessages(msg *types.DeleteMessages) error { }, nil) } if err != nil { - w.worker.Logger.Printf("error removing some messages: %v", err) + logging.Errorf("failed removing messages: %v", err) return err } return nil @@ -575,19 +576,18 @@ func (w *Worker) handleAnsweredMessages(msg *types.AnsweredMessages) error { for _, uid := range msg.Uids { m, err := w.c.Message(*w.selected, uid) if err != nil { - w.worker.Logger.Printf("could not get message: %v", err) + logging.Errorf("could not get message: %v", err) w.err(msg, err) continue } if err := m.MarkReplied(msg.Answered); err != nil { - w.worker.Logger.Printf( - "could not mark message as answered: %v", err) + logging.Errorf("could not mark message as answered: %v", err) w.err(msg, err) continue } info, err := m.MessageInfo() if err != nil { - w.worker.Logger.Printf("could not get message info: %v", err) + logging.Errorf("could not get message info: %v", err) w.err(msg, err) continue } @@ -608,19 +608,19 @@ func (w *Worker) handleFlagMessages(msg *types.FlagMessages) error { for _, uid := range msg.Uids { m, err := w.c.Message(*w.selected, uid) if err != nil { - w.worker.Logger.Printf("could not get message: %v", err) + logging.Errorf("could not get message: %v", err) w.err(msg, err) continue } flag := flagToMaildir[msg.Flag] if err := m.SetOneFlag(flag, msg.Enable); err != nil { - w.worker.Logger.Printf("could change flag %v to %v on message: %v", flag, msg.Enable, err) + logging.Errorf("could change flag %v to %v on message: %v", flag, msg.Enable, err) w.err(msg, err) continue } info, err := m.MessageInfo() if err != nil { - w.worker.Logger.Printf("could not get message info: %v", err) + logging.Errorf("could not get message info: %v", err) w.err(msg, err) continue } @@ -657,13 +657,12 @@ func (w *Worker) handleAppendMessage(msg *types.AppendMessage) error { dest := w.c.Dir(msg.Destination) _, writer, err := dest.Create(translateFlags(msg.Flags)) if err != nil { - w.worker.Logger.Printf("could not create message at %s: %v", - msg.Destination, err) + logging.Errorf("could not create message at %s: %v", msg.Destination, err) return err } defer writer.Close() if _, err := io.Copy(writer, msg.Reader); err != nil { - w.worker.Logger.Printf("could not write message to destination: %v", err) + logging.Errorf("could not write message to destination: %v", err) return err } w.worker.PostMessage(&types.Done{ @@ -676,12 +675,12 @@ func (w *Worker) handleAppendMessage(msg *types.AppendMessage) error { } func (w *Worker) handleSearchDirectory(msg *types.SearchDirectory) error { - w.worker.Logger.Printf("Searching directory %v with args: %v", *w.selected, msg.Argv) + logging.Infof("Searching directory %v with args: %v", *w.selected, msg.Argv) criteria, err := parseSearch(msg.Argv) if err != nil { return err } - w.worker.Logger.Printf("Searching with parsed criteria: %#v", criteria) + logging.Infof("Searching with parsed criteria: %#v", criteria) uids, err := w.search(criteria) if err != nil { return err diff --git a/worker/mbox/worker.go b/worker/mbox/worker.go index c7f105b..4c0a127 100644 --- a/worker/mbox/worker.go +++ b/worker/mbox/worker.go @@ -9,6 +9,7 @@ import ( "path/filepath" "sort" + "git.sr.ht/~rjarry/aerc/logging" "git.sr.ht/~rjarry/aerc/models" "git.sr.ht/~rjarry/aerc/worker/handlers" "git.sr.ht/~rjarry/aerc/worker/lib" @@ -68,7 +69,7 @@ func (w *mboxWorker) handleMessage(msg types.WorkerMessage) error { reterr = err break } else { - w.worker.Logger.Printf("mbox: configured with mbox file %s", dir) + logging.Infof("configured with mbox file %s", dir) } case *types.Connect, *types.Reconnect, *types.Disconnect: @@ -104,19 +105,19 @@ func (w *mboxWorker) handleMessage(msg types.WorkerMessage) error { Info: w.data.DirectoryInfo(msg.Directory), }, nil) w.worker.PostMessage(&types.Done{Message: types.RespondTo(msg)}, nil) - w.worker.Logger.Printf("mbox: %s opened\n", msg.Directory) + logging.Infof("%s opened", msg.Directory) case *types.FetchDirectoryContents: var infos []*models.MessageInfo for _, uid := range w.folder.Uids() { m, err := w.folder.Message(uid) if err != nil { - w.worker.Logger.Println("mbox: could not get message", err) + logging.Errorf("could not get message %v", err) continue } info, err := lib.MessageInfo(m) if err != nil { - w.worker.Logger.Println("mbox: could not get message info", err) + logging.Errorf("could not get message info %v", err) continue } infos = append(infos, info) @@ -174,7 +175,7 @@ func (w *mboxWorker) handleMessage(msg types.WorkerMessage) error { case *types.FetchMessageBodyPart: m, err := w.folder.Message(msg.Uid) if err != nil { - w.worker.Logger.Printf("could not get message %d: %v", msg.Uid, err) + logging.Errorf("could not get message %d: %v", msg.Uid, err) reterr = err break } @@ -193,7 +194,7 @@ func (w *mboxWorker) handleMessage(msg types.WorkerMessage) error { r, err := lib.FetchEntityPartReader(fullMsg, msg.Part) if err != nil { - w.worker.Logger.Printf( + logging.Errorf( "could not get body part reader for message=%d, parts=%#v: %v", msg.Uid, msg.Part, err) reterr = err @@ -212,18 +213,18 @@ func (w *mboxWorker) handleMessage(msg types.WorkerMessage) error { for _, uid := range msg.Uids { m, err := w.folder.Message(uid) if err != nil { - w.worker.Logger.Printf("could not get message for uid %d: %v", uid, err) + logging.Errorf("could not get message for uid %d: %v", uid, err) continue } r, err := m.NewReader() if err != nil { - w.worker.Logger.Printf("could not get message reader: %v", err) + logging.Errorf("could not get message reader: %v", err) continue } defer r.Close() b, err := ioutil.ReadAll(r) if err != nil { - w.worker.Logger.Printf("could not get message reader: %v", err) + logging.Errorf("could not get message reader: %v", err) continue } w.worker.PostMessage(&types.FullMessage{ @@ -258,16 +259,16 @@ func (w *mboxWorker) handleMessage(msg types.WorkerMessage) error { for _, uid := range msg.Uids { m, err := w.folder.Message(uid) if err != nil { - w.worker.Logger.Printf("could not get message: %v", err) + logging.Errorf("could not get message: %v", err) continue } if err := m.(*message).SetFlag(msg.Flag, msg.Enable); err != nil { - w.worker.Logger.Printf("could change flag %v to %v on message: %v", msg.Flag, msg.Enable, err) + logging.Errorf("could change flag %v to %t on message: %v", msg.Flag, msg.Enable, err) continue } info, err := lib.MessageInfo(m) if err != nil { - w.worker.Logger.Printf("could not get message info: %v", err) + logging.Errorf("could not get message info: %v", err) continue } @@ -308,12 +309,12 @@ func (w *mboxWorker) handleMessage(msg types.WorkerMessage) error { reterr = err break } - w.worker.Logger.Printf("Searching with parsed criteria: %#v", criteria) + logging.Infof("Searching with parsed criteria: %#v", criteria) m := make([]lib.RawMessage, 0, len(w.folder.Uids())) for _, uid := range w.folder.Uids() { msg, err := w.folder.Message(uid) if err != nil { - w.worker.Logger.Println("faild to get message for uid:", uid) + logging.Errorf("failed to get message for uid: %d", uid) continue } m = append(m, msg) diff --git a/worker/notmuch/eventhandlers.go b/worker/notmuch/eventhandlers.go index 3daabda..4eec1f6 100644 --- a/worker/notmuch/eventhandlers.go +++ b/worker/notmuch/eventhandlers.go @@ -3,6 +3,8 @@ package notmuch +import "git.sr.ht/~rjarry/aerc/logging" + func (w *worker) handleNotmuchEvent(et eventType) error { switch ev := et.(type) { case *updateDirCounts: @@ -16,7 +18,7 @@ func (w *worker) handleUpdateDirCounts(ev eventType) error { for name, query := range w.nameQueryMap { info, err := w.gatherDirectoryInfo(name, query) if err != nil { - w.w.Logger.Printf("could not gather DirectoryInfo: %v\n", err) + logging.Errorf("could not gather DirectoryInfo: %v", err) continue } w.w.PostMessage(info, nil) diff --git a/worker/notmuch/lib/database.go b/worker/notmuch/lib/database.go index 670130f..801f122 100644 --- a/worker/notmuch/lib/database.go +++ b/worker/notmuch/lib/database.go @@ -5,10 +5,10 @@ package lib import ( "fmt" - "log" "time" "git.sr.ht/~rjarry/aerc/lib/uidstore" + "git.sr.ht/~rjarry/aerc/logging" "git.sr.ht/~rjarry/aerc/worker/types" notmuch "github.com/zenhack/go.notmuch" ) @@ -18,18 +18,15 @@ const MAX_DB_AGE time.Duration = 10 * time.Second type DB struct { path string excludedTags []string - logger *log.Logger lastOpenTime time.Time db *notmuch.DB uidStore *uidstore.Store } -func NewDB(path string, excludedTags []string, - logger *log.Logger) *DB { +func NewDB(path string, excludedTags []string) *DB { db := &DB{ path: path, excludedTags: excludedTags, - logger: logger, uidStore: uidstore.NewStore(), } return db @@ -71,11 +68,11 @@ func (db *DB) withConnection(writable bool, cb func(*notmuch.DB) error) error { too_old := time.Now().After(db.lastOpenTime.Add(MAX_DB_AGE)) if db.db == nil || writable || too_old { if cerr := db.close(); cerr != nil { - db.logger.Printf("failed to close the notmuch db: %v", cerr) + logging.Errorf("failed to close the notmuch db: %v", cerr) } err := db.connect(writable) if err != nil { - db.logger.Printf("failed to open the notmuch db: %v", err) + logging.Errorf("failed to open the notmuch db: %v", err) return err } } @@ -83,7 +80,7 @@ func (db *DB) withConnection(writable bool, cb func(*notmuch.DB) error) error { if writable { // we need to close to commit the changes, else we block others if cerr := db.close(); cerr != nil { - db.logger.Printf("failed to close the notmuch db: %v", cerr) + logging.Errorf("failed to close the notmuch db: %v", cerr) } } return err @@ -239,7 +236,7 @@ func (db *DB) msgModify(key string, cb(msg) err = msg.TagsToMaildirFlags() if err != nil { - db.logger.Printf("could not sync maildir flags: %v", err) + logging.Errorf("could not sync maildir flags: %v", err) } return nil }) diff --git a/worker/notmuch/worker.go b/worker/notmuch/worker.go index 27be73d..6941809 100644 --- a/worker/notmuch/worker.go +++ b/worker/notmuch/worker.go @@ -65,18 +65,18 @@ func (w *worker) Run() { w.w.PostMessage(&types.Unsupported{ Message: types.RespondTo(msg), }, nil) - w.w.Logger.Printf("ProcessAction(%T) unsupported: %v", msg, err) + logging.Errorf("ProcessAction(%T) unsupported: %v", msg, err) } else if err != nil { w.w.PostMessage(&types.Error{ Message: types.RespondTo(msg), Error: err, }, nil) - w.w.Logger.Printf("ProcessAction(%T) failure: %v", msg, err) + logging.Errorf("ProcessAction(%T) failure: %v", msg, err) } case nmEvent := <-w.nmEvents: err := w.handleNotmuchEvent(nmEvent) if err != nil { - w.w.Logger.Printf("notmuch event failure: %v", err) + logging.Errorf("notmuch event failure: %v", err) } } } @@ -161,7 +161,7 @@ func (w *worker) handleConfigure(msg *types.Configure) error { u, err := url.Parse(msg.Config.Source) if err != nil { - w.w.Logger.Printf("error configuring notmuch worker: %v", err) + logging.Errorf("error configuring notmuch worker: %v", err) return err } home, err := homedir.Expand(u.Hostname()) @@ -174,7 +174,7 @@ func (w *worker) handleConfigure(msg *types.Configure) error { return fmt.Errorf("could not load query map configuration: %v", err) } excludedTags := w.loadExcludeTags(msg.Config) - w.db = notmuch.NewDB(pathToDB, excludedTags, w.w.Logger) + w.db = notmuch.NewDB(pathToDB, excludedTags) return nil } @@ -260,7 +260,7 @@ func (w *worker) queryFromName(name string) string { } func (w *worker) handleOpenDirectory(msg *types.OpenDirectory) error { - w.w.Logger.Printf("opening %s", msg.Directory) + logging.Infof("opening %s", msg.Directory) // try the friendly name first, if that fails assume it's a query w.query = w.queryFromName(msg.Directory) w.currentQueryName = msg.Directory @@ -301,13 +301,13 @@ func (w *worker) handleFetchMessageHeaders( for _, uid := range msg.Uids { m, err := w.msgFromUid(uid) if err != nil { - w.w.Logger.Printf("could not get message: %v", err) + logging.Errorf("could not get message: %v", err) w.err(msg, err) continue } err = w.emitMessageInfo(m, msg) if err != nil { - w.w.Logger.Printf(err.Error()) + logging.Errorf("could not emit message info: %v", err) w.err(msg, err) continue } @@ -348,12 +348,12 @@ func (w *worker) handleFetchMessageBodyPart( m, err := w.msgFromUid(msg.Uid) if err != nil { - w.w.Logger.Printf("could not get message %d: %v", msg.Uid, err) + logging.Errorf("could not get message %d: %v", msg.Uid, err) return err } r, err := m.NewBodyPartReader(msg.Part) if err != nil { - w.w.Logger.Printf( + logging.Errorf( "could not get body part reader for message=%d, parts=%#v: %v", msg.Uid, msg.Part, err) return err @@ -374,12 +374,12 @@ func (w *worker) handleFetchFullMessages(msg *types.FetchFullMessages) error { for _, uid := range msg.Uids { m, err := w.msgFromUid(uid) if err != nil { - w.w.Logger.Printf("could not get message %d: %v", uid, err) + logging.Errorf("could not get message %d: %v", uid, err) return err } r, err := m.NewReader() if err != nil { - w.w.Logger.Printf("could not get message reader: %v", err) + logging.Errorf("could not get message reader: %v", err) return err } defer r.Close() @@ -403,24 +403,24 @@ func (w *worker) handleAnsweredMessages(msg *types.AnsweredMessages) error { for _, uid := range msg.Uids { m, err := w.msgFromUid(uid) if err != nil { - w.w.Logger.Printf("could not get message: %v", err) + logging.Errorf("could not get message: %v", err) w.err(msg, err) continue } if err := m.MarkAnswered(msg.Answered); err != nil { - w.w.Logger.Printf("could not mark message as answered: %v", err) + logging.Errorf("could not mark message as answered: %v", err) w.err(msg, err) continue } err = w.emitMessageInfo(m, msg) if err != nil { - w.w.Logger.Printf(err.Error()) + logging.Errorf("could not emit message info: %v", err) w.err(msg, err) continue } } if err := w.emitDirectoryInfo(w.currentQueryName); err != nil { - w.w.Logger.Printf(err.Error()) + logging.Errorf("could not emit directory info: %v", err) } w.done(msg) return nil @@ -430,24 +430,24 @@ func (w *worker) handleFlagMessages(msg *types.FlagMessages) error { for _, uid := range msg.Uids { m, err := w.msgFromUid(uid) if err != nil { - w.w.Logger.Printf("could not get message: %v", err) + logging.Errorf("could not get message: %v", err) w.err(msg, err) continue } if err := m.SetFlag(msg.Flag, msg.Enable); err != nil { - w.w.Logger.Printf("could not set flag %v as %v for message: %v", msg.Flag, msg.Enable, err) + logging.Errorf("could not set flag %v as %t for message: %v", msg.Flag, msg.Enable, err) w.err(msg, err) continue } err = w.emitMessageInfo(m, msg) if err != nil { - w.w.Logger.Printf(err.Error()) + logging.Errorf("could not emit message info: %v", err) w.err(msg, err) continue } } if err := w.emitDirectoryInfo(w.currentQueryName); err != nil { - w.w.Logger.Printf(err.Error()) + logging.Errorf("could not emit directory info: %v", err) } w.done(msg) return nil @@ -476,7 +476,7 @@ func (w *worker) handleModifyLabels(msg *types.ModifyLabels) error { for _, uid := range msg.Uids { m, err := w.msgFromUid(uid) if err != nil { - return fmt.Errorf("could not get message from uid %v: %v", uid, err) + return fmt.Errorf("could not get message from uid %d: %v", uid, err) } err = m.ModifyTags(msg.Add, msg.Remove) if err != nil { @@ -496,7 +496,7 @@ func (w *worker) handleModifyLabels(msg *types.ModifyLabels) error { // and update the list of possible tags w.emitLabelList() if err = w.emitDirectoryInfo(w.currentQueryName); err != nil { - w.w.Logger.Printf(err.Error()) + logging.Errorf("could not emit directory info: %v", err) } w.done(msg) return nil @@ -563,7 +563,7 @@ func (w *worker) emitDirectoryContents(parent types.WorkerMessage) error { } sortedUids, err := w.sort(uids, w.currentSortCriteria) if err != nil { - w.w.Logger.Printf("error sorting directory: %v", err) + logging.Errorf("error sorting directory: %v", err) return err } w.w.PostMessage(&types.DirectoryContents{ @@ -607,7 +607,7 @@ func (w *worker) emitMessageInfo(m *Message, func (w *worker) emitLabelList() { tags, err := w.db.ListTags() if err != nil { - w.w.Logger.Printf("could not load tags: %v", err) + logging.Errorf("could not load tags: %v", err) return } w.w.PostMessage(&types.LabelList{Labels: tags}, nil) @@ -622,19 +622,19 @@ func (w *worker) sort(uids []uint32, for _, uid := range uids { m, err := w.msgFromUid(uid) if err != nil { - w.w.Logger.Printf("could not get message: %v", err) + logging.Errorf("could not get message: %v", err) continue } info, err := m.MessageInfo() if err != nil { - w.w.Logger.Printf("could not get message info: %v", err) + logging.Errorf("could not get message info: %v", err) continue } msgInfos = append(msgInfos, info) } sortedUids, err := lib.Sort(msgInfos, criteria) if err != nil { - w.w.Logger.Printf("could not sort the messages: %v", err) + logging.Errorf("could not sort the messages: %v", err) return nil, err } return sortedUids, nil diff --git a/worker/types/worker.go b/worker/types/worker.go index 85c19f1..8f179df 100644 --- a/worker/types/worker.go +++ b/worker/types/worker.go @@ -1,8 +1,9 @@ package types import ( - "log" "sync/atomic" + + "git.sr.ht/~rjarry/aerc/logging" ) var lastId int64 = 1 // access via atomic @@ -15,17 +16,15 @@ type Worker struct { Backend Backend Actions chan WorkerMessage Messages chan WorkerMessage - Logger *log.Logger actionCallbacks map[int64]func(msg WorkerMessage) messageCallbacks map[int64]func(msg WorkerMessage) } -func NewWorker(logger *log.Logger) *Worker { +func NewWorker() *Worker { return &Worker{ Actions: make(chan WorkerMessage, 50), Messages: make(chan WorkerMessage, 50), - Logger: logger, actionCallbacks: make(map[int64]func(msg WorkerMessage)), messageCallbacks: make(map[int64]func(msg WorkerMessage)), } @@ -36,15 +35,14 @@ func (worker *Worker) setId(msg WorkerMessage) { msg.setId(id) } -func (worker *Worker) PostAction(msg WorkerMessage, - cb func(msg WorkerMessage)) { +func (worker *Worker) PostAction(msg WorkerMessage, cb func(msg WorkerMessage)) { worker.setId(msg) if resp := msg.InResponseTo(); resp != nil { - worker.Logger.Printf("(ui)=> %T:%T\n", msg, resp) + logging.Debugf("PostAction %T:%T", msg, resp) } else { - worker.Logger.Printf("(ui)=> %T\n", msg) + logging.Debugf("PostAction %T", msg) } worker.Actions <- msg @@ -59,9 +57,9 @@ func (worker *Worker) PostMessage(msg WorkerMessage, worker.setId(msg) if resp := msg.InResponseTo(); resp != nil { - worker.Logger.Printf("->(ui) %T:%T\n", msg, resp) + logging.Debugf("PostMessage %T:%T", msg, resp) } else { - worker.Logger.Printf("->(ui) %T\n", msg) + logging.Debugf("PostMessage %T", msg) } worker.Messages <- msg @@ -72,10 +70,9 @@ func (worker *Worker) PostMessage(msg WorkerMessage, func (worker *Worker) ProcessMessage(msg WorkerMessage) WorkerMessage { if resp := msg.InResponseTo(); resp != nil { - worker.Logger.Printf("(ui)<= %T(%d):%T(%d)\n", - msg, msg.getId(), resp, resp.getId()) + logging.Debugf("ProcessMessage %T(%d):%T(%d)", msg, msg.getId(), resp, resp.getId()) } else { - worker.Logger.Printf("(ui)<= %T(%d)\n", msg, msg.getId()) + logging.Debugf("ProcessMessage %T(%d)", msg, msg.getId()) } if inResponseTo := msg.InResponseTo(); inResponseTo != nil { if f, ok := worker.actionCallbacks[inResponseTo.getId()]; ok { @@ -90,10 +87,9 @@ func (worker *Worker) ProcessMessage(msg WorkerMessage) WorkerMessage { func (worker *Worker) ProcessAction(msg WorkerMessage) WorkerMessage { if resp := msg.InResponseTo(); resp != nil { - worker.Logger.Printf("<-(ui) %T(%d):%T(%d)\n", - msg, msg.getId(), resp, resp.getId()) + logging.Debugf("ProcessAction %T(%d):%T(%d)", msg, msg.getId(), resp, resp.getId()) } else { - worker.Logger.Printf("<-(ui) %T(%d)\n", msg, msg.getId()) + logging.Debugf("ProcessAction %T(%d)", msg, msg.getId()) } if inResponseTo := msg.InResponseTo(); inResponseTo != nil { if f, ok := worker.messageCallbacks[inResponseTo.getId()]; ok { diff --git a/worker/worker.go b/worker/worker.go index f65f0e3..2af892c 100644 --- a/worker/worker.go +++ b/worker/worker.go @@ -1,8 +1,6 @@ package worker import ( - "fmt" - "log" "net/url" "strings" @@ -11,16 +9,15 @@ import ( ) // Guesses the appropriate worker type based on the given source string -func NewWorker(source string, logger *log.Logger) (*types.Worker, error) { +func NewWorker(source string) (*types.Worker, error) { u, err := url.Parse(source) if err != nil { return nil, err } - worker := types.NewWorker(logger) + worker := types.NewWorker() scheme := u.Scheme if strings.ContainsRune(scheme, '+') { scheme = scheme[:strings.IndexRune(scheme, '+')] - fmt.Println(scheme) } backend, err := handlers.GetHandlerForScheme(scheme, worker) if err != nil {